Loading examples/xasm/deuteron_task_initiate_args_translation.cpp 0 → 100644 +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); } runtime/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -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 runtime/qcor.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -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 runtime/qcor.hpp +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" Loading @@ -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> Loading Loading @@ -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 runtime/tests/CMakeLists.txt 0 → 100644 +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
examples/xasm/deuteron_task_initiate_args_translation.cpp 0 → 100644 +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); }
runtime/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -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
runtime/qcor.cpp +40 −0 Original line number Diff line number Diff line Loading @@ -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
runtime/qcor.hpp +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" Loading @@ -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> Loading Loading @@ -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
runtime/tests/CMakeLists.txt 0 → 100644 +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)