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

Add default cost/obj eval based on existing vqe algo



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 78d58e8b
Loading
Loading
Loading
Loading
+12 −24
Original line number Diff line number Diff line
@@ -5,31 +5,8 @@ namespace qcor {
bool CostFunctionEvaluator::initialize(Observable *observable,
                                       const HeterogeneousMap &params) {
  target_operator = observable;
  // TODO: use qcor data
  quantum_backend = nullptr;
  if (params.pointerLikeExists<Accelerator>("accelerator")) {
    quantum_backend = params.getPointerLike<Accelerator>("accelerator");
  }

  hyperParams = params;
  return target_operator && quantum_backend;
}

CostFunctionEvaluator *CostFunctionEvaluator::getInstance() {
  if (!instance) {
    instance = new CostFunctionEvaluator();
  }
  return instance;
}

double CostFunctionEvaluator::evaluate(
    std::shared_ptr<CompositeInstruction> state_prep) {

  // Measure the observables:
  // TODO: Port the existing VQE impl. as the default.

  // TODO:
  return 0.0;
  return target_operator != nullptr;
}

QuatumSimulationModel
@@ -68,4 +45,15 @@ getWorkflow(const std::string &name, const HeterogeneousMap &init_params) {
  // ERROR: unknown workflow or invalid initialization options.
  return nullptr;
}

std::shared_ptr<CostFunctionEvaluator>
getObjEvaluator(Observable *observable, const std::string &name,
                const HeterogeneousMap &init_params) {
  auto evaluator = xacc::getService<CostFunctionEvaluator>(name);
  if (evaluator && evaluator->initialize(observable, init_params)) {
    return evaluator;
  }
  // ERROR: unknown CostFunctionEvaluator or invalid initialization options.
  return nullptr;
}
} // namespace qcor
 No newline at end of file
+8 −8
Original line number Diff line number Diff line
@@ -39,21 +39,16 @@ public:
// CostFunctionEvaluator take an unknown quantum state (the circuit that
// prepares the unknown state) and a target operator (e.g. Hamiltonian
// Observable) as input and produce a estimation as output.
class CostFunctionEvaluator {
class CostFunctionEvaluator : public Identifiable {
public:
  // Evaluate the cost
  virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep);
  virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep) = 0;
  virtual bool initialize(Observable *observable,
                          const HeterogeneousMap &params = {});
  static CostFunctionEvaluator *getInstance();

protected:
  Observable *target_operator;
  Accelerator *quantum_backend;
  HeterogeneousMap hyperParams;

private:
  static inline CostFunctionEvaluator *instance = nullptr;
};

// Trotter time-dependent simulation workflow
@@ -140,10 +135,15 @@ public:
  execute(const QuatumSimulationModel &model) = 0;

protected:
  CostFunctionEvaluator *evaluator;
  std::shared_ptr<CostFunctionEvaluator> evaluator;
};

// Get workflow by name:
std::shared_ptr<QuatumSimulationWorkflow>
getWorkflow(const std::string &name, const HeterogeneousMap &init_params);

// Get the Obj (cost) function evaluator:
std::shared_ptr<CostFunctionEvaluator>
getObjEvaluator(Observable *observable, const std::string &name = "default",
                const HeterogeneousMap &init_params = {});
} // namespace qcor
 No newline at end of file
+19 −16
Original line number Diff line number Diff line
@@ -43,10 +43,7 @@ bool TimeDependentWorkflow::initialize(const HeterogeneousMap &params) {
QuatumSimulationResult
TimeDependentWorkflow::execute(const QuatumSimulationModel &model) {
  QuatumSimulationResult result;

  // TODO: support multiple evaluator
  evaluator = CostFunctionEvaluator::getInstance();
  evaluator->initialize(model.observable);
  evaluator = getObjEvaluator(model.observable);
  auto ham_func = model.hamiltonian;
  // A TD workflow: stepping through Trotter steps,
  // compute expectations at each step.
@@ -70,6 +67,7 @@ TimeDependentWorkflow::execute(const QuatumSimulationModel &model) {

    // Evaluate the expectation after these Trotter steps:
    const double ham_expect = evaluator->evaluate(totalCirc);
    std::cout << "<Ham> = " << ham_expect << "\n";
    resultExpectationValues.emplace_back(ham_expect);

    currentTime += dt;
@@ -100,23 +98,13 @@ VqeWorkflow::execute(const QuatumSimulationModel &model) {
  // If the model includes a concrete variational ansatz:
  if (model.user_defined_ansatz) {
    auto nParams = model.user_defined_ansatz->nParams();
    auto vqe = xacc::getAlgorithm("vqe");
    evaluator = getObjEvaluator(model.observable);
    auto qpu = xacc::internal_compiler::get_qpu();

    OptFunction f(
        [&](const std::vector<double> &x, std::vector<double> &dx) {
          auto kernel = model.user_defined_ansatz->evaluate_kernel(x);
          // std::cout << "Kernel:\n" << kernel->toString() << "\n";
          auto success = vqe->initialize({{"ansatz", kernel},
                                          {"accelerator", qpu},
                                          {"observable", model.observable}});
          if (!success) {
            xacc::error("QCOR VQE Workflow Error - could not initialize "
                        "internal xacc vqe algorithm.");
          }
          auto tmp_child = qalloc(model.user_defined_ansatz->getQreg().size());
          auto energy =
              vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0];
          auto energy = evaluator->evaluate(kernel);
          return energy;
        },
        nParams);
@@ -139,6 +127,19 @@ getWorkflow(const std::string &name, const HeterogeneousMap &init_params) {
  // ERROR: unknown workflow or invalid initialization options.
  return nullptr;
}

double
DefaultObjFuncEval::evaluate(std::shared_ptr<CompositeInstruction> state_prep) {
  // Reuse existing VQE util to evaluate the expectation value:
  auto vqe = xacc::getAlgorithm("vqe");
  auto qpu = xacc::internal_compiler::get_qpu();
  vqe->initialize({{"ansatz", state_prep},
                   {"accelerator", qpu},
                   {"observable", target_operator}});
  auto tmp_child = qalloc(state_prep->nPhysicalBits());
  auto energy = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0];
  return energy;
}
} // namespace qcor

#include "cppmicroservices/BundleActivator.h"
@@ -156,6 +157,8 @@ public:
        std::make_shared<qcor::TimeDependentWorkflow>());
    context.RegisterService<qcor::QuatumSimulationWorkflow>(
        std::make_shared<qcor::VqeWorkflow>());
    context.RegisterService<qcor::CostFunctionEvaluator>(
        std::make_shared<qcor::DefaultObjFuncEval>());
  }

  void Stop(BundleContext) {}
+9 −0
Original line number Diff line number Diff line
@@ -70,4 +70,13 @@ private:
  double dt;
  TdObservable ham_func;
};

class DefaultObjFuncEval : public CostFunctionEvaluator {
public:
  // Evaluate the cost
  virtual double
  evaluate(std::shared_ptr<CompositeInstruction> state_prep) override;
  virtual const std::string name() const override { return "default"; }
  virtual const std::string description() const override { return ""; }
};
} // namespace qcor
 No newline at end of file
+1 −3
Original line number Diff line number Diff line
#include "base/qcor_qsim.hpp"
// TODO: fix so that this can be build w/ the QCOR compiler.
using namespace qcor;
#include "qcor_qsim.hpp"

// High-level usage of Model Builder
int main(int argc, char **argv) {