Commit 544e72ea authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Merge branch 'master' into tnguyen/lambda-obj-fun

parents b39461ac 3a6b5f6c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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)
+20 −0
Original line number Diff line number Diff line
@@ -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
+93 −0
Original line number Diff line number Diff line
@@ -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);
}
+8 −6
Original line number Diff line number Diff line
@@ -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, ";
+22 −1
Original line number Diff line number Diff line
@@ -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