qiskit-superstaq 0.4.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit-superstaq-0.4.7/PKG-INFO +50 -0
- qiskit-superstaq-0.4.7/README.md +38 -0
- qiskit-superstaq-0.4.7/dev-requirements.txt +1 -0
- qiskit-superstaq-0.4.7/example-requirements.txt +2 -0
- qiskit-superstaq-0.4.7/pyproject.toml +41 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/__init__.py +35 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/_version.py +1 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/_version_test.py +12 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/compiler_output.py +310 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/compiler_output_test.py +264 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/custom_gates.py +549 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/custom_gates_test.py +285 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/daily_integration_test.py +231 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/py.typed +1 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/serialization.py +188 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/serialization_test.py +177 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_backend.py +401 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_backend_test.py +301 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_job.py +198 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_job_test.py +234 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_provider.py +381 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/superstaq_provider_test.py +417 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/validation.py +27 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq/validation_test.py +25 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq.egg-info/PKG-INFO +50 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq.egg-info/SOURCES.txt +29 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq.egg-info/dependency_links.txt +1 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq.egg-info/requires.txt +13 -0
- qiskit-superstaq-0.4.7/qiskit_superstaq.egg-info/top_level.txt +1 -0
- qiskit-superstaq-0.4.7/requirements.txt +4 -0
- qiskit-superstaq-0.4.7/setup.cfg +4 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: qiskit-superstaq
|
|
3
|
+
Version: 0.4.7
|
|
4
|
+
Summary: The Qiskit module that provides tools and access to Superstaq.
|
|
5
|
+
Author-email: Superstaq development team <superstaq@infleqtion.com>
|
|
6
|
+
License: Apache 2
|
|
7
|
+
Project-URL: homepage, https://github.com/Infleqtion/client-superstaq
|
|
8
|
+
Requires-Python: >=3.8.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Provides-Extra: examples
|
|
12
|
+
|
|
13
|
+
# `qiskit-superstaq`
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
This package is used to access Superstaq via a Web API through [Qiskit](https://qiskit.org/). Qiskit programmers
|
|
18
|
+
can take advantage of the applications, pulse level optimizations, and write-once-target-all
|
|
19
|
+
features of Superstaq with this package.
|
|
20
|
+
|
|
21
|
+
`qiskit-superstaq` is [available on PyPI](https://pypi.org/project/qiskit-superstaq/) and can be installed with:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
pip install qiskit-superstaq
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Please note that Python version `3.8` or higher is required. See installation instructions [here](https://github.com/Infleqtion/client-superstaq#readme).
|
|
28
|
+
|
|
29
|
+
### Creating and submitting a circuit through qiskit-superstaq
|
|
30
|
+
```python
|
|
31
|
+
import qiskit
|
|
32
|
+
import qiskit_superstaq as qss
|
|
33
|
+
|
|
34
|
+
token = "Insert superstaq token that you received from https://superstaq.super.tech"
|
|
35
|
+
|
|
36
|
+
superstaq = qss.superstaq_provider.SuperstaqProvider(token)
|
|
37
|
+
|
|
38
|
+
backend = superstaq.get_backend("ibmq_qasm_simulator")
|
|
39
|
+
qc = qiskit.QuantumCircuit(2, 2)
|
|
40
|
+
qc.h(0)
|
|
41
|
+
qc.cx(0, 1)
|
|
42
|
+
qc.measure(0, 0)
|
|
43
|
+
qc.measure(1, 1)
|
|
44
|
+
|
|
45
|
+
print(qc)
|
|
46
|
+
|
|
47
|
+
# Submitting a circuit to "ibmq_qasm_simulator". Providing the "dry-run" method parameter instructs Superstaq to simulate the circuit, and is available to free trial users.
|
|
48
|
+
job = backend.run(qc, shots=100, method="dry-run")
|
|
49
|
+
print(job.result().get_counts())
|
|
50
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# `qiskit-superstaq`
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
This package is used to access Superstaq via a Web API through [Qiskit](https://qiskit.org/). Qiskit programmers
|
|
6
|
+
can take advantage of the applications, pulse level optimizations, and write-once-target-all
|
|
7
|
+
features of Superstaq with this package.
|
|
8
|
+
|
|
9
|
+
`qiskit-superstaq` is [available on PyPI](https://pypi.org/project/qiskit-superstaq/) and can be installed with:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
pip install qiskit-superstaq
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Please note that Python version `3.8` or higher is required. See installation instructions [here](https://github.com/Infleqtion/client-superstaq#readme).
|
|
16
|
+
|
|
17
|
+
### Creating and submitting a circuit through qiskit-superstaq
|
|
18
|
+
```python
|
|
19
|
+
import qiskit
|
|
20
|
+
import qiskit_superstaq as qss
|
|
21
|
+
|
|
22
|
+
token = "Insert superstaq token that you received from https://superstaq.super.tech"
|
|
23
|
+
|
|
24
|
+
superstaq = qss.superstaq_provider.SuperstaqProvider(token)
|
|
25
|
+
|
|
26
|
+
backend = superstaq.get_backend("ibmq_qasm_simulator")
|
|
27
|
+
qc = qiskit.QuantumCircuit(2, 2)
|
|
28
|
+
qc.h(0)
|
|
29
|
+
qc.cx(0, 1)
|
|
30
|
+
qc.measure(0, 0)
|
|
31
|
+
qc.measure(1, 1)
|
|
32
|
+
|
|
33
|
+
print(qc)
|
|
34
|
+
|
|
35
|
+
# Submitting a circuit to "ibmq_qasm_simulator". Providing the "dry-run" method parameter instructs Superstaq to simulate the circuit, and is available to free trial users.
|
|
36
|
+
job = backend.run(qc, shots=100, method="dry-run")
|
|
37
|
+
print(job.result().get_counts())
|
|
38
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
general-superstaq[dev]~=0.4.7
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "qiskit-superstaq"
|
|
3
|
+
description = "The Qiskit module that provides tools and access to Superstaq."
|
|
4
|
+
authors = [
|
|
5
|
+
{ name = "Superstaq development team", email = "superstaq@infleqtion.com" },
|
|
6
|
+
]
|
|
7
|
+
readme = { file = "README.md", content-type = "text/markdown" }
|
|
8
|
+
license = { text = "Apache 2" }
|
|
9
|
+
requires-python = ">=3.8.0"
|
|
10
|
+
dynamic = ["version", "dependencies", "optional-dependencies"]
|
|
11
|
+
|
|
12
|
+
[project.urls]
|
|
13
|
+
homepage = "https://github.com/Infleqtion/client-superstaq"
|
|
14
|
+
|
|
15
|
+
[build-system]
|
|
16
|
+
requires = ["setuptools"]
|
|
17
|
+
build-backend = "setuptools.build_meta"
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
include = ["qiskit_superstaq*"]
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.package-data]
|
|
23
|
+
qiskit_superstaq = ["py.typed"]
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.dynamic.version]
|
|
26
|
+
attr = "qiskit_superstaq._version.__version__"
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.dynamic.dependencies]
|
|
29
|
+
file = ["requirements.txt"]
|
|
30
|
+
|
|
31
|
+
[tool.setuptools.dynamic.optional-dependencies.dev]
|
|
32
|
+
file = ["dev-requirements.txt", "example-requirements.txt"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.dynamic.optional-dependencies.examples]
|
|
35
|
+
file = ["example-requirements.txt"]
|
|
36
|
+
|
|
37
|
+
[tool.isort]
|
|
38
|
+
profile = "black"
|
|
39
|
+
line_length = 100
|
|
40
|
+
color_output = true
|
|
41
|
+
known_first_party = "qiskit_superstaq"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from . import compiler_output, serialization, validation
|
|
2
|
+
from ._version import __version__
|
|
3
|
+
from .compiler_output import active_qubit_indices, measured_qubit_indices
|
|
4
|
+
from .custom_gates import (
|
|
5
|
+
AceCR,
|
|
6
|
+
AQTiCCXGate,
|
|
7
|
+
AQTiToffoliGate,
|
|
8
|
+
ParallelGates,
|
|
9
|
+
StrippedCZGate,
|
|
10
|
+
ZZSwapGate,
|
|
11
|
+
)
|
|
12
|
+
from .serialization import deserialize_circuits, serialize_circuits
|
|
13
|
+
from .superstaq_backend import SuperstaqBackend
|
|
14
|
+
from .superstaq_job import SuperstaqJob
|
|
15
|
+
from .superstaq_provider import SuperstaqProvider
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"active_qubit_indices",
|
|
19
|
+
"AceCR",
|
|
20
|
+
"AQTiCCXGate",
|
|
21
|
+
"AQTiToffoliGate",
|
|
22
|
+
"compiler_output",
|
|
23
|
+
"deserialize_circuits",
|
|
24
|
+
"measured_qubit_indices",
|
|
25
|
+
"ParallelGates",
|
|
26
|
+
"serialization",
|
|
27
|
+
"serialize_circuits",
|
|
28
|
+
"StrippedCZGate",
|
|
29
|
+
"SuperstaqBackend",
|
|
30
|
+
"SuperstaqJob",
|
|
31
|
+
"SuperstaqProvider",
|
|
32
|
+
"validation",
|
|
33
|
+
"ZZSwapGate",
|
|
34
|
+
"__version__",
|
|
35
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.7"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# pylint: disable=missing-function-docstring,missing-class-docstring
|
|
2
|
+
import packaging.version
|
|
3
|
+
|
|
4
|
+
import qiskit_superstaq as qss
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_version() -> None:
|
|
8
|
+
assert (
|
|
9
|
+
packaging.version.Version("0.1.0")
|
|
10
|
+
< packaging.version.parse(qss.__version__)
|
|
11
|
+
< packaging.version.Version("1.0.0")
|
|
12
|
+
)
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import json
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import Any, Dict, List, Optional, Set, Union
|
|
7
|
+
|
|
8
|
+
import general_superstaq as gss
|
|
9
|
+
import qiskit
|
|
10
|
+
|
|
11
|
+
import qiskit_superstaq as qss
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import qtrl.sequence_utils.readout
|
|
15
|
+
except ModuleNotFoundError:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def active_qubit_indices(circuit: qiskit.QuantumCircuit) -> List[int]:
|
|
20
|
+
"""Returns the indices of the non-idle qubits in the input quantum circuit.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
circuit: A `qiskit.QuantumCircuit` circuit.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
A list containing the indices of the non-idle qubits.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
qubit_indices: Set[int] = set()
|
|
30
|
+
|
|
31
|
+
for inst, qubits, _ in circuit:
|
|
32
|
+
if inst.name != "barrier":
|
|
33
|
+
indices = [circuit.find_bit(q).index for q in qubits]
|
|
34
|
+
qubit_indices.update(indices)
|
|
35
|
+
|
|
36
|
+
return sorted(qubit_indices)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def measured_qubit_indices(circuit: qiskit.QuantumCircuit) -> List[int]:
|
|
40
|
+
"""Returns the indices of the measured qubits in the input quantum circuit.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
circuit: A `qiskit.QuantumCircuit` circuit.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
A list containing the indices of the measured qubits.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
measured_qubits: Set[qiskit.circuit.Qubit] = set()
|
|
50
|
+
|
|
51
|
+
for inst, qubits, clbits in circuit:
|
|
52
|
+
if isinstance(inst, qiskit.circuit.Measure):
|
|
53
|
+
measured_qubits.update(qubits)
|
|
54
|
+
|
|
55
|
+
# Recurse into definition if it involves classical bits
|
|
56
|
+
elif clbits and inst.definition is not None:
|
|
57
|
+
measured_qubits.update(qubits[i] for i in measured_qubit_indices(inst.definition))
|
|
58
|
+
|
|
59
|
+
return sorted(circuit.find_bit(qubit).index for qubit in measured_qubits)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CompilerOutput:
|
|
63
|
+
"""A class that stores the results of compiled circuits."""
|
|
64
|
+
|
|
65
|
+
def __init__(
|
|
66
|
+
self,
|
|
67
|
+
circuits: Union[
|
|
68
|
+
qiskit.QuantumCircuit, List[qiskit.QuantumCircuit], List[List[qiskit.QuantumCircuit]]
|
|
69
|
+
],
|
|
70
|
+
final_logical_to_physicals: Union[
|
|
71
|
+
Dict[int, int], List[Dict[int, int]], List[List[Dict[int, int]]]
|
|
72
|
+
],
|
|
73
|
+
pulse_sequences: Union[qiskit.pulse.Schedule, List[qiskit.pulse.Schedule]] = None,
|
|
74
|
+
seq: Optional[qtrl.sequencer.Sequence] = None,
|
|
75
|
+
jaqal_programs: Optional[Union[str, List[str]]] = None,
|
|
76
|
+
pulse_lists: Optional[Union[List[List[List[Any]]], List[List[List[List[Any]]]]]] = None,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Constructs a `CompilerOutput` object.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
circuits: Compiled circuit or list of compiled circuits.
|
|
82
|
+
final_logical_to_physics: Dictionary or list of dictionaries specifying mapping from
|
|
83
|
+
logical to physical qubits.
|
|
84
|
+
pulse_sequences: `qiskit.pulse.Schedule` or list thereof specifying the pulse
|
|
85
|
+
compilation.
|
|
86
|
+
seq: `qtrl.sequencer.Sequence` pulse sequence if `qtrl` is available locally.
|
|
87
|
+
jaqal_programs: Optional string or list of strings specifying Jaqal programs (for
|
|
88
|
+
QSCOUT).
|
|
89
|
+
pulse_lists: Optional list of pulse cycles if `qtrl` is available locally.
|
|
90
|
+
"""
|
|
91
|
+
if isinstance(circuits, qiskit.QuantumCircuit):
|
|
92
|
+
self.circuit = circuits
|
|
93
|
+
self.final_logical_to_physical = final_logical_to_physicals
|
|
94
|
+
self.pulse_sequence = pulse_sequences
|
|
95
|
+
self.pulse_list = pulse_lists
|
|
96
|
+
self.jaqal_program = jaqal_programs
|
|
97
|
+
else:
|
|
98
|
+
self.circuits = circuits
|
|
99
|
+
self.final_logical_to_physicals = final_logical_to_physicals
|
|
100
|
+
self.pulse_sequences = pulse_sequences
|
|
101
|
+
self.pulse_lists = pulse_lists
|
|
102
|
+
self.jaqal_programs = jaqal_programs
|
|
103
|
+
|
|
104
|
+
self.seq = seq
|
|
105
|
+
|
|
106
|
+
def has_multiple_circuits(self) -> bool:
|
|
107
|
+
"""Checks if this object represents multiple circuits.
|
|
108
|
+
|
|
109
|
+
If so, this object has .circuits and .pulse_lists attributes. Otherwise, this object
|
|
110
|
+
represents a single circuit, and has .circuit and .pulse_list attributes.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
A boolean indicating whether this object represents multiple circuits.
|
|
114
|
+
"""
|
|
115
|
+
return hasattr(self, "circuits")
|
|
116
|
+
|
|
117
|
+
def __repr__(self) -> str:
|
|
118
|
+
if not self.has_multiple_circuits():
|
|
119
|
+
return (
|
|
120
|
+
f"CompilerOutput({self.circuit!r}, {self.final_logical_to_physical!r}, "
|
|
121
|
+
f"{self.pulse_sequence!r}, {self.seq!r}, {self.jaqal_program!r}, "
|
|
122
|
+
f"{self.pulse_list!r})"
|
|
123
|
+
)
|
|
124
|
+
return (
|
|
125
|
+
f"CompilerOutput({self.circuits!r}, {self.final_logical_to_physicals!r}, "
|
|
126
|
+
f"{self.pulse_sequences!r}, {self.seq!r}, {self.jaqal_programs!r}, "
|
|
127
|
+
f"{self.pulse_lists!r})"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def __eq__(self, other: Any) -> bool:
|
|
131
|
+
if not isinstance(other, CompilerOutput):
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
if self.has_multiple_circuits() != other.has_multiple_circuits():
|
|
135
|
+
return False
|
|
136
|
+
elif self.has_multiple_circuits():
|
|
137
|
+
return (
|
|
138
|
+
self.circuits == other.circuits
|
|
139
|
+
and self.final_logical_to_physicals == other.final_logical_to_physicals
|
|
140
|
+
and self.pulse_sequences == other.pulse_sequences
|
|
141
|
+
and self.jaqal_programs == other.jaqal_programs
|
|
142
|
+
and self.pulse_lists == other.pulse_lists
|
|
143
|
+
and self.seq == other.seq
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
self.circuit == other.circuit
|
|
148
|
+
and self.final_logical_to_physical == other.final_logical_to_physical
|
|
149
|
+
and self.pulse_sequence == other.pulse_sequence
|
|
150
|
+
and self.jaqal_program == other.jaqal_program
|
|
151
|
+
and self.pulse_list == other.pulse_list
|
|
152
|
+
and self.seq == other.seq
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def read_json_aqt(
|
|
157
|
+
json_dict: Dict[str, str], circuits_is_list: bool, num_eca_circuits: Optional[int] = None
|
|
158
|
+
) -> CompilerOutput:
|
|
159
|
+
"""Reads out the returned JSON from Superstaq API's AQT compilation endpoint.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
json_dict: A JSON dictionary matching the format returned by /aqt_compile endpoint.
|
|
163
|
+
circuits_is_list: Bool flag that controls whether the returned object has a .circuits
|
|
164
|
+
attribute (if True) or a .circuit attribute (False).
|
|
165
|
+
num_eca_circuits: Optional number of logically equivalent random circuits to generate for
|
|
166
|
+
each input circuit.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
A `CompilerOutput` object with the compiled circuit(s). If `qtrl` is available locally,
|
|
170
|
+
the returned object also stores the pulse sequence in the .seq attribute and the
|
|
171
|
+
list(s) of cycles in the .pulse_list(s) attribute.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
compiled_circuits: Union[List[qiskit.QuantumCircuit], List[List[qiskit.QuantumCircuit]]]
|
|
175
|
+
compiled_circuits = qss.serialization.deserialize_circuits(json_dict["qiskit_circuits"])
|
|
176
|
+
|
|
177
|
+
final_logical_to_physicals_list: List[Dict[int, int]] = list(
|
|
178
|
+
map(dict, json.loads(json_dict["final_logical_to_physicals"]))
|
|
179
|
+
)
|
|
180
|
+
final_logical_to_physicals: Union[
|
|
181
|
+
List[Dict[int, int]], List[List[Dict[int, int]]]
|
|
182
|
+
] = final_logical_to_physicals_list
|
|
183
|
+
|
|
184
|
+
seq = None
|
|
185
|
+
pulse_lists = None
|
|
186
|
+
|
|
187
|
+
if "state_jp" not in json_dict:
|
|
188
|
+
warnings.warn(
|
|
189
|
+
"This output only contains compiled circuits (using a default AQT gate set). To "
|
|
190
|
+
"get back the corresponding pulse sequence, you must first upload your `qtrl` configs "
|
|
191
|
+
"using `provider.aqt_upload_configs`."
|
|
192
|
+
)
|
|
193
|
+
elif not importlib.util.find_spec("qtrl"):
|
|
194
|
+
warnings.warn(
|
|
195
|
+
"This output only contains compiled circuits. The `qtrl` package must be installed in "
|
|
196
|
+
"order to deserialize compiled pulse sequences."
|
|
197
|
+
)
|
|
198
|
+
else: # pragma: no cover, b/c qtrl is not open source so it is not in cirq-superstaq reqs
|
|
199
|
+
|
|
200
|
+
def _sequencer_from_state(state: Dict[str, Any]) -> qtrl.sequencer.Sequence:
|
|
201
|
+
seq = qtrl.sequencer.Sequence(n_elements=1)
|
|
202
|
+
seq.__setstate__(state)
|
|
203
|
+
seq.compile()
|
|
204
|
+
return seq
|
|
205
|
+
|
|
206
|
+
pulse_lists = gss.serialization.deserialize(json_dict["pulse_lists_jp"])
|
|
207
|
+
state = gss.serialization.deserialize(json_dict["state_jp"])
|
|
208
|
+
|
|
209
|
+
if "readout_jp" in json_dict:
|
|
210
|
+
readout_state = gss.serialization.deserialize(json_dict["readout_jp"])
|
|
211
|
+
readout_seq = _sequencer_from_state(readout_state)
|
|
212
|
+
|
|
213
|
+
if "readout_qubits" in json_dict:
|
|
214
|
+
readout_qubits = json.loads(json_dict["readout_qubits"])
|
|
215
|
+
readout_seq._readout = qtrl.sequence_utils.readout._ReadoutInfo(
|
|
216
|
+
readout_seq, readout_qubits, n_readouts=len(compiled_circuits)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
state["_readout"] = readout_seq
|
|
220
|
+
|
|
221
|
+
seq = _sequencer_from_state(state)
|
|
222
|
+
|
|
223
|
+
if num_eca_circuits is not None:
|
|
224
|
+
compiled_circuits = [
|
|
225
|
+
compiled_circuits[i : i + num_eca_circuits]
|
|
226
|
+
for i in range(0, len(compiled_circuits), num_eca_circuits)
|
|
227
|
+
]
|
|
228
|
+
|
|
229
|
+
pulse_lists = pulse_lists and [
|
|
230
|
+
pulse_lists[i : i + num_eca_circuits]
|
|
231
|
+
for i in range(0, len(pulse_lists), num_eca_circuits)
|
|
232
|
+
]
|
|
233
|
+
final_logical_to_physicals = [
|
|
234
|
+
final_logical_to_physicals_list[i : i + num_eca_circuits]
|
|
235
|
+
for i in range(0, len(final_logical_to_physicals_list), num_eca_circuits)
|
|
236
|
+
]
|
|
237
|
+
|
|
238
|
+
if circuits_is_list:
|
|
239
|
+
return CompilerOutput(
|
|
240
|
+
compiled_circuits, final_logical_to_physicals, seq=seq, pulse_lists=pulse_lists
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
pulse_lists = pulse_lists[0] if pulse_lists is not None else None
|
|
244
|
+
return CompilerOutput(
|
|
245
|
+
compiled_circuits[0], final_logical_to_physicals[0], seq=seq, pulse_lists=pulse_lists
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def read_json_qscout(
|
|
250
|
+
json_dict: Dict[str, Union[str, List[str]]],
|
|
251
|
+
circuits_is_list: bool,
|
|
252
|
+
) -> CompilerOutput:
|
|
253
|
+
"""Reads out the returned JSON from Superstaq API's QSCOUT compilation endpoint.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
json_dict: A JSON dictionary matching the format returned by /qscout_compile endpoint.
|
|
257
|
+
circuits_is_list: Bool flag that controls whether the returned object has a .circuits
|
|
258
|
+
attribute (if True) or a .circuit attribute (False).
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
A `CompilerOutput` object with the compiled circuit(s) and a list of
|
|
262
|
+
jaqal programs in a string representation.
|
|
263
|
+
"""
|
|
264
|
+
qiskit_circuits = json_dict["qiskit_circuits"]
|
|
265
|
+
jaqal_programs = json_dict["jaqal_programs"]
|
|
266
|
+
|
|
267
|
+
final_logical_to_physicals_str = json_dict["final_logical_to_physicals"]
|
|
268
|
+
assert isinstance(final_logical_to_physicals_str, str)
|
|
269
|
+
final_logical_to_physicals: List[Dict[int, int]] = list(
|
|
270
|
+
map(dict, json.loads(final_logical_to_physicals_str))
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
assert isinstance(qiskit_circuits, str)
|
|
274
|
+
assert isinstance(jaqal_programs, list)
|
|
275
|
+
compiled_circuits = qss.serialization.deserialize_circuits(qiskit_circuits)
|
|
276
|
+
|
|
277
|
+
if circuits_is_list:
|
|
278
|
+
return CompilerOutput(
|
|
279
|
+
circuits=compiled_circuits,
|
|
280
|
+
final_logical_to_physicals=final_logical_to_physicals,
|
|
281
|
+
jaqal_programs=jaqal_programs,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
return CompilerOutput(
|
|
285
|
+
compiled_circuits[0],
|
|
286
|
+
final_logical_to_physicals[0],
|
|
287
|
+
jaqal_programs=jaqal_programs[0],
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def read_json_only_circuits(json_dict: Dict[str, str], circuits_is_list: bool) -> CompilerOutput:
|
|
292
|
+
"""Reads the JSON returned from Superstaq API's CQ compilation endpoint.
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
json_dict: A JSON dictionary matching the format returned by /cq_compile endpoint.
|
|
296
|
+
circuits_is_list: Bool flag that controls whether the returned object has a .circuits
|
|
297
|
+
attribute (if True) or a .circuit attribute (False).
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
A `CompilerOutput` object with the compiled circuit(s).
|
|
301
|
+
"""
|
|
302
|
+
compiled_circuits = qss.serialization.deserialize_circuits(json_dict["qiskit_circuits"])
|
|
303
|
+
|
|
304
|
+
final_logical_to_physicals: List[Dict[int, int]] = list(
|
|
305
|
+
map(dict, json.loads(json_dict["final_logical_to_physicals"]))
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
if circuits_is_list:
|
|
309
|
+
return CompilerOutput(compiled_circuits, final_logical_to_physicals)
|
|
310
|
+
return CompilerOutput(compiled_circuits[0], final_logical_to_physicals[0])
|