Loading examples/quasimo/IterativeQpeVqe.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -25,16 +25,20 @@ int main(int argc, char **argv) { QuaSiMo::ModelFactory::createModel(eigen_state_prep, H, 2, 0); // Instantiate an IQPE workflow // NOTE: can turn off exp_i_theta compute-action-uncompute with {"cau-opt", false} auto workflow = QuaSiMo::getWorkflow("iqpe", {{"time-steps", 8}, {"iterations", 8}}); auto result = workflow->execute(problemModel); const double phaseValue = result.get<double>("phase"); const double energy = result.get<double>("energy"); auto n_insts = result.get<std::vector<int>>("n-kernel-instructions"); std::cout << "Final phase = " << phaseValue << "\n"; // Expect: ~ -1.7 (due to limited bit precision) std::cout << "Energy = " << energy << "\n"; print("N Instructions at Iter:"); for (auto [i,n] : enumerate(n_insts)) print("iter", i, ":" , n); return 0; } No newline at end of file lib/quasimo/impls/ansatz_generator/trotter.cpp +9 −3 Original line number Diff line number Diff line #include "trotter.hpp" #include "xacc_service.hpp" namespace qcor { Loading @@ -12,11 +13,16 @@ Ansatz TrotterEvolution::create_ansatz(Observable *obs, if (params.keyExists<double>("dt")) { dt = params.get<double>("dt"); } // always default to true auto cau_opt = params.get_or_default("cau-opt", true); // Just use exp_i_theta for now // TODO: formalize a standard library kernel for this. auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>( xacc::getService<xacc::Instruction>("exp_i_theta")); expCirc->expand({{"pauli", obs->toString()}}); expCirc->expand({{"pauli", obs->toString()}, {"__internal_compute_action_uncompute_opt__", cau_opt}}); result.circuit = expCirc->operator()({dt}); result.nb_qubits = expCirc->nRequiredBits(); Loading lib/quasimo/impls/workflow/iterative_qpe.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -15,13 +15,18 @@ bool IterativeQpeWorkflow::initialize(const HeterogeneousMap ¶ms) { if (params.keyExists<int>("iterations")) { num_iters = params.get<int>("iterations"); } // defaults to true all the way down, this really // just gives us a way to turn it off cau_opt = params.get_or_default("cau-opt", true); return (num_steps >= 1) && (num_iters >= 1); } std::shared_ptr<CompositeInstruction> IterativeQpeWorkflow::constructQpeTrotterCircuit( std::shared_ptr<Observable> obs, double trotter_step, size_t nbQubits, double compensatedAncRot, int steps, int k, double omega) { double compensatedAncRot, int steps, int k, double omega, bool cau_opt) { auto provider = xacc::getIRProvider("quantum"); auto kernel = provider->createComposite("__TEMP__QPE__LOOP__"); // Ancilla qubit is the last one in the register. Loading @@ -38,7 +43,7 @@ IterativeQpeWorkflow::constructQpeTrotterCircuit( // TODO: support other methods (e.g. Suzuki) auto method = xacc::getService<AnsatzGenerator>("trotter"); auto trotterCir = method->create_ansatz(obs.get(), {{"dt", trotter_step}}).circuit; method->create_ansatz(obs.get(), {{"dt", trotter_step}, {"cau-opt", cau_opt}}).circuit; // std::cout << "Trotter circ:\n" << trotterCir->toString() << "\n"; // Controlled-U Loading Loading @@ -82,7 +87,7 @@ std::shared_ptr<CompositeInstruction> IterativeQpeWorkflow::constructQpeCircuit( auto provider = xacc::getIRProvider("quantum"); const double trotterStepSize = -2 * M_PI / num_steps; auto kernel = constructQpeTrotterCircuit(obs, trotterStepSize, obs->nBits(), 0.0, num_steps, k, omega); 0.0, num_steps, k, omega, cau_opt); const auto nbQubits = obs->nBits(); // Ancilla qubit is the last one in the register Loading Loading @@ -133,6 +138,7 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { // We're using XACC IR construction API here, since using QCOR kernels here // seems to be complicated. double omega_coef = 0.0; std::vector<int> n_instructions; // Iterates over the num_iters // k runs from the number of iterations back to 1 for (int iterIdx = 0; iterIdx < num_iters; ++iterIdx) { Loading @@ -148,6 +154,15 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { auto iterQpe = constructQpeCircuit(stretchedObs, k, -2 * M_PI * omega_coef); kernel->addInstruction(iterQpe); int count = 0; xacc::InstructionIterator iter(kernel); while(iter.hasNext()) { auto next = iter.next(); if (next->isEnabled() && !next->isComposite()) { count++; } } n_instructions.push_back(count); // Executes the iterative QPE algorithm: auto temp_buffer = xacc::qalloc(stretchedObs->nBits() + 1); // std::cout << "Kernel: \n" << kernel->toString() << "\n"; Loading Loading @@ -184,7 +199,7 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { // omega_coef = " << omega_coef << "\n"; } return {{"phase", omega_coef}, return {{"phase", omega_coef}, {"n-kernel-instructions", n_instructions}, {"energy", ham_converter.computeEnergy(omega_coef)}}; } } // namespace QuaSiMo Loading lib/quasimo/impls/workflow/iterative_qpe.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public: static std::shared_ptr<CompositeInstruction> constructQpeTrotterCircuit( std::shared_ptr<Observable> obs, double trotter_step, size_t nbQubits, double compensatedAncRot = 0, int steps = 1, int k = 1, double omega = 0); double compensatedAncRot = 0, int steps = 1, int k = 1, double omega = 0, bool cau_opt = true); private: std::shared_ptr<CompositeInstruction> Loading @@ -38,6 +38,8 @@ private: // Number of iterations (>=1) int num_iters; HamOpConverter ham_converter; bool cau_opt = true; }; } // namespace QuaSiMo } // namespace qcor No newline at end of file Loading
examples/quasimo/IterativeQpeVqe.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -25,16 +25,20 @@ int main(int argc, char **argv) { QuaSiMo::ModelFactory::createModel(eigen_state_prep, H, 2, 0); // Instantiate an IQPE workflow // NOTE: can turn off exp_i_theta compute-action-uncompute with {"cau-opt", false} auto workflow = QuaSiMo::getWorkflow("iqpe", {{"time-steps", 8}, {"iterations", 8}}); auto result = workflow->execute(problemModel); const double phaseValue = result.get<double>("phase"); const double energy = result.get<double>("energy"); auto n_insts = result.get<std::vector<int>>("n-kernel-instructions"); std::cout << "Final phase = " << phaseValue << "\n"; // Expect: ~ -1.7 (due to limited bit precision) std::cout << "Energy = " << energy << "\n"; print("N Instructions at Iter:"); for (auto [i,n] : enumerate(n_insts)) print("iter", i, ":" , n); return 0; } No newline at end of file
lib/quasimo/impls/ansatz_generator/trotter.cpp +9 −3 Original line number Diff line number Diff line #include "trotter.hpp" #include "xacc_service.hpp" namespace qcor { Loading @@ -12,11 +13,16 @@ Ansatz TrotterEvolution::create_ansatz(Observable *obs, if (params.keyExists<double>("dt")) { dt = params.get<double>("dt"); } // always default to true auto cau_opt = params.get_or_default("cau-opt", true); // Just use exp_i_theta for now // TODO: formalize a standard library kernel for this. auto expCirc = std::dynamic_pointer_cast<xacc::quantum::Circuit>( xacc::getService<xacc::Instruction>("exp_i_theta")); expCirc->expand({{"pauli", obs->toString()}}); expCirc->expand({{"pauli", obs->toString()}, {"__internal_compute_action_uncompute_opt__", cau_opt}}); result.circuit = expCirc->operator()({dt}); result.nb_qubits = expCirc->nRequiredBits(); Loading
lib/quasimo/impls/workflow/iterative_qpe.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -15,13 +15,18 @@ bool IterativeQpeWorkflow::initialize(const HeterogeneousMap ¶ms) { if (params.keyExists<int>("iterations")) { num_iters = params.get<int>("iterations"); } // defaults to true all the way down, this really // just gives us a way to turn it off cau_opt = params.get_or_default("cau-opt", true); return (num_steps >= 1) && (num_iters >= 1); } std::shared_ptr<CompositeInstruction> IterativeQpeWorkflow::constructQpeTrotterCircuit( std::shared_ptr<Observable> obs, double trotter_step, size_t nbQubits, double compensatedAncRot, int steps, int k, double omega) { double compensatedAncRot, int steps, int k, double omega, bool cau_opt) { auto provider = xacc::getIRProvider("quantum"); auto kernel = provider->createComposite("__TEMP__QPE__LOOP__"); // Ancilla qubit is the last one in the register. Loading @@ -38,7 +43,7 @@ IterativeQpeWorkflow::constructQpeTrotterCircuit( // TODO: support other methods (e.g. Suzuki) auto method = xacc::getService<AnsatzGenerator>("trotter"); auto trotterCir = method->create_ansatz(obs.get(), {{"dt", trotter_step}}).circuit; method->create_ansatz(obs.get(), {{"dt", trotter_step}, {"cau-opt", cau_opt}}).circuit; // std::cout << "Trotter circ:\n" << trotterCir->toString() << "\n"; // Controlled-U Loading Loading @@ -82,7 +87,7 @@ std::shared_ptr<CompositeInstruction> IterativeQpeWorkflow::constructQpeCircuit( auto provider = xacc::getIRProvider("quantum"); const double trotterStepSize = -2 * M_PI / num_steps; auto kernel = constructQpeTrotterCircuit(obs, trotterStepSize, obs->nBits(), 0.0, num_steps, k, omega); 0.0, num_steps, k, omega, cau_opt); const auto nbQubits = obs->nBits(); // Ancilla qubit is the last one in the register Loading Loading @@ -133,6 +138,7 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { // We're using XACC IR construction API here, since using QCOR kernels here // seems to be complicated. double omega_coef = 0.0; std::vector<int> n_instructions; // Iterates over the num_iters // k runs from the number of iterations back to 1 for (int iterIdx = 0; iterIdx < num_iters; ++iterIdx) { Loading @@ -148,6 +154,15 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { auto iterQpe = constructQpeCircuit(stretchedObs, k, -2 * M_PI * omega_coef); kernel->addInstruction(iterQpe); int count = 0; xacc::InstructionIterator iter(kernel); while(iter.hasNext()) { auto next = iter.next(); if (next->isEnabled() && !next->isComposite()) { count++; } } n_instructions.push_back(count); // Executes the iterative QPE algorithm: auto temp_buffer = xacc::qalloc(stretchedObs->nBits() + 1); // std::cout << "Kernel: \n" << kernel->toString() << "\n"; Loading Loading @@ -184,7 +199,7 @@ IterativeQpeWorkflow::execute(const QuantumSimulationModel &model) { // omega_coef = " << omega_coef << "\n"; } return {{"phase", omega_coef}, return {{"phase", omega_coef}, {"n-kernel-instructions", n_instructions}, {"energy", ham_converter.computeEnergy(omega_coef)}}; } } // namespace QuaSiMo Loading
lib/quasimo/impls/workflow/iterative_qpe.hpp +3 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public: static std::shared_ptr<CompositeInstruction> constructQpeTrotterCircuit( std::shared_ptr<Observable> obs, double trotter_step, size_t nbQubits, double compensatedAncRot = 0, int steps = 1, int k = 1, double omega = 0); double compensatedAncRot = 0, int steps = 1, int k = 1, double omega = 0, bool cau_opt = true); private: std::shared_ptr<CompositeInstruction> Loading @@ -38,6 +38,8 @@ private: // Number of iterations (>=1) int num_iters; HamOpConverter ham_converter; bool cau_opt = true; }; } // namespace QuaSiMo } // namespace qcor No newline at end of file