Loading lib/qsim/base/qcor_qsim.hpp +12 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,18 @@ class CostFunctionEvaluator : public Identifiable { public: // Evaluate the cost virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep) = 0; // Batching evaluation: observing multiple kernels in batches. // E.g. for non-vqe cases (Trotter), we have all kernels ready for observable evaluation virtual std::vector<double> evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) { // Default is one-by-one, subclass to provide batching if supported. std::vector<double> result; for (auto &circuit : state_prep_circuits) { result.emplace_back(evaluate(circuit)); } return result; } virtual bool initialize(Observable *observable, const HeterogeneousMap ¶ms = {}); Loading lib/qsim/impls/cost_evaluator/partial_tomography.cpp +37 −0 Original line number Diff line number Diff line #include "partial_tomography.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" namespace qcor { namespace qsim { Loading @@ -14,5 +15,41 @@ double PartialTomoObjFuncEval::evaluate( const double energy = tmp_buffer.weighted_sum(target_operator); return energy; } std::vector<double> PartialTomoObjFuncEval::evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) { xacc::info("Batching " + std::to_string(state_prep_circuits.size()) + " kernel observable evaluations."); std::vector<size_t> nbSubKernelsPerObs; std::vector<std::shared_ptr<CompositeInstruction>> fsToExec; for (auto &circ : state_prep_circuits) { auto subKernels = qcor::__internal__::observe(xacc::as_shared_ptr(target_operator), circ); // Run the pass manager (optimization + placement) executePassManager(subKernels); // Track number of obs. kernels nbSubKernelsPerObs.emplace_back(subKernels.size()); fsToExec.insert(fsToExec.end(), subKernels.begin(), subKernels.end()); } auto tmp_buffer = qalloc(target_operator->nBits()); // Execute all kernels: xacc::internal_compiler::execute(tmp_buffer.results(), fsToExec); size_t bufferCounter = 0; std::vector<double> result; auto allChildBuffers = tmp_buffer.results()->getChildren(); // Segregates the child buffers into groups (of each obs eval.) for (const auto &nbChildBuffers : nbSubKernelsPerObs) { auto temp_buf = qalloc(tmp_buffer.size()); for (size_t idx = 0; idx < nbChildBuffers; ++idx) { auto bufferToAppend = allChildBuffers[bufferCounter + idx]; temp_buf.results()->appendChild(bufferToAppend->name(), bufferToAppend); } bufferCounter += nbChildBuffers; result.emplace_back(temp_buf.weighted_sum(target_operator)); } assert(result.size() == state_prep_circuits.size()); return result; } } // namespace qsim } // namespace qcor No newline at end of file lib/qsim/impls/cost_evaluator/partial_tomography.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ public: // Evaluate the cost virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep) override; virtual std::vector<double> evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) override; virtual const std::string name() const override { return "default"; } virtual const std::string description() const override { return ""; } }; Loading lib/qsim/impls/workflow/time_dependent.cpp +7 −5 Original line number Diff line number Diff line #include "time_dependent.hpp" #include "qsim_utils.hpp" #include "xacc_service.hpp" #include "xacc.hpp" namespace qcor { namespace qsim { Loading Loading @@ -29,11 +30,12 @@ TimeDependentWorkflow::execute(const QuantumSimulationModel &model) { // A TD workflow: stepping through Trotter steps, // compute expectations at each step. double currentTime = t_0; std::vector<double> resultExpectationValues; std::shared_ptr<CompositeInstruction> totalCirc; // Just support Trotter for now // TODO: support different methods: auto method = xacc::getService<AnsatzGenerator>("trotter"); // List of all circuits to evaluate: std::vector<std::shared_ptr<CompositeInstruction>> allCircuits; for (;;) { // Evaluate the time-dependent Hamiltonian: auto ham_t = ham_func(currentTime); Loading @@ -54,16 +56,16 @@ TimeDependentWorkflow::execute(const QuantumSimulationModel &model) { totalCirc->addInstructions(stepAnsatz.circuit->getInstructions()); } // std::cout << totalCirc->toString() << "\n"; // Evaluate the expectation after these Trotter steps: const double ham_expect = evaluator->evaluate(totalCirc); resultExpectationValues.emplace_back(ham_expect); // Add the circuit for this time step to the list for later execution allCircuits.emplace_back(xacc::ir::asComposite(totalCirc->clone())); currentTime += dt; if (currentTime > t_final) { break; } } // Evaluate exp-val at all timesteps auto resultExpectationValues = evaluator->evaluate(allCircuits); result.insert("exp-vals", resultExpectationValues); return result; } Loading Loading
lib/qsim/base/qcor_qsim.hpp +12 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,18 @@ class CostFunctionEvaluator : public Identifiable { public: // Evaluate the cost virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep) = 0; // Batching evaluation: observing multiple kernels in batches. // E.g. for non-vqe cases (Trotter), we have all kernels ready for observable evaluation virtual std::vector<double> evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) { // Default is one-by-one, subclass to provide batching if supported. std::vector<double> result; for (auto &circuit : state_prep_circuits) { result.emplace_back(evaluate(circuit)); } return result; } virtual bool initialize(Observable *observable, const HeterogeneousMap ¶ms = {}); Loading
lib/qsim/impls/cost_evaluator/partial_tomography.cpp +37 −0 Original line number Diff line number Diff line #include "partial_tomography.hpp" #include "qsim_utils.hpp" #include "xacc.hpp" namespace qcor { namespace qsim { Loading @@ -14,5 +15,41 @@ double PartialTomoObjFuncEval::evaluate( const double energy = tmp_buffer.weighted_sum(target_operator); return energy; } std::vector<double> PartialTomoObjFuncEval::evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) { xacc::info("Batching " + std::to_string(state_prep_circuits.size()) + " kernel observable evaluations."); std::vector<size_t> nbSubKernelsPerObs; std::vector<std::shared_ptr<CompositeInstruction>> fsToExec; for (auto &circ : state_prep_circuits) { auto subKernels = qcor::__internal__::observe(xacc::as_shared_ptr(target_operator), circ); // Run the pass manager (optimization + placement) executePassManager(subKernels); // Track number of obs. kernels nbSubKernelsPerObs.emplace_back(subKernels.size()); fsToExec.insert(fsToExec.end(), subKernels.begin(), subKernels.end()); } auto tmp_buffer = qalloc(target_operator->nBits()); // Execute all kernels: xacc::internal_compiler::execute(tmp_buffer.results(), fsToExec); size_t bufferCounter = 0; std::vector<double> result; auto allChildBuffers = tmp_buffer.results()->getChildren(); // Segregates the child buffers into groups (of each obs eval.) for (const auto &nbChildBuffers : nbSubKernelsPerObs) { auto temp_buf = qalloc(tmp_buffer.size()); for (size_t idx = 0; idx < nbChildBuffers; ++idx) { auto bufferToAppend = allChildBuffers[bufferCounter + idx]; temp_buf.results()->appendChild(bufferToAppend->name(), bufferToAppend); } bufferCounter += nbChildBuffers; result.emplace_back(temp_buf.weighted_sum(target_operator)); } assert(result.size() == state_prep_circuits.size()); return result; } } // namespace qsim } // namespace qcor No newline at end of file
lib/qsim/impls/cost_evaluator/partial_tomography.hpp +3 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ public: // Evaluate the cost virtual double evaluate(std::shared_ptr<CompositeInstruction> state_prep) override; virtual std::vector<double> evaluate( std::vector<std::shared_ptr<CompositeInstruction>> state_prep_circuits) override; virtual const std::string name() const override { return "default"; } virtual const std::string description() const override { return ""; } }; Loading
lib/qsim/impls/workflow/time_dependent.cpp +7 −5 Original line number Diff line number Diff line #include "time_dependent.hpp" #include "qsim_utils.hpp" #include "xacc_service.hpp" #include "xacc.hpp" namespace qcor { namespace qsim { Loading Loading @@ -29,11 +30,12 @@ TimeDependentWorkflow::execute(const QuantumSimulationModel &model) { // A TD workflow: stepping through Trotter steps, // compute expectations at each step. double currentTime = t_0; std::vector<double> resultExpectationValues; std::shared_ptr<CompositeInstruction> totalCirc; // Just support Trotter for now // TODO: support different methods: auto method = xacc::getService<AnsatzGenerator>("trotter"); // List of all circuits to evaluate: std::vector<std::shared_ptr<CompositeInstruction>> allCircuits; for (;;) { // Evaluate the time-dependent Hamiltonian: auto ham_t = ham_func(currentTime); Loading @@ -54,16 +56,16 @@ TimeDependentWorkflow::execute(const QuantumSimulationModel &model) { totalCirc->addInstructions(stepAnsatz.circuit->getInstructions()); } // std::cout << totalCirc->toString() << "\n"; // Evaluate the expectation after these Trotter steps: const double ham_expect = evaluator->evaluate(totalCirc); resultExpectationValues.emplace_back(ham_expect); // Add the circuit for this time step to the list for later execution allCircuits.emplace_back(xacc::ir::asComposite(totalCirc->clone())); currentTime += dt; if (currentTime > t_final) { break; } } // Evaluate exp-val at all timesteps auto resultExpectationValues = evaluator->evaluate(allCircuits); result.insert("exp-vals", resultExpectationValues); return result; } Loading