Commit 12b1d060 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

demonstrate use of ctrl on exp_i_theta and circuit opt with iterate qpe quasimo workflow

parent 0ddaa322
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+9 −3
Original line number Diff line number Diff line
#include "trotter.hpp"

#include "xacc_service.hpp"

namespace qcor {
@@ -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();

+19 −4
Original line number Diff line number Diff line
@@ -15,13 +15,18 @@ bool IterativeQpeWorkflow::initialize(const HeterogeneousMap &params) {
  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.
@@ -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
@@ -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
@@ -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) {
@@ -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";
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -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>
@@ -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