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

Merge branch 'master' into tnguyen/wip-ir-workshop-demo



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>

# Conflicts:
#	runtime/utils/qcor_utils.cpp
#	runtime/utils/qcor_utils.hpp
parents ced6909a ad011c77
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,3 +2,4 @@
#define QCOR_LIB_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}"
#define QCOR_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}"
#define XACC_ROOT "${XACC_ROOT}"
#define LLVM_ROOT "${LLVM_INSTALL_PREFIX}"
+1 −4
Original line number Diff line number Diff line
@@ -26,12 +26,10 @@ add_test(NAME qrt_add_3_5 COMMAND ${CMAKE_BINARY_DIR}/qcor -v -c ${CMAKE_CURRENT
add_qcor_compile_and_exe_test(qrt_mixed_language simple/mixed_language.cpp)
add_qcor_compile_and_exe_test(qrt_simple-demo simple/simple-demo.cpp)
add_qcor_compile_and_exe_test(qrt_deuteron_exp_inst deuteron/deuteron_exp_inst.cpp)
add_qcor_compile_and_exe_test(qrt_deuteron_task_initiate deuteron/deuteron_task_initiate.cpp)
add_qcor_compile_and_exe_test(qrt_qaoa_example qaoa/qaoa_example.cpp)
add_qcor_compile_and_exe_test(qrt_qpe_example qpe/qpe_example_qrt.cpp)
add_qcor_compile_and_exe_test(qrt_kernel_include simple/multiple_kernels.cpp)
add_qcor_compile_and_exe_test(qrt_grover grover/grover.cpp)
add_qcor_compile_and_exe_test(qrt_adapt hybrid/adapt_h2.cpp)
#add_qcor_compile_and_exe_test(compute_action_uncompute0 compute_action_uncompute/compute_action_uncompute_h2_ucc1_example.cpp)
add_qcor_compile_and_exe_test(compute_action_uncompute1 compute_action_uncompute/multiple_in_kernel.cpp)
add_qcor_compile_and_exe_test(compute_action_uncompute2 compute_action_uncompute/cau_capture_vars.cpp)
@@ -42,7 +40,7 @@ add_qcor_compile_and_exe_test(qrt_simple-implicit-parser argparse/simple-implici
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_simple ftqc_qrt/simple-demo.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_rus ftqc_qrt/repeat-until-success.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_qec ftqc_qrt/bit-flip-code.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_deuteron ftqc_qrt/deuteron.cpp)
# too long add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_deuteron ftqc_qrt/deuteron.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_bit_flip_qec_std_lib ftqc_qrt/error_correcting_code.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_five_qubit_qec_std_lib ftqc_qrt/five_qubit_qec_code.cpp)
add_qcor_ftqc_compile_and_exe_test(qrt_ftqc_steane_qec_std_lib ftqc_qrt/steane_qec_code.cpp)
@@ -62,7 +60,6 @@ add_qcor_compile_and_exe_test(multi_ctrl_test ctrl-gates/multiple_controls.cpp)

add_qcor_compile_and_exe_test(qrt_obj_func_simple simple/simple-objective-function.cpp)
add_qcor_compile_and_exe_test(qrt_kernel_autograd_simple simple/gradients_optimization.cpp)
add_qcor_compile_and_exe_test(qrt_hybrid_vqe_exe hybrid/deuteron_h2_vqe.cpp)
add_qcor_compile_and_exe_test(qrt_bell_ctrl bell/bell_control.cpp)

# Lambda tests

examples/adapt/adapt.cpp

deleted100644 → 0
+0 −143
Original line number Diff line number Diff line
#include "OperatorPool.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"

using ObservablePtr = std::shared_ptr<Observable>;

// Initial State is HF
__qpu__ void initial_state(qreg q) {
  X(q[0]);
  X(q[2]);
}

// Adapt Ansatz, grows as the vector of input Observables grows
__qpu__ void adapt_ansatz(qreg q, std::vector<double> x,
                          std::vector<ObservablePtr> ops) {
  initial_state(q);
  for (auto [i, op] : enumerate(ops)) {
    exp_i_theta(q, x[i], op);
  }
}

int main() {

  // Define the Hamiltonian using the QCOR API
  auto H = 0.1202 * Z(0) * Z(1) + 0.168336 * Z(0) * Z(2) +
           0.1202 * Z(2) * Z(3) + 0.17028 * Z(2) + 0.17028 * Z(0) +
           0.165607 * Z(0) * Z(3) + 0.0454063 * Y(0) * Y(1) * X(2) * X(3) -
           0.106477 - 0.220041 * Z(3) + 0.174073 * Z(1) * Z(3) +
           0.0454063 * Y(0) * Y(1) * Y(2) * Y(3) - 0.220041 * Z(1) +
           0.165607 * Z(1) * Z(2) + 0.0454063 * X(0) * X(1) * Y(2) * Y(3) +
           0.0454063 * X(0) * X(1) * X(2) * X(3);

  // Use XACC to generate the operator pool Ai
  auto pool =
      xacc::getService<xacc::quantum::OperatorPool>("singlet-adapted-uccsd");
  pool->optionalParameters({{"n-electrons", 2}});
  auto ops = pool->generate(H.nBits());

  // Compute all [H, Ai] commutators
  std::vector<ObservablePtr> commutators(ops.size());
  std::generate(commutators.begin(), commutators.end(),
                [n = 0, &H, &ops]() mutable {
                  auto c = H.commutator(ops[n]);
                  n++;
                  return c;
                });

  // Local Declarations
  double energy = 0.0;
  std::vector<double> x;
  std::vector<ObservablePtr> all_ops;

  // Get the Optimizer
  auto optimizer = createOptimizer("nlopt");

  // Allocate a qreg
  auto q = qalloc(H.nBits());

  // Create an ArgsTranslator to translate
  // vec<double> x -> qreg, vec<double> vec<ObservablePtr
  auto args_translator = std::make_shared<ArgsTranslator<
      qreg, std::vector<double>, std::vector<std::shared_ptr<Observable>>>>(
      [&](const std::vector<double> &xx) {
        return std::make_tuple(q, xx, all_ops);
      });

  // start ADAPT loop
  for (int iter = 0; iter < 100; iter++) {
    double max_grad = 0.0, grad_norm = 0.0;
    int max_grad_idx = 0, counter = 0;

    // Compute the gradient vector dEi = <[H,Ai]>
    std::vector<double> grad_vec(commutators.size());
    std::generate(grad_vec.begin(), grad_vec.end(), [&]() {
      // Create an ObjectiveFunction to compute <[H,Ai]>
      auto obj = createObjectiveFunction(adapt_ansatz, commutators[counter],
                                         args_translator, q, x.size());
      counter++;
      // compute the grad element <[H,Ai]>
      auto grad = (*obj)(x);
      // set the gradient norm
      grad_norm += grad * grad;
      return grad;
    });

    // grad_vec is filled, find the index of the max element
    auto max_idx = std::distance(
        grad_vec.begin(), std::max_element(grad_vec.begin(), grad_vec.end()));

    // Grow the list of operators to build the ansatz
    all_ops.push_back(ops[max_idx]);

    // Check for convergence
    if (grad_norm < 1e-6) {
      std::cout << "Converged on gradient norm\n";
      break;
    }

    // Add a new parameter to the ansatz params
    x.push_back(0.0);

    // Create another ObjectiveFunction to
    // run the VQE min
    auto vqe =
        createObjectiveFunction(adapt_ansatz, H, args_translator, q, x.size());

    // Set the initial parameters
    optimizer->appendOption("initial-parameters", x);

    // Run task initiate and sync
    auto handle = taskInitiate(vqe, optimizer);
    auto results = sync(handle);

    // Get the energy
    energy = results.opt_val;

    // Get the current optimal params
    x = results.opt_params;

    std::cout << "Current Adapt Energy = " << energy << "\n";
  }

  std::cout << "Adapt computing energy = " << energy << "\n";
  std::cout << "Number of Adapt Parameters = " << x.size() << "\n";
  std::cout << "Adapt Optimal Parameters = [";
  for (auto xx : x) {
    std::cout << xx << " ";
  }
  std::cout << "]\n";

  // Run the kernel
  {
    class adapt_ansatz t(qalloc(H.nBits()), x, all_ops);
    t.optimize_only = true;
    // kernel executed upon destruction,
    // will only build up circuit and run pass manager
  }
  std::cout << "NInsts: " << quantum::program->nInstructions() << "\n";
  std::cout << "Number of Adapt Ansatz Gates: "
            << quantum::program->nInstructions() << "\n";

  return 0;
}
 No newline at end of file
+1 −2
Original line number Diff line number Diff line
#include <qcor_hadamard_test>
using FO = FermionOperator;

int main() {

  std::vector<FermionOperator> exp_args{
  std::vector<Operator> exp_args{
      -4 * adag(0) * a(0) - 4 * adag(2) * a(2) +
          8 * adag(0) * a(0) * adag(2) * a(2),
      0.01 * adag(0) * a(1) + .01 * adag(3) * a(2) + .01 * adag(1) * a(0) +
+5 −2
Original line number Diff line number Diff line
@@ -9,18 +9,21 @@ int main(int argc, char **argv) {
  // Allocate 2 qubits
  auto q = qalloc(2);

  ansatz::print_kernel(q, 2.2);
  // Create the Deuteron Hamiltonian
  auto H = createObservable(
      "5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1");

  qcor::set_verbose(true);
  // Create the objective function
  auto objective = createObjectiveFunction(ansatz, H, q, 1);

  print(objective->operator()(std::vector<double>{2.2}));
  // Create a qcor Optimizer
  auto optimizer = createOptimizer("nlopt");

  // Optimize the above function
  auto [optval, opt_params] = optimizer->optimize(*objective.get());
  auto [optval, opt_params] = optimizer->optimize(objective);

  // Print the result
  printf("energy = %f\n", optval);
Loading