From e0faa091a100af3e54a4c93748470f46e534b29e Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 17 Sep 2024 14:38:57 -0700 Subject: [PATCH] Fix argument conversion issues (#2211) * temp * temp * temp * Remove printing * Fixed synthesis issues and added tests * Remove changes for remote sim * Address CR comments --- runtime/common/ArgumentConversion.cpp | 14 +- runtime/test/test_argument_conversion.cpp | 234 ++++++++++++++++-- .../Remote-Sim/qvector_init_from_state.cpp | 135 +++++++++- .../qvector_init_from_state_lazy.cpp | 91 +++++++ 4 files changed, 453 insertions(+), 21 deletions(-) create mode 100644 targettests/Remote-Sim/qvector_init_from_state_lazy.cpp diff --git a/runtime/common/ArgumentConversion.cpp b/runtime/common/ArgumentConversion.cpp index a9c12c0fe0..6667a90ccd 100644 --- a/runtime/common/ArgumentConversion.cpp +++ b/runtime/common/ArgumentConversion.cpp @@ -10,6 +10,7 @@ #include "cudaq/Optimizer/Builder/Intrinsics.h" #include "cudaq/Optimizer/Builder/Runtime.h" #include "cudaq/Todo.h" +#include "cudaq/qis/pauli_word.h" #include "llvm/ADT/TypeSwitch.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Complex/IR/Complex.h" @@ -199,7 +200,7 @@ Value dispatchSubtype(OpBuilder &builder, Type ty, void *p, ModuleOp substMod, return {}; }) .Case([&](cudaq::cc::CharspanType strTy) { - return genConstant(builder, *static_cast(p), + return genConstant(builder, static_cast(p)->str(), substMod); }) .Case([&](cudaq::cc::StdvecType ty) { @@ -224,6 +225,11 @@ Value genConstant(OpBuilder &builder, cudaq::cc::StdvecType vecTy, void *p, auto eleTy = vecTy.getElementType(); auto elePtrTy = cudaq::cc::PointerType::get(eleTy); auto eleSize = cudaq::opt::getDataSize(layout, eleTy); + if (isa(eleTy)) { + // char span type (i.e. pauli word) is a `vector` + eleSize = sizeof(VectorType); + } + assert(eleSize && "element must have a size"); auto loc = builder.getUnknownLoc(); std::int32_t vecSize = delta / eleSize; @@ -361,7 +367,7 @@ void cudaq::opt::ArgumentConverter::gen(const std::vector &arguments) { return {}; }) .Case([&](cc::CharspanType strTy) { - return buildSubst(*static_cast(argPtr), + return buildSubst(static_cast(argPtr)->str(), substModule); }) .Case([&](cc::PointerType ptrTy) -> cc::ArgumentSubstitutionOp { @@ -406,8 +412,10 @@ void cudaq::opt::ArgumentConverter::gen_drop_front( if (numDrop >= arguments.size()) return; std::vector partialArgs; + int drop = numDrop; for (void *arg : arguments) { - if (numDrop--) { + if (drop > 0) { + drop--; partialArgs.push_back(nullptr); continue; } diff --git a/runtime/test/test_argument_conversion.cpp b/runtime/test/test_argument_conversion.cpp index 8c36fd1389..9fe3d92f8f 100644 --- a/runtime/test/test_argument_conversion.cpp +++ b/runtime/test/test_argument_conversion.cpp @@ -15,8 +15,10 @@ #include "common/ArgumentConversion.h" #include "cudaq/Optimizer/Dialect/CC/CCDialect.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeDialect.h" +#include "cudaq/qis/pauli_word.h" #include "mlir/InitAllDialects.h" #include "mlir/Parser/Parser.h" +#include void doSimpleTest(mlir::MLIRContext *ctx, const std::string &typeName, std::vector args) { @@ -29,6 +31,50 @@ func.func @__nvqpp__mlirgen__testy(%0: )#" + typeName + R"#() -> () return })#"; + // Create the Module + auto mod = mlir::parseSourceString(code, ctx); + llvm::outs() << "Source module:\n" << *mod << '\n'; + cudaq::opt::ArgumentConverter ab{"testy", *mod}; + // Create the argument conversions + ab.gen(args); + // Dump the conversions + llvm::outs() << "========================================\n" + "Substitution module:\n" + << ab.getSubstitutionModule() << '\n'; +} + +void doTest(mlir::MLIRContext *ctx, std::vector &typeNames, + std::vector args, std::size_t startingArgIdx = 0) { + + std::string code; + llvm::raw_string_ostream ss(code); + + // Create code + std::vector indices(args.size()); + std::iota(indices.begin(), indices.end(), 0); + auto argPairs = llvm::zip_equal(indices, typeNames); + + ss << "func.func private @callee("; + llvm::interleaveComma(argPairs, ss, [&](auto p) { + ss << "%" << std::get<0>(p) << ": " << std::get<1>(p); + }); + ss << ")\n"; + + ss << "func.func @__nvqpp__mlirgen__testy("; + llvm::interleaveComma(argPairs, ss, [&](auto p) { + ss << "%" << std::get<0>(p) << ": " << std::get<1>(p); + }); + ss << ") {"; + + ss << " call @callee("; + llvm::interleaveComma(indices, ss, [&](auto p) { ss << "%" << p; }); + + ss << "): ("; + llvm::interleaveComma(typeNames, ss, [&](auto t) { ss << t; }); + ss << ") -> ()\n"; + + ss << " return\n"; + ss << "}\n"; // Create the Module auto mod = mlir::parseSourceString(code, ctx); @@ -36,7 +82,7 @@ func.func @__nvqpp__mlirgen__testy(%0: )#" + cudaq::opt::ArgumentConverter ab{"testy", *mod}; // Create the argument conversions - ab.gen(args); + ab.gen_drop_front(args, startingArgIdx); // Dump the conversions llvm::outs() << "========================================\n" @@ -146,7 +192,7 @@ void test_scalars(mlir::MLIRContext *ctx) { // clang-format on { - std::string x = "Hi, there!"; + cudaq::pauli_word x{"XYZ"}; std::vector v = {static_cast(&x)}; doSimpleTest(ctx, "!cc.charspan", v); } @@ -156,12 +202,12 @@ void test_scalars(mlir::MLIRContext *ctx) { // CHECK: Substitution module: // CHECK-LABEL: cc.arg_subst[0] { -// CHECK: %[[VAL_0:.*]] = cc.address_of @cstr.48692C2074686572652100 : !cc.ptr> -// CHECK: %[[VAL_1:.*]] = cc.cast %[[VAL_0]] : (!cc.ptr>) -> !cc.ptr -// CHECK: %[[VAL_2:.*]] = arith.constant 10 : i64 +// CHECK: %[[VAL_0:.*]] = cc.address_of @cstr.58595A00 : !cc.ptr> +// CHECK: %[[VAL_1:.*]] = cc.cast %[[VAL_0]] : (!cc.ptr>) -> !cc.ptr +// CHECK: %[[VAL_2:.*]] = arith.constant 3 : i64 // CHECK: %[[VAL_3:.*]] = cc.stdvec_init %[[VAL_1]], %[[VAL_2]] : (!cc.ptr, i64) -> !cc.charspan // CHECK: } -// CHECK: llvm.mlir.global private constant @cstr.48692C2074686572652100("Hi, there!\00") {addr_space = 0 : i32} +// CHECK-DAG: llvm.mlir.global private constant @cstr.58595A00("XYZ\00") {addr_space = 0 : i32} // clang-format on } @@ -194,6 +240,34 @@ void test_vectors(mlir::MLIRContext *ctx) { // CHECK: %[[VAL_10:.*]] = cc.stdvec_init %[[VAL_0]], %[[VAL_9]] : (!cc.ptr>, i64) -> !cc.stdvec // CHECK: } // clang-format on + + { + std::vector x = {cudaq::pauli_word{"XX"}, + cudaq::pauli_word{"XY"}}; + std::vector v = {static_cast(&x)}; + doSimpleTest(ctx, "!cc.stdvec", v); + } + // clang-format off +// CHECK-LABEL: cc.arg_subst[0] { +// CHECK: %[[VAL_0:.*]] = cc.alloca !cc.array +// CHECK: %[[VAL_1:.*]] = cc.address_of @cstr.585800 : !cc.ptr> +// CHECK: %[[VAL_2:.*]] = cc.cast %[[VAL_1]] : (!cc.ptr>) -> !cc.ptr +// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_4:.*]] = cc.stdvec_init %[[VAL_2]], %[[VAL_3]] : (!cc.ptr, i64) -> !cc.charspan +// CHECK: %[[VAL_5:.*]] = cc.compute_ptr %[[VAL_0]][0] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_4]], %[[VAL_5]] : !cc.ptr +// CHECK: %[[VAL_6:.*]] = cc.address_of @cstr.585900 : !cc.ptr> +// CHECK: %[[VAL_7:.*]] = cc.cast %[[VAL_6]] : (!cc.ptr>) -> !cc.ptr +// CHECK: %[[VAL_8:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_9:.*]] = cc.stdvec_init %[[VAL_7]], %[[VAL_8]] : (!cc.ptr, i64) -> !cc.charspan +// CHECK: %[[VAL_10:.*]] = cc.compute_ptr %[[VAL_0]][1] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_9:.*]], %[[VAL_10:.*]] : !cc.ptr +// CHECK: %[[VAL_11:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_12:.*]] = cc.stdvec_init %[[VAL_0]], %[[VAL_11]] : (!cc.ptr>, i64) -> !cc.stdvec +// CHECK: } +// CHECK-DAG: llvm.mlir.global private constant @cstr.585800("XX\00") {addr_space = 0 : i32} +// CHECK-DAG: llvm.mlir.global private constant @cstr.585900("XY\00") {addr_space = 0 : i32} + // clang-format on } void test_aggregates(mlir::MLIRContext *ctx) { @@ -304,18 +378,147 @@ void test_state(mlir::MLIRContext *ctx) { // CHECK: func.func private @callee(!cc.ptr) // CHECK: Substitution module: -// CHECK-LABEL: cc.arg_subst[0] { -// CHECK: %[[VAL_0:.*]] = cc.address_of @[[VAL_GC:.*]] : !cc.ptr x 8>> -// CHECK: %[[VAL_1:.*]] = cc.load %[[VAL_0]] : !cc.ptr x 8>> -// CHECK: %[[VAL_2:.*]] = arith.constant 8 : i64 -// CHECK: %[[VAL_3:.*]] = cc.alloca !cc.array x 8> -// CHECK: cc.store %[[VAL_1]], %[[VAL_3]] : !cc.ptr x 8>> -// CHECK: %[[VAL_4:.*]] = cc.cast %[[VAL_3]] : (!cc.ptr x 8>>) -> !cc.ptr -// CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr -// CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr +// CHECK-LABEL: cc.arg_subst[0] { +// CHECK: %[[VAL_0:.*]] = cc.address_of @[[VAL_GC:.*]] : !cc.ptr x 8>> +// CHECK: %[[VAL_1:.*]] = cc.load %[[VAL_0]] : !cc.ptr x 8>> +// CHECK: %[[VAL_2:.*]] = arith.constant 8 : i64 +// CHECK: %[[VAL_3:.*]] = cc.alloca !cc.array x 8> +// CHECK: cc.store %[[VAL_1]], %[[VAL_3]] : !cc.ptr x 8>> +// CHECK: %[[VAL_4:.*]] = cc.cast %[[VAL_3]] : (!cc.ptr x 8>>) -> !cc.ptr +// CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr +// CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr +// CHECK: } +// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +// CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr + // clang-format on +} + +void test_combinations(mlir::MLIRContext *ctx) { + { + bool x = true; + std::vector v = {static_cast(&x)}; + std::vector t = {"i1"}; + doTest(ctx, t, v); + } + // clang-format off +// CHECK-LABEL: Source module: +// CHECK: func.func private @callee(i1) +// CHECK: Substitution module: + +// CHECK-LABEL: cc.arg_subst[0] { +// CHECK: %[[VAL_0:.*]] = arith.constant true +// CHECK: } + // clang-format on + + { + bool x = true; + bool y = false; + std::vector v = {static_cast(&x), static_cast(&y)}; + std::vector t = {"i1", "i1"}; + doTest(ctx, t, v); + } + // clang-format off +// CHECK: Source module: +// CHECK: func.func private @callee(i1, i1) +// CHECK: Substitution module: + +// CHECK-LABEL: cc.arg_subst[0] { +// CHECK: %[[VAL_0:.*]] = arith.constant true +// CHECK: } +// CHECK-LABEL: cc.arg_subst[1] { +// CHECK: %[[VAL_1:.*]] = arith.constant false +// CHECK: } + // clang-format on + + { + bool x = true; + std::int32_t y = 42; + std::vector v = {static_cast(&x), static_cast(&y)}; + std::vector t = {"i1", "i32"}; + doTest(ctx, t, v, 1); + } + + // clang-format off +// CHECK: Source module: +// CHECK: func.func private @callee(i1, i32) +// CHECK: Substitution module: + +// CHECK-LABEL: cc.arg_subst[1] { +// CHECK: %[[VAL_0:.*]] = arith.constant 42 : i32 +// CHECK: } + // clang-format on + + { + std::vector> data{M_SQRT1_2, M_SQRT1_2, 0., 0., + 0., 0., 0., 0.}; + + std::vector x = {0.5, 0.6}; + cudaq::state y{new FakeSimulationState(data.size(), data.data())}; + std::vector z = { + cudaq::pauli_word{"XX"}, + cudaq::pauli_word{"XY"}, + }; + + std::vector v = {static_cast(&x), static_cast(&y), + static_cast(&z)}; + std::vector t = {"!cc.stdvec", "!cc.ptr", + "!cc.stdvec"}; + doTest(ctx, t, v); + } + + // clang-format off +// CHECK: Source module: +// CHECK: func.func private @callee(!cc.stdvec, !cc.ptr, !cc.stdvec) +// CHECK: Substitution module: + +// CHECK-LABEL: cc.arg_subst[0] { +// CHECK: %[[VAL_0:.*]] = cc.alloca !cc.array +// CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_2:.*]] = cc.compute_ptr %[[VAL_0]][0] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_1]], %[[VAL_2]] : !cc.ptr +// CHECK: %[[VAL_3:.*]] = arith.constant 1.750000e+00 : f32 +// CHECK: %[[VAL_4:.*]] = cc.compute_ptr %[[VAL_0]][1] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_3]], %[[VAL_4]] : !cc.ptr +// CHECK: %[[VAL_5:.*]] = arith.constant 4.17232506E-8 : f32 +// CHECK: %[[VAL_6:.*]] = cc.compute_ptr %[[VAL_0]][2] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_5]], %[[VAL_6]] : !cc.ptr +// CHECK: %[[VAL_7:.*]] = arith.constant 1.775000e+00 : f32 +// CHECK: %[[VAL_8:.*]] = cc.compute_ptr %[[VAL_0]][3] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_7]], %[[VAL_8]] : !cc.ptr +// CHECK: %[[VAL_9:.*]] = arith.constant 4 : i64 +// CHECK: %[[VAL_10:.*]] = cc.stdvec_init %[[VAL_0]], %[[VAL_9]] : (!cc.ptr>, i64) -> !cc.stdvec +// CHECK: } +// CHECK-LABEL: cc.arg_subst[1] { +// CHECK: %[[VAL_0:.*]] = cc.address_of @[[VAL_GC:.*]] : !cc.ptr x 8>> +// CHECK: %[[VAL_1:.*]] = cc.load %[[VAL_0]] : !cc.ptr x 8>> +// CHECK: %[[VAL_2:.*]] = arith.constant 8 : i64 +// CHECK: %[[VAL_3:.*]] = cc.alloca !cc.array x 8> +// CHECK: cc.store %[[VAL_1]], %[[VAL_3]] : !cc.ptr x 8>> +// CHECK: %[[VAL_4:.*]] = cc.cast %[[VAL_3]] : (!cc.ptr x 8>>) -> !cc.ptr +// CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr +// CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr // CHECK: } // CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> // CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr +// CHECK-LABEL: cc.arg_subst[2] { +// CHECK: %[[VAL_0:.*]] = cc.alloca !cc.array +// CHECK: %[[VAL_1:.*]] = cc.address_of @cstr.585800 : !cc.ptr> +// CHECK: %[[VAL_2:.*]] = cc.cast %[[VAL_1]] : (!cc.ptr>) -> !cc.ptr +// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_4:.*]] = cc.stdvec_init %[[VAL_2]], %[[VAL_3]] : (!cc.ptr, i64) -> !cc.charspan +// CHECK: %[[VAL_5:.*]] = cc.compute_ptr %[[VAL_0]][0] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_4]], %[[VAL_5]] : !cc.ptr +// CHECK: %[[VAL_6:.*]] = cc.address_of @cstr.585900 : !cc.ptr> +// CHECK: %[[VAL_7:.*]] = cc.cast %[[VAL_6]] : (!cc.ptr>) -> !cc.ptr +// CHECK: %[[VAL_8:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_9:.*]] = cc.stdvec_init %[[VAL_7]], %[[VAL_8]] : (!cc.ptr, i64) -> !cc.charspan +// CHECK: %[[VAL_10:.*]] = cc.compute_ptr %[[VAL_0]][1] : (!cc.ptr>) -> !cc.ptr +// CHECK: cc.store %[[VAL_9]], %[[VAL_10]] : !cc.ptr +// CHECK: %[[VAL_11:.*]] = arith.constant 2 : i64 +// CHECK: %[[VAL_12:.*]] = cc.stdvec_init %[[VAL_0]], %[[VAL_11]] : (!cc.ptr>, i64) -> !cc.stdvec +// CHECK: } +// CHECK-DAG: llvm.mlir.global private constant @cstr.585800("XX\00") {addr_space = 0 : i32} +// CHECK-DAG: llvm.mlir.global private constant @cstr.585900("XY\00") {addr_space = 0 : i32} // clang-format on } @@ -330,5 +533,6 @@ int main() { test_aggregates(&context); test_recursive(&context); test_state(&context); + test_combinations(&context); return 0; } diff --git a/targettests/Remote-Sim/qvector_init_from_state.cpp b/targettests/Remote-Sim/qvector_init_from_state.cpp index 7aacd122b8..d1cd32a534 100644 --- a/targettests/Remote-Sim/qvector_init_from_state.cpp +++ b/targettests/Remote-Sim/qvector_init_from_state.cpp @@ -16,6 +16,8 @@ #include #include +#include +#include __qpu__ void test_init_state() { cudaq::qvector q(2); @@ -31,6 +33,25 @@ __qpu__ void test_state_param(cudaq::state* state) { cudaq::qvector q1(state); } +__qpu__ void test_state_param2(cudaq::state* state, cudaq::pauli_word w) { + cudaq::qvector q(state); + cudaq::exp_pauli(.5, q, w); +} + +__qpu__ void test_state_param3(cudaq::state *initial_state, std::vector& words) { + cudaq::qvector q(initial_state); + for (std::size_t i = 0; i < words.size(); ++i) { + cudaq::exp_pauli(.5, q, words[i]); + } +} + +__qpu__ void test_state_param4(cudaq::state *initial_state, std::vector &coefficients, std::vector& words) { + cudaq::qvector q(initial_state); + for (std::size_t i = 0; i < words.size(); ++i) { + cudaq::exp_pauli(coefficients[i], q, words[i]); + } +} + void printCounts(cudaq::sample_result& result) { std::vector values{}; for (auto &&[bits, counts] : result) { @@ -49,7 +70,7 @@ int main() { auto state = cudaq::state::from_data(vec); auto state1 = cudaq::state::from_data(vec1); { - // Passing state created from data as argument (kernel mode) + std::cout << "Passing state created from data as argument (kernel mode)\n"; auto counts = cudaq::sample(test_state_param, &state); printCounts(counts); @@ -57,6 +78,7 @@ int main() { printCounts(counts); } +// CHECK: Passing state created from data as argument (kernel mode) // CHECK: 000 // CHECK: 100 @@ -64,22 +86,129 @@ int main() { // CHECK: 111 { - // Passing state from another kernel as argument (kernel mode) + std::cout << "Passing state from another kernel as argument (kernel mode)\n"; auto state = cudaq::get_state(test_init_state); auto counts = cudaq::sample(test_state_param, &state); printCounts(counts); } +// CHECK: Passing state from another kernel as argument (kernel mode) // CHECK: 00 // CHECK: 10 { - // Passing large state from another kernel as argument (kernel mode) + std::cout << "Passing large state from another kernel as argument (kernel mode)\n"; auto largeState = cudaq::get_state(test_init_large_state); auto counts = cudaq::sample(test_state_param, &largeState); printCounts(counts); } +// CHECK: Passing large state from another kernel as argument (kernel mode) // CHECK: 00000000000000 // CHECK: 10000000000000 + + { + std::cout << "Passing state from another kernel as argument iteratively (kernel mode)\n"; + auto state = cudaq::get_state(test_init_state); + for (auto i = 0; i < 4; i++) { + auto counts = cudaq::sample(test_state_param2, &state, cudaq::pauli_word{"XX"}); + std::cout << "Iteration: " << i << std::endl; + printCounts(counts); + state = cudaq::get_state(test_state_param2, &state, cudaq::pauli_word{"XX"}); + } + } + +// CHECK: Passing state from another kernel as argument iteratively (kernel mode) +// CHECK: Iteration: 0 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 1 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 2 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 3 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 + + { + std::cout << "Passing state from another kernel as argument iteratively with vector args (kernel mode)\n"; + auto state = cudaq::get_state(test_init_state); + auto words = std::vector{cudaq::pauli_word{"XX"}}; + for (auto i = 0; i < 4; i++) { + auto counts = cudaq::sample(test_state_param3, &state, words); + std::cout << "Iteration: " << i << std::endl; + printCounts(counts); + state = cudaq::get_state(test_state_param3, &state, words); + words = std::vector{cudaq::pauli_word{"XY"}}; + } + } + +// Passing state from another kernel as argument iteratively with vector args (kernel mode) +// CHECK: Iteration: 0 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 1 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 2 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 3 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 + + { + std::cout << "Passing state from another kernel as argument iteratively with vector args with 2 elements (kernel mode)\n"; + auto state = cudaq::get_state(test_init_state); + auto words = std::vector{cudaq::pauli_word{"XX"}, cudaq::pauli_word{"YY"}}; + auto coeffs = std::vector{0.5, 0.6}; + for (auto i = 0; i < 4; i++) { + auto counts = cudaq::sample(test_state_param4, &state, coeffs, words); + std::cout << "Iteration: " << i << std::endl; + printCounts(counts); + state = cudaq::get_state(test_state_param4, &state, coeffs, words); + words = std::vector{cudaq::pauli_word{"XY"}, cudaq::pauli_word{"YX"}}; + coeffs = std::vector{0.5 * i}; + } + } + +// CHECK: Passing state from another kernel as argument iteratively with vector args with 2 elements (kernel mode) +// CHECK: Iteration: 0 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 1 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 2 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 +// CHECK: Iteration: 3 +// CHECK: 00 +// CHECK: 01 +// CHECK: 10 +// CHECK: 11 } diff --git a/targettests/Remote-Sim/qvector_init_from_state_lazy.cpp b/targettests/Remote-Sim/qvector_init_from_state_lazy.cpp new file mode 100644 index 0000000000..99dd261aac --- /dev/null +++ b/targettests/Remote-Sim/qvector_init_from_state_lazy.cpp @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +// REQUIRES: remote-sim +// REQUIRES: c++20 + +// clang-format off +// TODO-FIX-KERNEL-EXEC +// RUN: nvq++ %cpp_std --enable-mlir --target remote-mqpu -fkernel-exec-kind=2 %s -o %t && %t | FileCheck %s +// clang-format on + +#include +#include + +struct test_init_state { + void operator()() __qpu__ { + cudaq::qvector q(2); + ry(M_PI/2.0, q[0]); + } +}; + +struct test_init_large_state { + void operator()() __qpu__ { + cudaq::qvector q(14); + ry(M_PI/2.0, q[0]); + } +}; + +struct test_state_param { + void operator()(cudaq::state *initial_state) __qpu__ { + cudaq::qvector q(initial_state); + } +}; + +void printCounts(cudaq::sample_result& result) { + std::vector values{}; + for (auto &&[bits, counts] : result) { + values.push_back(bits); + } + + std::sort(values.begin(), values.end()); + for (auto &&bits : values) { + std::cout << bits << '\n'; + } +} + +int main() { + std::vector vec{M_SQRT1_2, M_SQRT1_2, 0., 0., 0., 0., 0., 0.}; + std::vector vec1{0., 0., 0., 0., 0., 0., M_SQRT1_2, M_SQRT1_2}; + auto state = cudaq::state::from_data(vec); + auto state1 = cudaq::state::from_data(vec1); + { + // Passing state created from data as argument (kernel mode) + auto counts = cudaq::sample(test_state_param{}, &state); + printCounts(counts); + + counts = cudaq::sample(test_state_param{}, &state1); + printCounts(counts); + } + +// CHECK: 000 +// CHECK: 100 + +// CHECK: 011 +// CHECK: 111 + + { + // Passing state from another kernel as argument (kernel mode) + auto state = cudaq::get_state(test_init_state{}); + auto counts = cudaq::sample(test_state_param{}, &state); + printCounts(counts); + } + +// CHECK: 00 +// CHECK: 10 + + { + // Passing large state from another kernel as argument (kernel mode) + auto largeState = cudaq::get_state(test_init_large_state{}); + auto counts = cudaq::sample(test_state_param{}, &largeState); + printCounts(counts); + } + +// CHECK: 00000000000000 +// CHECK: 10000000000000 +}