Skip to content

Commit

Permalink
Merge pull request #85 from Blueqat/globalphase-adjust2
Browse files Browse the repository at this point in the history
Global phase adjustment and numba debug
  • Loading branch information
gyu-don authored Jan 20, 2020
2 parents 4c10473 + c5ad487 commit 08af386
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 76 deletions.
71 changes: 39 additions & 32 deletions blueqat/backends/_numba_backend_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .backendbase import Backend

DEFAULT_DTYPE = np.complex128
FASTMATH = True

# Typedef
# Index of Qubit
Expand Down Expand Up @@ -95,15 +96,15 @@ def _mult_shifted(masks, idx):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _zgate(qubits, n_qubits, target):
lower_mask = (1 << _QSMask(target)) - 1
for i in prange(1 << (_QSMask(n_qubits) - 1)):
qubits[_shifted(lower_mask, i)] *= -1


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _xgate(qubits, n_qubits, target):
lower_mask = (1 << _QSMask(target)) - 1
for i in prange(1 << (_QSMask(n_qubits) - 1)):
Expand All @@ -114,7 +115,7 @@ def _xgate(qubits, n_qubits, target):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _ygate(qubits, n_qubits, target):
lower_mask = (1 << _QSMask(target)) - 1
for i in prange(1 << (_QSMask(n_qubits) - 1)):
Expand All @@ -126,7 +127,7 @@ def _ygate(qubits, n_qubits, target):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _hgate(qubits, n_qubits, target):
sqrt2_inv = 0.7071067811865475
lower_mask = (1 << _QSMask(target)) - 1
Expand All @@ -139,7 +140,7 @@ def _hgate(qubits, n_qubits, target):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _diaggate(qubits, n_qubits, target, factor):
lower_mask = (1 << _QSMask(target)) - 1
for i in prange(1 << (_QSMask(n_qubits) - 1)):
Expand All @@ -149,7 +150,7 @@ def _diaggate(qubits, n_qubits, target, factor):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _rzgate(qubits, n_qubits, target, ang):
ang *= 0.5
eit = cmath.exp(1.j * ang)
Expand All @@ -164,7 +165,7 @@ def _rzgate(qubits, n_qubits, target, ang):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _rygate(qubits, n_qubits, target, ang):
ang *= 0.5
cos = math.cos(ang)
Expand All @@ -179,7 +180,7 @@ def _rygate(qubits, n_qubits, target, ang):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _rxgate(qubits, n_qubits, target, ang):
ang *= 0.5
cos = math.cos(ang)
Expand All @@ -194,7 +195,7 @@ def _rxgate(qubits, n_qubits, target, ang):


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _u3gate(qubits, n_qubits, target, theta, phi, lambd):
theta *= 0.5
cos = math.cos(theta)
Expand All @@ -214,34 +215,36 @@ def _u3gate(qubits, n_qubits, target, theta, phi, lambd):
qubits[i0 + (1 << target)] = c * t + d * u


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _czgate(qubits, n_qubits, controls_target):
target = controls_target[-1]
masks = _create_masks(controls_target)
all1 = _QSMask(0)
for b in controls_target:
all1 |= _QSMask(1) << b
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(n_loop):
i11 = _mult_shifted(masks, i) | all1
qubits[i11] *= -1


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _cxgate(qubits, n_qubits, controls_target):
c_mask = _QSMask(0)
for c in controls_target[:-1]:
c_mask |= _QSMask(1) << c
t_mask = 1 << controls_target[-1]
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
for i in prange(n_loop):
i10 = _mult_shifted(masks, i) | c_mask
i11 = i10 | t_mask
t = qubits[i10]
qubits[i10] = qubits[i11]
qubits[i11] = t


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _crxgate(qubits, n_qubits, controls_target, ang):
ang *= 0.5
cos = math.cos(ang)
Expand All @@ -250,17 +253,18 @@ def _crxgate(qubits, n_qubits, controls_target, ang):
for c in controls_target[:-1]:
c_mask |= _QSMask(1) << c
t_mask = 1 << controls_target[-1]
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
for i in prange(n_loop):
i10 = _mult_shifted(masks, i) | c_mask
i11 = i10 | t_mask
t = qubits[i10]
u = qubits[i10 + (1 << controls_target[-1])]
u = qubits[i11]
qubits[i10] = cos * t + nisin * u
qubits[i11] = nisin * t + cos * u


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _crygate(qubits, n_qubits, controls_target, ang):
ang *= 0.5
cos = math.cos(ang)
Expand All @@ -269,17 +273,18 @@ def _crygate(qubits, n_qubits, controls_target, ang):
for c in controls_target[:-1]:
c_mask |= _QSMask(1) << c
t_mask = 1 << controls_target[-1]
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
for i in prange(n_loop):
i10 = _mult_shifted(masks, i) | c_mask
i11 = i10 | t_mask
t = qubits[i10]
u = qubits[i10 + (1 << controls_target[-1])]
u = qubits[i11]
qubits[i10] = cos * t - sin * u
qubits[i11] = sin * t + cos * u


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _crzgate(qubits, n_qubits, controls_target, ang):
ang *= 0.5
eit = cmath.exp(1.j * ang)
Expand All @@ -288,29 +293,31 @@ def _crzgate(qubits, n_qubits, controls_target, ang):
for c in controls_target[:-1]:
c_mask |= _QSMask(1) << c
t_mask = 1 << controls_target[-1]
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
for i in prange(n_loop):
i10 = _mult_shifted(masks, i) | c_mask
i11 = i10 | t_mask
qubits[i10] *= eitstar
qubits[i11] *= eit


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _cphasegate(qubits, n_qubits, controls_target, ang):
eit = cmath.exp(1.j * ang)
c_mask = _QSMask(0)
for c in controls_target[:-1]:
c_mask |= _QSMask(1) << c
t_mask = 1 << controls_target[-1]
n_loop = 1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))
masks = _create_masks(controls_target)
for i in prange(1 << (_QSMask(n_qubits) - _QSMask(len(controls_target)))):
for i in prange(n_loop):
i11 = _mult_shifted(masks, i) | c_mask | t_mask
qubits[i11] *= eit


@njit(locals={'lower_mask': _QSMask},
nogil=True, parallel=True)
nogil=True, parallel=True, fastmath=FASTMATH)
def _p0calc(qubits, target, n_qubits):
p0 = 0.0
lower_mask = (1 << _QSMask(target)) - 1
Expand All @@ -320,7 +327,7 @@ def _p0calc(qubits, target, n_qubits):
return p0


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _reduce0(qubits, target, n_qubits, p0):
sqrtp_inv = 1.0 / math.sqrt(p0)
lower_mask = (1 << _QSMask(target)) - 1
Expand All @@ -330,7 +337,7 @@ def _reduce0(qubits, target, n_qubits, p0):
qubits[i0 + (1 << target)] = 0.0


@njit(nogil=True, parallel=True)
@njit(nogil=True, parallel=True, fastmath=FASTMATH)
def _reduce1(qubits, target, n_qubits, p0):
sqrtp_inv = 1.0 / math.sqrt(1.0 - p0)
lower_mask = (1 << _QSMask(target)) - 1
Expand Down Expand Up @@ -519,17 +526,17 @@ def gate_ry(self, gate, ctx):
def gate_rz(self, gate, ctx):
qubits = ctx.qubits
n_qubits = ctx.n_qubits
factor = cmath.exp(1.j * gate.theta)
theta = gate.theta
for target in gate.target_iter(n_qubits):
_diaggate(qubits, n_qubits, target, factor)
_rzgate(qubits, n_qubits, target, theta)
return ctx

def gate_phase(self, gate, ctx):
qubits = ctx.qubits
n_qubits = ctx.n_qubits
factor = cmath.exp(1.j * gate.theta)
for target in gate.target_iter(n_qubits):
_rzgate(qubits, n_qubits, target, factor)
_diaggate(qubits, n_qubits, target, factor)
return ctx

def gate_crx(self, gate, ctx):
Expand Down Expand Up @@ -579,9 +586,9 @@ def gate_ccx(self, gate, ctx):
def gate_u1(self, gate, ctx):
qubits = ctx.qubits
n_qubits = ctx.n_qubits
factor = cmath.exp(1.j * gate.lambd)
angle = gate.lambd
for target in gate.target_iter(n_qubits):
_diaggate(qubits, n_qubits, target, factor)
_rzgate(qubits, n_qubits, target, angle)
return ctx

def gate_u3(self, gate, ctx):
Expand Down
Loading

0 comments on commit 08af386

Please sign in to comment.