Skip to content

Commit

Permalink
Merge pull request #267 from king-p3nguin/bump-up-qiskit-version
Browse files Browse the repository at this point in the history
Make TQ Compatible with Qiskit ≥1.0.0
  • Loading branch information
Hanrui-Wang authored Jun 12, 2024
2 parents 3a04848 + 15605d0 commit ad384fa
Show file tree
Hide file tree
Showing 28 changed files with 896 additions and 856 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/functional_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name: Python package

on:
push:
push:
pull_request:

jobs:
Expand All @@ -17,16 +17,16 @@ jobs:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
python -m pip install flake8 pytest qiskit-aer qiskit_ibm_runtime
python -m pip install flake8 pytest
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Python 3.8
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Update pip and install lint utilities
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pull_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: pre-commit/[email protected]
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ opt_einsum
pathos>=0.2.7
pylatexenc>=2.10
pyscf>=2.0.1
qiskit>=0.39.0,<1.0.0
qiskit>=1.0.0
recommonmark
qiskit_ibm_runtime==0.20.0
qiskit-aer==0.13.3
qiskit-ibm-runtime>=0.20.0
qiskit-aer>=0.13.3

scipy>=1.5.2
setuptools>=52.0.0
Expand Down
4 changes: 3 additions & 1 deletion test/functional/test_controlled_unitary.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
SOFTWARE.
"""

import torchquantum as tq
from test.utils import check_all_close

import numpy as np

import torchquantum as tq


def test_controlled_unitary():
state = tq.QuantumDevice(n_wires=2)
Expand Down
3 changes: 2 additions & 1 deletion test/functional/test_func_mat_exp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@
SOFTWARE.
"""

import numpy as np
import torch

import torchquantum as tq
import numpy as np


def test_func_mat_exp():
Expand Down
6 changes: 4 additions & 2 deletions test/hadamard_grad/test_hadamard_grad.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import numpy as np
import pytest

from examples.hadamard_grad.circ import Circ1, Circ2, Circ3
from examples.hadamard_grad.hadamard_grad import hadamard_grad
import pytest


@pytest.mark.skip
def test_hadamard_grad():
Expand Down Expand Up @@ -38,4 +40,4 @@ def test_hadamard_grad():


if __name__ == "__main__":
test_hadamard_grad()
test_hadamard_grad()
15 changes: 8 additions & 7 deletions test/layers/test_nlocal.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import torchquantum as tq
from qiskit.circuit.library import (
TwoLocal,
EfficientSU2,
ExcitationPreserving,
PauliTwoDesign,
RealAmplitudes,
TwoLocal,
)

import torchquantum as tq


def compare_tq_to_qiskit(tq_circuit, qiskit_circuit, instance_info=""):
"""
Expand All @@ -16,8 +17,8 @@ def compare_tq_to_qiskit(tq_circuit, qiskit_circuit, instance_info=""):
qiskit_ops = []
for bit in qiskit_circuit.decompose():
wires = []
for qu in bit.qubits:
wires.append(qu.index)
for qb in bit.qubits:
wires.append(qiskit_circuit.find_bit(qb).index)
qiskit_ops.append(
{
"name": bit.operation.name,
Expand All @@ -29,9 +30,9 @@ def compare_tq_to_qiskit(tq_circuit, qiskit_circuit, instance_info=""):
tq_ops = [
{
"name": op["name"],
"wires": (op["wires"],)
if isinstance(op["wires"], int)
else tuple(op["wires"]),
"wires": (
(op["wires"],) if isinstance(op["wires"], int) else tuple(op["wires"])
),
}
for op in tq_circuit.op_history
]
Expand Down
26 changes: 13 additions & 13 deletions test/layers/test_rotgate.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import torchquantum as tq
import qiskit
from qiskit import Aer, execute

from torchquantum.util import (
switch_little_big_endian_matrix,
find_global_phase,
)

from qiskit.circuit.library import GR, GRX, GRY, GRZ
import numpy as np
from qiskit import transpile
from qiskit.circuit.library import GR, GRX, GRY, GRZ
from qiskit_aer import AerSimulator

import torchquantum as tq
from torchquantum.util import find_global_phase, switch_little_big_endian_matrix

all_pairs = [
{"qiskit": GR, "tq": tq.layer.GlobalR, "params": 2},
Expand All @@ -19,6 +15,7 @@

ITERATIONS = 2


def test_rotgates():
# test each pair
for pair in all_pairs:
Expand All @@ -28,15 +25,18 @@ def test_rotgates():
for _ in range(ITERATIONS):
# generate random parameters
params = [
np.random.uniform(-2 * np.pi, 2 * np.pi) for _ in range(pair["params"])
np.random.uniform(-2 * np.pi, 2 * np.pi)
for _ in range(pair["params"])
]

# create the qiskit circuit
qiskit_circuit = pair["qiskit"](num_wires, *params)

# get the unitary from qiskit
backend = Aer.get_backend("unitary_simulator")
result = execute(qiskit_circuit, backend).result()
backend = AerSimulator(method="unitary")
qiskit_circuit = transpile(qiskit_circuit, backend)
qiskit_circuit.save_unitary()
result = backend.run(qiskit_circuit).result()
unitary_qiskit = result.get_unitary(qiskit_circuit)

# create tq circuit
Expand Down
43 changes: 22 additions & 21 deletions test/measurement/test_eval_observable.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@
SOFTWARE.
"""

from qiskit import QuantumCircuit
import numpy as np
import random
from qiskit.opflow import StateFn, X, Y, Z, I

import torchquantum as tq
import numpy as np
from qiskit import QuantumCircuit
from qiskit.quantum_info import Pauli, Statevector

import torchquantum as tq
from torchquantum.measurement import expval_joint_analytical, expval_joint_sampling
from torchquantum.plugin import op_history2qiskit
from torchquantum.util import switch_little_big_endian_state

import torch

X = Pauli("X")
Y = Pauli("Y")
Z = Pauli("Z")
I = Pauli("I")
pauli_str_op_dict = {
"X": X,
"Y": Y,
Expand Down Expand Up @@ -67,20 +69,19 @@ def test_expval_observable():
for ob in obs[1:]:
# note here the order is reversed because qiskit is in little endian
operator = pauli_str_op_dict[ob] ^ operator
psi = StateFn(qiskit_circ)
psi_evaled = psi.eval()._primitive._data
psi = Statevector(qiskit_circ)
state_tq = switch_little_big_endian_state(
qdev.get_states_1d().detach().numpy()
)[0]
assert np.allclose(psi_evaled, state_tq, atol=1e-5)
assert np.allclose(psi.data, state_tq, atol=1e-5)

expval_qiskit = (~psi @ operator @ psi).eval().real
expval_qiskit = psi.expectation_value(operator).real
# print(expval_tq, expval_qiskit)
assert np.isclose(expval_tq, expval_qiskit, atol=1e-5)
if (
n_wires <= 3
): # if too many wires, the stochastic method is not accurate due to limited shots
assert np.isclose(expval_tq_sampling, expval_qiskit, atol=1e-2)
assert np.isclose(expval_tq_sampling, expval_qiskit, atol=0.015)

print("expval observable test passed")

Expand All @@ -92,34 +93,34 @@ def util0():
qc.x(0)

operator = Z ^ I
psi = StateFn(qc)
expectation_value = (~psi @ operator @ psi).eval()
psi = Statevector(qc)
expectation_value = psi.expectation_value(operator)
print(expectation_value.real)
# result: 1.0, means measurement result is 0, so Z is on qubit 1

operator = I ^ Z
psi = StateFn(qc)
expectation_value = (~psi @ operator @ psi).eval()
psi = Statevector(qc)
expectation_value = psi.expectation_value(operator)
print(expectation_value.real)
# result: -1.0 means measurement result is 1, so Z is on qubit 0

operator = I ^ I
psi = StateFn(qc)
expectation_value = (~psi @ operator @ psi).eval()
psi = Statevector(qc)
expectation_value = psi.expectation_value(operator)
print(expectation_value.real)

operator = Z ^ Z
psi = StateFn(qc)
expectation_value = (~psi @ operator @ psi).eval()
psi = Statevector(qc)
expectation_value = psi.expectation_value(operator)
print(expectation_value.real)

qc = QuantumCircuit(3)

qc.x(0)

operator = I ^ I ^ Z
psi = StateFn(qc)
expectation_value = (~psi @ operator @ psi).eval()
psi = Statevector(qc)
expectation_value = psi.expectation_value(operator)
print(expectation_value.real)


Expand Down
9 changes: 5 additions & 4 deletions test/measurement/test_expval_joint_sampling_grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
SOFTWARE.
"""

import random

import numpy as np

import torchquantum as tq
from torchquantum.measurement import (
expval_joint_analytical,
expval_joint_sampling_grouping,
)

import numpy as np
import random


def test_expval_joint_sampling_grouping():
n_obs = 20
Expand All @@ -54,7 +55,7 @@ def test_expval_joint_sampling_grouping():
)
for obs in obs_all:
# assert
assert np.isclose(expval_ana[obs], expval_sam[obs][0].item(), atol=1e-2)
assert np.isclose(expval_ana[obs], expval_sam[obs][0].item(), atol=0.015)
print(obs, expval_ana[obs], expval_sam[obs][0].item())


Expand Down
9 changes: 5 additions & 4 deletions test/measurement/test_measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
SOFTWARE.
"""

import torchquantum as tq
import numpy as np
from qiskit import transpile
from qiskit_aer import AerSimulator

import torchquantum as tq
from torchquantum.plugin import op_history2qiskit
from qiskit import Aer, transpile
import numpy as np


def test_measure():
Expand All @@ -42,7 +43,7 @@ def test_measure():

circ = op_history2qiskit(qdev.n_wires, qdev.op_history)
circ.measure_all()
simulator = Aer.get_backend("aer_simulator")
simulator = AerSimulator()
circ = transpile(circ, simulator)
qiskit_res = simulator.run(circ, shots=n_shots).result()
qiskit_counts = qiskit_res.get_counts()
Expand Down
3 changes: 1 addition & 2 deletions test/operator/test_ControlledU.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@
# test the controlled unitary function


import torchquantum as tq
import torchquantum.functional as tqf
from test.utils import check_all_close

# import pdb
# pdb.set_trace()
import numpy as np

import torchquantum as tq

flag = 4

Expand Down
6 changes: 3 additions & 3 deletions test/plugin/test_qiskit2tq_op_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
SOFTWARE.
"""

from torchquantum.plugin import qiskit2tq_op_history
import torchquantum as tq
from qiskit.circuit.random import random_circuit
from qiskit import QuantumCircuit

import torchquantum as tq
from torchquantum.plugin import qiskit2tq_op_history


def test_qiskit2tp_op_history():
circ = QuantumCircuit(3, 3)
Expand Down
Loading

0 comments on commit ad384fa

Please sign in to comment.