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

Added support for Hetmap inputs



It'd be difficult to reuse XACC PyHetmap since the list of types may become different in the future, hence just port the code over.

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

from qcor import *
import numpy as np
import matplotlib.pyplot as plt

# Set up QCOR runtime
Initialize(qpu="qpp")
@@ -16,8 +17,9 @@ def td_hamiltonian(t):
  omega = 4.8 * 2 * np.pi * 1e-3
  return -Jz * Z(0) * Z(1)  - Jz * Z(1) * Z(2) + (-epsilon * np.cos(omega * t)) * (X(0) + X(1) + X(2)) 

# Observable = average magnetization
observable = (1.0 / 3.0) * (Z(0) + Z(1) + Z(2))
print("observable = ", observable.toString())

# 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)
@@ -28,3 +30,16 @@ workflow = qsim.getWorkflow(

# Result contains the observable expectation value along Trotter steps.
result = workflow.execute(problemModel)

# Plot the result:
t = np.linspace(0, 300, 101)
y = result["exp-vals"]
axes = plt.axes()
axes.plot(t, y)
axes.axhline(y=0.0, color='r', linestyle='--')
axes.set_xlim([0,300])
axes.set_ylim([-1,1])
axes.set_title("$\epsilon_{ph} = J_z$, 3-qubit")
# Save the plot to a file:
os.chdir(os.path.dirname(os.path.abspath(__file__)))
plt.savefig("avg_magnetization_plot.pdf")  
 No newline at end of file
+55 −16
Original line number Diff line number Diff line
#include "base/qcor_qsim.hpp"
#include "py_costFunctionEvaluator.hpp"
#include "py_qsimWorkflow.hpp"
#include "xacc.hpp"
#include <pybind11/functional.h>
#include <pybind11/pybind11.h>
#include "xacc.hpp"
namespace py = pybind11;

namespace pybind11 {
namespace detail {
template <typename... Ts>
struct type_caster<xacc::Variant<Ts...>>
    : variant_caster<xacc::Variant<Ts...>> {};

template <> struct visit_helper<xacc::Variant> {
  template <typename... Args>
  static auto call(Args &&... args) -> decltype(mpark::visit(args...)) {
    return mpark::visit(args...);
  }
};

template <typename... Ts>
struct type_caster<mpark::variant<Ts...>>
    : variant_caster<mpark::variant<Ts...>> {};

template <> struct visit_helper<mpark::variant> {
  template <typename... Args>
  static auto call(Args &&... args) -> decltype(mpark::visit(args...)) {
    return mpark::visit(args...);
  }
};
} // namespace detail
} // namespace pybind11

namespace {
// Add type name to this list to support receiving from Python.
using PyHeterogeneousMapTypes = xacc::Variant<bool, int, double, std::string>;

using PyHeterogeneousMap = std::map<std::string, PyHeterogeneousMapTypes>;

// Helper to convert a Python *dict* (as a map of variants) into a native
// HetMap.
xacc::HeterogeneousMap
heterogeneousMapConvert(const PyHeterogeneousMap &in_pyMap) {
  xacc::HeterogeneousMap result;
  for (auto &item : in_pyMap) {
    auto visitor = [&](const auto &value) { result.insert(item.first, value); };
    mpark::visit(visitor, item.second);
  }

  return result;
}
} // namespace

PYBIND11_MODULE(_pyqcor, m) {
  m.doc() = "Python bindings for QCOR.";
  // Handle QCOR CLI arguments:
@@ -30,18 +76,10 @@ PYBIND11_MODULE(_pyqcor, m) {
  // Expose QCOR API functions
  m.def(
      "createOptimizer",
      [](const std::string &name, py::dict p = {}) {
        xacc::HeterogeneousMap params;
        std::cout << "HOWDY: " << name << "\n";
        /// TODO: reuse XACC PyHetMap here
        for (auto item : p) {
          std::cout << "key=" << std::string(py::str(item.first)) << ", "
                    << "value=" << std::string(py::str(item.second)) << "\n";
        }

        return qcor::createOptimizer(name, std::move(params));
      [](const std::string &name, PyHeterogeneousMap p = {}) {
        return qcor::createOptimizer(name, heterogeneousMapConvert(p));
      },
      py::arg("name"), py::arg("p") = py::dict(),
      py::arg("name"), py::arg("p") = PyHeterogeneousMap(),
      py::return_value_policy::reference,
      "Return the Optimizer with given name.");

@@ -116,10 +154,11 @@ PYBIND11_MODULE(_pyqcor, m) {
            "Execute the workflow for the input problem model.");
    qsim.def(
        "getWorkflow",
        [](const std::string &name, py::dict p = {}) {
          return qcor::qsim::getWorkflow(name, {});
        [](const std::string &name, PyHeterogeneousMap p = {}) {
          auto nativeHetMap = heterogeneousMapConvert(p);
          return qcor::qsim::getWorkflow(name, nativeHetMap);
        },
        py::arg("name"), py::arg("p") = py::dict(),
        py::arg("name"), py::arg("p") = PyHeterogeneousMap(),
        py::return_value_policy::reference,
        "Return the quantum simulation workflow.");
  }