QNLP  v1.0
Simulator_pybind11.cpp
Go to the documentation of this file.
1 #include "pybind11/pybind11.h"
2 #include "pybind11/iostream.h"
3 #include "Simulator.hpp"
4 #include "IntelSimulator.cpp"
5 #include "pybind11/complex.h"
6 #include "pybind11/stl.h"
7 #include <pybind11/numpy.h>
8 #include <mpi.h>
9 
10 #define PYBIND11_EXPORT __attribute__ ((visibility("default")))
11 
12 namespace py = pybind11;
13 using namespace QNLP;
14 using DCM = qhipster::TinyMatrix<std::complex<double>, 2u, 2u, 32u>;
15 
16 class IntelSimPy : public IntelSimulator{
17  public:
18 
19  IntelSimPy(int numQubits, bool useFusion=false) : IntelSimulator(numQubits, useFusion) { }
20  IntelSimPy(std::unique_ptr<IntelSimulator, std::default_delete<IntelSimulator> > iSim) : IntelSimulator(iSim->getNumQubits(), false) {}
22 
23  void applyGateNCU_nonlinear(const DCM& U, std::vector<std::size_t>& ctrl_indices, std::size_t target, std::string label){
24  this->applyGateNCU(U, ctrl_indices, {}, target, label);
25  }
26  void applyGateNCU_5CX_Opt(const DCM& U, std::vector<std::size_t>& ctrl_indices, std::vector<std::size_t>& aux_indices, std::size_t target, std::string label){
27  this->applyGateNCU(U, ctrl_indices, aux_indices, target, label);
28  }
29  void applyOracle_U(std::size_t bit_pattern, const DCM& U, std::vector<std::size_t>& ctrl_indices, std::size_t target, std::string label){
30  this->applyOracleU( bit_pattern, ctrl_indices, target, U, label);
31  }
32  void applyOracle_Opt(std::size_t bit_pattern, const DCM& U, std::vector<std::size_t>& ctrl_indices, std::vector<std::size_t>& aux_indices, std::size_t target, std::string label){
33  this->applyOracleU( bit_pattern, ctrl_indices, aux_indices, target, U, label);
34  }
35 
36  void addUToCache_U(const DCM& U, std::string label){
37  this->addUToCache(label, U);
38  }
39 
40  complex<double> computeOverlap(IntelSimPy& sim){
41  return this->overlap(sim);
42  }
43 };
44 
45 template <class SimulatorType>
46 void intel_simulator_binding(py::module &m){
47 
48  py::class_<SimulatorType>(m, "PyQNLPSimulator")
49  .def(py::init<const std::size_t &, const bool &>())
50  .def("getGateX", &SimulatorType::getGateX, py::return_value_policy::reference)
51  .def("getGateY", &SimulatorType::getGateY, py::return_value_policy::reference)
52  .def("getGateZ", &SimulatorType::getGateZ, py::return_value_policy::reference)
53  .def("getGateI", &SimulatorType::getGateI, py::return_value_policy::reference)
54  .def("getGateH", &SimulatorType::getGateH, py::return_value_policy::reference)
55  .def("applyGateX", &SimulatorType::applyGateX)
56  .def("applyGateY", &SimulatorType::applyGateY)
57  .def("applyGateZ", &SimulatorType::applyGateZ)
58  .def("applyGateH", &SimulatorType::applyGateH)
59  .def("applyGateI", &SimulatorType::applyGateH)
60  .def("applyGateSqrtX", &SimulatorType::applyGateSqrtX)
61  .def("applyGateRotX", &SimulatorType::applyGateRotX)
62  .def("applyGateRotY", &SimulatorType::applyGateRotY)
63  .def("applyGateRotZ", &SimulatorType::applyGateRotZ)
64  .def("applyGateCRotX", &SimulatorType::applyGateCRotX)
65  .def("applyGateCRotY", &SimulatorType::applyGateCRotY)
66  .def("applyGateCRotZ", &SimulatorType::applyGateCRotZ)
67  .def("applyGateU", &SimulatorType::applyGateU)
68  .def("applyGateCU", &SimulatorType::applyGateCU)
69  .def("applyGateSwap", &SimulatorType::applyGateSwap)
70  .def("applyGateSqrtSwap", &SimulatorType::applyGateSqrtSwap)
71  .def("applyGatePhaseShift", &SimulatorType::applyGatePhaseShift)
72  .def("applyGateCPhaseShift", &SimulatorType::applyGateCPhaseShift)
73  .def("applyGateCX", &SimulatorType::applyGateCX)
74  .def("applyGateCCX", &SimulatorType::applyGateCCX)
75  .def("applyGateCSwap", &SimulatorType::applyGateCSwap)
76  .def("getNumQubits", &SimulatorType::getNumQubits)
77  .def("applyQFT", &SimulatorType::applyQFT)
78  .def("applyIQFT", &SimulatorType::applyIQFT)
79  .def("applyDiffusion", &SimulatorType::applyDiffusion)
80  .def("encodeToRegister", &SimulatorType::encodeToRegister)
81  .def("encodeBinToSuperpos_unique", &SimulatorType::encodeBinToSuperpos_unique)
82  .def("applyHammingDistanceRotY", &SimulatorType::applyHammingDistanceRotY)
83  .def("applyMeasurement", &SimulatorType::applyMeasurement)
84  .def("applyMeasurementToRegister", &SimulatorType::applyMeasurementToRegister)
85  .def("collapseToBasisZ", &SimulatorType::collapseToBasisZ)
86  .def("initRegister", &SimulatorType::initRegister)
87  .def("printStates", &SimulatorType::PrintStates, py::call_guard<py::scoped_ostream_redirect,py::scoped_estream_redirect>())
88  .def("applyGateNCU", &SimulatorType::applyGateNCU_nonlinear)
89  .def("applyGateNCU", &SimulatorType::applyGateNCU_5CX_Opt)
90  .def("addUToCache", &SimulatorType::addUToCache_U)
91  .def("subReg", &SimulatorType::subReg)
92  .def("sumReg", &SimulatorType::sumReg)
93  .def("applyOracleU", &SimulatorType::applyOracle_U)
94  .def("applyOracleU", &SimulatorType::applyOracle_Opt)
95  .def("getGateCounts", &SimulatorType::getGateCounts)
96  .def("applyOraclePhase", &SimulatorType::applyOraclePhase)
97  .def("groupQubits", &SimulatorType::groupQubits)
98  .def("overlap", &SimulatorType::computeOverlap)
99  .def("applyHammingDistanceOverwrite", &SimulatorType::applyHammingDistanceOverwrite);
100 /*
101  .def("adjointMatrix", &SimulatorType::adjointMatrix)
102  .def("matrixSqrt", &SimulatorType::matrixSqrt)
103  .def("getQubitRegister", &SimulatorType::getQubitRegister)
104 */
105 
106  //TinyMatrix
107  py::class_<DCM>(m, "DCMatrix")
108  .def(py::init<>())
109  .def(py::init([](std::vector<std::complex<double>> &values) {
110  DCM m;
111  m(0,0) = values[0];
112  m(0,1) = values[1];
113  m(1,0) = values[2];
114  m(1,1) = values[3];
115  return m;
116  }))
117  .def("__repr__",
118  [](const DCM &s) {
119  return s.tostr();
120  }
121  )
122  .def("__getitem__",
123  [](const DCM &s, std::size_t i, std::size_t j) {
124  if (i >= 2 || j >= 2)
125  throw py::index_error();
126  return s(i,j);
127  })
128  .def("__mul__", [](const DCM &s0, const DCM &s1) {
129  DCM m;
130  m(0,0) = s0(0,0)*s1(0,0) + s0(0,1)*s1(1,0);
131  m(0,1) = s0(0,0)*s1(1,0) + s0(0,1)*s1(1,1);
132  m(1,0) = s0(1,0)*s1(0,0) + s0(1,1)*s1(1,0);
133  m(1,1) = s0(1,0)*s1(1,0) + s0(1,1)*s1(1,1);
134  return m;
135  })
136  .def("__rmul__", [](const DCM &s0, std::complex<double> d1) {
137  DCM m(s0);
138  m(0,0) *= d1;
139  m(0,1) *= d1;
140  m(1,0) *= d1;
141  m(1,1) *= d1;
142  return m;
143  })
144  .def("__mul__", [](const DCM &s0, std::complex<double> d1) {
145  DCM m(s0);
146  m(0,0) *= d1;
147  m(0,1) *= d1;
148  m(1,0) *= d1;
149  m(1,1) *= d1;
150  return m;
151  })
152  .def("__radd__", [](const DCM &s0, std::complex<double> d1) {
153  DCM m(s0);
154  m(0,0) += d1;
155  m(0,1) += d1;
156  m(1,0) += d1;
157  m(1,1) += d1;
158  return m;
159  })
160  .def("__add__", [](const DCM &s0, const DCM &s1) {
161  DCM m(s0);
162  m(0,0) += s1(0,0);
163  m(0,1) += s1(0,1);
164  m(1,0) += s1(1,0);
165  m(1,1) += s1(1,1);
166  return m;
167  })
168  .def("__sub__", [](const DCM &s0, const DCM &s1) {
169  DCM m(s0);
170  m(0,0) -= s1(0,0);
171  m(0,1) -= s1(0,1);
172  m(1,0) -= s1(1,0);
173  m(1,1) -= s1(1,1);
174  return m;
175  })
176  .def("adjoint", [](const DCM &s0) {
177  return SimulatorType::adjointMatrix(s0);;
178  })
179  .def("conjugate", [](const DCM &s0) {
180  DCM m(s0);
181  m(0,0) = std::conj(m(0,0));
182  m(0,1) = std::conj(m(0,1));
183  m(1,0) = std::conj(m(1,0));
184  m(1,1) = std::conj(m(1,1));
185  return m;
186  })
187  .def("transpose", [](const DCM &s0) {
188  DCM m(s0);
189  auto tmp = m(0,1);
190  m(0,1) = m(1,0);
191  m(1,0) = tmp;
192  return m;
193  })
194  .def("as_numpy",[](DCM &s0){
195  py::array_t<std::complex<double>> arr({ 2, 2 });
196  py::buffer_info arr_buff = arr.request();
197  std::complex<double>* ptr = (std::complex<double>*) arr_buff.ptr;
198 
199  ptr[0] = s0(0,0);
200  ptr[1] = s0(0,1);
201  ptr[2] = s0(1,0);
202  ptr[3] = s0(1,1);
203 
204  return arr;
205  });
206 }
207 
208 PYBIND11_MODULE(_PyQNLPSimulator, m){
209  intel_simulator_binding<IntelSimPy>(m);
210 }
void intel_simulator_binding(py::module &m)
qhipster::TinyMatrix< std::complex< double >, 2u, 2u, 32u > DCM
Class definition for IntelSimulator. The purpose of this class is to map the functionality of the und...
void addUToCache_U(const DCM &U, std::string label)
Mat2x2Type adjointMatrix(const Mat2x2Type &U)
Function to calculate the adjoint of an input matrix.
Definition: mat_ops.hpp:54
void applyGateNCU_nonlinear(const DCM &U, std::vector< std::size_t > &ctrl_indices, std::size_t target, std::string label)
void applyGateNCU_5CX_Opt(const DCM &U, std::vector< std::size_t > &ctrl_indices, std::vector< std::size_t > &aux_indices, std::size_t target, std::string label)
void applyOracle_Opt(std::size_t bit_pattern, const DCM &U, std::vector< std::size_t > &ctrl_indices, std::vector< std::size_t > &aux_indices, std::size_t target, std::string label)
IntelSimPy(std::unique_ptr< IntelSimulator, std::default_delete< IntelSimulator > > iSim)
IntelSimPy(int numQubits, bool useFusion=false)
void applyOracle_U(std::size_t bit_pattern, const DCM &U, std::vector< std::size_t > &ctrl_indices, std::size_t target, std::string label)
complex< double > computeOverlap(IntelSimPy &sim)
PYBIND11_MODULE(_PyQNLPSimulator, m)