|
| 1 | +/******************************************************************************* |
| 2 | + * Copyright (c) 2022 - 2025 NVIDIA Corporation & Affiliates. * |
| 3 | + * All rights reserved. * |
| 4 | + * * |
| 5 | + * This source code and the accompanying materials are made available under * |
| 6 | + * the terms of the Apache License 2.0 which accompanies this distribution. * |
| 7 | + ******************************************************************************/ |
| 8 | + |
| 9 | +// RUN: cudaq-quake %cpp_std %s | cudaq-opt -memtoreg=quantum=0 -canonicalize | FileCheck %s |
| 10 | + |
| 11 | +#include <cudaq.h> |
| 12 | + |
| 13 | +std::vector<bool> func_achat(cudaq::qview<> &qv) __qpu__ { |
| 14 | + // measure the entire register |
| 15 | + return mz(qv); |
| 16 | +} |
| 17 | + |
| 18 | +// CHECK-LABEL: func.func @__nvqpp__mlirgen__function_func_achat._Z10func_achatRN5cudaq5qviewILm2EEE( |
| 19 | +// CHECK-SAME: %[[VAL_0:.*]]: !quake.veq<?>) -> !cc.stdvec<i1> attributes {"cudaq-kernel", no_this} { |
| 20 | +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 |
| 21 | +// CHECK: %[[VAL_2:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<?>) -> !cc.stdvec<!quake.measure> |
| 22 | +// CHECK: %[[VAL_3:.*]] = quake.discriminate %[[VAL_2]] : (!cc.stdvec<!quake.measure>) -> !cc.stdvec<i1> |
| 23 | +// CHECK: %[[VAL_4:.*]] = cc.stdvec_data %[[VAL_3]] : (!cc.stdvec<i1>) -> !cc.ptr<i8> |
| 24 | +// CHECK: %[[VAL_5:.*]] = cc.stdvec_size %[[VAL_3]] : (!cc.stdvec<i1>) -> i64 |
| 25 | +// CHECK: %[[VAL_6:.*]] = call @__nvqpp_vectorCopyCtor(%[[VAL_4]], %[[VAL_5]], %[[VAL_1]]) : (!cc.ptr<i8>, i64, i64) -> !cc.ptr<i8> |
| 26 | +// CHECK: %[[VAL_7:.*]] = cc.stdvec_init %[[VAL_6]], %[[VAL_5]] : (!cc.ptr<i8>, i64) -> !cc.stdvec<i1> |
| 27 | +// CHECK: return %[[VAL_7]] : !cc.stdvec<i1> |
| 28 | +// CHECK: } |
| 29 | + |
| 30 | +int func_shiim(cudaq::qvector<> &qv) __qpu__ { |
| 31 | + auto vs = qv.slice(1, 3); |
| 32 | + auto bs = func_achat(vs); |
| 33 | + int i; |
| 34 | + for (auto b : bs) { |
| 35 | + if (b) |
| 36 | + ++i; |
| 37 | + } |
| 38 | + return i; |
| 39 | +} |
| 40 | + |
| 41 | +// CHECK-LABEL: func.func @__nvqpp__mlirgen__function_func_shiim._Z10func_shiimRN5cudaq7qvectorILm2EEE( |
| 42 | +// CHECK-SAME: %[[VAL_0:.*]]: !quake.veq<?>) -> i32 attributes |
| 43 | +// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 1 : i64 |
| 44 | +// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 0 : i64 |
| 45 | +// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 1 : i32 |
| 46 | +// CHECK: %[[VAL_4:.*]] = quake.subveq %[[VAL_0]], 1, 3 : (!quake.veq<?>) -> !quake.veq<3> |
| 47 | +// CHECK: %[[VAL_5:.*]] = quake.relax_size %[[VAL_4]] : (!quake.veq<3>) -> !quake.veq<?> |
| 48 | +// CHECK: %[[VAL_6:.*]] = call @__nvqpp__mlirgen__function_func_achat._Z10func_achatRN5cudaq5qviewILm2EEE(%[[VAL_5]]) : (!quake.veq<?>) -> !cc.stdvec<i1> |
| 49 | +// CHECK: %[[VAL_7:.*]] = cc.stdvec_data %[[VAL_6]] : (!cc.stdvec<i1>) -> !cc.ptr<i8> |
| 50 | +// CHECK: %[[VAL_8:.*]] = cc.stdvec_size %[[VAL_6]] : (!cc.stdvec<i1>) -> i64 |
| 51 | +// CHECK: %[[VAL_9:.*]] = cc.alloca i8{{\[}}%[[VAL_8]] : i64] |
| 52 | +// CHECK: %[[VAL_10:.*]] = cc.cast %[[VAL_9]] : (!cc.ptr<!cc.array<i8 x ?>>) -> !cc.ptr<i8> |
| 53 | +// CHECK: call @__nvqpp_vectorCopyToStack(%[[VAL_10]], %[[VAL_7]], %[[VAL_8]]) : (!cc.ptr<i8>, !cc.ptr<i8>, i64) -> () |
| 54 | +// CHECK: %[[VAL_11:.*]] = cc.undef i32 |
| 55 | +// CHECK: %[[VAL_12:.*]] = cc.cast %[[VAL_9]] : (!cc.ptr<!cc.array<i8 x ?>>) -> !cc.ptr<!cc.array<i1 x ?>> |
| 56 | +// CHECK: %[[VAL_13:.*]]:2 = cc.loop while ((%[[VAL_14:.*]] = %[[VAL_2]], %[[VAL_15:.*]] = %[[VAL_11]]) -> (i64, i32)) { |
| 57 | +// CHECK: %[[VAL_16:.*]] = arith.cmpi slt, %[[VAL_14]], %[[VAL_8]] : i64 |
| 58 | +// CHECK: cc.condition %[[VAL_16]](%[[VAL_14]], %[[VAL_15]] : i64, i32) |
| 59 | +// CHECK: } do { |
| 60 | +// CHECK: ^bb0(%[[VAL_17:.*]]: i64, %[[VAL_18:.*]]: i32): |
| 61 | +// CHECK: %[[VAL_19:.*]] = cc.compute_ptr %[[VAL_12]]{{\[}}%[[VAL_17]]] : (!cc.ptr<!cc.array<i1 x ?>>, i64) -> !cc.ptr<i1> |
| 62 | +// CHECK: %[[VAL_20:.*]] = cc.load %[[VAL_19]] : !cc.ptr<i1> |
| 63 | +// CHECK: %[[VAL_21:.*]] = cc.if(%[[VAL_20]]) -> i32 { |
| 64 | +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_18]], %[[VAL_3]] : i32 |
| 65 | +// CHECK: cc.continue %[[VAL_22]] : i32 |
| 66 | +// CHECK: } else { |
| 67 | +// CHECK: cc.continue %[[VAL_18]] : i32 |
| 68 | +// CHECK: } |
| 69 | +// CHECK: cc.continue %[[VAL_17]], %[[VAL_23:.*]] : i64, i32 |
| 70 | +// CHECK: } step { |
| 71 | +// CHECK: ^bb0(%[[VAL_24:.*]]: i64, %[[VAL_25:.*]]: i32): |
| 72 | +// CHECK: %[[VAL_26:.*]] = arith.addi %[[VAL_24]], %[[VAL_1]] : i64 |
| 73 | +// CHECK: cc.continue %[[VAL_26]], %[[VAL_25]] : i64, i32 |
| 74 | +// CHECK: } {invariant} |
| 75 | +// CHECK: return %[[VAL_27:.*]]#1 : i32 |
| 76 | +// CHECK: } |
| 77 | + |
| 78 | +bool func_shlosh(cudaq::qvector<> &qv) __qpu__ { |
| 79 | + auto i = func_shiim(qv); |
| 80 | + return i; |
| 81 | +} |
| 82 | + |
| 83 | +// CHECK-LABEL: func.func @__nvqpp__mlirgen__function_func_shlosh._Z11func_shloshRN5cudaq7qvectorILm2EEE( |
| 84 | +// CHECK-SAME: %[[VAL_0:.*]]: !quake.veq<?>) -> i1 attributes {"cudaq-kernel", no_this} { |
| 85 | +// CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32 |
| 86 | +// CHECK: %[[VAL_2:.*]] = call @__nvqpp__mlirgen__function_func_shiim._Z10func_shiimRN5cudaq7qvectorILm2EEE(%[[VAL_0]]) : (!quake.veq<?>) -> i32 |
| 87 | +// CHECK: %[[VAL_3:.*]] = arith.cmpi ne, %[[VAL_2]], %[[VAL_1]] : i32 |
| 88 | +// CHECK: return %[[VAL_3]] : i1 |
| 89 | +// CHECK: } |
| 90 | + |
| 91 | +void func_arba() __qpu__ { |
| 92 | + cudaq::qvector qv(10); |
| 93 | + z(qv); |
| 94 | + auto b = func_shlosh(qv); |
| 95 | + if (b) |
| 96 | + h(qv); |
| 97 | + x(qv); |
| 98 | + h(qv); |
| 99 | +} |
| 100 | + |
| 101 | +// CHECK-LABEL: func.func @__nvqpp__mlirgen__function_func_arba._Z9func_arbav() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { |
| 102 | +// CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : i64 |
| 103 | +// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 1 : i64 |
| 104 | +// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 0 : i64 |
| 105 | +// CHECK-DAG: %[[VAL_3:.*]] = quake.alloca !quake.veq<10> |
| 106 | +// CHECK: %[[VAL_4:.*]] = quake.relax_size %[[VAL_3]] : (!quake.veq<10>) -> !quake.veq<?> |
| 107 | +// CHECK: %[[VAL_5:.*]] = cc.loop while ((%[[VAL_6:.*]] = %[[VAL_2]]) -> (i64)) { |
| 108 | +// CHECK: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_0]] : i64 |
| 109 | +// CHECK: cc.condition %[[VAL_7]](%[[VAL_6]] : i64) |
| 110 | +// CHECK: } do { |
| 111 | +// CHECK: ^bb0(%[[VAL_8:.*]]: i64): |
| 112 | +// CHECK: %[[VAL_9:.*]] = quake.extract_ref %[[VAL_3]]{{\[}}%[[VAL_8]]] : (!quake.veq<10>, i64) -> !quake.ref |
| 113 | +// CHECK: quake.z %[[VAL_9]] : (!quake.ref) -> () |
| 114 | +// CHECK: cc.continue %[[VAL_8]] : i64 |
| 115 | +// CHECK: } step { |
| 116 | +// CHECK: ^bb0(%[[VAL_10:.*]]: i64): |
| 117 | +// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_10]], %[[VAL_1]] : i64 |
| 118 | +// CHECK: cc.continue %[[VAL_11]] : i64 |
| 119 | +// CHECK: } {invariant} |
| 120 | +// CHECK: %[[VAL_12:.*]] = call @__nvqpp__mlirgen__function_func_shlosh._Z11func_shloshRN5cudaq7qvectorILm2EEE(%[[VAL_4]]) : (!quake.veq<?>) -> i1 |
| 121 | +// CHECK: cc.if(%[[VAL_12]]) { |
| 122 | +// CHECK: %[[VAL_13:.*]] = cc.loop while ((%[[VAL_14:.*]] = %[[VAL_2]]) -> (i64)) { |
| 123 | +// CHECK: %[[VAL_15:.*]] = arith.cmpi slt, %[[VAL_14]], %[[VAL_0]] : i64 |
| 124 | +// CHECK: cc.condition %[[VAL_15]](%[[VAL_14]] : i64) |
| 125 | +// CHECK: } do { |
| 126 | +// CHECK: ^bb0(%[[VAL_16:.*]]: i64): |
| 127 | +// CHECK: %[[VAL_17:.*]] = quake.extract_ref %[[VAL_3]]{{\[}}%[[VAL_16]]] : (!quake.veq<10>, i64) -> !quake.ref |
| 128 | +// CHECK: quake.h %[[VAL_17]] : (!quake.ref) -> () |
| 129 | +// CHECK: cc.continue %[[VAL_16]] : i64 |
| 130 | +// CHECK: } step { |
| 131 | +// CHECK: ^bb0(%[[VAL_18:.*]]: i64): |
| 132 | +// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_18]], %[[VAL_1]] : i64 |
| 133 | +// CHECK: cc.continue %[[VAL_19]] : i64 |
| 134 | +// CHECK: } {invariant} |
| 135 | +// CHECK: } |
| 136 | +// CHECK: %[[VAL_20:.*]] = cc.loop while ((%[[VAL_21:.*]] = %[[VAL_2]]) -> (i64)) { |
| 137 | +// CHECK: %[[VAL_22:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_0]] : i64 |
| 138 | +// CHECK: cc.condition %[[VAL_22]](%[[VAL_21]] : i64) |
| 139 | +// CHECK: } do { |
| 140 | +// CHECK: ^bb0(%[[VAL_23:.*]]: i64): |
| 141 | +// CHECK: %[[VAL_24:.*]] = quake.extract_ref %[[VAL_3]]{{\[}}%[[VAL_23]]] : (!quake.veq<10>, i64) -> !quake.ref |
| 142 | +// CHECK: quake.x %[[VAL_24]] : (!quake.ref) -> () |
| 143 | +// CHECK: cc.continue %[[VAL_23]] : i64 |
| 144 | +// CHECK: } step { |
| 145 | +// CHECK: ^bb0(%[[VAL_25:.*]]: i64): |
| 146 | +// CHECK: %[[VAL_26:.*]] = arith.addi %[[VAL_25]], %[[VAL_1]] : i64 |
| 147 | +// CHECK: cc.continue %[[VAL_26]] : i64 |
| 148 | +// CHECK: } {invariant} |
| 149 | +// CHECK: %[[VAL_27:.*]] = cc.loop while ((%[[VAL_28:.*]] = %[[VAL_2]]) -> (i64)) { |
| 150 | +// CHECK: %[[VAL_29:.*]] = arith.cmpi slt, %[[VAL_28]], %[[VAL_0]] : i64 |
| 151 | +// CHECK: cc.condition %[[VAL_29]](%[[VAL_28]] : i64) |
| 152 | +// CHECK: } do { |
| 153 | +// CHECK: ^bb0(%[[VAL_30:.*]]: i64): |
| 154 | +// CHECK: %[[VAL_31:.*]] = quake.extract_ref %[[VAL_3]]{{\[}}%[[VAL_30]]] : (!quake.veq<10>, i64) -> !quake.ref |
| 155 | +// CHECK: quake.h %[[VAL_31]] : (!quake.ref) -> () |
| 156 | +// CHECK: cc.continue %[[VAL_30]] : i64 |
| 157 | +// CHECK: } step { |
| 158 | +// CHECK: ^bb0(%[[VAL_32:.*]]: i64): |
| 159 | +// CHECK: %[[VAL_33:.*]] = arith.addi %[[VAL_32]], %[[VAL_1]] : i64 |
| 160 | +// CHECK: cc.continue %[[VAL_33]] : i64 |
| 161 | +// CHECK: } {invariant} |
| 162 | +// CHECK: return |
| 163 | +// CHECK: } |
0 commit comments