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

Supprt control and by-val capture for qpu_lambda



QJIT is non-copyable but we accidentally made a couple of copies of capture vars along the call chain.

Also, support capture by-value with [=] notation if needed.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 9e9139d5
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
# Add a QCOR compilation and run test.
# The test can use qcor_expect macro to check expected results.
function(add_qcor_compile_and_exe_test test_name relative_source_location)
  add_test(
  NAME
    ${test_name}
  COMMAND
    bash -c "${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/${relative_source_location} -o ${test_name}; \
              ${CMAKE_CURRENT_BINARY_DIR}/${test_name}"
  )
endfunction()

add_test(NAME qrt_bell_multi COMMAND ${CMAKE_BINARY_DIR}/qcor -c ${CMAKE_CURRENT_SOURCE_DIR}/bell/bell_multi_qreg.cpp)
add_test(NAME qrt_add_3_5 COMMAND ${CMAKE_BINARY_DIR}/qcor -v -c ${CMAKE_CURRENT_SOURCE_DIR}/adder/add_3_5.cpp WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/adder)
add_test(NAME qrt_mixed_language COMMAND ${CMAKE_BINARY_DIR}/qcor -c ${CMAKE_CURRENT_SOURCE_DIR}/simple/mixed_language.cpp)
@@ -29,3 +41,6 @@ add_test(NAME quasimo_verified_qpe COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURR
add_test(NAME hadamard_ctrl_test COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/ctrl-gates/simple_hadamard_test.cpp)
add_test(NAME multi_ctrl_test COMMAND ${CMAKE_BINARY_DIR}/qcor ${CMAKE_CURRENT_SOURCE_DIR}/ctrl-gates/multiple_controls.cpp)

add_qcor_compile_and_exe_test(qrt_bell_ctrl bell/bell_control.cpp)
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)
 No newline at end of file
+5 −0
Original line number Diff line number Diff line
@@ -6,9 +6,14 @@ __qpu__ void bell(qubit q, qubit r) {
}

int main() {
  set_shots(1024);
  auto q = qalloc(1);
  auto r = qalloc(1);
  bell(q[0],r[0]);
  q.print();
  r.print();
  qcor_expect(q.counts().size() == 2);
  qcor_expect(r.counts().size() == 2);
  qcor_expect(q.counts()["0"] == r.counts()["0"]);
  qcor_expect(q.counts()["1"] == r.counts()["1"]);
}
 No newline at end of file
+34 −1
Original line number Diff line number Diff line
#include "qcor.hpp"

int main(int argc, char** argv) {
  set_shots(1024);
  int n = argc;
  double m = 22;

@@ -11,16 +12,48 @@ int main(int argc, char** argv) {
        H(q[0]);
      }
      Measure(q[0]);
      m++;
  }, n, m);

  // By-value capture
  auto b = qpu_lambda([=](qreg q) {
      print("[By-val] n was captured, and is ", n);
      print("[By-val] m was captured, and is ", m);
      for (int i = 0; i < n; i++) {
        H(q[0]);
      }
      Measure(q[0]);
  }, n, m);

  auto q = qalloc(1);
  a(q);
  auto qb = qalloc(1);
  b(qb);
  print("m after lambda", m);
  // m was modified by the lambda...
  qcor_expect(m == 23);
  
  q.print();
  // Run 1 Hadamard
  qcor_expect(q.counts().size() == 2);
  qcor_expect(q.counts()["0"] > 400);
  qcor_expect(q.counts()["1"] > 400);
  qcor_expect(q.counts()["0"] + q.counts()["1"] == 1024);

  n = 2;
  m = 33.0;
  auto r = qalloc(1);
  print("running again to show capture variables are captured by reference");
  auto rb = qalloc(1);
  print("running again to show capture variables are captured by reference and by value");
  a(r);
  b(rb);
  r.print();
  // H - H == I
  qcor_expect(r.counts()["0"] == 1024);
  // b still uses n = 1 (capture by value...)
  rb.print();
  qcor_expect(rb.counts().size() == 2);
  qcor_expect(rb.counts()["0"] > 400);
  qcor_expect(rb.counts()["1"] > 400);
  qcor_expect(rb.counts()["0"] + rb.counts()["1"] == 1024);
}
+24 −0
Original line number Diff line number Diff line
#include "qcor.hpp"

int main(int argc, char** argv) {
  set_shots(1024);

  auto x_lambda = qpu_lambda([](qubit q) { 
    X(q); });
  
  auto bell = qpu_lambda([](qreg q) {
    H(q[0]);
    // Call the captured lambda
    x_lambda.ctrl(q[0], q[1]);
    Measure(q);
  }, x_lambda);
  
  auto q = qalloc(2);
  bell(q);
  q.print();
  qcor_expect(q.counts().size() == 2);
  qcor_expect(q.counts()["00"] > 400);
  qcor_expect(q.counts()["11"] > 400);
  // Entangled...
  qcor_expect(q.counts()["00"] + q.counts()["11"] == 1024);
}
+2 −2
Original line number Diff line number Diff line
@@ -58,10 +58,10 @@ class QJIT {
  void write_cache();

  template <typename... Args>
  void invoke(const std::string &kernel_name, Args... args) {
  void invoke(const std::string &kernel_name, Args &&... args) {
    auto f_ptr = kernel_name_to_f_ptr[kernel_name];
    void (*kernel_functor)(Args...) = (void (*)(Args...))f_ptr;
    kernel_functor(args...);
    kernel_functor(std::forward<Args>(args)...);
  }

  template <typename... Args>
Loading