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


Add grover test and check the integer add in FTQC

These kernels are nested and use kernel modifiers.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 299e3011
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_five_qubit_qec_std_lib ftqc_qrt/five
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_steane_qec_std_lib ftqc_qrt/steane_qec_code.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_qalloc ftqc_qrt/qalloc_ftqc.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_arithmetic ftqc_qrt/integer_add.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_grover ftqc_qrt/grover.cpp)
add_qcor_compile_and_exe_test(quasimo_vqe quasimo/VqeWithAnsatzCircuit.cpp)
add_qcor_compile_and_exe_test(quasimo_trotter quasimo/TrotterTdWorkflow.cpp)
add_qcor_compile_and_exe_test(quasimo_iqpe_vqe quasimo/IterativeQpeVqe.cpp)
+66 −0
Original line number Diff line number Diff line
// Create a general grover search algorithm.
// Let's create that marks 2 states
// Show figures Init - [Oracle - Amplification for i in iters] - Measure
// https://www.nature.com/articles/s41467-017-01904-7

// Show off kernel composition, common patterns,
// functional programming (kernels taking other kernels)

using GroverPhaseOracle = KernelSignature<qreg>;

__qpu__ void amplification(qreg q) {
  // H q X q ctrl-ctrl-...-ctrl-Z H q Xq
  // compute - action - uncompute

  compute {
    H(q);
    X(q);
  }
  action {
    auto ctrl_bits = q.head(q.size() - 1);
    auto last_qubit = q.tail();
    Z::ctrl(ctrl_bits, last_qubit);
  }
}

__qpu__ void run_grover(qreg q, GroverPhaseOracle oracle, const int iterations,
                        int shots, std::vector<int> &results) {
  for (int k = 0; k < shots; k++) {
    H(q);

    for (int i = 0; i < iterations; i++) {
      oracle(q);
      amplification(q);
    }
    int bit_string = 0;
    for (int qid = 0; qid < q.size(); qid++) {
      if (Measure(q[qid])) {
        bit_string = bit_string + (1 << qid);
        X(q[qid]);
      }
    }
    // print("Result:", bit_string);
    results.emplace_back(bit_string);
  }
}

__qpu__ void oracle(qreg q) {
  // Mark 101 and 011
  CZ(q[0], q[2]);
  CZ(q[1], q[2]);
}

int main() {
  const int N = 3;

  // Allocate some qubits
  auto q = qalloc(N);
  // Call grover given the oracle and n iterations
  std::vector<int> results;
  run_grover(q, oracle, 1, 1024, results);
  qcor_expect(results.size() == 1024);
  for (const auto &val : results) {
    // Only 2 possible values: 5 and 6:
    qcor_expect(val == 5 || val == 6);
  }
}
 No newline at end of file
+1 −0
Original line number Diff line number Diff line
@@ -28,5 +28,6 @@ int main(int argc, char **argv) {
  int result = 0;
  test_mul_integer_inline(x_reg2, a_val, N_val, result);
  std::cout << "Result = " << result << "\n";
  qcor_expect(result == 2 || result == 6);
  return 0;
}
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public:
      entryPoint = p;
    } else {
      if (p.get() == entryPoint.get()) {
        std::cout << "Restart FTQC execution\n";
        // std::cout << "Restart FTQC execution\n";
        instruction_collect_mode = false;
        // Now apply these gates:
        // std::cout << entryPoint->toString() << "\n";
@@ -172,7 +172,7 @@ public:
        // We have executed all pending instructions...
        entryPoint->clear();
      } else {
        std::cout << "Begin instruction collection\n";
        // std::cout << "Begin instruction collection\n";
        // Switch to NISQ mode to collect these instructions
        instruction_collector = p;
        instruction_collect_mode = true;