Loading examples/hybrid/deuteron_h2_qaoa.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -32,15 +32,4 @@ int main() { std::cout << "<H> = " << energy << "\n"; // note you could also call execute_async() -> Handle and // manually qcor::sync(handle) // or you could call execute(initial_params:vector<double>) // or you could call execute_async(initial_params:vector<double>) // or you could call execute(optimizer, initial_params:vector<double>) // or you could call execute(optimizer) // If you wanted to provide initial-parameters, you can // query the size of vector you need with // qaoa.n_parameters() (also have n_gamma(), n_beta(), and n_steps()) } No newline at end of file examples/hybrid/deuteron_h2_vqe.cpp +1 −8 Original line number Diff line number Diff line Loading @@ -60,14 +60,7 @@ int main() { // Now do the same for the vector double ansatz, but // also demonstrate the async interface VQE vqe_vec(ansatz_vec, H); auto handle = vqe_vec.execute_async(std::vector<double>{0.0}); // Can go do other work, quantum execution is happening on // separate thread // Get the energy, this call will kick off a wait if needed const auto [energy_vec, params_vec] = vqe_vec.sync(handle); const auto [energy_vec, params_vec] = vqe_vec.execute(std::vector<double>{0.0}); std::cout << "<H>(" << params_vec[0] << ") = " << energy_vec << "\n"; // Now run with the mixed language kernel, Loading examples/hybrid/parameter_sweep.cpp 0 → 100644 +26 −0 Original line number Diff line number Diff line #include "qcor_hybrid.hpp" // Define one quantum kernel that takes // double angle parameter __qpu__ void ansatz(qreg q, double x) { X(q[0]); Ry(q[1], x); CX(q[1], q[0]); } int main() { // Define the Hamiltonian using the QCOR API auto H = 5.907 - 2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1); // Create a VQE instance, must give it // the parameterized ansatz functor and Observable VQE vqe(ansatz, H); for (auto [iter, x] : enumerate(linspace(-constants::pi, constants::pi, 20))) { std::cout << iter << ", " << x << ", " << vqe({x}) << "\n"; } vqe.persist_data("param_sweep_data.json"); } No newline at end of file lib/hybrid/qcor_hybrid.hpp +33 −39 Original line number Diff line number Diff line Loading @@ -112,29 +112,13 @@ public: // Execute the VQE task synchronously, assumes default optimizer VQEResultType execute(KernelArgs... initial_params) { auto optimizer = qcor::createOptimizer(DEFAULT_OPTIMIZER); auto handle = execute_async(optimizer, initial_params...); return this->sync(handle); } // Execute the VQE task asynchronously, default optimizer Handle execute_async(KernelArgs... initial_params) { auto optimizer = qcor::createOptimizer(DEFAULT_OPTIMIZER); return execute_async(optimizer, initial_params...); return execute(optimizer, initial_params...); } // Execute the VQE task synchronously, use provided Optimizer // template <typename... Args> VQEResultType execute(std::shared_ptr<Optimizer> optimizer, KernelArgs... initial_params) { auto handle = execute_async(optimizer, initial_params...); return this->sync(handle); } // Execute the VQE task asynchronously, use provided Optimizer // template <typename... Args> Handle execute_async(std::shared_ptr<Optimizer> optimizer, KernelArgs... initial_params) { auto ansatz_casted = reinterpret_cast<void (*)(std::shared_ptr<CompositeInstruction>, qreg, KernelArgs...)>(ansatz_ptr); Loading Loading @@ -177,15 +161,34 @@ public: } options.insert("observable", __internal__::qcor_as_shared(&observable)); objective->set_options(options); return optimizer->optimize(*objective.get()); } // Run TaskInitiate, kick of the VQE job asynchronously return qcor::taskInitiate(objective, optimizer); double operator()(const std::vector<double> x) { auto ansatz_casted = reinterpret_cast<void (*)(std::shared_ptr<CompositeInstruction>, qreg, KernelArgs...)>(ansatz_ptr); // Create the Arg Translator TranslationFunctor<qreg, KernelArgs...> arg_translator; if (translation_functor.has_value()) { arg_translator = std::any_cast<TranslationFunctor<qreg, KernelArgs...>>( translation_functor); } else { __internal__::TranslationFunctorAutoGenerator auto_gen; arg_translator = auto_gen(q, std::tuple<KernelArgs...>()); } // Sync up the results with the host thread VQEResultType sync(Handle &h) { auto results = qcor::sync(h); return std::make_pair(results.opt_val, results.opt_params); // Get the VQE ObjectiveFunction and set the qreg auto objective = qcor::createObjectiveFunction( ansatz_casted, observable, std::make_shared<ArgsTranslator<qreg, KernelArgs...>>(arg_translator), q, x.size()); options.insert("observable", __internal__::qcor_as_shared(&observable)); objective->set_options(options); return (*objective)(x); } // Return all unique parameter sets this VQE run used Loading @@ -210,6 +213,11 @@ public: } return ret; } void persist_data(const std::string& filename) { q.write_file(filename); } }; namespace __internal__ { Loading Loading @@ -371,15 +379,6 @@ public: // initial parameters Will fail if initial_parameters.size() != n_parameters() QAOAResultType execute(std::shared_ptr<Optimizer> optimizer, const std::vector<double> initial_parameters = {}) { auto handle = execute_async(optimizer, initial_parameters); auto results = this->sync(handle); return std::make_pair(results.first, results.second); } // Execute the algorithm asynchronously, provding an Optimizer and optionally // initial parameters Will fail if initial_parameters.size() != n_parameters() Handle execute_async(std::shared_ptr<Optimizer> optimizer, const std::vector<double> initial_parameters = {}) { q = qalloc(cost.nBits()); auto n_params = nSteps * (n_gamma() + n_beta()); Loading Loading @@ -422,14 +421,9 @@ public: objective->set_options(options); optimizer->appendOption("initial-parameters", init_params); return qcor::taskInitiate(objective, optimizer); return optimizer->optimize(*objective.get());// qcor::taskInitiate(objective, optimizer); } // Sync up the results with the host thread QAOAResultType sync(Handle &h) { auto results = qcor::sync(h); return std::make_pair(results.opt_val, results.opt_params); } }; // namespace qcor void execute_adapt(qreg q, const HeterogeneousMap &&m); Loading runtime/objectives/vqe/vqe.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -13,7 +13,20 @@ using namespace cppmicroservices; #include "xacc_internal_compiler.hpp" #include "xacc_service.hpp" namespace { template <typename T> std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) { os << "["; for (int i = 0; i < v.size(); ++i) { os << v[i]; if (i != v.size() - 1) os << ","; } os << "]"; return os; } } // namespace namespace qcor { class VQEObjective : public ObjectiveFunction { Loading @@ -35,13 +48,43 @@ public: auto tmp_child = qalloc(qreg.size()); auto val = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0]; double std_dev = 0.0; if (options.keyExists<int>("vqe-gather-statistics")) { std::vector<double> all_energies; all_energies.push_back(val); auto n = options.get<int>("vqe-gather-statistics"); for (int i = 1; i < n; i++) { auto tmp_child = qalloc(qreg.size()); auto local_val = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0]; all_energies.push_back(local_val); } auto sum = std::accumulate(all_energies.begin(), all_energies.end(), 0.); val = sum / all_energies.size(); double sq_sum = std::inner_product( all_energies.begin(), all_energies.end(), all_energies.begin(), 0.0); std_dev = std::sqrt(sq_sum / all_energies.size() - val * val); } std::cout << "<H>(" << this->current_iterate_parameters << ") = " << val; if (std::fabs(std_dev) > 1e-12) { std::cout << " +- " << std_dev << "\n"; } else { std::cout << std::endl; } // want to store parameters, have to do it here for (auto &child : tmp_child.results()->getChildren()) { child->addExtraInfo("parameters", current_iterate_parameters); auto tmp = current_iterate_parameters; tmp.push_back(val); child->addExtraInfo("qcor-params-energy", tmp); if (std::fabs(std_dev) > 1e-12) { child->addExtraInfo("qcor-energy-stddev", std_dev); } child->addExtraInfo("iteration", current_iteration); } current_iteration++; qreg.addChild(tmp_child); if (!dx.empty() && options.stringExists("gradient-strategy")) { Loading @@ -68,6 +111,7 @@ public: } public: int current_iteration = 0; const std::string name() const override { return "vqe"; } const std::string description() const override { return ""; } }; Loading Loading
examples/hybrid/deuteron_h2_qaoa.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -32,15 +32,4 @@ int main() { std::cout << "<H> = " << energy << "\n"; // note you could also call execute_async() -> Handle and // manually qcor::sync(handle) // or you could call execute(initial_params:vector<double>) // or you could call execute_async(initial_params:vector<double>) // or you could call execute(optimizer, initial_params:vector<double>) // or you could call execute(optimizer) // If you wanted to provide initial-parameters, you can // query the size of vector you need with // qaoa.n_parameters() (also have n_gamma(), n_beta(), and n_steps()) } No newline at end of file
examples/hybrid/deuteron_h2_vqe.cpp +1 −8 Original line number Diff line number Diff line Loading @@ -60,14 +60,7 @@ int main() { // Now do the same for the vector double ansatz, but // also demonstrate the async interface VQE vqe_vec(ansatz_vec, H); auto handle = vqe_vec.execute_async(std::vector<double>{0.0}); // Can go do other work, quantum execution is happening on // separate thread // Get the energy, this call will kick off a wait if needed const auto [energy_vec, params_vec] = vqe_vec.sync(handle); const auto [energy_vec, params_vec] = vqe_vec.execute(std::vector<double>{0.0}); std::cout << "<H>(" << params_vec[0] << ") = " << energy_vec << "\n"; // Now run with the mixed language kernel, Loading
examples/hybrid/parameter_sweep.cpp 0 → 100644 +26 −0 Original line number Diff line number Diff line #include "qcor_hybrid.hpp" // Define one quantum kernel that takes // double angle parameter __qpu__ void ansatz(qreg q, double x) { X(q[0]); Ry(q[1], x); CX(q[1], q[0]); } int main() { // Define the Hamiltonian using the QCOR API auto H = 5.907 - 2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1); // Create a VQE instance, must give it // the parameterized ansatz functor and Observable VQE vqe(ansatz, H); for (auto [iter, x] : enumerate(linspace(-constants::pi, constants::pi, 20))) { std::cout << iter << ", " << x << ", " << vqe({x}) << "\n"; } vqe.persist_data("param_sweep_data.json"); } No newline at end of file
lib/hybrid/qcor_hybrid.hpp +33 −39 Original line number Diff line number Diff line Loading @@ -112,29 +112,13 @@ public: // Execute the VQE task synchronously, assumes default optimizer VQEResultType execute(KernelArgs... initial_params) { auto optimizer = qcor::createOptimizer(DEFAULT_OPTIMIZER); auto handle = execute_async(optimizer, initial_params...); return this->sync(handle); } // Execute the VQE task asynchronously, default optimizer Handle execute_async(KernelArgs... initial_params) { auto optimizer = qcor::createOptimizer(DEFAULT_OPTIMIZER); return execute_async(optimizer, initial_params...); return execute(optimizer, initial_params...); } // Execute the VQE task synchronously, use provided Optimizer // template <typename... Args> VQEResultType execute(std::shared_ptr<Optimizer> optimizer, KernelArgs... initial_params) { auto handle = execute_async(optimizer, initial_params...); return this->sync(handle); } // Execute the VQE task asynchronously, use provided Optimizer // template <typename... Args> Handle execute_async(std::shared_ptr<Optimizer> optimizer, KernelArgs... initial_params) { auto ansatz_casted = reinterpret_cast<void (*)(std::shared_ptr<CompositeInstruction>, qreg, KernelArgs...)>(ansatz_ptr); Loading Loading @@ -177,15 +161,34 @@ public: } options.insert("observable", __internal__::qcor_as_shared(&observable)); objective->set_options(options); return optimizer->optimize(*objective.get()); } // Run TaskInitiate, kick of the VQE job asynchronously return qcor::taskInitiate(objective, optimizer); double operator()(const std::vector<double> x) { auto ansatz_casted = reinterpret_cast<void (*)(std::shared_ptr<CompositeInstruction>, qreg, KernelArgs...)>(ansatz_ptr); // Create the Arg Translator TranslationFunctor<qreg, KernelArgs...> arg_translator; if (translation_functor.has_value()) { arg_translator = std::any_cast<TranslationFunctor<qreg, KernelArgs...>>( translation_functor); } else { __internal__::TranslationFunctorAutoGenerator auto_gen; arg_translator = auto_gen(q, std::tuple<KernelArgs...>()); } // Sync up the results with the host thread VQEResultType sync(Handle &h) { auto results = qcor::sync(h); return std::make_pair(results.opt_val, results.opt_params); // Get the VQE ObjectiveFunction and set the qreg auto objective = qcor::createObjectiveFunction( ansatz_casted, observable, std::make_shared<ArgsTranslator<qreg, KernelArgs...>>(arg_translator), q, x.size()); options.insert("observable", __internal__::qcor_as_shared(&observable)); objective->set_options(options); return (*objective)(x); } // Return all unique parameter sets this VQE run used Loading @@ -210,6 +213,11 @@ public: } return ret; } void persist_data(const std::string& filename) { q.write_file(filename); } }; namespace __internal__ { Loading Loading @@ -371,15 +379,6 @@ public: // initial parameters Will fail if initial_parameters.size() != n_parameters() QAOAResultType execute(std::shared_ptr<Optimizer> optimizer, const std::vector<double> initial_parameters = {}) { auto handle = execute_async(optimizer, initial_parameters); auto results = this->sync(handle); return std::make_pair(results.first, results.second); } // Execute the algorithm asynchronously, provding an Optimizer and optionally // initial parameters Will fail if initial_parameters.size() != n_parameters() Handle execute_async(std::shared_ptr<Optimizer> optimizer, const std::vector<double> initial_parameters = {}) { q = qalloc(cost.nBits()); auto n_params = nSteps * (n_gamma() + n_beta()); Loading Loading @@ -422,14 +421,9 @@ public: objective->set_options(options); optimizer->appendOption("initial-parameters", init_params); return qcor::taskInitiate(objective, optimizer); return optimizer->optimize(*objective.get());// qcor::taskInitiate(objective, optimizer); } // Sync up the results with the host thread QAOAResultType sync(Handle &h) { auto results = qcor::sync(h); return std::make_pair(results.opt_val, results.opt_params); } }; // namespace qcor void execute_adapt(qreg q, const HeterogeneousMap &&m); Loading
runtime/objectives/vqe/vqe.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -13,7 +13,20 @@ using namespace cppmicroservices; #include "xacc_internal_compiler.hpp" #include "xacc_service.hpp" namespace { template <typename T> std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) { os << "["; for (int i = 0; i < v.size(); ++i) { os << v[i]; if (i != v.size() - 1) os << ","; } os << "]"; return os; } } // namespace namespace qcor { class VQEObjective : public ObjectiveFunction { Loading @@ -35,13 +48,43 @@ public: auto tmp_child = qalloc(qreg.size()); auto val = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0]; double std_dev = 0.0; if (options.keyExists<int>("vqe-gather-statistics")) { std::vector<double> all_energies; all_energies.push_back(val); auto n = options.get<int>("vqe-gather-statistics"); for (int i = 1; i < n; i++) { auto tmp_child = qalloc(qreg.size()); auto local_val = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0]; all_energies.push_back(local_val); } auto sum = std::accumulate(all_energies.begin(), all_energies.end(), 0.); val = sum / all_energies.size(); double sq_sum = std::inner_product( all_energies.begin(), all_energies.end(), all_energies.begin(), 0.0); std_dev = std::sqrt(sq_sum / all_energies.size() - val * val); } std::cout << "<H>(" << this->current_iterate_parameters << ") = " << val; if (std::fabs(std_dev) > 1e-12) { std::cout << " +- " << std_dev << "\n"; } else { std::cout << std::endl; } // want to store parameters, have to do it here for (auto &child : tmp_child.results()->getChildren()) { child->addExtraInfo("parameters", current_iterate_parameters); auto tmp = current_iterate_parameters; tmp.push_back(val); child->addExtraInfo("qcor-params-energy", tmp); if (std::fabs(std_dev) > 1e-12) { child->addExtraInfo("qcor-energy-stddev", std_dev); } child->addExtraInfo("iteration", current_iteration); } current_iteration++; qreg.addChild(tmp_child); if (!dx.empty() && options.stringExists("gradient-strategy")) { Loading @@ -68,6 +111,7 @@ public: } public: int current_iteration = 0; const std::string name() const override { return "vqe"; } const std::string description() const override { return ""; } }; Loading