Loading examples/CMakeLists.txt +2 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ add_qcor_compile_and_exe_test(qrt_qpu_lambda_simple qpu_lambda/lambda_test.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_bell qpu_lambda/lambda_test_bell.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_grover qpu_lambda/grover_lambda_oracle.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambdas_in_loop qpu_lambda/deuteron_lambda.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_deuteron qpu_lambda/deuteron_vqe.cpp) # Arithmetic tests add_qcor_compile_and_exe_test(qrt_qpu_arith_adder arithmetic/simple.cpp) Loading examples/qpu_lambda/deuteron_vqe.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -6,16 +6,36 @@ int main() { 6.125 * Z(1) + 5.907; auto ansatz = qpu_lambda([](qreg q, double x) { print("x = ", x); X(q[0]); Ry(q[1], x); CX(q[1], q[0]); }); auto ansatz_take_vec = qpu_lambda([](qreg q, std::vector<double> x) { print("x = ", x[0]); X(q[0]); Ry(q[1], x[0]); CX(q[1], q[0]); }); OptFunction opt_function( [&](std::vector<double> x) { return ansatz.observe(H, qalloc(2), x[0]); }, 1); OptFunction opt_function_vec( [&](std::vector<double> x) { return ansatz_take_vec.observe(H, qalloc(2), x); }, 1); auto optimizer = createOptimizer("nlopt"); auto [ground_energy, opt_params] = optimizer->optimize(opt_function); print("Energy: ", ground_energy); qcor_expect(std::abs(ground_energy + 1.74886) < 0.1); auto [ground_energy_vec, opt_params_vec] = optimizer->optimize(opt_function_vec); print("Energy: ", ground_energy_vec); qcor_expect(std::abs(ground_energy_vec + 1.74886) < 0.1); } No newline at end of file examples/qpu_lambda/lambda_test.cpp +93 −0 Original line number Diff line number Diff line Loading @@ -56,4 +56,97 @@ int main(int argc, char** argv) { qcor_expect(rb.counts()["0"] > 400); qcor_expect(rb.counts()["1"] > 400); qcor_expect(rb.counts()["0"] + rb.counts()["1"] == 1024); // Test passing an r-val to lambda auto ansatz_X0X1 = qpu_lambda([](qreg q, double x) { print("ansatz: x = ", x); X(q[0]); Ry(q[1], x); CX(q[1], q[0]); H(q); Measure(q); }); auto qtest = qalloc(2); // Pass an rval... ansatz_X0X1(qtest, 1.2334); auto exp = qtest.exp_val_z(); print("<X0X1> = ", exp); // Test a loop: const std::vector<double> expectedResults{ 0.0, -0.324699, -0.614213, -0.837166, -0.9694, -0.996584, -0.915773, -0.735724, -0.475947, -0.164595, 0.164595, 0.475947, 0.735724, 0.915773, 0.996584, 0.9694, 0.837166, 0.614213, 0.324699, 0.0}; const auto angles = linspace(-M_PI, M_PI, 20); for (size_t i = 0; i < angles.size(); ++i) { auto buffer = qalloc(2); ansatz_X0X1(buffer, angles[i]); auto exp = buffer.exp_val_z(); print("<X0X1>(", angles[i], ") = ", exp, "; expected:", expectedResults[i]); qcor_expect(std::abs(expectedResults[i] - exp) < 0.1); } // Test by-ref argument... auto add_one = qpu_lambda([](qreg q, int &result) { print("add_one: result =", result); result++; }); // capture add_one lambda and use by-ref arguments. auto add_two = qpu_lambda( [](qreg q, int &result) { add_one(q, result); add_one(q, result); }, add_one); auto buffer_test = qalloc(2); int test_val = 1; add_one(buffer_test, test_val); qcor_expect(test_val == 2); add_two(buffer_test, test_val); qcor_expect(test_val == 4); auto add_one_copy = qpu_lambda([](qreg q, int result) { print("add_one: entry result =", result); result++; print("add_one: exit result =", result); }); auto test_val_const = 12; add_one_copy(buffer_test, test_val_const); // Should stay the same qcor_expect(test_val_const == 12); auto count_qubits = qpu_lambda([](qreg q, int &result) { result = q.size(); }); int nb_qubits = 0; count_qubits(qalloc(20), nb_qubits); std::cout << "Count = " << nb_qubits << "\n"; qcor_expect(nb_qubits == 20); auto vector_sum = qpu_lambda([](qreg q, std::vector<double> input, double &result) { result = 0.0; for (auto &val : input) { result = result + val; } }); double check = 0.0; std::vector<double> vec_to_check { 1.0, 2.0, 3.0 }; vector_sum(qalloc(1), vec_to_check, check); std::cout << "Sum: " << check << "\n"; qcor_expect(std::abs(check - 6.0) < 1e-12); check = 0.0; // Inline construction vector_sum(qalloc(1), std::vector<double>{2.0, 4.0, 6.0}, check); std::cout << "Sum: " << check << "\n"; qcor_expect(std::abs(check - 12.0) < 1e-12); } handlers/token_collector/pyxasm/pyxasm_visitor.hpp +8 −6 Original line number Diff line number Diff line Loading @@ -320,12 +320,14 @@ class pyxasm_visitor : public pyxasmBaseVisitor { // This kernel *callable* is not an intrinsic instruction, just // reassemble the call: // Check that the *first* argument is a *qreg* in the current context of // *this* kernel. if (!context->trailer().empty() && context->trailer()[0]->arglist() && // *this* kernel or the function name is a kernel in translation unit. if (xacc::container::contains(::quantum::kernels_in_translation_unit, inst_name) || (!context->trailer().empty() && context->trailer()[0]->arglist() && !context->trailer()[0]->arglist()->argument().empty() && xacc::container::contains( bufferNames, context->trailer()[0]->arglist()->argument(0)->getText())) { context->trailer()[0]->arglist()->argument(0)->getText()))) { std::stringstream ss; // Use the kernel call with a parent kernel arg. ss << inst_name << "(parent_kernel, "; Loading python/tests/test_jit_kernel_signature.py +22 −1 Original line number Diff line number Diff line Loading @@ -70,6 +70,27 @@ class TestKernelJIT(unittest.TestCase): self.assertEqual(comp.getInstruction(2).bits()[0], 1) self.assertEqual(comp.getInstruction(2).bits()[1], 0) def test_kernel_signature_substitute(self): @qjit def htest(q : qreg, sp_var : KernelSignature(qreg)): H(q[0]) psi = q[1:q.size()] sp_var(psi) @qjit def sp(q : qreg): X(q) q = qalloc(3) comp = htest.extract_composite(q, sp) print(comp) self.assertEqual(comp.nInstructions(), 3) self.assertEqual(comp.getInstruction(0).name(), "H") self.assertEqual(comp.getInstruction(0).bits()[0], 0) self.assertEqual(comp.getInstruction(1).name(), "X") self.assertEqual(comp.getInstruction(1).bits()[0], 1) self.assertEqual(comp.getInstruction(2).name(), "X") self.assertEqual(comp.getInstruction(2).bits()[0], 2) if __name__ == '__main__': unittest.main() No newline at end of file Loading
examples/CMakeLists.txt +2 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,8 @@ add_qcor_compile_and_exe_test(qrt_qpu_lambda_simple qpu_lambda/lambda_test.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_bell qpu_lambda/lambda_test_bell.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_grover qpu_lambda/grover_lambda_oracle.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambdas_in_loop qpu_lambda/deuteron_lambda.cpp) add_qcor_compile_and_exe_test(qrt_qpu_lambda_deuteron qpu_lambda/deuteron_vqe.cpp) # Arithmetic tests add_qcor_compile_and_exe_test(qrt_qpu_arith_adder arithmetic/simple.cpp) Loading
examples/qpu_lambda/deuteron_vqe.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -6,16 +6,36 @@ int main() { 6.125 * Z(1) + 5.907; auto ansatz = qpu_lambda([](qreg q, double x) { print("x = ", x); X(q[0]); Ry(q[1], x); CX(q[1], q[0]); }); auto ansatz_take_vec = qpu_lambda([](qreg q, std::vector<double> x) { print("x = ", x[0]); X(q[0]); Ry(q[1], x[0]); CX(q[1], q[0]); }); OptFunction opt_function( [&](std::vector<double> x) { return ansatz.observe(H, qalloc(2), x[0]); }, 1); OptFunction opt_function_vec( [&](std::vector<double> x) { return ansatz_take_vec.observe(H, qalloc(2), x); }, 1); auto optimizer = createOptimizer("nlopt"); auto [ground_energy, opt_params] = optimizer->optimize(opt_function); print("Energy: ", ground_energy); qcor_expect(std::abs(ground_energy + 1.74886) < 0.1); auto [ground_energy_vec, opt_params_vec] = optimizer->optimize(opt_function_vec); print("Energy: ", ground_energy_vec); qcor_expect(std::abs(ground_energy_vec + 1.74886) < 0.1); } No newline at end of file
examples/qpu_lambda/lambda_test.cpp +93 −0 Original line number Diff line number Diff line Loading @@ -56,4 +56,97 @@ int main(int argc, char** argv) { qcor_expect(rb.counts()["0"] > 400); qcor_expect(rb.counts()["1"] > 400); qcor_expect(rb.counts()["0"] + rb.counts()["1"] == 1024); // Test passing an r-val to lambda auto ansatz_X0X1 = qpu_lambda([](qreg q, double x) { print("ansatz: x = ", x); X(q[0]); Ry(q[1], x); CX(q[1], q[0]); H(q); Measure(q); }); auto qtest = qalloc(2); // Pass an rval... ansatz_X0X1(qtest, 1.2334); auto exp = qtest.exp_val_z(); print("<X0X1> = ", exp); // Test a loop: const std::vector<double> expectedResults{ 0.0, -0.324699, -0.614213, -0.837166, -0.9694, -0.996584, -0.915773, -0.735724, -0.475947, -0.164595, 0.164595, 0.475947, 0.735724, 0.915773, 0.996584, 0.9694, 0.837166, 0.614213, 0.324699, 0.0}; const auto angles = linspace(-M_PI, M_PI, 20); for (size_t i = 0; i < angles.size(); ++i) { auto buffer = qalloc(2); ansatz_X0X1(buffer, angles[i]); auto exp = buffer.exp_val_z(); print("<X0X1>(", angles[i], ") = ", exp, "; expected:", expectedResults[i]); qcor_expect(std::abs(expectedResults[i] - exp) < 0.1); } // Test by-ref argument... auto add_one = qpu_lambda([](qreg q, int &result) { print("add_one: result =", result); result++; }); // capture add_one lambda and use by-ref arguments. auto add_two = qpu_lambda( [](qreg q, int &result) { add_one(q, result); add_one(q, result); }, add_one); auto buffer_test = qalloc(2); int test_val = 1; add_one(buffer_test, test_val); qcor_expect(test_val == 2); add_two(buffer_test, test_val); qcor_expect(test_val == 4); auto add_one_copy = qpu_lambda([](qreg q, int result) { print("add_one: entry result =", result); result++; print("add_one: exit result =", result); }); auto test_val_const = 12; add_one_copy(buffer_test, test_val_const); // Should stay the same qcor_expect(test_val_const == 12); auto count_qubits = qpu_lambda([](qreg q, int &result) { result = q.size(); }); int nb_qubits = 0; count_qubits(qalloc(20), nb_qubits); std::cout << "Count = " << nb_qubits << "\n"; qcor_expect(nb_qubits == 20); auto vector_sum = qpu_lambda([](qreg q, std::vector<double> input, double &result) { result = 0.0; for (auto &val : input) { result = result + val; } }); double check = 0.0; std::vector<double> vec_to_check { 1.0, 2.0, 3.0 }; vector_sum(qalloc(1), vec_to_check, check); std::cout << "Sum: " << check << "\n"; qcor_expect(std::abs(check - 6.0) < 1e-12); check = 0.0; // Inline construction vector_sum(qalloc(1), std::vector<double>{2.0, 4.0, 6.0}, check); std::cout << "Sum: " << check << "\n"; qcor_expect(std::abs(check - 12.0) < 1e-12); }
handlers/token_collector/pyxasm/pyxasm_visitor.hpp +8 −6 Original line number Diff line number Diff line Loading @@ -320,12 +320,14 @@ class pyxasm_visitor : public pyxasmBaseVisitor { // This kernel *callable* is not an intrinsic instruction, just // reassemble the call: // Check that the *first* argument is a *qreg* in the current context of // *this* kernel. if (!context->trailer().empty() && context->trailer()[0]->arglist() && // *this* kernel or the function name is a kernel in translation unit. if (xacc::container::contains(::quantum::kernels_in_translation_unit, inst_name) || (!context->trailer().empty() && context->trailer()[0]->arglist() && !context->trailer()[0]->arglist()->argument().empty() && xacc::container::contains( bufferNames, context->trailer()[0]->arglist()->argument(0)->getText())) { context->trailer()[0]->arglist()->argument(0)->getText()))) { std::stringstream ss; // Use the kernel call with a parent kernel arg. ss << inst_name << "(parent_kernel, "; Loading
python/tests/test_jit_kernel_signature.py +22 −1 Original line number Diff line number Diff line Loading @@ -70,6 +70,27 @@ class TestKernelJIT(unittest.TestCase): self.assertEqual(comp.getInstruction(2).bits()[0], 1) self.assertEqual(comp.getInstruction(2).bits()[1], 0) def test_kernel_signature_substitute(self): @qjit def htest(q : qreg, sp_var : KernelSignature(qreg)): H(q[0]) psi = q[1:q.size()] sp_var(psi) @qjit def sp(q : qreg): X(q) q = qalloc(3) comp = htest.extract_composite(q, sp) print(comp) self.assertEqual(comp.nInstructions(), 3) self.assertEqual(comp.getInstruction(0).name(), "H") self.assertEqual(comp.getInstruction(0).bits()[0], 0) self.assertEqual(comp.getInstruction(1).name(), "X") self.assertEqual(comp.getInstruction(1).bits()[0], 1) self.assertEqual(comp.getInstruction(2).name(), "X") self.assertEqual(comp.getInstruction(2).bits()[0], 2) if __name__ == '__main__': unittest.main() No newline at end of file