Loading handlers/qcor_syntax_handler.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,26 @@ void QCORSyntaxHandler::GetReplacement( << program_parameters[i] << "\")"; } OS << ") {}\n"; // Forth constructor, give us a way to provide a HeterogeneousMap of // arguments, and set a parent kernel - this is also used for Pythonic // QJIT... KERNEL_NAME(std::shared_ptr<CompositeInstruction> parent, // HeterogeneousMap args); OS << kernel_name << "(std::shared_ptr<CompositeInstruction> parent, HeterogeneousMap& " "args): QuantumKernel<" << kernel_name << ", " << program_arg_types[0]; for (int i = 1; i < program_arg_types.size(); i++) { OS << ", " << program_arg_types[i]; } OS << "> (parent, args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; for (int i = 1; i < program_parameters.size(); i++) { OS << ", " << "args.get<" << program_arg_types[i] << ">(\"" << program_parameters[i] << "\")"; } OS << ") {}\n"; } // Destructor definition Loading Loading @@ -316,6 +336,12 @@ void QCORSyntaxHandler::GetReplacement( << "__with_hetmap_args(HeterogeneousMap& args) {\n"; OS << "class " << kernel_name << " __ker__temp__(args);\n"; OS << "}\n"; OS << "void " << kernel_name << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> parent, " "HeterogeneousMap& args) {\n"; OS << "class " << kernel_name << " __ker__temp__(parent, args);\n"; OS << "}\n"; } auto s = OS.str(); qcor::info("[qcor syntax-handler] Rewriting " + kernel_name + " to\n\n" + s); Loading lib/qsim/base/kernel_evaluator.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ protected: qreg q; public: KernelFunctor() = default; KernelFunctor(qreg qReg) : q(qReg){}; qreg &getQreg() { return q; } size_t nParams() const { return nbParams; } Loading python/CMakeLists.txt +1 −1 Original line number Diff line number Diff line set(LIBRARY_NAME _pyqcor) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-attributes") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -O2 -g -pipe -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wformat -fexceptions --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=native -D_GNU_SOURCE -fPIC -fwrapv") if(APPLE) Loading python/examples/vqe_qcor_spec.py 0 → 100644 +26 −0 Original line number Diff line number Diff line from qcor import * # Define the quantum kernel by providing a # python function that is annotated with qjit for # quantum just in time compilation @qjit def ansatz(q: qreg, theta: List[float]): X(q[0]) Ry(q[1], theta[0]) CX(q[1], q[0]) # Define the hamiltonian H = -2.1433 * X(0) * X(1) - 2.1433 * \ Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1) + 5.907 # Create the ObjectiveFunction, default is VQE n_params = 1 obj = createObjectiveFunction(ansatz, H, n_params) # evaluate at a concrete set of params vqe_energy = obj([.59]) # Run full optimization optimizer = createOptimizer('nlopt') results = optimizer.optimize(obj) print(results) No newline at end of file python/py-qcor.cpp +134 −2 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ #include "py_costFunctionEvaluator.hpp" #include "py_qsimWorkflow.hpp" #include "qcor_jit.hpp" #include "qcor_observable.hpp" #include "qrt.hpp" #include "xacc.hpp" #include "xacc_internal_compiler.hpp" #include "xacc_service.hpp" namespace py = pybind11; using namespace xacc; Loading Loading @@ -68,7 +70,8 @@ class KernelArgDictToHeterogeneousMap { }; // Add type name to this list to support receiving from Python. using PyHeterogeneousMapTypes = xacc::Variant<bool, int, double, std::string>; using PyHeterogeneousMapTypes = xacc::Variant<bool, int, double, std::string, std::shared_ptr<qcor::Optimizer>>; using PyHeterogeneousMap = std::map<std::string, PyHeterogeneousMapTypes>; // Helper to convert a Python *dict* (as a map of variants) into a native Loading @@ -85,6 +88,92 @@ xacc::HeterogeneousMap heterogeneousMapConvert( } } // namespace namespace qcor { class PyObjectiveFunction : public qcor::ObjectiveFunction { protected: py::object py_kernel; std::shared_ptr<ObjectiveFunction> helper; xacc::internal_compiler::qreg qreg; QJIT qjit; public: const std::string name() const override { return "py-objective-impl"; } const std::string description() const override { return ""; } PyObjectiveFunction(py::object q, qcor::PauliOperator &qq, const int n_dim, const std::string &helper_name) : py_kernel(q) { _dim = n_dim; helper = xacc::getService<qcor::ObjectiveFunction>(helper_name); observable = xacc::as_shared_ptr(&qq); helper->update_observable(observable); auto src = py_kernel.attr("get_internal_src")().cast<std::string>(); // this will be fast if already done, and we just do it once qjit.jit_compile(src, true); } double operator()(const KernelArgDict args) { xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } auto kernel_name = py_kernel.attr("kernel_name")().cast<std::string>(); kernel = qjit.extract_composite_with_hetmap(kernel_name, m); helper->update_kernel(kernel); std::vector<double> dx; return (*helper)(qreg, dx); } double operator()(const std::vector<double> &x, std::vector<double> &dx) override { current_iterate_parameters = x; helper->update_current_iterate_parameters(x); // Translate x into kernel args qreg = ::qalloc(observable->nBits()); auto args = py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>(); // args will be a dictionary, arg_name to arg return operator()(args); } virtual double operator()(xacc::internal_compiler::qreg &qreg, std::vector<double> &dx) { throw std::bad_function_call(); return 0.0; } }; class PyKernelFunctor : public qcor::KernelFunctor { protected: py::object py_kernel; QJIT qjit; std::size_t n_qubits; public: PyKernelFunctor(py::object q, const std::size_t nq, const std::size_t np) : py_kernel(q), n_qubits(nq) { nbParams = np; auto src = py_kernel.attr("get_internal_src")().cast<std::string>(); // this will be fast if already done, and we just do it once qjit.jit_compile(src, true); } std::shared_ptr<xacc::CompositeInstruction> evaluate_kernel( const std::vector<double> &x) override { // Translate x into kernel args auto qreg = ::qalloc(n_qubits); auto args = py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>(); xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } auto kernel_name = py_kernel.attr("kernel_name")().cast<std::string>(); return qjit.extract_composite_with_hetmap(kernel_name, m); } }; } // namespace qcor PYBIND11_MODULE(_pyqcor, m) { m.doc() = "Python bindings for QCOR."; Loading Loading @@ -148,6 +237,7 @@ PYBIND11_MODULE(_pyqcor, m) { .def("counts", &xacc::internal_compiler::qreg::counts, "") .def("exp_val_z", &xacc::internal_compiler::qreg::exp_val_z, ""); // m.def("createObjectiveFunction", [](const std::string name, )) py::class_<qcor::QJIT, std::shared_ptr<qcor::QJIT>>(m, "QJIT", "") .def(py::init<>(), "") .def("jit_compile", &qcor::QJIT::jit_compile, "") Loading @@ -169,6 +259,36 @@ PYBIND11_MODULE(_pyqcor, m) { } qjit.invoke_with_hetmap(name, m); }, "") .def("extract_composite", [](qcor::QJIT &qjit, const std::string name, KernelArgDict args) { xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } return qjit.extract_composite_with_hetmap(name, m); }); py::class_<qcor::ObjectiveFunction, std::shared_ptr<qcor::ObjectiveFunction>>( m, "ObjectiveFunction", "") .def("dimensions", &qcor::ObjectiveFunction::dimensions, "") .def( "__call__", [](qcor::ObjectiveFunction &obj, std::vector<double> x) { return obj(x); }, ""); m.def( "createObjectiveFunction", [](py::object kernel, qcor::PauliOperator &obs, const int n_params) { auto q = ::qalloc(obs.nBits()); std::shared_ptr<qcor::ObjectiveFunction> obj = std::make_shared<qcor::PyObjectiveFunction>(kernel, obs, n_params, "vqe"); return obj; }, ""); // qsim sub-module bindings: Loading @@ -193,7 +313,19 @@ PYBIND11_MODULE(_pyqcor, m) { [](qcor::PauliOperator &obs, qcor::qsim::TdObservable ham_func) { return qcor::qsim::ModelBuilder::createModel(obs, ham_func); }, "Return the Model for a time-dependent problem."); "Return the Model for a time-dependent problem.") .def( "createModel", [](py::object py_kernel, qcor::PauliOperator &obs, const int n_qubits, const int n_params) { qcor::qsim::QuantumSimulationModel model; auto kernel_functor = std::make_shared<qcor::PyKernelFunctor>( py_kernel, n_qubits, n_params); model.observable = &obs; model.user_defined_ansatz = kernel_functor; return std::move(model); }, ""); // CostFunctionEvaluator bindings py::class_<qcor::qsim::CostFunctionEvaluator, Loading Loading
handlers/qcor_syntax_handler.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -217,6 +217,26 @@ void QCORSyntaxHandler::GetReplacement( << program_parameters[i] << "\")"; } OS << ") {}\n"; // Forth constructor, give us a way to provide a HeterogeneousMap of // arguments, and set a parent kernel - this is also used for Pythonic // QJIT... KERNEL_NAME(std::shared_ptr<CompositeInstruction> parent, // HeterogeneousMap args); OS << kernel_name << "(std::shared_ptr<CompositeInstruction> parent, HeterogeneousMap& " "args): QuantumKernel<" << kernel_name << ", " << program_arg_types[0]; for (int i = 1; i < program_arg_types.size(); i++) { OS << ", " << program_arg_types[i]; } OS << "> (parent, args.get<" << program_arg_types[0] << ">(\"" << program_parameters[0] << "\")"; for (int i = 1; i < program_parameters.size(); i++) { OS << ", " << "args.get<" << program_arg_types[i] << ">(\"" << program_parameters[i] << "\")"; } OS << ") {}\n"; } // Destructor definition Loading Loading @@ -316,6 +336,12 @@ void QCORSyntaxHandler::GetReplacement( << "__with_hetmap_args(HeterogeneousMap& args) {\n"; OS << "class " << kernel_name << " __ker__temp__(args);\n"; OS << "}\n"; OS << "void " << kernel_name << "__with_parent_and_hetmap_args(std::shared_ptr<CompositeInstruction> parent, " "HeterogeneousMap& args) {\n"; OS << "class " << kernel_name << " __ker__temp__(parent, args);\n"; OS << "}\n"; } auto s = OS.str(); qcor::info("[qcor syntax-handler] Rewriting " + kernel_name + " to\n\n" + s); Loading
lib/qsim/base/kernel_evaluator.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ protected: qreg q; public: KernelFunctor() = default; KernelFunctor(qreg qReg) : q(qReg){}; qreg &getQreg() { return q; } size_t nParams() const { return nbParams; } Loading
python/CMakeLists.txt +1 −1 Original line number Diff line number Diff line set(LIBRARY_NAME _pyqcor) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations -Wno-attributes") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing -O2 -g -pipe -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wformat -fexceptions --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=native -D_GNU_SOURCE -fPIC -fwrapv") if(APPLE) Loading
python/examples/vqe_qcor_spec.py 0 → 100644 +26 −0 Original line number Diff line number Diff line from qcor import * # Define the quantum kernel by providing a # python function that is annotated with qjit for # quantum just in time compilation @qjit def ansatz(q: qreg, theta: List[float]): X(q[0]) Ry(q[1], theta[0]) CX(q[1], q[0]) # Define the hamiltonian H = -2.1433 * X(0) * X(1) - 2.1433 * \ Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1) + 5.907 # Create the ObjectiveFunction, default is VQE n_params = 1 obj = createObjectiveFunction(ansatz, H, n_params) # evaluate at a concrete set of params vqe_energy = obj([.59]) # Run full optimization optimizer = createOptimizer('nlopt') results = optimizer.optimize(obj) print(results) No newline at end of file
python/py-qcor.cpp +134 −2 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ #include "py_costFunctionEvaluator.hpp" #include "py_qsimWorkflow.hpp" #include "qcor_jit.hpp" #include "qcor_observable.hpp" #include "qrt.hpp" #include "xacc.hpp" #include "xacc_internal_compiler.hpp" #include "xacc_service.hpp" namespace py = pybind11; using namespace xacc; Loading Loading @@ -68,7 +70,8 @@ class KernelArgDictToHeterogeneousMap { }; // Add type name to this list to support receiving from Python. using PyHeterogeneousMapTypes = xacc::Variant<bool, int, double, std::string>; using PyHeterogeneousMapTypes = xacc::Variant<bool, int, double, std::string, std::shared_ptr<qcor::Optimizer>>; using PyHeterogeneousMap = std::map<std::string, PyHeterogeneousMapTypes>; // Helper to convert a Python *dict* (as a map of variants) into a native Loading @@ -85,6 +88,92 @@ xacc::HeterogeneousMap heterogeneousMapConvert( } } // namespace namespace qcor { class PyObjectiveFunction : public qcor::ObjectiveFunction { protected: py::object py_kernel; std::shared_ptr<ObjectiveFunction> helper; xacc::internal_compiler::qreg qreg; QJIT qjit; public: const std::string name() const override { return "py-objective-impl"; } const std::string description() const override { return ""; } PyObjectiveFunction(py::object q, qcor::PauliOperator &qq, const int n_dim, const std::string &helper_name) : py_kernel(q) { _dim = n_dim; helper = xacc::getService<qcor::ObjectiveFunction>(helper_name); observable = xacc::as_shared_ptr(&qq); helper->update_observable(observable); auto src = py_kernel.attr("get_internal_src")().cast<std::string>(); // this will be fast if already done, and we just do it once qjit.jit_compile(src, true); } double operator()(const KernelArgDict args) { xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } auto kernel_name = py_kernel.attr("kernel_name")().cast<std::string>(); kernel = qjit.extract_composite_with_hetmap(kernel_name, m); helper->update_kernel(kernel); std::vector<double> dx; return (*helper)(qreg, dx); } double operator()(const std::vector<double> &x, std::vector<double> &dx) override { current_iterate_parameters = x; helper->update_current_iterate_parameters(x); // Translate x into kernel args qreg = ::qalloc(observable->nBits()); auto args = py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>(); // args will be a dictionary, arg_name to arg return operator()(args); } virtual double operator()(xacc::internal_compiler::qreg &qreg, std::vector<double> &dx) { throw std::bad_function_call(); return 0.0; } }; class PyKernelFunctor : public qcor::KernelFunctor { protected: py::object py_kernel; QJIT qjit; std::size_t n_qubits; public: PyKernelFunctor(py::object q, const std::size_t nq, const std::size_t np) : py_kernel(q), n_qubits(nq) { nbParams = np; auto src = py_kernel.attr("get_internal_src")().cast<std::string>(); // this will be fast if already done, and we just do it once qjit.jit_compile(src, true); } std::shared_ptr<xacc::CompositeInstruction> evaluate_kernel( const std::vector<double> &x) override { // Translate x into kernel args auto qreg = ::qalloc(n_qubits); auto args = py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>(); xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } auto kernel_name = py_kernel.attr("kernel_name")().cast<std::string>(); return qjit.extract_composite_with_hetmap(kernel_name, m); } }; } // namespace qcor PYBIND11_MODULE(_pyqcor, m) { m.doc() = "Python bindings for QCOR."; Loading Loading @@ -148,6 +237,7 @@ PYBIND11_MODULE(_pyqcor, m) { .def("counts", &xacc::internal_compiler::qreg::counts, "") .def("exp_val_z", &xacc::internal_compiler::qreg::exp_val_z, ""); // m.def("createObjectiveFunction", [](const std::string name, )) py::class_<qcor::QJIT, std::shared_ptr<qcor::QJIT>>(m, "QJIT", "") .def(py::init<>(), "") .def("jit_compile", &qcor::QJIT::jit_compile, "") Loading @@ -169,6 +259,36 @@ PYBIND11_MODULE(_pyqcor, m) { } qjit.invoke_with_hetmap(name, m); }, "") .def("extract_composite", [](qcor::QJIT &qjit, const std::string name, KernelArgDict args) { xacc::HeterogeneousMap m; for (auto &item : args) { KernelArgDictToHeterogeneousMap vis(m, item.first); mpark::visit(vis, item.second); } return qjit.extract_composite_with_hetmap(name, m); }); py::class_<qcor::ObjectiveFunction, std::shared_ptr<qcor::ObjectiveFunction>>( m, "ObjectiveFunction", "") .def("dimensions", &qcor::ObjectiveFunction::dimensions, "") .def( "__call__", [](qcor::ObjectiveFunction &obj, std::vector<double> x) { return obj(x); }, ""); m.def( "createObjectiveFunction", [](py::object kernel, qcor::PauliOperator &obs, const int n_params) { auto q = ::qalloc(obs.nBits()); std::shared_ptr<qcor::ObjectiveFunction> obj = std::make_shared<qcor::PyObjectiveFunction>(kernel, obs, n_params, "vqe"); return obj; }, ""); // qsim sub-module bindings: Loading @@ -193,7 +313,19 @@ PYBIND11_MODULE(_pyqcor, m) { [](qcor::PauliOperator &obs, qcor::qsim::TdObservable ham_func) { return qcor::qsim::ModelBuilder::createModel(obs, ham_func); }, "Return the Model for a time-dependent problem."); "Return the Model for a time-dependent problem.") .def( "createModel", [](py::object py_kernel, qcor::PauliOperator &obs, const int n_qubits, const int n_params) { qcor::qsim::QuantumSimulationModel model; auto kernel_functor = std::make_shared<qcor::PyKernelFunctor>( py_kernel, n_qubits, n_params); model.observable = &obs; model.user_defined_ansatz = kernel_functor; return std::move(model); }, ""); // CostFunctionEvaluator bindings py::class_<qcor::qsim::CostFunctionEvaluator, Loading