Commit c96df1be authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Work on Qsim Python binding



Add workflow binding and an 'Initialize' method to set up QCOR runtime.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent d6b7f65f
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
import sys
from pathlib import Path
sys.path.insert(1, str(Path.home()) + '/.xacc')
sys.path.insert(1, str(Path.home()) + "/.xacc")

from qcor import *
import numpy as np

# Set up QCOR runtime
Initialize(qpu="qpp")

# Time-dependent Hamiltonian: 
# Returns the Pauli operators at a time point.
def td_hamiltonian(t):
@@ -14,4 +18,13 @@ def td_hamiltonian(t):

observable = (1.0 / 3.0) * (Z(0) + Z(1) + Z(2))
print("observable = ", observable.toString())
model = qsim.ModelBuilder.createModel(observable, td_hamiltonian)
 No newline at end of file
# Example: build model and TD workflow for Fig. 2 of
# https://journals.aps.org/prb/pdf/10.1103/PhysRevB.101.184305
problemModel = qsim.ModelBuilder.createModel(observable, td_hamiltonian)
# TD workflow with hyper-parameters: 
# Trotter step = 3fs, number of steps = 100 -> end time = 300fs
workflow = qsim.getWorkflow(
      "td-evolution", {"method": "trotter", "dt": 3.0, "steps": 100})

# Result contains the observable expectation value along Trotter steps.
result = workflow.execute(problemModel)
 No newline at end of file
+46 −0
Original line number Diff line number Diff line
#include "base/qcor_qsim.hpp"
#include "py_costFunctionEvaluator.hpp"
#include "py_qsimWorkflow.hpp"
#include <pybind11/functional.h>
#include <pybind11/pybind11.h>
#include "xacc.hpp"
namespace py = pybind11;

PYBIND11_MODULE(_pyqcor, m) {
  m.doc() = "Python bindings for QCOR.";
  // Handle QCOR CLI arguments:
  // when using via Python, we use this to set those runtime parameters. 
  m.def(
      "Initialize",
      [](py::kwargs kwargs) {
        if (kwargs) {
          for (auto arg : kwargs) {
            const auto key = std::string(py::str(arg.first));
            const auto value = std::string(py::str(arg.second));
            // Handle "qpu" key
            if (key == "qpu") {
              xacc::internal_compiler::qpu = xacc::getAccelerator(value);
            }
            /// TODO: handle other CLI parameters.
          }
        }
      },
      "Initialize QCOR runtime environment.");

  // Expose QCOR API functions
  m.def(
      "createOptimizer",
@@ -76,5 +97,30 @@ PYBIND11_MODULE(_pyqcor, m) {
        py::arg("obs"), py::arg("name") = "default", py::arg("p") = py::dict(),
        py::return_value_policy::reference,
        "Return the CostFunctionEvaluator.");

    // QuantumSimulationWorkflow bindings
    py::class_<qcor::qsim::QuantumSimulationWorkflow,
               std::shared_ptr<qcor::qsim::QuantumSimulationWorkflow>,
               qcor::qsim::PyQuantumSimulationWorkflow>(
        qsim, "QuantumSimulationWorkflow",
        "The QuantumSimulationWorkflow interface provides methods to "
        "execute a quantum simulation workflow.")
        .def(py::init<>())
        .def(
            "execute",
            [](qcor::qsim::QuantumSimulationWorkflow &self,
               const qcor::qsim::QuantumSimulationModel &model)
                -> qcor::qsim::QuantumSimulationResult {
              return self.execute(model);
            },
            "Execute the workflow for the input problem model.");
    qsim.def(
        "getWorkflow",
        [](const std::string &name, py::dict p = {}) {
          return qcor::qsim::getWorkflow(name, {});
        },
        py::arg("name"), py::arg("p") = py::dict(),
        py::return_value_policy::reference,
        "Return the quantum simulation workflow.");
  }
}
+33 −0
Original line number Diff line number Diff line
#include "base/qcor_qsim.hpp"
#include <memory>
#include <pybind11/complex.h>
#include <pybind11/eigen.h>
#include <pybind11/functional.h>
#include <pybind11/iostream.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>

namespace py = pybind11;
namespace qcor {
namespace qsim {
class PyQuantumSimulationWorkflow : public QuantumSimulationWorkflow {
  const std::string name() const override {
    PYBIND11_OVERLOAD_PURE(const std::string, QuantumSimulationWorkflow, name);
  }
  const std::string description() const override {
    PYBIND11_OVERLOAD_PURE(const std::string, QuantumSimulationWorkflow,
                           description);
  }
  QuantumSimulationResult
  execute(const QuantumSimulationModel &model) override {
    PYBIND11_OVERLOAD_PURE(QuantumSimulationResult, QuantumSimulationWorkflow,
                           evaluate);
  }
  bool initialize(const HeterogeneousMap &params) override {
    PYBIND11_OVERLOAD_PURE(bool, QuantumSimulationWorkflow, initialize);
  }
};
} // namespace qsim
} // namespace qcor