Loading examples/quasimo/qite_deuteron_qsearch.cpp 0 → 100644 +35 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" __qpu__ void state_prep(qreg q) { X(q[0]); } int main(int argc, char** argv) { set_verbose(true); using namespace QuaSiMo; // Create the qsearch IR Transformation auto qsearch_optimizer = createTransformation("qsearch"); // Create the Hamiltonian auto observable = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1) + 5.907; // We'll run with 5 steps and .1 step size const int nbSteps = 5; const double stepSize = 0.1; // Create the model (2 qubits, 0 variational params in above state_prep) // and QITE workflow auto problemModel = ModelFactory::createModel(state_prep, &observable, 2, 0); auto workflow = getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}, {"circuit-optimizer", qsearch_optimizer}}); // Execute auto result = workflow->execute(problemModel); // Get the energy and final circuit const auto energy = result.get<double>("energy"); auto finalCircuit = result.getPointerLike<CompositeInstruction>("circuit"); printf("\n%s\nEnergy=%f\n", finalCircuit->toString().c_str(), energy); } No newline at end of file lib/quasimo/impls/cost_evaluator/partial_tomography.cpp +8 −3 Original line number Diff line number Diff line #include "partial_tomography.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" Loading @@ -10,7 +11,11 @@ double PartialTomoObjFuncEval::evaluate( xacc::as_shared_ptr(target_operator), state_prep); // Run the pass manager (optimization + placement) executePassManager(subKernels); auto tmp_buffer = qalloc(state_prep->nPhysicalBits()); // Set qreg size to the bigger of target_operator bits or state prep physical bits auto tmp_buffer = qalloc(target_operator->nBits() > state_prep->nPhysicalBits() ? target_operator->nBits() : state_prep->nPhysicalBits()); xacc::internal_compiler::execute(tmp_buffer.results(), subKernels); const double energy = tmp_buffer.weighted_sum(target_operator); return energy; Loading lib/quasimo/impls/workflow/qite.cpp +63 −34 Original line number Diff line number Diff line #include "qite.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" #include "xacc_service.hpp" #include "qsim_utils.hpp" namespace { // Helper to generate all permutation of Pauli observables: Loading Loading @@ -51,12 +52,28 @@ bool QiteWorkflow::initialize(const HeterogeneousMap ¶ms) { std::cout << "'step-size' is required.\n"; initializeOk = false; } if (params.keyExists<std::shared_ptr<xacc::IRTransformation>>( "circuit-optimizer")) { extra_circuit_optimizers.push_back( params.get<std::shared_ptr<xacc::IRTransformation>>( "circuit-optimizer")); } else if (params.keyExists< std::vector<std::shared_ptr<xacc::IRTransformation>>>( "circuit-optimizers")) { auto opts = params.get<std::vector<std::shared_ptr<xacc::IRTransformation>>>( "circuit-optimizers"); extra_circuit_optimizers.insert(extra_circuit_optimizers.end(), opts.begin(), opts.end()); } config_params = params; return initializeOk; } QuantumSimulationResult QiteWorkflow::execute(const QuantumSimulationModel &model) { QuantumSimulationResult QiteWorkflow::execute( const QuantumSimulationModel &model) { const auto nbSteps = config_params.get<int>("steps"); const auto stepSize = config_params.get<double>("step-size"); auto qite = xacc::getService<xacc::Algorithm>("qite"); Loading @@ -73,9 +90,9 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { std::vector<double> energyAtStep; auto constructPropagateCircuit = [](const std::vector<std::shared_ptr<Observable>> &in_Aops, const std::shared_ptr<KernelFunctor> &in_statePrep, double in_stepSize) -> std::shared_ptr<CompositeInstruction> { [this, &acc](const std::vector<std::shared_ptr<Observable>> &in_Aops, const std::shared_ptr<KernelFunctor> &in_statePrep, double in_stepSize) -> std::shared_ptr<CompositeInstruction> { auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum"); auto propagateKernel = gateRegistry->createComposite("statePropCircuit"); Loading @@ -93,11 +110,17 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // i.e. regular evolution which approximates the imaginary time evolution. for (const auto &term : aObs->getNonIdentitySubTerms()) { auto method = xacc::getService<AnsatzGenerator>("trotter"); auto trotterCir = method->create_ansatz(term.get(), {{"dt", 0.5 * in_stepSize}}).circuit; auto trotterCir = method->create_ansatz(term.get(), {{"dt", 0.5 * in_stepSize}}) .circuit; propagateKernel->addInstructions(trotterCir->getInstructions()); } } for (auto &opt : extra_circuit_optimizers) { opt->apply(propagateKernel, acc, config_params); } // std::cout << "Progagated kernel:\n" << propagateKernel->toString() << // "\n"; return propagateKernel; Loading @@ -106,7 +129,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Cost function (observable) evaluator auto calcCurrentEnergy = [&]() { // Trotter kernel up to this point auto propagateKernel = constructPropagateCircuit(approxOps, model.user_defined_ansatz, stepSize); auto propagateKernel = constructPropagateCircuit( approxOps, model.user_defined_ansatz, stepSize); evaluator = getEvaluator(model.observable, config_params); return evaluator->evaluate(propagateKernel); }; Loading @@ -114,7 +138,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Initial energy energyAtStep.emplace_back(calcCurrentEnergy()); const auto pauliOps = generatePauliPermutation(nbQubits); const auto evaluateTomographyAtStep = [&](const std::shared_ptr<CompositeInstruction>& in_kernel) { const auto evaluateTomographyAtStep = [&](const std::shared_ptr<CompositeInstruction> &in_kernel) { // Observe the kernels using the various Pauli // operators to calculate S and b. std::vector<double> sigmaExpectation(pauliOps.size()); Loading @@ -126,7 +151,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { tomoObservable->fromString(pauliObsStr); assert(tomoObservable->getSubTerms().size() == 1); assert(tomoObservable->getNonIdentitySubTerms().size() == 1); auto temp_evaluator = getEvaluator(tomoObservable.get(), config_params); auto temp_evaluator = getEvaluator(tomoObservable.get(), config_params); sigmaExpectation[i] = temp_evaluator->evaluate(in_kernel); } return sigmaExpectation; Loading @@ -135,13 +161,16 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Main QITE time-stepping loop: for (int i = 0; i < nbSteps; ++i) { // Propagates the state via Trotter steps: auto kernel = constructPropagateCircuit(approxOps, model.user_defined_ansatz, stepSize); const std::vector<double> sigmaExpectation = evaluateTomographyAtStep(kernel); auto kernel = constructPropagateCircuit( approxOps, model.user_defined_ansatz, stepSize); const std::vector<double> sigmaExpectation = evaluateTomographyAtStep(kernel); auto tmp_buffer = qalloc(nbQubits); auto normVal = qite->calculate( "approximate-ops", xacc::as_shared_ptr(tmp_buffer.results()), {{"pauli-ops", pauliOps}, {"pauli-ops-exp-val", sigmaExpectation}}); const std::string AopsStr = tmp_buffer.results()->getInformation("Aops-str").as<std::string>(); const std::string AopsStr = tmp_buffer.results()->getInformation("Aops-str").as<std::string>(); auto new_approx_ops = createObservable(AopsStr); approxOps.emplace_back(new_approx_ops); energyAtStep.emplace_back(calcCurrentEnergy()); Loading lib/quasimo/impls/workflow/qite.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ namespace qcor { namespace QuaSiMo { class QiteWorkflow : public QuantumSimulationWorkflow { protected: std::vector<std::shared_ptr<xacc::IRTransformation>> extra_circuit_optimizers; public: virtual bool initialize(const HeterogeneousMap ¶ms) override; virtual QuantumSimulationResult Loading lib/quasimo/impls/workflow/tests/QiteWorkflowTester.cpp +34 −4 Original line number Diff line number Diff line #include <gtest/gtest.h> #include "qcor.hpp" #include "qcor_qsim.hpp" #include "xacc.hpp" #include <gtest/gtest.h> TEST(QiteWorkflowTester, checkSimple) { using namespace qcor; Loading @@ -10,8 +11,8 @@ TEST(QiteWorkflowTester, checkSimple) { const int nbSteps = 25; const double stepSize = 0.1; auto problemModel = QuaSiMo::ModelFactory::createModel(&observable); auto workflow = QuaSiMo::getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}}); auto workflow = QuaSiMo::getWorkflow( "qite", {{"steps", nbSteps}, {"step-size", stepSize}}); auto result = workflow->execute(problemModel); const auto energy = result.get<double>("energy"); const auto energyAtStep = result.get<std::vector<double>>("exp-vals"); Loading @@ -20,10 +21,39 @@ TEST(QiteWorkflowTester, checkSimple) { } // Minimal Energy = -1 EXPECT_NEAR(energy, -1.0, 1e-2); auto finalCircuit = result.getPointerLike<xacc::CompositeInstruction>("circuit"); auto finalCircuit = result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << "HOWDY:\n" << finalCircuit->toString() << "\n"; } // TEST(QiteWorkflowTester, checkDeuteronH2) { // using namespace qcor; // xacc::set_verbose(true); // auto compiler = xacc::getCompiler("xasm"); // auto ir = compiler->compile(R"(__qpu__ void f(qbit q) { X(q[0]); })", nullptr); // auto x = ir->getComposite("f"); // auto observable = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + // .21829 * Z(0) - 6.125 * Z(1) + 5.907; // xacc::internal_compiler::qpu = xacc::getAccelerator("qpp"); // const int nbSteps = 5; // const double stepSize = 0.1; // auto problemModel = QuaSiMo::ModelFactory::createModel(x, &observable); // auto workflow = QuaSiMo::getWorkflow( // "qite", {{"steps", nbSteps}, {"step-size", stepSize}, {"circuit-optimizer", xacc::getIRTransformation("qsearch")}}); // auto result = workflow->execute(problemModel); // const auto energy = result.get<double>("energy"); // const auto energyAtStep = result.get<std::vector<double>>("exp-vals"); // for (const auto &val : energyAtStep) { // std::cout << val << "\n"; // } // // Minimal Energy = -1 // // EXPECT_NEAR(energy, -1.0, 1e-2); // // auto finalCircuit = // // result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << // // "HOWDY:\n" << finalCircuit->toString() << "\n"; // } int main(int argc, char **argv) { xacc::Initialize(); ::testing::InitGoogleTest(&argc, argv); Loading Loading
examples/quasimo/qite_deuteron_qsearch.cpp 0 → 100644 +35 −0 Original line number Diff line number Diff line #include "qcor_qsim.hpp" __qpu__ void state_prep(qreg q) { X(q[0]); } int main(int argc, char** argv) { set_verbose(true); using namespace QuaSiMo; // Create the qsearch IR Transformation auto qsearch_optimizer = createTransformation("qsearch"); // Create the Hamiltonian auto observable = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + .21829 * Z(0) - 6.125 * Z(1) + 5.907; // We'll run with 5 steps and .1 step size const int nbSteps = 5; const double stepSize = 0.1; // Create the model (2 qubits, 0 variational params in above state_prep) // and QITE workflow auto problemModel = ModelFactory::createModel(state_prep, &observable, 2, 0); auto workflow = getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}, {"circuit-optimizer", qsearch_optimizer}}); // Execute auto result = workflow->execute(problemModel); // Get the energy and final circuit const auto energy = result.get<double>("energy"); auto finalCircuit = result.getPointerLike<CompositeInstruction>("circuit"); printf("\n%s\nEnergy=%f\n", finalCircuit->toString().c_str(), energy); } No newline at end of file
lib/quasimo/impls/cost_evaluator/partial_tomography.cpp +8 −3 Original line number Diff line number Diff line #include "partial_tomography.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" Loading @@ -10,7 +11,11 @@ double PartialTomoObjFuncEval::evaluate( xacc::as_shared_ptr(target_operator), state_prep); // Run the pass manager (optimization + placement) executePassManager(subKernels); auto tmp_buffer = qalloc(state_prep->nPhysicalBits()); // Set qreg size to the bigger of target_operator bits or state prep physical bits auto tmp_buffer = qalloc(target_operator->nBits() > state_prep->nPhysicalBits() ? target_operator->nBits() : state_prep->nPhysicalBits()); xacc::internal_compiler::execute(tmp_buffer.results(), subKernels); const double energy = tmp_buffer.weighted_sum(target_operator); return energy; Loading
lib/quasimo/impls/workflow/qite.cpp +63 −34 Original line number Diff line number Diff line #include "qite.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" #include "xacc_service.hpp" #include "qsim_utils.hpp" namespace { // Helper to generate all permutation of Pauli observables: Loading Loading @@ -51,12 +52,28 @@ bool QiteWorkflow::initialize(const HeterogeneousMap ¶ms) { std::cout << "'step-size' is required.\n"; initializeOk = false; } if (params.keyExists<std::shared_ptr<xacc::IRTransformation>>( "circuit-optimizer")) { extra_circuit_optimizers.push_back( params.get<std::shared_ptr<xacc::IRTransformation>>( "circuit-optimizer")); } else if (params.keyExists< std::vector<std::shared_ptr<xacc::IRTransformation>>>( "circuit-optimizers")) { auto opts = params.get<std::vector<std::shared_ptr<xacc::IRTransformation>>>( "circuit-optimizers"); extra_circuit_optimizers.insert(extra_circuit_optimizers.end(), opts.begin(), opts.end()); } config_params = params; return initializeOk; } QuantumSimulationResult QiteWorkflow::execute(const QuantumSimulationModel &model) { QuantumSimulationResult QiteWorkflow::execute( const QuantumSimulationModel &model) { const auto nbSteps = config_params.get<int>("steps"); const auto stepSize = config_params.get<double>("step-size"); auto qite = xacc::getService<xacc::Algorithm>("qite"); Loading @@ -73,9 +90,9 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { std::vector<double> energyAtStep; auto constructPropagateCircuit = [](const std::vector<std::shared_ptr<Observable>> &in_Aops, const std::shared_ptr<KernelFunctor> &in_statePrep, double in_stepSize) -> std::shared_ptr<CompositeInstruction> { [this, &acc](const std::vector<std::shared_ptr<Observable>> &in_Aops, const std::shared_ptr<KernelFunctor> &in_statePrep, double in_stepSize) -> std::shared_ptr<CompositeInstruction> { auto gateRegistry = xacc::getService<xacc::IRProvider>("quantum"); auto propagateKernel = gateRegistry->createComposite("statePropCircuit"); Loading @@ -93,11 +110,17 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // i.e. regular evolution which approximates the imaginary time evolution. for (const auto &term : aObs->getNonIdentitySubTerms()) { auto method = xacc::getService<AnsatzGenerator>("trotter"); auto trotterCir = method->create_ansatz(term.get(), {{"dt", 0.5 * in_stepSize}}).circuit; auto trotterCir = method->create_ansatz(term.get(), {{"dt", 0.5 * in_stepSize}}) .circuit; propagateKernel->addInstructions(trotterCir->getInstructions()); } } for (auto &opt : extra_circuit_optimizers) { opt->apply(propagateKernel, acc, config_params); } // std::cout << "Progagated kernel:\n" << propagateKernel->toString() << // "\n"; return propagateKernel; Loading @@ -106,7 +129,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Cost function (observable) evaluator auto calcCurrentEnergy = [&]() { // Trotter kernel up to this point auto propagateKernel = constructPropagateCircuit(approxOps, model.user_defined_ansatz, stepSize); auto propagateKernel = constructPropagateCircuit( approxOps, model.user_defined_ansatz, stepSize); evaluator = getEvaluator(model.observable, config_params); return evaluator->evaluate(propagateKernel); }; Loading @@ -114,7 +138,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Initial energy energyAtStep.emplace_back(calcCurrentEnergy()); const auto pauliOps = generatePauliPermutation(nbQubits); const auto evaluateTomographyAtStep = [&](const std::shared_ptr<CompositeInstruction>& in_kernel) { const auto evaluateTomographyAtStep = [&](const std::shared_ptr<CompositeInstruction> &in_kernel) { // Observe the kernels using the various Pauli // operators to calculate S and b. std::vector<double> sigmaExpectation(pauliOps.size()); Loading @@ -126,7 +151,8 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { tomoObservable->fromString(pauliObsStr); assert(tomoObservable->getSubTerms().size() == 1); assert(tomoObservable->getNonIdentitySubTerms().size() == 1); auto temp_evaluator = getEvaluator(tomoObservable.get(), config_params); auto temp_evaluator = getEvaluator(tomoObservable.get(), config_params); sigmaExpectation[i] = temp_evaluator->evaluate(in_kernel); } return sigmaExpectation; Loading @@ -135,13 +161,16 @@ QiteWorkflow::execute(const QuantumSimulationModel &model) { // Main QITE time-stepping loop: for (int i = 0; i < nbSteps; ++i) { // Propagates the state via Trotter steps: auto kernel = constructPropagateCircuit(approxOps, model.user_defined_ansatz, stepSize); const std::vector<double> sigmaExpectation = evaluateTomographyAtStep(kernel); auto kernel = constructPropagateCircuit( approxOps, model.user_defined_ansatz, stepSize); const std::vector<double> sigmaExpectation = evaluateTomographyAtStep(kernel); auto tmp_buffer = qalloc(nbQubits); auto normVal = qite->calculate( "approximate-ops", xacc::as_shared_ptr(tmp_buffer.results()), {{"pauli-ops", pauliOps}, {"pauli-ops-exp-val", sigmaExpectation}}); const std::string AopsStr = tmp_buffer.results()->getInformation("Aops-str").as<std::string>(); const std::string AopsStr = tmp_buffer.results()->getInformation("Aops-str").as<std::string>(); auto new_approx_ops = createObservable(AopsStr); approxOps.emplace_back(new_approx_ops); energyAtStep.emplace_back(calcCurrentEnergy()); Loading
lib/quasimo/impls/workflow/qite.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ namespace qcor { namespace QuaSiMo { class QiteWorkflow : public QuantumSimulationWorkflow { protected: std::vector<std::shared_ptr<xacc::IRTransformation>> extra_circuit_optimizers; public: virtual bool initialize(const HeterogeneousMap ¶ms) override; virtual QuantumSimulationResult Loading
lib/quasimo/impls/workflow/tests/QiteWorkflowTester.cpp +34 −4 Original line number Diff line number Diff line #include <gtest/gtest.h> #include "qcor.hpp" #include "qcor_qsim.hpp" #include "xacc.hpp" #include <gtest/gtest.h> TEST(QiteWorkflowTester, checkSimple) { using namespace qcor; Loading @@ -10,8 +11,8 @@ TEST(QiteWorkflowTester, checkSimple) { const int nbSteps = 25; const double stepSize = 0.1; auto problemModel = QuaSiMo::ModelFactory::createModel(&observable); auto workflow = QuaSiMo::getWorkflow("qite", {{"steps", nbSteps}, {"step-size", stepSize}}); auto workflow = QuaSiMo::getWorkflow( "qite", {{"steps", nbSteps}, {"step-size", stepSize}}); auto result = workflow->execute(problemModel); const auto energy = result.get<double>("energy"); const auto energyAtStep = result.get<std::vector<double>>("exp-vals"); Loading @@ -20,10 +21,39 @@ TEST(QiteWorkflowTester, checkSimple) { } // Minimal Energy = -1 EXPECT_NEAR(energy, -1.0, 1e-2); auto finalCircuit = result.getPointerLike<xacc::CompositeInstruction>("circuit"); auto finalCircuit = result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << "HOWDY:\n" << finalCircuit->toString() << "\n"; } // TEST(QiteWorkflowTester, checkDeuteronH2) { // using namespace qcor; // xacc::set_verbose(true); // auto compiler = xacc::getCompiler("xasm"); // auto ir = compiler->compile(R"(__qpu__ void f(qbit q) { X(q[0]); })", nullptr); // auto x = ir->getComposite("f"); // auto observable = -2.1433 * X(0) * X(1) - 2.1433 * Y(0) * Y(1) + // .21829 * Z(0) - 6.125 * Z(1) + 5.907; // xacc::internal_compiler::qpu = xacc::getAccelerator("qpp"); // const int nbSteps = 5; // const double stepSize = 0.1; // auto problemModel = QuaSiMo::ModelFactory::createModel(x, &observable); // auto workflow = QuaSiMo::getWorkflow( // "qite", {{"steps", nbSteps}, {"step-size", stepSize}, {"circuit-optimizer", xacc::getIRTransformation("qsearch")}}); // auto result = workflow->execute(problemModel); // const auto energy = result.get<double>("energy"); // const auto energyAtStep = result.get<std::vector<double>>("exp-vals"); // for (const auto &val : energyAtStep) { // std::cout << val << "\n"; // } // // Minimal Energy = -1 // // EXPECT_NEAR(energy, -1.0, 1e-2); // // auto finalCircuit = // // result.getPointerLike<xacc::CompositeInstruction>("circuit"); std::cout << // // "HOWDY:\n" << finalCircuit->toString() << "\n"; // } int main(int argc, char **argv) { xacc::Initialize(); ::testing::InitGoogleTest(&argc, argv); Loading