Unverified Commit 5b6642ab authored by Mccaskey, Alex's avatar Mccaskey, Alex Committed by GitHub
Browse files

Merge pull request #79 from tnguyen-ornl/tnguyen/pass-manager-python-api

Add Python API for configuring placement and optimization
parents f9e71d41 40d4033b
Loading
Loading
Loading
Loading
Loading
+43 −1
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ class KernelArgDictToHeterogeneousMap {
// Add type name to this list to support receiving from Python.
using PyHeterogeneousMapTypes =
    xacc::Variant<bool, int, double, std::string, std::vector<int>,
                  std::shared_ptr<qcor::Optimizer>, std::vector<double>, std::vector<std::vector<double>>>;
                  std::vector<std::pair<int, int>>,
                  std::shared_ptr<qcor::Optimizer>, std::vector<double>,
                  std::vector<std::vector<double>>>;
using PyHeterogeneousMap = std::map<std::string, PyHeterogeneousMapTypes>;

// Helper to convert a Python *dict* (as a map of variants) into a native
@@ -448,6 +450,46 @@ PYBIND11_MODULE(_pyqcor, m) {
      py::arg("name"), py::arg("p") = PyHeterogeneousMap(),
      "Set the QPU backend.");

  m.def(
      "set_opt_level",
      [](int level) { xacc::internal_compiler::__opt_level = level; },
      py::arg("level"), "Set QCOR runtime optimization level.");

  m.def(
      "add_pass",
      [](const std::string &pass_name) {
        // Note: we expect __user_opt_passes to be a comma-separated list of
        // pass names.
        if (xacc::internal_compiler::__user_opt_passes.empty()) {
          xacc::internal_compiler::__user_opt_passes = pass_name;
        } else {
          xacc::internal_compiler::__user_opt_passes += ("," + pass_name);
        }
      },
      py::arg("pass_name"),
      "Add an optimization pass to be run by the PassManager.");

  m.def(
      "get_placement_names",
      []() {
        std::vector<std::string> result;
        auto ir_transforms = xacc::getServices<xacc::IRTransformation>();
        for (const auto &plugin : ir_transforms) {
          if (plugin->type() == xacc::IRTransformationType::Placement) {
            result.emplace_back(plugin->name());
          }
        }
        return result;
      },
      "Get names of all available placement plugins.");

  m.def(
      "set_placement",
      [](const std::string &placement_name) {
        xacc::internal_compiler::__placement_name = placement_name;
      },
      py::arg("placement_name"), "Set the placement strategy.");

  m.def("qalloc", &::qalloc, py::return_value_policy::reference, "");
  py::class_<xacc::internal_compiler::qreg>(m, "qreg", "")
      .def("size", &xacc::internal_compiler::qreg::size, "")
+8 −1
Original line number Diff line number Diff line
@@ -39,3 +39,10 @@ add_test (NAME qcor_kernel_ftqc_python
)
set_tests_properties(qcor_kernel_ftqc_python
   PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}:$ENV{PYTHONPATH}")

add_test (NAME qcor_python_jit_pass_manager
   COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_jit_pass_manager.py
   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 )
 set_tests_properties(qcor_python_jit_pass_manager
     PROPERTIES ENVIRONMENT "PYTHONPATH=${CMAKE_INSTALL_PREFIX}:$ENV{PYTHONPATH}")
 No newline at end of file
+40 −0
Original line number Diff line number Diff line
import unittest
from qcor import *

class TestKernelJIT(unittest.TestCase):
    def test_opt_level(self):
        @qjit
        def test1(q : qreg):
            H(q[0])
            X(q[0])
            H(q[0])

        q = qalloc(1)
        comp = test1.extract_composite(q)
        self.assertEqual(comp.nInstructions(), 3)   
        # Activate opt-level 1
        set_opt_level(1)
        comp_opt = test1.extract_composite(q)
        # Should become 1 gate: Z, i.e. Rz(pi)
        self.assertEqual(comp_opt.nInstructions(), 1)   
    
    def test_placement_query(self):
        placement_names = get_placement_names()
        self.assertTrue(len(placement_names) > 0)   
        print(placement_names)

    def test_placement(self):
        @qjit
        def test2(q : qreg):
            CX(q[0], q[3])
        # Define a connectivity topology
        set_qpu('qpp', { 'connectivity': [[0,1], [0,2], [1,2], [2,3], [2,4], [3,4]] })
        set_placement('swap-shortest-path')
        q = qalloc(5)
        comp = test2.extract_composite(q)
        print(comp)
        # This becomes 1 SWAP + 1 CNOT => 4 CNOT's
        self.assertEqual(comp.nInstructions(), 4)    

if __name__ == '__main__':
  unittest.main()
 No newline at end of file