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

Implemented QAOA for qsim



Also, move qsim vqe test to the new location.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent e7ca6510
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,4 +39,5 @@ install(TARGETS ${LIBRARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/plugins)

if (QCOR_BUILD_TESTS)
  add_subdirectory(cost_evaluator/tests)
  add_subdirectory(workflow/tests)
endif()
 No newline at end of file
+1 −6
Original line number Diff line number Diff line
@@ -11,8 +11,3 @@ add_test(NAME qcor_TimeSeriesQpeNoiseTester COMMAND TimeSeriesQpeNoiseTester)
target_include_directories(TimeSeriesQpeNoiseTester PRIVATE ../../ ../../../base ${XACC_ROOT}/include/gtest ${XACC_ROOT}/include/eigen)
target_compile_definitions(TimeSeriesQpeNoiseTester PRIVATE RESOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources")
target_link_libraries(TimeSeriesQpeNoiseTester ${XACC_TEST_LIBRARIES} xacc::xacc xacc::quantum_gate qcor-qsim)
 No newline at end of file

add_executable(VqeWorkflowTester VqeWorkflowTester.cpp)
add_test(NAME qcor_VqeWorkflowTester COMMAND VqeWorkflowTester)
target_include_directories(VqeWorkflowTester PRIVATE ../../ ../../../base ${XACC_ROOT}/include/gtest)
target_link_libraries(VqeWorkflowTester ${XACC_TEST_LIBRARIES} xacc::xacc xacc::quantum_gate qcor-qsim)
 No newline at end of file
+81 −2
Original line number Diff line number Diff line
#include "qaoa.hpp"
#include "AlgorithmGradientStrategy.hpp"
#include "qsim_utils.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"

namespace qcor {
namespace qsim {
@@ -17,8 +21,83 @@ bool QaoaWorkflow::initialize(const HeterogeneousMap &params) {

QuantumSimulationResult
QaoaWorkflow::execute(const QuantumSimulationModel &model) {
  // TODO
  return {};
  int nbSteps = 1;
  if (config_params.keyExists<int>("steps")) {
    nbSteps = config_params.get<int>("steps");
  }

  std::string parameterScheme = "Standard";
  if (config_params.stringExists("parameter-scheme")) {
    parameterScheme = config_params.getString("parameter-scheme");
  }

  auto qaoa_kernel = std::dynamic_pointer_cast<xacc::CompositeInstruction>(
      xacc::getService<xacc::Instruction>("qaoa"));
  qaoa_kernel->expand({{"nbQubits", model.observable->nBits()},
                       {"nbSteps", nbSteps},
                       {"cost-ham", model.observable},
                       {"parameter-scheme", parameterScheme}});
  evaluator = getEvaluator(model.observable, config_params);
  size_t nParams = qaoa_kernel->nVariables();
  assert(nParams > 1);
  const std::vector<double> init_params =
      qcor::random_vector(-1.0, 1.0, nParams);
  optimizer->appendOption("initial-parameters", init_params);
  std::shared_ptr<xacc::AlgorithmGradientStrategy> gradient_strategy;
  if (optimizer->isGradientBased()) {
    if (config_params.stringExists("gradient-strategy")) {
      gradient_strategy = xacc::getService<xacc::AlgorithmGradientStrategy>(
          config_params.getString("gradient-strategy"));
    } else {
      // Default is to use autodiff
      gradient_strategy =
          xacc::getService<xacc::AlgorithmGradientStrategy>("autodiff");
    }
    gradient_strategy->initialize(
        {{"observable", xacc::as_shared_ptr(model.observable)}});
  }

  OptFunction f(
      [&](const std::vector<double> &x, std::vector<double> &dx) {
        auto kernel = qaoa_kernel->operator()(x);
        auto energy = evaluator->evaluate(kernel);
        if (gradient_strategy) {
          if (gradient_strategy->isNumerical()) {
            gradient_strategy->setFunctionValue(
                energy -
                (model.observable->getIdentitySubTerm() ? std::real(
                    model.observable->getIdentitySubTerm()->coefficient()) : 0.0));
          }

          auto grad_kernels =
              gradient_strategy->getGradientExecutions(qaoa_kernel, x);

          if (!grad_kernels.empty()) {
            auto tmp_grad = qalloc(model.observable->nBits());
            // Important note: these gradient kernels (not using the qsim
            // evaluator) need to be processed by the pass manager (e.g. perform
            // placement).
            executePassManager(grad_kernels);
            xacc::internal_compiler::execute(tmp_grad.results(), grad_kernels);
            auto tmp_grad_children = tmp_grad.results()->getChildren();
            gradient_strategy->compute(dx, tmp_grad_children);
          }
          // This is an autodiff gradient calculation:
          else {
            gradient_strategy->compute(dx, {});
          }
        }
        // std::cout << "E(";
        // for (const auto &val : x) {
        //   std::cout << val << ",";
        // }
        // std::cout << ") = " << energy << "\n";
        return energy;
      },
      nParams);

  auto result = optimizer->optimize(f);
  return {{"energy", (double)result.first}, {"opt-params", result.second}};
}
} // namespace qsim
} // namespace qcor
 No newline at end of file
+11 −0
Original line number Diff line number Diff line
link_directories(${XACC_ROOT}/lib)

add_executable(VqeWorkflowTester VqeWorkflowTester.cpp)
add_test(NAME qcor_VqeWorkflowTester COMMAND VqeWorkflowTester)
target_include_directories(VqeWorkflowTester PRIVATE ../../ ../../../base ${XACC_ROOT}/include/gtest)
target_link_libraries(VqeWorkflowTester ${XACC_TEST_LIBRARIES} xacc::xacc xacc::quantum_gate qcor-qsim)

add_executable(QaoaWorkflowTester QaoaWorkflowTester.cpp)
add_test(NAME QaoaWorkflowTester COMMAND QaoaWorkflowTester)
target_include_directories(QaoaWorkflowTester PRIVATE ../../ ../../../base ${XACC_ROOT}/include/gtest)
target_link_libraries(QaoaWorkflowTester ${XACC_TEST_LIBRARIES} xacc::xacc xacc::quantum_gate qcor-qsim)
 No newline at end of file
+40 −0
Original line number Diff line number Diff line
#include "qcor.hpp"
#include "qcor_qsim.hpp"
#include "xacc.hpp"
#include <gtest/gtest.h>

TEST(QaoaWorkflowTester, checkGradientFree) {
  using namespace qcor;
  auto observable = 5.907 - 2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) +
                    .21829 * Z(0) - 6.125 * Z(1);
  xacc::internal_compiler::qpu = xacc::getAccelerator("qsim");
  auto problemModel = qsim::ModelBuilder::createModel(&observable);
  auto optimizer = createOptimizer("nlopt", {{"nlopt-maxeval", 500}});
  auto workflow = qsim::getWorkflow("qaoa", {{"optimizer", optimizer}, {"steps", 8}});
  auto result = workflow->execute(problemModel);
  const auto energy = result.get<double>("energy");
  std::cout << "Min energy: " << energy << "\n";
  EXPECT_NEAR(energy, -1.74, 0.25);
}

TEST(QaoaWorkflowTester, checkGradient) {
  using namespace qcor;
  auto observable = Z(0)*Z(1) + Z(0)*Z(2) + Z(1)*Z(2);
  xacc::internal_compiler::qpu = xacc::getAccelerator("qpp");
  auto problemModel = qsim::ModelBuilder::createModel(&observable);
  auto optimizer = createOptimizer("mlpack");
  auto workflow = qsim::getWorkflow("qaoa", {{"optimizer", optimizer}});
  auto result = workflow->execute(problemModel);
  const auto energy = result.get<double>("energy");
  std::cout << "Min energy: " << energy << "\n";
  const double maxCutVal = -0.5*energy + 0.5*3;
  EXPECT_NEAR(maxCutVal, 2.0, 0.1);
}

int main(int argc, char **argv) {
  xacc::Initialize();
  ::testing::InitGoogleTest(&argc, argv);
  auto ret = RUN_ALL_TESTS();
  xacc::Finalize();
  return ret;
}
 No newline at end of file
Loading