Commit 15dd8ba2 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Removed need for variadic createObjectiveFunction function, kernel created in...


Removed need for variadic createObjectiveFunction function, kernel created in variadic operator() method now

Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent b4be1767
Loading
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -25,8 +25,7 @@ int main(int argc, char **argv) {
  // need to provide ansatz and the Observable
  // Must also provide initial params for ansatz (under the hood, uses
  // variadic template)
  auto objective = qcor::createObjectiveFunction("vqe", ansatz, H, q,
                                                 std::vector<double>(10));
  auto objective = qcor::createObjectiveFunction("vqe", ansatz, H);


  qcor::OptFunction f(
+2 −2
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ int main(int argc, char **argv) {
  // need to provide ansatz and the Observable
  // Must also provide initial params for ansatz (under the hood, uses 
  // variadic template)
  auto objective = qcor::createObjectiveFunction("vqe", ansatz, H, q, 0.0);
  auto objective = qcor::createObjectiveFunction("vqe", ansatz, H);

  // Evaluate the ObjectiveFunction at a specified set of parameters
  auto energy = (*objective)(q, .59);
@@ -51,7 +51,7 @@ int main(int argc, char **argv) {
  q.reset();

  // Create the Objective again
  auto objective2 = qcor::createObjectiveFunction("vqe", ansatz2, H, q, std::vector<double>{0.0});
  auto objective2 = qcor::createObjectiveFunction("vqe", ansatz2, H);

  // Evaluate, but with a vector
  energy = (*objective2)(q, std::vector<double>{.59});
+24 −0
Original line number Diff line number Diff line
#include "qcor.hpp"

__qpu__ void ansatz(qreg q, double theta) {
  X(q[0]);
  Ry(q[1], theta);
  CX(q[1],q[0]);
}

int main(int argc, char **argv) {
  // Allocate 2 qubits
  auto q = qalloc(2);

  // Create the Deuteron Hamiltonian (Observable)
  auto H = qcor::getObservable(
      "5.907 - 2.1433 X0X1 - 2.1433 Y0Y1 + .21829 Z0 - 6.125 Z1");

  // Create the ObjectiveFunction, here we want to run VQE
  // need to provide ansatz and the Observable
  auto objective = qcor::createObjectiveFunction("vqe", ansatz, H);

  // Evaluate the ObjectiveFunction at a specified set of parameters
  auto energy = (*objective)(q, .59);
  printf("vqe-energy = %f\n", energy);
}
+51 −33
Original line number Diff line number Diff line
@@ -12,35 +12,11 @@
namespace qcor {

using OptFunction = xacc::OptFunction;
using HeterogeneousMap = xacc::HeterogeneousMap;

void set_verbose(bool verbose);

class ObjectiveFunction : public xacc::Identifiable {
protected:
  std::shared_ptr<xacc::Observable> observable;
  xacc::CompositeInstruction * kernel;
  xacc::internal_compiler::qreg qreg;

  virtual double operator()() = 0;

public:
  ObjectiveFunction() = default;
  virtual void initialize(std::shared_ptr<xacc::Observable> obs,
                          xacc::CompositeInstruction * qk) {
    observable = obs;
    kernel = qk;
  }

  void set_qreg(xacc::internal_compiler::qreg q) {
      qreg = q;
  }
  template <typename... ArgumentTypes>
  double operator()(ArgumentTypes... args) {
    kernel->updateRuntimeArguments(args...);
    return operator()();
  }
};

class ObjectiveFunction;

namespace __internal__ {

@@ -75,6 +51,49 @@ std::shared_ptr<ObjectiveFunction> get_objective(const char * type);

} // namespace __internal__


class ObjectiveFunction : public xacc::Identifiable {
protected:
  std::shared_ptr<xacc::Observable> observable;
  xacc::CompositeInstruction * kernel;
  xacc::internal_compiler::qreg qreg;
  void * pointer_to_functor = nullptr;

  virtual double operator()() = 0;

public:
  // Publicly visible to clients for use in OptFunctions
  std::vector<double> current_gradient;

  ObjectiveFunction() = default;
  virtual void initialize(std::shared_ptr<xacc::Observable> obs,
                          xacc::CompositeInstruction * qk) {
    observable = obs;
    kernel = qk;
  }

  virtual void initialize(std::shared_ptr<xacc::Observable> obs,
                          void * qk) {
    observable = obs;
    pointer_to_functor = qk;
  }

  void set_qreg(xacc::internal_compiler::qreg q) {
      qreg = q;
  }

  template <typename... ArgumentTypes>
  double operator()(ArgumentTypes... args) {
    if (!kernel) {
       auto functor = reinterpret_cast<void (*)(ArgumentTypes...)>(pointer_to_functor);
       kernel = __internal__::kernel_as_composite_instruction(functor, args...);
       qreg = std::get<0>(std::forward_as_tuple(args...));
    }
    kernel->updateRuntimeArguments(args...);
    return operator()();
  }
};

template <typename QuantumKernel, typename... Args>
auto observe(QuantumKernel &kernel, std::shared_ptr<xacc::Observable> obs,
             Args... args) {
@@ -110,16 +129,15 @@ xacc::Optimizer *getOptimizer();
// Get a pauli observable from a string representation
std::shared_ptr<xacc::Observable> getObservable(const char *repr);

template <typename QuantumKernel, typename... KernelArguments>
template <typename QuantumKernel>
std::shared_ptr<ObjectiveFunction>
createObjectiveFunction(const char *obj_name, QuantumKernel &kernel,
                        std::shared_ptr<xacc::Observable> observable,
                        KernelArguments... args) {
                        std::shared_ptr<xacc::Observable> observable) {
  auto obj_func = qcor::__internal__::get_objective(obj_name);
  auto q = std::get<0>(std::forward_as_tuple(args...));
  obj_func->set_qreg(q);
  auto program = __internal__::kernel_as_composite_instruction(kernel, args...);
  obj_func->initialize(observable, program);
  // We can store this function pointer to a void* on ObjectiveFunction
  // to be converted to CompositeInstruction later
  void* kk = reinterpret_cast<void*>(kernel);
  obj_func->initialize(observable, kk);
  return obj_func;
}