Commit 23ce9bb1 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Got qaoa working with new quantum kernel work

parent 0f2565dd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

__qpu__ void qaoa_ansatz(qreg q, int n_steps, std::vector<double> gamma,
                         std::vector<double> beta,
                         qcor::PauliOperator &cost_ham) {
                         qcor::PauliOperator cost_ham) {

  // Local Declarations
  auto nQubits = q.size();
@@ -77,7 +77,7 @@ int main(int argc, char **argv) {
            std::vector<double> gamma(x.begin(), x.begin() + nSteps * nGamma),
                beta(x.begin() + nSteps * nGamma,
                     x.begin() + nSteps * nGamma + nSteps * nBeta);
            return std::make_tuple(qalloc(4), nSteps, gamma, beta, cost_ham);
            return std::tuple(qalloc(4), nSteps, gamma, beta, cost_ham);
          });

  qcor::set_verbose(true);
+0 −61
Original line number Diff line number Diff line
// In this demo, we use a built-in QAOA ansatz circuit
// with QCOR's VQE Objective Function.
// Note: we can also explicitly construct this ansatz circuit in QCOR.
// e.g., see qaoa_example.cpp
#include "qcor.hpp"
#include <qalloc>

__qpu__ void qaoa_ansatz(qreg q, int n, std::vector<double> betas,
                         std::vector<double> gammas,
                         qcor::PauliOperator &costHamiltonian,
                         qcor::PauliOperator &refHamiltonian) {
  // Just use the built-in qaoa circuit
  qaoa(q, n, betas, gammas, costHamiltonian, refHamiltonian);
}

// Compile (using Qpp simulator backend)
// qcor -o qaoa-example -qpu qpp qaoa-builtin-circuit.cpp
int main(int argc, char **argv) {
  auto buffer = qalloc(2);
  auto optimizer = qcor::createOptimizer("nlopt");
  // Cost Hamiltonian
  auto observable = 5.907 - 2.1433 * qcor::X(0) * qcor::X(1) -
                    2.1433 * qcor::Y(0) * qcor::Y(1) + 0.21829 * qcor::Z(0) -
                    6.125 * qcor::Z(1);
  // Mixer Hamiltonian
  auto refHamiltonian = qcor::X(0) + qcor::X(1);

  // VQE objective function
  auto vqe = qcor::createObjectiveFunction("vqe", qaoa_ansatz, observable);
  vqe->set_qreg(buffer);

  // QAOA variational parameters
  const int nbSteps = 2;
  const int nbParamsPerStep = 2 /*beta (mixer)*/ + 4 /*gamma (cost)*/;
  const int totalParams = nbSteps * nbParamsPerStep;
  int iterCount = 0;
  // Optimization function
  qcor::OptFunction f(
      [&](const std::vector<double> x, std::vector<double> &grad) {
        std::vector<double> betas;
        std::vector<double> gammas;
        // Unpack nlopt params
        // Beta: nbSteps * number qubits
        for (int i = 0; i < nbSteps * buffer.size(); ++i) {
          betas.emplace_back(x[i]);
        }

        for (int i = betas.size(); i < x.size(); ++i) {
          gammas.emplace_back(x[i]);
        }
        // Evaluate the objective function
        const double costVal = (*vqe)(buffer, buffer.size(), betas, gammas,
                                      observable, refHamiltonian);
        std::cout << "Iter " << iterCount << ": Cost = " << costVal << "\n";
        iterCount++;
        return costVal;
      },
      totalParams);
  auto results = optimizer->optimize(f);
  std::cout << "Final cost: " << results.first << "\n";
}
+2 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ protected:
  inline static const std::string DEFAULT_OPTIMIZER = "nlopt";

  // Reference to the paramerized
  // quantum kernel functor
  // quantum kernel functor as a void pointer
  void *ansatz_ptr;

  // Reference to the Hamiltonian / Observable,
@@ -175,6 +175,7 @@ public:
    // Create the Arg Translator
    TranslationFunctor<qreg, KernelArgs...> arg_translator;
    if (translation_functor.has_value()) {
        std::cout << "Using this arg translator\n";
      arg_translator = std::any_cast<TranslationFunctor<qreg, KernelArgs...>>(
          translation_functor);
    } else {