Commit 30706ae1 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

bug fix for mapping observables from pyscf/psi4 at python api, bug fix for...


bug fix for mapping observables from pyscf/psi4 at python api, bug fix for allocated qreg in vqe workflow, added u3 gate to unitary matrix converter visitor

Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 0bce4a16
Loading
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -187,9 +187,16 @@ std::shared_ptr<qcor::Observable> convertToQCOROperator(
      }
      return qcor::createOperator(ss.str());
    }
  } else if (py::hasattr(op, "toString") && py::hasattr(op, "observe")) {
    auto string_rep = op.attr("toString");
    auto op_str = string_rep().cast<std::string>();
    if (op_str.find("^") != std::string::npos) {
      return qcor::createOperator("fermion", op_str);
    } else {
      return qcor::createOperator(op_str);
    }
  } else {
    // throw an error
    std::cout << "THrowing an error\n";
    qcor::error(
        "Invalid python object passed as a QCOR Operator/Observable. "
        "Currently, we only accept OpenFermion datastructures.");
@@ -228,6 +235,8 @@ class PyObjectiveFunction : public qcor::ObjectiveFunction {
    // Set the OptFunction dimensions
    _dim = n_dim;

    qreg = ::qalloc(qq.nBits());

    // Set the helper objective
    helper = xacc::getService<qcor::ObjectiveFunction>(helper_name);

@@ -257,6 +266,7 @@ class PyObjectiveFunction : public qcor::ObjectiveFunction {
      : py_kernel(q) {
    // Set the OptFunction dimensions
    _dim = n_dim;
    qreg = ::qalloc(qq->nBits());

    // Set the helper objective
    helper = xacc::getService<qcor::ObjectiveFunction>(helper_name);
@@ -285,7 +295,8 @@ class PyObjectiveFunction : public qcor::ObjectiveFunction {
  double operator()(const KernelArgDict args, std::vector<double> &dx) {
    std::function<std::shared_ptr<CompositeInstruction>(std::vector<double>)>
        kernel_evaluator = [&](std::vector<double> x) {
          qreg = ::qalloc(observable->nBits());
          // qreg = ::qalloc(observable->nBits());
          // std::cout << "Allocating " << qreg.name() << "\n";
          auto _args =
              py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>();
          // Map the kernel args to a hetmap
@@ -315,7 +326,7 @@ class PyObjectiveFunction : public qcor::ObjectiveFunction {
    helper->update_current_iterate_parameters(x);

    // Translate x into kernel args
    qreg = ::qalloc(observable->nBits());
    // qreg = ::qalloc(observable->nBits());
    auto args = py_kernel.attr("translate")(qreg, x).cast<KernelArgDict>();
    // args will be a dictionary, arg_name to arg
    return operator()(args, dx);
@@ -326,6 +337,8 @@ class PyObjectiveFunction : public qcor::ObjectiveFunction {
    throw std::bad_function_call();
    return 0.0;
  }

  xacc::internal_compiler::qreg get_qreg() override { return qreg; }
};

// PyKernelFunctor is a subtype of KernelFunctor from the qsim library
@@ -497,6 +510,10 @@ PYBIND11_MODULE(_pyqcor, m) {
      .def("print", &xacc::internal_compiler::qreg::print, "")
      .def("counts", &xacc::internal_compiler::qreg::counts, "")
      .def("exp_val_z", &xacc::internal_compiler::qreg::exp_val_z, "")
      .def("results", [](xacc::internal_compiler::qreg& q){
        auto buffer = q.results_shared();
        return buffer;
      }, "")
      .def(
          "getInformation",
          [](xacc::internal_compiler::qreg &q, const std::string &key) {
@@ -588,7 +605,8 @@ PYBIND11_MODULE(_pyqcor, m) {
            auto val = obj(x, dx);
            return std::make_pair(val, dx);
          },
          "");
          "")
      .def("get_qreg", &qcor::ObjectiveFunction::get_qreg, "");

  m.def(
      "createObjectiveFunction",
+5 −4
Original line number Diff line number Diff line
@@ -48,8 +48,8 @@ public:
          "QCOR VQE Error - could not initialize internal xacc vqe algorithm.");
    }

    auto tmp_child = qalloc(qreg.size());
    auto val = vqe->execute(xacc::as_shared_ptr(tmp_child.results()), {})[0];
    auto tmp_child = std::make_shared<xacc::AcceleratorBuffer>("temp_vqe_child", qreg.size());
    auto val = vqe->execute(tmp_child, {})[0];
    double std_dev = 0.0;
    if (options.keyExists<int>("vqe-gather-statistics")) {
      std::vector<double> all_energies;
@@ -76,7 +76,7 @@ public:
    }
    
    // want to store parameters, have to do it here
    for (auto &child : tmp_child.results()->getChildren()) {
    for (auto &child : tmp_child->getChildren()) {
      child->addExtraInfo("parameters", current_iterate_parameters);
      auto tmp = current_iterate_parameters;
      tmp.push_back(val);
@@ -85,9 +85,10 @@ public:
        child->addExtraInfo("qcor-energy-stddev", std_dev);
      }
      child->addExtraInfo("iteration", current_iteration);
      qreg.results()->appendChild(child->name(), child);
    }
    current_iteration++;
    qreg.addChild(tmp_child);
    // qreg.addChild(tmp_child);

    if (!dx.empty() && options.stringExists("gradient-strategy")) {
      // Compute the gradient
+19 −3
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ std::shared_ptr<xacc::CompositeInstruction> compile(const std::string &src) {
}

namespace __internal__ {
std::string translate(const std::string compiler, std::shared_ptr<CompositeInstruction> program) {
std::string translate(const std::string compiler,
                      std::shared_ptr<CompositeInstruction> program) {
  return xacc::getCompiler(compiler)->translate(program);
}

@@ -238,13 +239,28 @@ void KernelToUnitaryVisitor::visit(T &t) {
void KernelToUnitaryVisitor::visit(Tdg &tdg) {
  m_circuitMat = singleQubitGateExpand(Tdg_Mat, tdg.bits()[0]) * m_circuitMat;
}
void KernelToUnitaryVisitor::visit(CPhase &cphase) {xacc::error("Need to implement CPhase gate to matrix.");}
void KernelToUnitaryVisitor::visit(CPhase &cphase) {
  xacc::error("Need to implement CPhase gate to matrix.");
}

void KernelToUnitaryVisitor::visit(Measure &measure) {}
void KernelToUnitaryVisitor::visit(Identity &i) {}
void KernelToUnitaryVisitor::visit(U &u) {
  xacc::error("We don't support U3 gate to matrix.");
  double in_theta = u.getParameter(0).as<double>();
  double in_phi = u.getParameter(1).as<double>();
  double in_lambda = u.getParameter(2).as<double>();

  MatrixXcd u_mat(2, 2);
  u_mat << std::cos(in_theta / 2.0),
      -std::exp(std::complex<double>(0, in_lambda)) * std::sin(in_theta / 2.0),
      std::exp(std::complex<double>(0, in_phi)) * std::sin(in_theta / 2.0),
      std::exp(std::complex<double>(0, in_phi + in_lambda)) *
          std::cos(in_theta / 2.0);
  m_circuitMat = singleQubitGateExpand(u_mat, u.bits()[0]) * m_circuitMat;

  // xacc::error("We don't support U3 gate to matrix.");
}

void KernelToUnitaryVisitor::visit(IfStmt &ifStmt) {}
// Identifiable Impl
MatrixXcd KernelToUnitaryVisitor::getMat() const { return m_circuitMat; }