final first commit
This commit is contained in:
129
qibojit-benchmarks/benchmarks/libraries/projectq.py
Normal file
129
qibojit-benchmarks/benchmarks/libraries/projectq.py
Normal file
@@ -0,0 +1,129 @@
|
||||
import numpy as np
|
||||
from benchmarks.libraries import abstract
|
||||
|
||||
class ProjectQ(abstract.ParserBackend):
|
||||
|
||||
def __init__(self, max_qubits="0", local_optimizer="0"):
|
||||
"""Initialize data members.
|
||||
|
||||
Args:
|
||||
max_qubits (str): if "0", gate fusion is disabled, otherwise it's enabled.
|
||||
Note that it's not possible to set the maximum fused gate size.
|
||||
local_optimizer (str): if "0", local optimization of circuits is disabled,
|
||||
otherwise it's enabled.
|
||||
"""
|
||||
import projectq
|
||||
self.name = "projectq"
|
||||
self.projectq = projectq
|
||||
self.__version__ = None
|
||||
self.gate_fusion = int(max_qubits) > 0
|
||||
self.local_optimizer = bool(int(local_optimizer))
|
||||
|
||||
def RX(self, theta):
|
||||
return self.projectq.ops.Rx(theta)
|
||||
|
||||
def RY(self, theta):
|
||||
return self.projectq.ops.Ry(theta)
|
||||
|
||||
def RZ(self, theta):
|
||||
return self.projectq.ops.Rz(theta)
|
||||
|
||||
def U1(self, theta):
|
||||
return self.projectq.ops.R(theta)
|
||||
|
||||
def U2(self, phi, lam):
|
||||
pplus, pminus = np.exp(0.5j * (phi + lam)), np.exp(0.5j * (phi - lam))
|
||||
matrix = np.array([[np.conj(pplus), -np.conj(pminus)],
|
||||
[pminus, pplus]])
|
||||
matrix /= np.sqrt(2)
|
||||
return self.projectq.ops.MatrixGate(matrix)
|
||||
|
||||
def U3(self, theta, phi, lam):
|
||||
cost, sint = np.cos(theta / 2.0), np.sin(theta / 2.0)
|
||||
pplus, pminus = np.exp(0.5j * (phi + lam)), np.exp(0.5j * (phi - lam))
|
||||
matrix = np.array([[np.conj(pplus) * cost, -np.conj(pminus) * sint],
|
||||
[pminus * sint, pplus * cost]])
|
||||
return self.projectq.ops.MatrixGate(matrix)
|
||||
|
||||
|
||||
def SWAP(self):
|
||||
return self.projectq.ops.Swap
|
||||
|
||||
def CRX(self, theta):
|
||||
return self.projectq.ops.C(self.RX(theta))
|
||||
|
||||
def CRY(self, theta):
|
||||
return self.projectq.ops.C(self.RY(theta))
|
||||
|
||||
def CRZ(self, theta):
|
||||
return self.projectq.ops.CRz(theta)
|
||||
|
||||
def CU1(self, theta):
|
||||
U1 = self.projectq.ops.R(theta)
|
||||
return self.projectq.ops.C(U1, n_qubits=1)
|
||||
|
||||
def CU3(self, theta):
|
||||
raise NotImplementedError
|
||||
|
||||
def RZZ(self, theta):
|
||||
return self.projectq.ops.Rzz(theta)
|
||||
|
||||
def __getattr__(self, x):
|
||||
return getattr(self.projectq.ops, x)
|
||||
|
||||
def __item__(self, x):
|
||||
return getattr(self.projectq.ops, x)
|
||||
|
||||
def from_qasm(self, qasm):
|
||||
nqubits, gatelist = self.parse(qasm)
|
||||
backend = self.projectq.backends.Simulator(gate_fusion=self.gate_fusion)
|
||||
if self.local_optimizer:
|
||||
self.eng = self.projectq.MainEngine(
|
||||
backend=backend, engine_list=[self.projectq.cengines.LocalOptimizer()]
|
||||
)
|
||||
else:
|
||||
self.eng = self.projectq.MainEngine(backend=backend)
|
||||
qureg = self.eng.allocate_qureg(nqubits)
|
||||
for gatename, qubits, params in gatelist:
|
||||
gate = getattr(self, gatename)
|
||||
if params is not None:
|
||||
parameters = list(params)
|
||||
if len(qubits) > 1:
|
||||
gate(*parameters) | tuple(qureg[i] for i in qubits)
|
||||
else:
|
||||
gate(*parameters) | qureg[qubits[0]]
|
||||
elif len(qubits) > 1:
|
||||
if gatename == "SWAP":
|
||||
gate() | tuple(qureg[i] for i in qubits)
|
||||
else:
|
||||
gate | tuple(qureg[i] for i in qubits)
|
||||
else:
|
||||
gate | qureg[qubits[0]]
|
||||
|
||||
return qureg
|
||||
|
||||
def __call__(self, qureg):
|
||||
self.eng.flush()
|
||||
self.qubit_id, wave = self.eng.backend.cheat()
|
||||
# measure everything to avoid error when running
|
||||
self.projectq.ops.All(self.projectq.ops.Measure) | qureg
|
||||
return np.array(wave)
|
||||
|
||||
def transpose_state(self, x):
|
||||
shape = tuple(x.shape)
|
||||
nqubits = int(np.log2(shape[0]))
|
||||
x = np.reshape(x, nqubits * (2,))
|
||||
x = np.transpose(x, range(nqubits - 1, -1, -1))
|
||||
x = np.transpose(x, tuple(self.qubit_id[key] for key in self.qubit_id))
|
||||
x = np.reshape(x, shape)
|
||||
return x
|
||||
|
||||
def set_precision(self, precision):
|
||||
if precision != "double":
|
||||
raise NotImplementedError(f"Cannot set {precision} precision for {self.name} backend.")
|
||||
|
||||
def get_precision(self):
|
||||
return "double"
|
||||
|
||||
def get_device(self):
|
||||
return None
|
||||
Reference in New Issue
Block a user