Loading examples/qrt/qaoa_demo.cpp 0 → 100644 +63 −0 Original line number Diff line number Diff line #include "qcor.hpp" #include <random> // Use QAOA algorithm to solve a QUBO problem // QUBO function: // y = -5x1 - 3x2 - 8x3 - 6x4 + 4x1x2 + 8x1x3 + 2x2x3 + 10x3x4 // Adapted from https://docs.entropicalabs.io/qaoa/notebooks/6_solvingqubowithqaoa // Instructions: // Compile: qcor -o qaoa -qpu qpp qaoa_demo.cpp // Run: ./qaoa int main(int argc, char **argv) { // Create corresponding QUBO Hamiltonian (cost Observable) auto observable = qcor::createObservable( "-5.0 - 0.5 Z0 - 1.0 Z2 + 0.5 Z3 + 1.0 Z0 Z1 + 2.0 Z0 Z2 + 0.5 Z1 Z2 + 2.5 Z2 Z3"); // Allocate 4 qubits (number of variables) auto q = qalloc(4); // QAOA 'p' steps: const int nbSteps = 6; // We have 4 params for the mixer Hamiltonian terms (one for each qubit) // and 7 terms for the above cost Hamiltonian. // i.e. 11 params/step. const int nbParams = nbSteps*11; // We need to seed the 'nlopt' optimizer with random numbers // to prevent it from being stuck. std::vector<double> initialParams; std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dis(-2.0, 2.0); // Init random parameters for (int i = 0; i < nbParams; ++i) { initialParams.emplace_back(dis(gen)); } // Create the Optimizer auto optimizer = qcor::createOptimizer("nlopt", xacc::HeterogeneousMap{ std::make_pair("initial-parameters", initialParams), // Scale the number of iters by the number of params // to guarantee convergence. std::make_pair("nlopt-maxeval", nbParams*100) }); auto algorithm = qcor::createAlgorithm("QAOA", { std::make_pair("optimizer", optimizer), std::make_pair("observable", observable), std::make_pair("accelerator", get_qpu()), // number of time steps (p) param std::make_pair("steps", nbSteps) }); // Call taskInitiate, kick off QAOA optimization run // on the backend (Async call). auto handle = qcor::taskInitiate(algorithm, q); // Go do other work... // Query results when ready. auto results = qcor::sync(handle); // Print the optimal value. printf("<Min QUBO> = %f\n", results.opt_val); } runtime/qcor.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,20 @@ std::shared_ptr<xacc::Observable> createObservable(const char *repr) { return xacc::quantum::getObservable("pauli", std::string(repr)); } std::shared_ptr<xacc::Algorithm> createAlgorithm(const char *type, HeterogeneousMap &&options) { if (!xacc::isInitialized()) xacc::internal_compiler::compiler_InitializeXACC(); auto algorithm = xacc::getAlgorithm(type); const bool initOk = algorithm->initialize(options); if (!initOk) { std::cout << "Algorithm '" << type << "' initialization failed!\n"; } return algorithm; } std::shared_ptr<xacc::CompositeInstruction> compile(const std::string &src) { return xacc::getCompiler("xasm")->compile(src)->getComposites()[0]; } Loading Loading @@ -101,4 +115,17 @@ Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective, }); } Handle taskInitiate(const std::shared_ptr<Algorithm>& algorithm, xacc::internal_compiler::qreg& qubitReg) { return std::async(std::launch::async, [&]() -> ResultsBuffer { auto buffer = xacc::as_shared_ptr(qubitReg.results()); algorithm->execute(buffer); ResultsBuffer rb; rb.q_buffer = qubitReg; rb.opt_params = (*buffer)["opt-params"].as<std::vector<double>>(); rb.opt_val = (*buffer)["opt-val"].as<double>(); return rb; }); } } // namespace qcor No newline at end of file runtime/qcor.hpp +11 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "CompositeInstruction.hpp" #include "Observable.hpp" #include "Optimizer.hpp" #include "Algorithm.hpp" #include "qalloc" #include "xacc_internal_compiler.hpp" Loading @@ -21,6 +22,7 @@ using OptFunction = xacc::OptFunction; using HeterogeneousMap = xacc::HeterogeneousMap; using Observable = xacc::Observable; using Optimizer = xacc::Optimizer; using Algorithm = xacc::Algorithm; class ResultsBuffer { public: Loading Loading @@ -233,6 +235,10 @@ createOptimizer(const char *type, HeterogeneousMap &&options = {}); // Create an observable from a string representation std::shared_ptr<Observable> createObservable(const char *repr); // Create the desired Algorithm std::shared_ptr<Algorithm> createAlgorithm(const char *type, HeterogeneousMap &&options = {}); std::shared_ptr<ObjectiveFunction> createObjectiveFunction( const char *obj_name, std::shared_ptr<xacc::CompositeInstruction> kernel, std::shared_ptr<Observable> observable, HeterogeneousMap &&options = {}) { Loading Loading @@ -286,6 +292,11 @@ Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective, }, nParameters); } // Execute an algorithm on the qubit register. Handle taskInitiate(const std::shared_ptr<Algorithm>& algorithm, xacc::internal_compiler::qreg& qubitReg); } // namespace qcor #endif Loading
examples/qrt/qaoa_demo.cpp 0 → 100644 +63 −0 Original line number Diff line number Diff line #include "qcor.hpp" #include <random> // Use QAOA algorithm to solve a QUBO problem // QUBO function: // y = -5x1 - 3x2 - 8x3 - 6x4 + 4x1x2 + 8x1x3 + 2x2x3 + 10x3x4 // Adapted from https://docs.entropicalabs.io/qaoa/notebooks/6_solvingqubowithqaoa // Instructions: // Compile: qcor -o qaoa -qpu qpp qaoa_demo.cpp // Run: ./qaoa int main(int argc, char **argv) { // Create corresponding QUBO Hamiltonian (cost Observable) auto observable = qcor::createObservable( "-5.0 - 0.5 Z0 - 1.0 Z2 + 0.5 Z3 + 1.0 Z0 Z1 + 2.0 Z0 Z2 + 0.5 Z1 Z2 + 2.5 Z2 Z3"); // Allocate 4 qubits (number of variables) auto q = qalloc(4); // QAOA 'p' steps: const int nbSteps = 6; // We have 4 params for the mixer Hamiltonian terms (one for each qubit) // and 7 terms for the above cost Hamiltonian. // i.e. 11 params/step. const int nbParams = nbSteps*11; // We need to seed the 'nlopt' optimizer with random numbers // to prevent it from being stuck. std::vector<double> initialParams; std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dis(-2.0, 2.0); // Init random parameters for (int i = 0; i < nbParams; ++i) { initialParams.emplace_back(dis(gen)); } // Create the Optimizer auto optimizer = qcor::createOptimizer("nlopt", xacc::HeterogeneousMap{ std::make_pair("initial-parameters", initialParams), // Scale the number of iters by the number of params // to guarantee convergence. std::make_pair("nlopt-maxeval", nbParams*100) }); auto algorithm = qcor::createAlgorithm("QAOA", { std::make_pair("optimizer", optimizer), std::make_pair("observable", observable), std::make_pair("accelerator", get_qpu()), // number of time steps (p) param std::make_pair("steps", nbSteps) }); // Call taskInitiate, kick off QAOA optimization run // on the backend (Async call). auto handle = qcor::taskInitiate(algorithm, q); // Go do other work... // Query results when ready. auto results = qcor::sync(handle); // Print the optimal value. printf("<Min QUBO> = %f\n", results.opt_val); }
runtime/qcor.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,20 @@ std::shared_ptr<xacc::Observable> createObservable(const char *repr) { return xacc::quantum::getObservable("pauli", std::string(repr)); } std::shared_ptr<xacc::Algorithm> createAlgorithm(const char *type, HeterogeneousMap &&options) { if (!xacc::isInitialized()) xacc::internal_compiler::compiler_InitializeXACC(); auto algorithm = xacc::getAlgorithm(type); const bool initOk = algorithm->initialize(options); if (!initOk) { std::cout << "Algorithm '" << type << "' initialization failed!\n"; } return algorithm; } std::shared_ptr<xacc::CompositeInstruction> compile(const std::string &src) { return xacc::getCompiler("xasm")->compile(src)->getComposites()[0]; } Loading Loading @@ -101,4 +115,17 @@ Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective, }); } Handle taskInitiate(const std::shared_ptr<Algorithm>& algorithm, xacc::internal_compiler::qreg& qubitReg) { return std::async(std::launch::async, [&]() -> ResultsBuffer { auto buffer = xacc::as_shared_ptr(qubitReg.results()); algorithm->execute(buffer); ResultsBuffer rb; rb.q_buffer = qubitReg; rb.opt_params = (*buffer)["opt-params"].as<std::vector<double>>(); rb.opt_val = (*buffer)["opt-val"].as<double>(); return rb; }); } } // namespace qcor No newline at end of file
runtime/qcor.hpp +11 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include "CompositeInstruction.hpp" #include "Observable.hpp" #include "Optimizer.hpp" #include "Algorithm.hpp" #include "qalloc" #include "xacc_internal_compiler.hpp" Loading @@ -21,6 +22,7 @@ using OptFunction = xacc::OptFunction; using HeterogeneousMap = xacc::HeterogeneousMap; using Observable = xacc::Observable; using Optimizer = xacc::Optimizer; using Algorithm = xacc::Algorithm; class ResultsBuffer { public: Loading Loading @@ -233,6 +235,10 @@ createOptimizer(const char *type, HeterogeneousMap &&options = {}); // Create an observable from a string representation std::shared_ptr<Observable> createObservable(const char *repr); // Create the desired Algorithm std::shared_ptr<Algorithm> createAlgorithm(const char *type, HeterogeneousMap &&options = {}); std::shared_ptr<ObjectiveFunction> createObjectiveFunction( const char *obj_name, std::shared_ptr<xacc::CompositeInstruction> kernel, std::shared_ptr<Observable> observable, HeterogeneousMap &&options = {}) { Loading Loading @@ -286,6 +292,11 @@ Handle taskInitiate(std::shared_ptr<ObjectiveFunction> objective, }, nParameters); } // Execute an algorithm on the qubit register. Handle taskInitiate(const std::shared_ptr<Algorithm>& algorithm, xacc::internal_compiler::qreg& qubitReg); } // namespace qcor #endif