Skip to content

Commit

Permalink
Merge branch 'develop' into docs/improve_credentials_docs
Browse files Browse the repository at this point in the history
  • Loading branch information
cqc-melf authored Mar 5, 2024
2 parents 2a74c00 + ff1b092 commit de16113
Show file tree
Hide file tree
Showing 12 changed files with 63 additions and 50 deletions.
2 changes: 1 addition & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Unreleased
----------

* Update pytket version requirement to 1.25.
* Update qiskit version requirement to 0.46.
* Update qiskit version requirement to 1.0.
* Update qiskit-ibm-provider version requirement to 0.10.
* Update qiskit-ibm-runtime version requirement to 0.19.
* Add ``IBMQLocalEmulatorBackend`` for running local emulation of
Expand Down
2 changes: 1 addition & 1 deletion docs/intro.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pytket-qiskit
#############

IBM's `Qiskit <https://qiskit.org>`_ is an open-source framework for quantum
IBM's `Qiskit <https://www.ibm.com/quantum/qiskit>`_ is an open-source framework for quantum
computation, ranging from high-level algorithms to low-level circuit
representations, simulation and access to the `IBMQ <https://www.research.ibm.com/ibm-q/>`_ Experience devices.

Expand Down
8 changes: 4 additions & 4 deletions pytket/extensions/qiskit/backends/aer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

import numpy as np
from qiskit import transpile # type: ignore
from qiskit.providers.aer.noise import NoiseModel # type: ignore
from qiskit_aer.noise import NoiseModel # type: ignore
from qiskit.quantum_info.operators import Pauli as qk_Pauli # type: ignore
from qiskit.quantum_info.operators.symplectic.sparse_pauli_op import SparsePauliOp # type: ignore
from qiskit_aer import Aer # type: ignore
Expand Down Expand Up @@ -80,8 +80,8 @@
)

if TYPE_CHECKING:
from qiskit.providers.aer import AerJob # type: ignore
from qiskit.providers.aer.backends.aerbackend import AerBackend as QiskitAerBackend # type: ignore
from qiskit_aer import AerJob
from qiskit_aer.backends.aerbackend import AerBackend as QiskitAerBackend # type: ignore


def _default_q_index(q: Qubit) -> int:
Expand Down Expand Up @@ -455,7 +455,7 @@ class AerBackend(_AerBaseBackend):
:param noise_model: Noise model to apply during simulation. Defaults to None.
:type noise_model: Optional[NoiseModel], optional
:param simulation_method: Simulation method, see
https://qiskit.org/documentation/stubs/qiskit.providers.aer.AerSimulator.html
https://qiskit.github.io/qiskit-aer/stubs/qiskit_aer.AerSimulator.html
for available values. Defaults to "automatic".
:type simulation_method: str
:param crosstalk_params: Apply crosstalk noise simulation to the circuits before
Expand Down
2 changes: 1 addition & 1 deletion pytket/extensions/qiskit/backends/crosstalk_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from typing import List, Tuple, Union, Dict, Optional
from dataclasses import dataclass

from qiskit.providers.aer.noise import NoiseModel # type: ignore
from qiskit_aer.noise import NoiseModel # type: ignore
from qiskit_aer.noise.errors.standard_errors import amplitude_damping_error, phase_damping_error # type: ignore

import numpy as np
Expand Down
2 changes: 1 addition & 1 deletion pytket/extensions/qiskit/backends/ibmq_emulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
)
from warnings import warn

from qiskit.providers.aer.noise.noise_model import NoiseModel # type: ignore
from qiskit_aer.noise.noise_model import NoiseModel # type: ignore
from qiskit_ibm_runtime import ( # type: ignore
QiskitRuntimeService,
Session,
Expand Down
2 changes: 1 addition & 1 deletion pytket/extensions/qiskit/backends/ibmq_local_emulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
Union,
)

from qiskit.providers.aer.noise.noise_model import NoiseModel # type: ignore
from qiskit_aer.noise.noise_model import NoiseModel # type: ignore

from qiskit_ibm_provider import IBMProvider # type: ignore

Expand Down
19 changes: 13 additions & 6 deletions pytket/extensions/qiskit/qiskit_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@
Unitary2qBox,
Unitary3qBox,
UnitType,
CustomGateDef,
Bit,
Qubit,
QControlBox,
Expand Down Expand Up @@ -339,7 +338,10 @@ def add_xs(
if ((c >> i) & 1) == 0:
self.tkc.X(self.qbmap[qargs[i]])

def add_qiskit_data(self, data: "QuantumCircuitData") -> None:
def add_qiskit_data(
self, circuit: QuantumCircuit, data: Optional["QuantumCircuitData"] = None
) -> None:
data = data or circuit.data
for instr, qargs, cargs in data:
condition_kwargs = {}
if instr.condition is not None:
Expand All @@ -350,9 +352,14 @@ def add_qiskit_data(self, data: "QuantumCircuitData") -> None:
"condition_value": instr.condition[1],
}
elif type(instr.condition[0]) == Clbit:
cond_reg = self.cregmap[instr.condition[0].register]
# .find_bit() returns type:
# tuple[index, list[tuple[ClassicalRegister, index]]]
# We assume each bit belongs to exactly one register.
index = circuit.find_bit(instr.condition[0])[0]
register = circuit.find_bit(instr.condition[0])[1][0][0]
cond_reg = self.cregmap[register]
condition_kwargs = {
"condition_bits": [cond_reg[instr.condition[0].index]],
"condition_bits": [cond_reg[index]],
"condition_value": instr.condition[1],
}
else:
Expand Down Expand Up @@ -501,7 +508,7 @@ def add_qiskit_data(self, data: "QuantumCircuitData") -> None:
else []
)
builder = CircuitBuilder(qregs, cregs)
builder.add_qiskit_data(instr.definition)
builder.add_qiskit_data(circuit, instr.definition)
subc = builder.circuit()
subc.name = instr.name
self.tkc.add_circbox(CircBox(subc), qubits + bits, **condition_kwargs) # type: ignore
Expand Down Expand Up @@ -551,7 +558,7 @@ def qiskit_to_tk(qcirc: QuantumCircuit, preserve_param_uuid: bool = False) -> Ci
name=circ_name,
phase=param_to_tk(qcirc.global_phase),
)
builder.add_qiskit_data(qcirc.data)
builder.add_qiskit_data(qcirc)
return builder.circuit()


Expand Down
2 changes: 1 addition & 1 deletion pytket/extensions/qiskit/tket_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from qiskit.providers import BackendV1 # type: ignore
from qiskit.transpiler.basepasses import TransformationPass, BasePass as qBasePass # type: ignore
from qiskit.converters import circuit_to_dag, dag_to_circuit # type: ignore
from qiskit.providers.aer.aerprovider import AerProvider # type: ignore # type: ignore
from qiskit_aer.aerprovider import AerProvider # type: ignore # type: ignore
from qiskit_ibm_provider import IBMProvider # type: ignore


Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
include_package_data=True,
install_requires=[
"pytket ~= 1.25",
"qiskit ~= 0.46.0",
"qiskit ~= 1.0",
"qiskit-algorithms ~= 0.2.1",
"qiskit-ibm-runtime ~= 0.19.0",
"qiskit-aer ~= 0.13.0",
"qiskit-aer ~= 0.13.3",
"qiskit-ibm-provider ~= 0.10.0",
"numpy",
],
Expand Down
16 changes: 8 additions & 8 deletions tests/backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@

from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister # type: ignore
from qiskit.circuit import Parameter # type: ignore
from qiskit.providers.aer.noise.noise_model import NoiseModel # type: ignore
from qiskit.providers.aer.noise import ReadoutError # type: ignore
from qiskit.providers.aer.noise.errors import depolarizing_error, pauli_error # type: ignore
from qiskit_aer.noise.noise_model import NoiseModel # type: ignore
from qiskit_aer.noise import ReadoutError # type: ignore
from qiskit_aer.noise.errors import depolarizing_error, pauli_error # type: ignore

from qiskit_ibm_provider import IBMProvider # type: ignore
from qiskit_aer import Aer # type: ignore
Expand Down Expand Up @@ -1114,17 +1114,17 @@ def test_postprocess() -> None:

@pytest.mark.flaky(reruns=3, reruns_delay=10)
@pytest.mark.skipif(skip_remote_tests, reason=REASON)
def test_postprocess_emu(brisbane_emulator_backend: IBMQEmulatorBackend) -> None:
assert brisbane_emulator_backend.supports_contextual_optimisation
def test_postprocess_emu(ibmq_qasm_emulator_backend: IBMQEmulatorBackend) -> None:
assert ibmq_qasm_emulator_backend.supports_contextual_optimisation
c = Circuit(2, 2)
c.X(0).X(1).measure_all()
c = brisbane_emulator_backend.get_compiled_circuit(c)
h = brisbane_emulator_backend.process_circuit(c, n_shots=10, postprocess=True)
c = ibmq_qasm_emulator_backend.get_compiled_circuit(c)
h = ibmq_qasm_emulator_backend.process_circuit(c, n_shots=10, postprocess=True)
ppcirc = Circuit.from_dict(json.loads(cast(str, h[3])))
ppcmds = ppcirc.get_commands()
assert len(ppcmds) > 0
assert all(ppcmd.op.type == OpType.ClassicalTransform for ppcmd in ppcmds)
r = brisbane_emulator_backend.get_result(h)
r = ibmq_qasm_emulator_backend.get_result(h)
counts = r.get_counts()
assert sum(counts.values()) == 10

Expand Down
16 changes: 8 additions & 8 deletions tests/qiskit_backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import numpy as np
import pytest

from qiskit import QuantumCircuit, execute # type: ignore
from qiskit import QuantumCircuit # type: ignore
from qiskit.primitives import BackendSampler # type: ignore
from qiskit.providers import JobStatus # type: ignore
from qiskit_algorithms import Grover, AmplificationProblem, AlgorithmError # type: ignore
Expand Down Expand Up @@ -66,7 +66,7 @@ def test_samples() -> None:
b = AerBackend()
for comp in (None, b.default_compilation_pass()):
tb = TketBackend(b, comp)
job = execute(qc, tb, shots=100, memory=True)
job = tb.run(qc, shots=100, memory=True)
shots = job.result().get_memory()
assert all(((r[0] == "1" and r[1] == r[2]) for r in shots))
counts = job.result().get_counts()
Expand All @@ -78,12 +78,12 @@ def test_state() -> None:
b = AerStateBackend()
for comp in (None, b.default_compilation_pass()):
tb = TketBackend(b, comp)
job = execute(qc, tb)
job = tb.run(qc)
state = job.result().get_statevector()
qb = Aer.get_backend("aer_simulator_statevector")
qc1 = qc.copy()
qc1.save_state()
job2 = execute(qc1, qb)
job2 = qb.run(qc1)
state2 = job2.result().get_statevector()
assert np.allclose(state, state2)

Expand All @@ -93,12 +93,12 @@ def test_unitary() -> None:
b = AerUnitaryBackend()
for comp in (None, b.default_compilation_pass()):
tb = TketBackend(b, comp)
job = execute(qc, tb)
job = tb.run(qc)
u = job.result().get_unitary()
qb = Aer.get_backend("aer_simulator_unitary")
qc1 = qc.copy()
qc1.save_unitary()
job2 = execute(qc1, qb)
job2 = qb.run(qc1)
u2 = job2.result().get_unitary()
assert np.allclose(u, u2)

Expand All @@ -107,7 +107,7 @@ def test_cancel() -> None:
b = AerBackend()
tb = TketBackend(b)
qc = circuit_gen()
job = execute(qc, tb, shots=1024)
job = tb.run(qc, shots=1024)
job.cancel()
assert job.status() in [JobStatus.CANCELLED, JobStatus.DONE]

Expand Down Expand Up @@ -161,7 +161,7 @@ def test_architectures() -> None:
# without architecture
b = MockShotBackend(arch=arch)
tb = TketBackend(b, b.default_compilation_pass())
job = execute(qc, tb, shots=100, memory=True)
job = tb.run(qc, shots=100, memory=True)
shots = job.result().get_memory()
assert all(((r[0] == "1" and r[1] == r[2]) for r in shots))
counts = job.result().get_counts()
Expand Down
38 changes: 22 additions & 16 deletions tests/qiskit_convert_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
QuantumCircuit,
QuantumRegister,
ClassicalRegister,
execute,
transpile,
)
from qiskit.quantum_info import SparsePauliOp, Statevector, Operator # type: ignore
from qiskit.transpiler import PassManager # type: ignore
Expand All @@ -33,7 +33,7 @@
from qiskit_aer import Aer # type: ignore
from qiskit.transpiler.passes import BasisTranslator # type: ignore
from qiskit.circuit.equivalence_library import StandardEquivalenceLibrary # type: ignore
from qiskit.providers.fake_provider import FakeGuadalupe # type: ignore
from qiskit_ibm_runtime.fake_provider import FakeGuadalupe # type: ignore
from qiskit.circuit.parameterexpression import ParameterExpression # type: ignore

from pytket.circuit import (
Expand Down Expand Up @@ -188,10 +188,12 @@ def test_convert() -> None:
backend = Aer.get_backend("aer_simulator_statevector")

qc.save_state()
job = execute([qc], backend)
qc = transpile(qc, backend)
job = backend.run([qc])
state0 = job.result().get_statevector(qc)
qc1.save_state()
job1 = execute([qc1], backend)
qc1 = transpile(qc1, backend)
job1 = backend.run([qc1])
state1 = job1.result().get_statevector(qc1)
assert np.allclose(state0, state1, atol=1e-10)

Expand All @@ -214,7 +216,7 @@ def test_symbolic() -> None:
qc = tk_to_qiskit(tkc2)
assert qc.name == tkc.name
qc.save_state()
job = execute([qc], backend)
job = backend.run([qc])
state1 = job.result().get_statevector(qc)
state0 = np.array(
[
Expand All @@ -234,11 +236,13 @@ def test_symbolic() -> None:
def test_measures() -> None:
qc = get_test_circuit(True)
backend = Aer.get_backend("aer_simulator")
job = execute([qc], backend, seed_simulator=7)
qc = transpile(qc, backend)
job = backend.run([qc], seed_simulator=7)
counts0 = job.result().get_counts(qc)
tkc = qiskit_to_tk(qc)
qc = tk_to_qiskit(tkc)
job = execute([qc], backend, seed_simulator=7)
qc = transpile(qc, backend)
job = backend.run([qc], seed_simulator=7)
counts1 = job.result().get_counts(qc)
for result, count in counts1.items():
result_str = result.replace(" ", "")
Expand Down Expand Up @@ -276,7 +280,7 @@ def test_Unitary1qBox() -> None:
# Verify that unitary from simulator is correct
back = Aer.get_backend("aer_simulator_unitary")
qc.save_unitary()
job = execute(qc, back).result()
job = back.run(qc).result()
a = job.get_unitary(qc)
u1 = np.asarray(a)
assert np.allclose(u1, u)
Expand All @@ -292,7 +296,7 @@ def test_Unitary2qBox() -> None:
# Verify that unitary from simulator is correct
back = Aer.get_backend("aer_simulator_unitary")
qc.save_unitary()
job = execute(qc, back).result()
job = back.run(qc).result()
a = job.get_unitary(qc)
u1 = permute_rows_cols_in_unitary(np.asarray(a), (1, 0)) # correct for endianness
assert np.allclose(u1, u)
Expand All @@ -319,7 +323,7 @@ def test_Unitary3qBox() -> None:
# Verify that unitary from simulator is correct
back = Aer.get_backend("aer_simulator_unitary")
qc.save_unitary()
job = execute(qc, back).result()
job = back.run(qc).result()
a = job.get_unitary(qc)
u1 = permute_rows_cols_in_unitary(
np.asarray(a), (2, 1, 0)
Expand Down Expand Up @@ -351,13 +355,13 @@ def test_tketpass() -> None:
tkpass.apply(tkc)
qc1 = tk_to_qiskit(tkc)
qc1.save_unitary()
res = execute(qc1, back).result()
res = back.run(qc1).result()
u1 = res.get_unitary(qc1)
qispass = TketPass(tkpass)
pm = PassManager(qispass)
qc2 = pm.run(qc)
qc2.save_unitary()
res = execute(qc2, back).result()
res = back.run(qc2).result()
u2 = res.get_unitary(qc2)
assert np.allclose(u1, u2)

Expand Down Expand Up @@ -517,7 +521,8 @@ def test_customgate() -> None:
states = []
for qc in (qc1, qc2, correct_qc):
qc.save_state()
job = execute([qc], backend)
qc = transpile(qc, backend)
job = backend.run([qc])
states.append(job.result().get_statevector(qc))

assert compare_statevectors(states[0], states[1])
Expand All @@ -538,7 +543,7 @@ def test_convert_result() -> None:
simulator = Aer.get_backend("aer_simulator_statevector")
qc1 = qc.copy()
qc1.save_state()
qisk_result = execute(qc1, simulator, shots=10).result()
qisk_result = simulator.run(qc1, shots=10).result()

tk_res = next(qiskit_result_to_backendresult(qisk_result))

Expand All @@ -552,7 +557,7 @@ def test_convert_result() -> None:
qc.measure(qr2[1], cr2[0])

simulator = Aer.get_backend("aer_simulator")
qisk_result = execute(qc, simulator, shots=10).result()
qisk_result = simulator.run(qc, shots=10).result()

tk_res = next(qiskit_result_to_backendresult(qisk_result))
one_bits = [Bit("z", 0), Bit("b", 0)]
Expand Down Expand Up @@ -652,7 +657,8 @@ def assert_equivalence(
assert isinstance(circ, QuantumCircuit)
circ1 = circ.copy()
circ1.save_unitary()
job = execute(circ1, backend)
circ1 = transpile(circ1, backend)
job = backend.run(circ1)
unitaries.append(job.result().get_unitary(circ1))
for nn in range(1, len(circuits)):
# Default np.allclose is very lax here, so use strict tolerances
Expand Down

0 comments on commit de16113

Please sign in to comment.