Commit 60af5b4f authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding a few more taskInitiate variants, adding qcor runtime tester

parent 5bcc5e6e
Loading
Loading
Loading
Loading
Loading
+42 −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::createObservable(
      "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);

  // Create the Optimizer
  auto optimizer = qcor::createOptimizer("nlopt");

  // Create mechanism for mapping Optimizer std::vector<double> parameters 
  // to the ObjectiveFunction variadic arguments of qreg and double
  auto args_translation = qcor::TranslationFunctor<qreg, double>(
      [&](const std::vector<double> x) { return std::make_tuple(q, x[0]); });

  // Call taskInitiate, kick off optimization of the give
  // functor dependent on the ObjectiveFunction, async call
  // Need to translate Optimizer std::vector<double> x params to Objective 
  // Function evaluation args qreg, double.
  auto handle = qcor::taskInitiate(objective, optimizer, args_translation, 1);

  // Go do other work...

  // Query results when ready.
  auto results = qcor::sync(handle);

  // Print the optimal value.
  printf("<H> = %f\n", results.opt_val);
}
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ install(FILES ${HEADERS} DESTINATION include/qcor)
install(TARGETS ${LIBRARY_NAME} DESTINATION lib)

if (QCOR_BUILD_TESTS)
  #add_subdirectory(tests)
  add_subdirectory(tests)
endif()

add_subdirectory(objectives)
 No newline at end of file
+40 −0
Original line number Diff line number Diff line
@@ -59,4 +59,44 @@ std::shared_ptr<xacc::CompositeInstruction> compile(const std::string &src) {
  return xacc::getCompiler("xasm")->compile(src)->getComposites()[0];
}

Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer,
                    std::function<double(const std::vector<double>,
                                         std::vector<double> &)> &&opt_function,
                    const int nParameters) {
  return std::async(std::launch::async, [=]() -> ResultsBuffer {
    qcor::OptFunction f(opt_function, nParameters);
    auto results = optimizer->optimize(f);
    ResultsBuffer rb;
    rb.q_buffer = objective->get_qreg();
    rb.opt_params = results.second;
    rb.opt_val = results.first;
    return rb;
  });
}

Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer, qcor::OptFunction &&opt_function) {
  return std::async(std::launch::async, [=, &opt_function]() -> ResultsBuffer {
    auto results = optimizer->optimize(opt_function);
    ResultsBuffer rb;
    rb.q_buffer = objective->get_qreg();
    rb.opt_params = results.second;
    rb.opt_val = results.first;
    return rb;
  });
}

Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer, qcor::OptFunction &opt_function) {
  return std::async(std::launch::async, [=, &opt_function]() -> ResultsBuffer {
    auto results = optimizer->optimize(opt_function);
    ResultsBuffer rb;
    rb.q_buffer = objective->get_qreg();
    rb.opt_params = results.second;
    rb.opt_val = results.first;
    return rb;
  });
}

} // namespace qcor
 No newline at end of file
+51 −19
Original line number Diff line number Diff line
#ifndef RUNTIME_QCOR_HPP_
#define RUNTIME_QCOR_HPP_

#include <functional>
#include <future>
#include <memory>
#include <tuple>

#include "CompositeInstruction.hpp"
#include "Observable.hpp"
@@ -26,16 +28,37 @@ public:
};

using Handle = std::future<ResultsBuffer>;
ResultsBuffer sync(Handle& handle) {
    return handle.get();
}
ResultsBuffer sync(Handle &handle) { return handle.get(); }

void set_verbose(bool verbose);

class ObjectiveFunction;

template <typename... Args> class ArgTranslator {
public:
  std::function<std::tuple<Args...>(std::vector<double>)> t;
  ArgTranslator(std::function<std::tuple<Args...>(std::vector<double> x)> &&ts)
      : t(ts) {}

  std::tuple<Args...> operator()(std::vector<double> x) { return t(x); }
};

template <typename... Args>
using TranslationFunctor =
    std::function<std::tuple<Args...>(const std::vector<double>)>;

namespace __internal__ {

template <typename Function, typename Tuple, size_t... I>
auto call(Function f, Tuple t, std::index_sequence<I...>) {
  return f->operator()(std::get<I>(t)...);
}

template <typename Function, typename Tuple> auto call(Function f, Tuple t) {
  static constexpr auto size = std::tuple_size<Tuple>::value;
  return call(f, t, std::make_index_sequence<size>{});
}

// Given a quantum kernel functor / function pointer, create the xacc
// CompositeInstruction representation of it
template <typename QuantumKernel, typename... Args>
@@ -223,23 +246,32 @@ createObjectiveFunction(const char *obj_name, QuantumKernel &kernel,
  return obj_func;
}

Handle taskInitiate(
    std::shared_ptr<ObjectiveFunction> objective,
Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer,
                    std::function<double(const std::vector<double>,
                                         std::vector<double> &)> &&opt_function,
                    const int nParameters);

Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer,
    std::function<double(const std::vector<double>, std::vector<double> &)>
        &&opt_function,
                    qcor::OptFunction &&opt_function);

Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer,
                    qcor::OptFunction &opt_function);
template <typename... Args>
Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective,
                    std::shared_ptr<Optimizer> optimizer,
                    TranslationFunctor<Args...> translation,
                    const int nParameters) {
  return std::async(std::launch::async, [=]() -> ResultsBuffer {
    qcor::OptFunction f(opt_function, nParameters);
    auto results = optimizer->optimize(f);
    ResultsBuffer rb;
    rb.q_buffer = objective->get_qreg();
    rb.opt_params = results.second;
    rb.opt_val = results.first;
    return rb;
  });
  return taskInitiate(
      objective, optimizer,
      [=](const std::vector<double> x, std::vector<double> &dx) {
        auto translated_tuple = translation(x);
        return qcor::__internal__::call(objective, translated_tuple);
      },
      nParameters);
}

} // namespace qcor

#endif
+5 −0
Original line number Diff line number Diff line
link_directories(${XACC_ROOT}/lib)
add_executable(QCORTester QCORTester.cpp)
add_test(NAME qcor_QCORTester COMMAND QCORTester)
target_include_directories(QCORTester PRIVATE ${XACC_ROOT}/include/gtest)
target_link_libraries(QCORTester ${XACC_TEST_LIBRARIES} qcor)
Loading