Skip to content

Commit

Permalink
feat: implemented numba clifford operations
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoLiegiBastonLiegi committed Dec 11, 2023
1 parent c621acf commit ce82a33
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 0 deletions.
139 changes: 139 additions & 0 deletions src/qibojit/backends/clifford.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from numba import njit
from qibo.backends.clifford import CliffordOperations as CO


class CliffordOperations(CO):
def __init__(self, engine):
super().__init__(engine)

@staticmethod
def I(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.I)(
symplectic_matrix, q, nqubits
)

@staticmethod
def H(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.H)(
symplectic_matrix, q, nqubits
)

@staticmethod
def CNOT(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CNOT)(
symplectic_matrix, control_q, target_q, nqubits
)

@staticmethod
def CZ(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CZ)(
symplectic_matrix, control_q, target_q, nqubits
)

@staticmethod
def S(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.S)(
symplectic_matrix, q, nqubits
)

@staticmethod
def Z(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.Z)(
symplectic_matrix, q, nqubits
)

@staticmethod
def X(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.X)(
symplectic_matrix, q, nqubits
)

@staticmethod
def Y(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.Y)(
symplectic_matrix, q, nqubits
)

@staticmethod
def SX(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SX)(
symplectic_matrix, q, nqubits
)

@staticmethod
def SDG(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SDG)(
symplectic_matrix, q, nqubits
)

@staticmethod
def SXDG(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SXDG)(
symplectic_matrix, q, nqubits
)

@staticmethod
def RX(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RX)(
symplectic_matrix, q, nqubits, theta
)

@staticmethod
def RZ(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RZ)(
symplectic_matrix, q, nqubits, theta
)

@staticmethod
def RY(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RY)(
symplectic_matrix, q, nqubits, theta
)

@staticmethod
def SWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.SWAP)(
symplectic_matrix, control_q, target_q, nqubits
)

@staticmethod
def iSWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(
CO.iSWAP
)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def FSWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(
CO.FSWAP
)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def CY(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CY)(
symplectic_matrix, control_q, target_q, nqubits
)

@staticmethod
def CRX(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(
CO.CRX
)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def CRZ(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(
CO.CRZ
)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def CRY(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(
CO.CRY
)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def ECR(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.ECR)(
symplectic_matrix, control_q, target_q, nqubits
)
95 changes: 95 additions & 0 deletions src/qibojit/backends/clifford.py~
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from numba import njit
from qibo.backends.clifford import CliffordOperations as CO

class CliffordOperations(CO):

def __init__(self, engine):
super().__init__(engine)

@staticmethod
def I(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.I)(symplectic_matrix, q, nqubits)

@staticmethod
def H(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.H)(symplectic_matrix, q, nqubits)

@staticmethod
def CNOT(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CNOT)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def CZ(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CZ)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def S(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.S)(symplectic_matrix, q, nqubits)

@staticmethod
def Z(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.Z)(symplectic_matrix, q, nqubits)

@staticmethod
def X(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.X)(symplectic_matrix, q, nqubits)

@staticmethod
def Y(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.Y)(symplectic_matrix, q, nqubits)

@staticmethod
def SX(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SX)(symplectic_matrix, q, nqubits)

@staticmethod
def SDG(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SDG)(symplectic_matrix, q, nqubits)

@staticmethod
def SXDG(symplectic_matrix, q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8)", parallel=True, cache=True)(CO.SXDG)(symplectic_matrix, q, nqubits)

@staticmethod
def RX(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RX)(symplectic_matrix, q, nqubits, theta)

@staticmethod
def RZ(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RZ)(symplectic_matrix, q, nqubits, theta)

@staticmethod
def RY(symplectic_matrix, q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, f4)", parallel=True, cache=True)(CO.RY)(symplectic_matrix, q, nqubits, theta)

@staticmethod
def SWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.SWAP)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def iSWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.iSWAP)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def FSWAP(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.FSWAP)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def CY(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.CY)(symplectic_matrix, control_q, target_q, nqubits)

@staticmethod
def CRX(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(CO.CRX)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def CRZ(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(CO.CRZ)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def CRY(symplectic_matrix, control_q, target_q, nqubits, theta):
return njit("b1[:,:](b1[:,:], u8, u8, u8, f4)", parallel=True, cache=True)(CO.CRY)(symplectic_matrix, control_q, target_q, nqubits, theta)

@staticmethod
def ECR(symplectic_matrix, control_q, target_q, nqubits):
return njit("b1[:,:](b1[:,:], u8, u8, u8)", parallel=True, cache=True)(CO.ECR)(symplectic_matrix, control_q, target_q, nqubits)
5 changes: 5 additions & 0 deletions src/qibojit/backends/cpu.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
from numba import njit
from qibo.backends.numpy import NumpyBackend
from qibo.config import log
from qibo.gates.abstract import ParametrizedGate
Expand Down Expand Up @@ -69,6 +70,10 @@ def __init__(self):
else:
self.set_threads(len(psutil.Process().cpu_affinity()))

from qibojit.backends.clifford import CliffordOperations

self.clifford_operations = CliffordOperations(self.np)

def set_precision(self, precision):
if precision != self.precision:
super().set_precision(precision)
Expand Down

0 comments on commit ce82a33

Please sign in to comment.