This repository is archived.
See this page for details of the currently-supported extensions.
extensions for pytket quantum SDK
License: Apache License 2.0
This repository is archived.
See this page for details of the currently-supported extensions.
Currently the docs are built monolithically, by running make html
from the docs
directory, which builds and indexes docs for all extensions together. But when we release an update to one extension we need to be able to update the docs for that extension only.
This means giving each module its own docs build, and probably publishing them into subdirectories of https://cqcl.github.io/pytket/build/html/extensions/ instead of having a flat structure.
And update CI scripts.
https://github.com/github/renaming
I tried to use IBMQ.enable_account()
to set up credentials for IBMQBackend
rather than using IBMQ.save_account()
, as I have a workflow where we want to not save credentials to disk.
But it looks like IBMQBackend only looks for credentials in three places:
IBMQ.save_account()
saves themqiskitrc
file if there is onepytket-qiskit
, if there is oneand all of those look for the credentials on disk, and can't do anything with the qiskit AccountProvider
that .enable_account()
returns.
This could be fixed with an optional extra AccountProvider
parameter to IBMQBackend
and IBMQEmulatorBackend
. If this is passed, then rather than using stored credentials and the parameters passed in, you could instead use the credentials and the hub/project/group in the passed AccountProvider
.
Will make a PR for this.
I've run into an error in a workflow that uses a new BraketBackend
instance for each step of processing. In this case:
BraketBackend.get_result
calls self.circuit_status
to get the result and put it into the BraketBackend result cache.self.circuit_status
assumes that we already have our particular ResultHandle in the cache and thus directly does self._cache[handle].update
.This is okay if we used the same BraketBackend
to process the circuits and to retrieve the results, but if we don't then the cache is empty when it comes to getting the results, and we get a KeyError on self._cache[handle]
.
I think we could fix this by creating self._cache[handle]
if it doesn’t exist, as is done in the Honeywell backend.
Will open a PR for this.
Can be seen in comparison with AerStateBackend:
from pytket.extensions.cirq import CirqStateSimBackend
from pytket.extensions.qiskit import AerStateBackend
from pytket import Circuit
cirq_state = CirqStateSimBackend()
c = Circuit(2).X(1)
print(cirq_state.get_state(c))
aer_state = AerStateBackend()
print(aer_state.get_state(c))
array([0.+0.j, 1.+0.j)
array([0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j])
I'd like to use pytket-braket in an automated fashion, and so it would be good to have a way to pass credentials into BraketBackend
programmatically, rather than relying on the AWS CLI.
This might be doable if BraketBackend
took an optional argument of a boto3 Session, which can take credentials directly, or a braket AwsSession which can take a boto3.Session.
I'll work on a PR for this if that's okay.
Some words.
With qiskit 0.28 we get the following deprecation warnings when running the tests:
/home/alec/r/pytket-extensions/modules/pytket-qiskit/pytket/extensions/qiskit/tket_backend.py:101: DeprecationWarning: The BaseBackend abstract interface is deprecated as of the 0.18.0 release and will be removed in a future release. Instead you should build your backends using the BackendV1 abstract class (which is the current latest version of the backend interface)
super().__init__(configuration=config, provider=None)
and
/home/alec/r/pytket-extensions/modules/pytket-qiskit/pytket/extensions/qiskit/tket_job.py:39: DeprecationWarning: The BaseJob abstract interface is deprecated as of the 0.18.0 release and will be removed in a future release. Instead you should build your backends using the JobV1 abstract class (which is the current latest version of the backend interface)
super().__init__(backend, str(handles[0]))
Note that updating the qiskit version to 0.24.0 causes test_tketautopass
to fail. apparently because a qiskit.providers.ibmq.IBMQBackend
is no longer an instance of a qiskit.providers.BaseBackend
, meaning that we can't construct a TketAutoPass
from one. (IBMQ credentials required to run this test.)
e.g.
p = Program()
ro = p.declare('ro', 'BIT', 2)
p += CPHASE(0, 1, 0)
p += MEASURE(0, ro[0])
p += MEASURE(1, ro[1])
is not converted correctly due to integer phase in CPHASE
And include them in the generated documentation.
In order to work around #84 we use a forked and modified version of sphinx. We should try to go back to using the release version, either by submitting our patch or otherwise.
The docs build currently includes only cirq_to_tk
, tk_to_cirq
and process_characterisation
from pytket-cirq. It should include the backends as well.
If I have a circuit containing qiskit Parameter objects, I can convert back and forth between qiskit and pytket using qiskit_to_tk
and tk_to_qiskit
but I get an error when I try to compile the circuits. Is this a bug, or is this not something that is supported?
I have pytket v0.9.0 and pytket-qiskit v0.9.1 installed through pip.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from pytket.extensions.qiskit import qiskit_to_tk, tk_to_qiskit, IBMQBackend
circ = QuantumCircuit(2)
circ.rx(Parameter('a'),0,)
circ.ry(Parameter('b'),1)
circ.cx(0,1)
# circ.draw()
pytket_circ = qiskit_to_tk(circ)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
pytket_backend = IBMQBackend(
'ibmq_santiago',
hub='ibm-q',
group='open',
project='main',
)
pytket_backend.compile_circuit(pytket_circ, optimisation_level=2)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
gives an error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-bb05aab7fce3> in <module>
19 project='main',
20 )
---> 21 pytket_backend.compile_circuit(pytket_circ, optimisation_level=2)
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/pytket/backends/backend.py in compile_circuit(self, circuit, optimisation_level)
141 :type optimisation_level: int, optional
142 """
--> 143 self.default_compilation_pass(optimisation_level).apply(circuit)
144
145 @property
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/pytket/extensions/qiskit/backends/ibm.py in _tk1_to_x_sx_rz(a, b, c)
111 def _tk1_to_x_sx_rz(a: float, b: float, c: float) -> Circuit:
112 circ = Circuit(1)
--> 113 if _approx_0_mod_2(b):
114 circ.Rz(a + c, 0)
115 elif _approx_0_mod_2(b + 1):
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/pytket/extensions/qiskit/backends/ibm.py in _approx_0_mod_2(x, eps)
106 def _approx_0_mod_2(x: float, eps: float = 1e-10) -> bool:
107 x %= 2
--> 108 return min(x, 2 - x) < eps
109
110
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/sympy/core/relational.py in __bool__(self)
393
394 def __bool__(self):
--> 395 raise TypeError("cannot determine truth value of Relational")
396
397 def _eval_as_set(self):
TypeError: cannot determine truth value of Relational
But if I bind the parameters first everything works fine:
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from pytket.extensions.qiskit import qiskit_to_tk, tk_to_qiskit, IBMQBackend
circ = QuantumCircuit(2)
circ.rx(Parameter('a'),0,)
circ.ry(Parameter('b'),1)
circ.cx(0,1)
circ = circ.bind_parameters([1,1])
# circ.draw()
pytket_circ = qiskit_to_tk(circ)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
pytket_backend = IBMQBackend(
'ibmq_santiago',
hub='ibm-q',
group='open',
project='main',
)
pytket_backend.compile_circuit(pytket_circ, optimisation_level=2)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
print(final_circ)
global phase: π
node_0: ────────────────────────────────────────────────────────────────
┌────┐ ┌────────────┐ ┌────┐ ┌───────┐ ┌───┐
node_1: ───┤ √X ├──┤ RZ(10.425) ├────┤ √X ├────┤ RZ(π) ├───────────┤ X ├
┌──┴────┴─┐└───┬────┬───┘┌───┴────┴───┐└─┬────┬┘┌─────────┐└─┬─┘
node_2: ┤ RZ(π/2) ├────┤ √X ├────┤ RZ(10.425) ├──┤ √X ├─┤ RZ(π/2) ├──■──
└─────────┘ └────┘ └────────────┘ └────┘ └─────────┘
pytket-cirq has the requirement cirq ~= 0.10
, which accepts 0.11 (released yesterday). This breaks some of our code:
ModuleNotFoundError: No module named 'cirq.devices'
We should (a) make pytket-cirq compatible with cirq 0.11, and (b) change the requirement to cirq ~= 0.11.0
so that this doesn't happen next time.
See qiskit-community/qiskit-aqua#1448 (comment).
"At the next release Aqua will be deprecated. Core content, such as algorithms and opflow have been moved to Terra, and domain logic to separate repos, such as qiskit-optimization."
We should use these modules instead of aqua
in the tests, and also update the TketBackend
docstring which discusses wrapping it in an aqua.QuantumInstance
,
Simplest fix is to require websockets < 9.0
.
Although compilation succeeds, the circuit is still invalid for the backend.
from pytket import Circuit
from pytket.extensions.qiskit import IBMQBackend
c = Circuit(1,1)
c.add_c_setbits([True], [0])
c.measure_all()
b = IBMQBackend("ibmq_santiago", hub="ibm-q", group="open", project="main")
b.compile_circuit(c)
b.process_circuit(c, n_shots=1)
Error:
CircuitNotValidError: Circuit with index 0 in submitted does not satisfy GateSetPredicate:{ SX Measure noop CX U1 U2 U3 Reset X Barrier Rz } (try running backend.compile_circuit(circuit) first).
The test_device
test (which is not run on the CI because it requires IBMQ credentials) takes far too long. (There are thousands of jobs on the queue for ibmq_santiago
.) We should probably just delete it.
If I compile parameterised circuits using pytket the circuit returned contains parameter objects that have the same names, but do not pass ==
tests with the original parameter objects used to build the circuit. This means the original parameter objects cannot be used to bind values using a dictionary.
I have pytket 0.10.0 installed, and I have the up-to-date develop branch of pytket-qiskit (commit c50f7c2) installed.
This is an example of the problem:
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from pytket.extensions.qiskit import qiskit_to_tk, tk_to_qiskit, IBMQBackend
param_a = Parameter('a')
param_b = Parameter('b')
circ = QuantumCircuit(2)
circ.rx(param_a,0,)
circ.ry(param_b,1)
circ.cx(0,1)
# circ.draw()
print(circ.parameters)
print(param_a in circ.parameters)
print(param_b in circ.parameters)
pytket_circ = qiskit_to_tk(circ)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
pytket_backend = IBMQBackend(
'ibmq_santiago',
hub='ibm-q',
group='open',
project='main',
)
pytket_backend.compile_circuit(pytket_circ, optimisation_level=2)
final_circ = tk_to_qiskit(pytket_circ)
# final_circ.draw()
print(final_circ.parameters)
print(param_a in final_circ.parameters)
print(param_b in final_circ.parameters)
param_dict = dict(zip([param_a, param_b], [1, 2]))
final_circ.bind_parameters(param_dict)
This gives output:
ParameterView([Parameter(a), Parameter(b)])
True
True
ParameterView([Parameter(a), Parameter(b)])
False
False
---------------------------------------------------------------------------
CircuitError Traceback (most recent call last)
<ipython-input-5-57fb80c7dd47> in <module>
36
37 param_dict = dict(zip([param_a, param_b], [1, 2]))
---> 38 final_circ.bind_parameters(param_dict)
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/qiskit/utils/deprecation.py in wrapper(*args, **kwargs)
54 if kwargs:
55 _rename_kwargs(func.__name__, kwargs, kwarg_map)
---> 56 return func(*args, **kwargs)
57 return wrapper
58 return decorator
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/qiskit/circuit/quantumcircuit.py in bind_parameters(self, values, value_dict)
2084 raise TypeError(
2085 'Found ParameterExpression in values; use assign_parameters() instead.')
-> 2086 return self.assign_parameters(values)
2087 else:
2088 if any(isinstance(value, ParameterExpression) for value in values):
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/qiskit/utils/deprecation.py in wrapper(*args, **kwargs)
54 if kwargs:
55 _rename_kwargs(func.__name__, kwargs, kwarg_map)
---> 56 return func(*args, **kwargs)
57 return wrapper
58 return decorator
/opt/anaconda3/envs/qiskit0.25.2-qcoptim/lib/python3.8/site-packages/qiskit/circuit/quantumcircuit.py in assign_parameters(self, parameters, inplace, param_dict)
2048 if param_key not in unsorted_parameters]
2049 if len(params_not_in_circuit) > 0:
-> 2050 raise CircuitError('Cannot bind parameters ({}) not present in the circuit.'.format(
2051 ', '.join(map(str, params_not_in_circuit))))
2052
CircuitError: 'Cannot bind parameters (a, b) not present in the circuit.'
A full run of the pytket-qiskit tests generates quite a lot of deprecation warnings. Let's try and get rid of these.
PendingDeprecationWarning: Using a qobj for run() is deprecated and will be removed in a future release.
return func(*args, **kwargs)
PendingDeprecationWarning: The `QasmSimulator` backend will be deprecated in the future. It has been superseded by the `AerSimulator` backend.
warn('The `QasmSimulator` backend will be deprecated in the'
DeprecationWarning: Passing a Qobj to Backend.run is deprecated and will be removed in a future release. Please pass in circuits or pulse schedules instead.
job = self._backend.run(qobj)
PendingDeprecationWarning: The `snapshot_expectation_value` circuit method will be deprecated in the future. It has been superseded by the `save_expectation_value` and `save_expectation_value_variance` circuit methods.
warn('The `snapshot_expectation_value` circuit method will be deprecated '
PendingDeprecationWarning: The `SnapshotExpectationValue` instruction will be deprecated in the future. It has been superseded by the `SaveExpectationValue` and `SaveExpectationValueVariance` instructions.
warn('The `SnapshotExpectationValue` instruction will be deprecated in the'
DeprecationWarning: Back-references to from Bit instances to their containing Registers have been deprecated. Instead, inspect Registers to find their contained Bits.
qubits = [self.qregmap[qbit.register][qbit.index] for qbit in qargs]
DeprecationWarning: Back-references to from Bit instances to their containing Registers have been deprecated. Instead, inspect Registers to find their contained Bits.
bits = [self.cregmap[bit.register][bit.index] for bit in cargs]
PendingDeprecationWarning: The `UnitarySimulator` backend will be deprecated in the future. It has been superseded by the `AerSimulator` backend. To obtain legacy functionality initalize with `AerSimulator(method="unitary")` and append run circuits with the `save_state` instruction.
warn('The `UnitarySimulator` backend will be deprecated in the'
DeprecationWarning: Passing a Qobj to Backend.run is deprecated and will be removed in a future release. Please pass in circuits or pulse schedules instead.
return super().run(circuits, job_name=job_name, job_share_level=job_share_level,
DeprecationWarning: The QuantumCircuit.cu1 method is deprecated as of 0.16.0. It will be removed no earlier than 3 months after the release date. You should use the QuantumCircuit.cp method instead, which acts identically.
qc.cu1(pi / 5, qr[2], qr[3])
DeprecationWarning: The QuantumCircuit.cu3 method is deprecated as of 0.16.0. It will be removed no earlier than 3 months after the release date. You should use the QuantumCircuit.cu method instead, where cu3(ϴ,φ,λ) = cu(ϴ,φ,λ,0).
qc.cu3(pi / 4, pi / 5, pi / 6, qr[3], qr[0])
DeprecationWarning: The QuantumCircuit.u1 method is deprecated as of 0.16.0. It will be removed no earlier than 3 months after the release date. You should use the QuantumCircuit.p method instead, which acts identically.
qc.u1(pi / 2, qr[1])
DeprecationWarning: The QuantumCircuit.u2 method is deprecated as of 0.16.0. It will be removed no earlier than 3 months after the release date. You can use the general 1-qubit gate QuantumCircuit.u instead: u2(φ,λ) = u(π/2, φ, λ). Alternatively, you can decompose it interms of QuantumCircuit.p and QuantumCircuit.sx: u2(φ,λ) = p(π/2+φ) sx p(λ-π/2) (1 pulse on hardware).
qc.u2(pi / 2, pi / 3, qr[2])
DeprecationWarning: The QuantumCircuit.u3 method is deprecated as of 0.16.0. It will be removed no earlier than 3 months after the release date. You should use QuantumCircuit.u instead, which acts identically. Alternatively, you can decompose u3 in terms of QuantumCircuit.p and QuantumCircuit.sx: u3(ϴ,φ,λ) = p(φ+π) sx p(ϴ+π) sx p(λ) (2 pulses on hardware).
qc.u3(pi / 2, pi / 3, pi / 4, qr[3])
V and SX differ by phase, so SX should be picked instead of V
Expectation value either takes order of magnitude longer to run with version pytket-qiskit 0.10, or tries to consume too much memory.
ForestBackend uses self._cache
to store two items from .process_results()
, and relies on them being set for .get_results()
:
c_bits
, the classical bits used in the quantum circuit.qam
, a PyQuil Quantum Abstract Machine, which is an interface over the machine running the circuit.This means that ForestBackend won't currently work in a workflow that has different backend instances for process_results()
and `get_results().
c_bits
could potentially be added to the ResultHandle, but I don't think qam
could be - we are limited in the types we can pass in a ResultHandle.
We also can't re-derive qam
in get_results
because QAM objects are stateful, so creating one in a new backend instance would not have the results.
A better fix for ForestBackend may be to wait for a release that contains rigetti/pyquil#1331, which removes the statefulness from QAM objects and offers its own handles that we could put into the ResultHandle to query later.
Merging #83 seems to have caused the docs build to fail for pytket-cirq (both on CI and locally).
.../pytket-extensions/modules/pytket-cirq/docs$ sphinx-build -b html . build
Running Sphinx v4.0.1
[autosummary] generating autosummary for: api.rst, changelog.rst, index.rst
Extension error (sphinx.ext.autosummary):
Handler <function process_generate_options at 0x7fb5485c71f0> for event 'builder-inited' threw an exception (exception: list.remove(x): x not in list)
AerBackend appears to only pick one n_shots value in the new interface that allows different numbers of shots to be specified for each circuit using process_circuits
.
Failing example:
from pytket import Circuit
from pytket.extensions.qiskit import AerBackend
b = AerBackend()
circuit = Circuit(1)
assert [len(res.get_shots()) for res in b.get_results(b.process_circuits((circuit, circuit), n_shots=(1, 2)))] == [1, 2]
The replacement CX circuit is a controlled (-X) instead of a controlled X. The replacement tk1 circuit has its parameters in the reverse order.
This means that calling it works differently to all the other backends in this repository, which do have @property
for their .device
method.
Will submit a PR to address this.
With the release of openfermion 1.0.1 we should no longer need to install a special build for compatibility with cirq 0.11.
The pytket-cirq tests are rather sparse in their coverage. In particular, the following functionality is not tested:
package_result()
;_get_default_uids()
(called from run_circuit()
and run_circuit_moments()
) in the case where circuit.qubit_readout
is non-empty;cirq_to_tk()
with GridQubit
and NamedQubit
qubit types.This test requires IBMQ credentials so isn't run on the CI.
It fails with the following error:
____________________________________________________ test_ibmq_mid_measure _____________________________________________________
@pytest.mark.skipif(skip_remote_tests, reason="Skipping remote tests")
def test_ibmq_mid_measure() -> None:
c = Circuit(3, 3).H(1).CX(1, 2).Measure(0, 0).Measure(1, 1)
c.add_barrier([0, 1, 2])
c.CX(1, 0).H(0).Measure(2, 2)
# test open backend does not support mid-measure
# cannot test premium backends that do
b = IBMQEmulatorBackend("ibmq_athens")
with pytest.raises(RuntimeError) as warninfo:
b.compile_circuit(c)
> assert "Not a valid operation" in str(warninfo.value)
backend_test.py:829:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ExceptionInfo for raises contextmanager>
@property
def value(self) -> _E:
"""The exception value."""
> assert (
self._excinfo is not None
), ".value can only be used after the context manager exits"
E AssertionError: .value can only be used after the context manager exits
Also check if any other important ones are missing.
Currently tk_to_qiskit
raises an error if the circuit contains V gates.
When a PassManager
is constructed from a TketPass
, it can be used to run single circuits, but when a list of circuits is passed to the run()
method it falls over with a message about not being able to pickle the pass object.
from pytket.extensions.qiskit.tket_pass import TketPass
from pytket.passes import FullPeepholeOptimise
from qiskit import QuantumRegister, QuantumCircuit
from qiskit.transpiler import PassManager
qr = QuantumRegister(1)
qc = QuantumCircuit(qr)
qc.h(qr[0])
tkpass = FullPeepholeOptimise()
qispass = TketPass(tkpass)
pm = PassManager(qispass)
pm.run(qc) # OK
pm.run([qc, qc]) # TypeError: cannot pickle 'pytket._tket.passes.BasePass' object
This makes the PassManager
unusable in many qiskit algorithms.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.