Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HybridQ #25

Merged
merged 32 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e157fda
Remove redudant line
stavros11 Nov 17, 2021
ec68658
Add HybridQ backend
stavros11 Nov 19, 2021
016c31a
Merge branch 'fusion' into hybridq
stavros11 Nov 19, 2021
0bc0c88
Add fusion option
stavros11 Nov 19, 2021
1c06b29
Merge fusion
stavros11 Nov 19, 2021
1ecb828
Fix merge
stavros11 Nov 19, 2021
157ea98
Fix hybridq fusion
stavros11 Nov 19, 2021
93f40a6
Merge branch 'fusion' into hybridq
stavros11 Nov 19, 2021
0eb14db
Fix final state shape
stavros11 Nov 21, 2021
793f07f
Merge branch 'fusion' into hybridq
stavros11 Nov 21, 2021
61a37d1
Implement more gates
stavros11 Nov 21, 2021
14e078c
Skip tests that are not supported
stavros11 Nov 21, 2021
6746b7f
Add hybridq in rules
stavros11 Nov 21, 2021
0972ac6
Change Python version to 3.8
stavros11 Nov 22, 2021
853a9f0
Merge fusion
stavros11 Nov 22, 2021
0e61ecf
Merge fusion
stavros11 Dec 19, 2021
7986df2
Add hybridq-gpu
stavros11 Dec 19, 2021
103d80b
Fix CU3 gate for hybridq
stavros11 Dec 19, 2021
1939fba
Merge fusion branch
stavros11 Dec 21, 2021
5c04ff2
Fix RZZ gate for hybridq
stavros11 Dec 21, 2021
ab2e978
Add simplify option
stavros11 Dec 21, 2021
ae710c0
Add threads setter (not working)
stavros11 Dec 21, 2021
4c17e49
Install hybridq before tensorflow
stavros11 Dec 21, 2021
a510cbc
Merge randomtests branch
stavros11 Dec 22, 2021
3077b0e
Disable tfq tests and add py3.9
stavros11 Dec 22, 2021
10485b2
Add py3.9
stavros11 Dec 22, 2021
d266906
Fix typo in CU3
stavros11 Dec 22, 2021
64b6344
Remove py3.8
stavros11 Dec 22, 2021
6442335
Add tfq
stavros11 Dec 22, 2021
ac29237
Remove skipped tests
stavros11 Dec 22, 2021
5d50786
Remove nthreads option
stavros11 Dec 28, 2021
60da3c2
Implement precision setter
stavros11 Jan 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install pytest
pip install qiskit openfermion qulacs
pip install qiskit openfermion qulacs hybridq
pip install tensorflow==2.5.1
pip install tensorflow_quantum
pip install projectq
Expand Down
7 changes: 7 additions & 0 deletions benchmarks/libraries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,11 @@ def get(backend_name, options=None):
from benchmarks.libraries.projectq import ProjectQ
return ProjectQ(**options)

elif backend_name == "hybridq":
from benchmarks.libraries.hybridq import HybridQ
return HybridQ(**options)
elif backend_name == "hybridq-gpu":
from benchmarks.libraries.hybridq import HybridQGPU
return HybridQGPU(**options)

raise KeyError(f"Unknown simulation library {backend_name}.")
124 changes: 124 additions & 0 deletions benchmarks/libraries/hybridq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import os
import numpy as np
from benchmarks.libraries import abstract


class HybridQ(abstract.ParserBackend):

def __init__(self, max_qubits="0", simplify="False"):
from hybridq.gate import Gate, MatrixGate
self.name = "hybridq"
self.__version__ = "0.7.7.post2"
self.Gate = Gate
self.MatrixGate = MatrixGate
self.max_qubits = int(max_qubits)
if simplify in ("true", "True"):
self.simplify = True
else:
self.simplify = False
self.max_qubits = int(max_qubits)

def H(self, q):
return self.Gate('H', qubits=(q,))

def X(self, q):
return self.Gate('X', qubits=(q,))

def Y(self, q):
return self.Gate('Y', qubits=(q,))

def Z(self, q):
return self.Gate('Z', qubits=(q,))

def RX(self, q, theta):
return self.Gate('RX', params=[theta], qubits=(q,))

def RY(self, q, theta):
return self.Gate('RY', params=[theta], qubits=(q,))

def RZ(self, q, theta):
return self.Gate('RZ', params=[theta], qubits=(q,))

def U1(self, q, theta):
phase = np.exp(1j * theta)
matrix = np.diag([1, phase])
return self.MatrixGate(U=matrix, qubits=(q,))

def U2(self, q, phi, lam):
plus = np.exp(0.5j * (phi + lam))
minus = np.exp(0.5j * (phi - lam))
matrix = np.array([[np.conj(plus), -np.conj(minus)], [minus, plus]]) / np.sqrt(2)
return self.MatrixGate(U=matrix, qubits=(q,))

def U3(self, q, theta, phi, lam):
return self.Gate('U3', params=[theta, phi, lam], qubits=(q,))

def CNOT(self, q1, q2):
return self.Gate('CNOT', qubits=(q1, q2))

def SWAP(self, q1, q2):
return self.Gate('SWAP', qubits=(q1, q2))

def CZ(self, q1, q2):
return self.Gate('CZ', qubits=(q1, q2))

def CU1(self, q1, q2, theta):
return self.Gate('CPHASE', params=[theta], qubits=(q1, q2))

def CU3(self, q1, q2, theta, phi, lam):
from hybridq.gate import Control
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]])
gate = self.MatrixGate(U=matrix, qubits=(q2,))
return Control((q1,), gate=gate)

def RZZ(self, q1, q2, theta):
phase = np.exp(0.5j * theta)
phasec = np.conj(phase)
matrix = np.diag([phasec, phase, phase, phasec])
return self.MatrixGate(U=matrix, qubits=(q1, q2))

def from_qasm(self, qasm):
from hybridq.circuit import Circuit
nqubits, gatelist = self.parse(qasm)
circuit = Circuit()
for gatename, qubits, params in gatelist:
args = list(qubits)
if params:
args.extend(params)
gate = getattr(self, gatename)(*args)
circuit.append(gate)
return circuit

def __call__(self, circuit):
from hybridq.circuit.simulation import simulate
initial_state = len(circuit.all_qubits()) * '0'
final_state = simulate(circuit, optimize="evolution",
initial_state=initial_state,
simplify=self.simplify,
compress=self.max_qubits)
return final_state.ravel()

def transpose_state(self, x):
return x

def get_precision(self):
return "single"

def get_device(self):
return None


class HybridQGPU(HybridQ):

def __call__(self, circuit):
from hybridq.circuit.simulation import simulate
initial_state = len(circuit.all_qubits()) * '0'
final_state = simulate(circuit, optimize="evolution-einsum",
backend="jax",
initial_state=initial_state,
simplify=self.simplify,
compress=self.max_qubits)
return final_state.ravel()
2 changes: 1 addition & 1 deletion benchmarks/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NQUBITS = "3,4,5"
MAX_QUBITS = "0,1,2,3,4"
QIBO_BACKENDS = "qibojit,tensorflow,numpy"
LIBRARIES = "qibo,qiskit,cirq,qsim,tfq,qulacs,projectq"
LIBRARIES = "qibo,qiskit,cirq,qsim,tfq,qulacs,projectq,hybridq"


def pytest_addoption(parser):
Expand Down
14 changes: 3 additions & 11 deletions benchmarks/tests/test_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,10 @@ def test_two_qubit_gate(nqubits, library, nlayers, gate, qibo_gate):


@pytest.mark.parametrize("gate,qibo_gate,params",
[("crx", "CRX", {"theta": 0.1}),
("crz", "CRZ", {"theta": 0.2}),
("cu1", "CU1", {"theta": 0.3}),
[("cu1", "CU1", {"theta": 0.3}),
#("cu2", "CU2", {"phi": 0.1, "lam": 0.3}), # not supported by OpenQASM
("cu3", "CU3", {"theta": 0.1, "phi": 0.2, "lam": 0.3})])
("cu3", "CU3", {"theta": 0.1, "phi": 0.2, "lam": 0.3})])
def test_two_qubit_gate_parametrized(nqubits, library, gate, qibo_gate, params):
skip_libraries = {"qiskit", "qiskit-default", "qiskit-twoqubitfusion",
"qiskit-gpu", "cirq", "tfq", "qsim", "qsim-gpu", "qsim-cuquantum",
"qulacs", "qulacs-gpu", "qcgpu"}
if gate in {"crx", "crz"} and library in skip_libraries:
pytest.skip("Skipping {} test because it is not supported by {}."
"".format(gate, library))
if gate in {"cu1", "cu2", "cu3"} and library == "tfq":
pytest.skip("Skipping {} test because it is not supported by {}."
"".format(gate, library))
Expand Down Expand Up @@ -136,7 +128,7 @@ def test_hidden_shift(nqubits, library, library_options):


def test_qaoa_circuit(library, library_options):
if library in {"qibo", "qibojit", "qcgpu"}:
if library in {"qibo", "qcgpu"}:
pytest.skip(f"{library} does not have built-in RZZ gate.")
import pathlib
folder = str(pathlib.Path(__file__).with_name("graphs") / "testgraph8.json")
Expand Down