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

Added Qcor helper kernels to implement iterative QPE algorithm



Also, change the code rewrite to use a more distinct variable name of `__ker__temp__` rather than `k` to prevent collision with user params.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 818bf7e9
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
#include <qcor_qpe>


/// Compile with:
/// qcor -qpu qpp qpe_ham_op.cpp

int main(int argc, char **argv) {
  auto q = qalloc(3);
  auto H = X(0) * X(1);
  int k = 1;
  double omega = 1.234;
  const int num_time_slices = 2;
  std::cout << "Kernel:\n";
  pauli_qpe_iter::print_kernel(std::cout, q, k, omega, H, num_time_slices, true);
}
+2 −2
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ void QCORSyntaxHandler::GetReplacement(
    OS << ", " << program_arg_types[i] << " " << program_parameters[i];
  }
  OS << ") {\n";
  OS << "class " << kernel_name << " k(parent, " << program_parameters[0];
  OS << "class " << kernel_name << " __ker__temp__(parent, " << program_parameters[0];
  for (int i = 1; i < program_parameters.size(); i++) {
    OS << ", " << program_parameters[i];
  }
@@ -279,7 +279,7 @@ void QCORSyntaxHandler::GetReplacement(
    OS << ", " << program_arg_types[i] << " " << program_parameters[i];
  }
  OS << ") {\n";
  OS << "class " << kernel_name << " k(" << program_parameters[0];
  OS << "class " << kernel_name << " __ker__temp__(" << program_parameters[0];
  for (int i = 1; i < program_parameters.size(); i++) {
    OS << ", " << program_parameters[i];
  }
+50 −0
Original line number Diff line number Diff line
#pragma once

// Common QCOR kernels to support iterative Quantum Phase Estimation algorithm.

// First-order Trotter evolution
__qpu__ void pauli_trotter_evolution(qreg q, qcor::PauliOperator pauli_ham,
                                     double evo_time, int num_time_slices) {
  const double theta = evo_time / num_time_slices;
  for (int i = 0; i < num_time_slices; ++i) {
    exp_i_theta(q, theta, pauli_ham);
  }
}

// Raise Pauli evolution to a power: i.e. U^power.
__qpu__ void pauli_power_trotter_evolution(qreg q,
                                           qcor::PauliOperator pauli_ham,
                                           double evo_time, int num_time_slices,
                                           int power) {
  for (int i = 0; i < power; ++i) {
    pauli_trotter_evolution(q, pauli_ham, evo_time, num_time_slices);
  }
}

// Kernel for a single iteration of iterative QPE
/// k: the iteration idx.
/// omega: the feedback angle.
/// pauli_ham: hamiltonian
/// num_time_slices: number of trotter steps
/// measure: if true, add measure gate on ancilla qubit.
__qpu__ void pauli_qpe_iter(qreg q, int k, double omega,
                            qcor::PauliOperator pauli_ham, int num_time_slices,
                            int measure) {
  // Ancilla qubit is the last qubit in the register
  auto anc_idx = q.size() - 1;
  // Hadamard on ancilla qubit
  H(q[anc_idx]);
  // Controlled-U
  int power = 1 << (k - 1);
  double evo_time = -2 * M_PI;
  pauli_power_trotter_evolution::ctrl(anc_idx, q, pauli_ham, evo_time,
                                      num_time_slices, power);

  // Rz on ancilla qubit
  Rz(q[anc_idx], omega);
  // Hadamard on ancilla qubit
  H(q[anc_idx]);
  if (measure) {
    Measure(q[anc_idx]);
  }
}
 No newline at end of file

lib/qcor_qpe

0 → 100644
+2 −0
Original line number Diff line number Diff line
#pragma once
#include "impl/quantum_phase_estimation.hpp"
+13 −5
Original line number Diff line number Diff line
@@ -121,15 +121,23 @@ VqeWorkflow::execute(const QuatumSimulationModel &model) {
}

bool IterativeQpeWorkflow::initialize(const HeterogeneousMap &params) {
  // TODO:
  std::cout << "Howdy: initialize\n";
  return true;
  // Default params:
  num_steps = 1;
  num_iters = 1;
  if (params.keyExists<int>("time-steps")) {
    num_steps = params.get<int>("time-steps");
  }

  if (params.keyExists<int>("iterations")) {
    num_iters = params.get<int>("iterations");
  }

  return (num_steps >= 1) && (num_iters >= 1);
}

QuatumSimulationResult
IterativeQpeWorkflow::execute(const QuatumSimulationModel &model) {
  // TODO:
  std::cout << "Howdy: execute\n";
  // 

  return {};
}