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

Port FTQC VQE to standard lib



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 9b77d7ab
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -14,3 +14,4 @@ add_test(NAME qrt_adapt COMMAND ${CMAKE_BINARY_DIR}/qcor -c ${CMAKE_CURRENT_SOUR
add_test(NAME qrt_ftqc_simple COMMAND ${CMAKE_BINARY_DIR}/qcor -c -qrt ftqc ${CMAKE_CURRENT_SOURCE_DIR}/ftqc_qrt/simple-demo.cpp)
add_test(NAME qrt_ftqc_rus COMMAND ${CMAKE_BINARY_DIR}/qcor -c -qrt ftqc ${CMAKE_CURRENT_SOURCE_DIR}/ftqc_qrt/repeat-until-success.cpp)
add_test(NAME qrt_ftqc_qec COMMAND ${CMAKE_BINARY_DIR}/qcor -c -qrt ftqc ${CMAKE_CURRENT_SOURCE_DIR}/ftqc_qrt/bit-flip-code.cpp)
add_test(NAME qrt_ftqc_deuteron COMMAND ${CMAKE_BINARY_DIR}/qcor -c -qrt ftqc ${CMAKE_CURRENT_SOURCE_DIR}/ftqc_qrt/deuteron.cpp)
 No newline at end of file
+4 −7
Original line number Diff line number Diff line
#include "ftqc/vqe.hpp"
#include "xacc.hpp"
#include <qcor_vqe>

// Compile with:
// qcor -qpu qpp -qrt ftqc -I<qcor/examples/shared> deuteron.cpp 
// qcor -qpu qpp -qrt ftqc deuteron.cpp 

__qpu__ void ansatz(qreg q, double theta) {
  X(q[0]);
@@ -15,10 +16,6 @@ int main(int argc, char **argv) {
  // Hamiltonian
  auto H = 5.907 - 2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) -
           6.125 * Z(1);
  // TODO:
  // We can hook this up to the QCOR's Objective function
  // The amount of code to manually instantiate the optimization loop here is
  // also very minimal.
  auto optimizer = createOptimizer("nlopt");
  xacc::OptFunction f(
      [&](const std::vector<double> &x, std::vector<double> &dx) {
@@ -26,7 +23,7 @@ int main(int argc, char **argv) {
        auto statePrep =
            std::function<void(qreg)>{[angle](qreg q) { ansatz(q, angle); }};
        double energy = 0.0;
        EstimateEnergy(q, statePrep, H, 1024, energy);
        ftqc::estimate_energy(q, statePrep, H, 1024, energy);
        std::cout << "Energy(" << angle << ") = " << energy << "\n";
        return energy;
      },
+19 −11
Original line number Diff line number Diff line
@@ -4,7 +4,13 @@
#include "qcor_observable.hpp"
#include <qcor_common>

__qpu__ void EstimateTermExpectation(qreg q, const std::function<void(qreg)>& statePrep, std::vector<qcor::PauliOperator> bases, int nSamples, double& out_energy) {

#ifdef _QCOR_FTQC_RUNTIME
namespace ftqc {
__qpu__ void estimate_term_expectation(qreg q,
                                     const std::function<void(qreg)> &statePrep,
                                     std::vector<qcor::PauliOperator> bases,
                                     int nSamples, double &out_energy) {
  double sum = 0.0;
  for (int i = 0; i < nSamples; ++i) {
    statePrep(q);
@@ -20,8 +26,8 @@ __qpu__ void EstimateTermExpectation(qreg q, const std::function<void(qreg)>& st
  out_energy = sum / nSamples;
}

// Estimates the energy of a Pauli observable by summing the energy contributed by the individual terms.
// Input:
// Estimates the energy of a Pauli observable by summing the energy contributed
// by the individual terms. Input:
// - observable
// The Pauli Hamiltonian.
// - nSamples
@@ -29,7 +35,9 @@ __qpu__ void EstimateTermExpectation(qreg q, const std::function<void(qreg)>& st
//
// Output
// The estimated energy of the observable
__qpu__ void EstimateEnergy(qreg q, const std::function<void(qreg)>& statePrep, qcor::PauliOperator observable, int nSamples, double& out_energy) {
__qpu__ void estimate_energy(qreg q, const std::function<void(qreg)> &statePrep,
                            qcor::PauliOperator observable, int nSamples,
                            double &out_energy) {
  std::complex<double> energy = 0.0;
  for (auto &[termStr, pauliInst] : observable.getTerms()) {
    auto coeff = pauliInst.coeff();
@@ -48,14 +56,14 @@ __qpu__ void EstimateEnergy(qreg q, const std::function<void(qreg)>& statePrep,
    }
    if (!ops.empty()) {
      double termEnergy = 0.0;
      EstimateTermExpectation(q, statePrep, ops, nSamples, termEnergy);
      estimate_term_expectation(q, statePrep, ops, nSamples, termEnergy);
      energy = energy + (coeff * termEnergy);
    }
    else {
    } else {
      // Identity term:
      energy = energy + coeff;
    }
  }
  out_energy = energy.real();
}
} // namespace ftqc
#endif

lib/qcor_vqe

0 → 100644
+2 −0
Original line number Diff line number Diff line
#pragma once
#include "impl/vqe.hpp"