Skip to content

Commit

Permalink
drop .pulse_lists from aqt_compile (#929)
Browse files Browse the repository at this point in the history
these haven't been used (or maintained) in ages
  • Loading branch information
richrines1 authored Mar 22, 2024
1 parent c16879d commit d0e27e4
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 113 deletions.
27 changes: 5 additions & 22 deletions cirq-superstaq/cirq_superstaq/compiler_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ def __init__(
pulse_sequences: Any | None = None,
seq: qtrl.sequencer.Sequence | None = None,
jaqal_programs: list[str] | str | None = None,
pulse_lists: list[list[list[Any]]] | list[list[list[list[Any]]]] | None = None,
) -> None:
"""Initializes the `CompilerOutput` attributes.
Expand All @@ -115,32 +114,28 @@ def __init__(
seq: A `qtrl` pulse sequence, if `qtrl` is available locally.
jaqal_programs: The Jaqal program (resp. programs) as a string (resp. list of
strings).
pulse_lists: Optional list of pulse cycles if `qtrl` is available locally.
"""
if isinstance(circuits, cirq.Circuit):
self.circuit = circuits
self.initial_logical_to_physical = initial_logical_to_physicals
self.final_logical_to_physical = final_logical_to_physicals
self.pulse_list = pulse_lists
self.pulse_gate_circuit = pulse_gate_circuits
self.pulse_sequence = pulse_sequences
self.jaqal_program = jaqal_programs
else:
self.circuits = circuits
self.initial_logical_to_physicals = initial_logical_to_physicals
self.final_logical_to_physicals = final_logical_to_physicals
self.pulse_lists = pulse_lists
self.pulse_gate_circuits = pulse_gate_circuits
self.pulse_sequences = pulse_sequences
self.jaqal_programs = jaqal_programs

self.seq = seq

def has_multiple_circuits(self) -> bool:
"""Checks if an object has .circuits and .pulse_lists attributes.
"""Checks if this object has plural attributes (e.g. `.circuits`).
Otherwise, the object represents a single circuit, and has .circuit
and .pulse_list attributes.
Otherwise, the object represents a single circuit, and has singular attributes (`.circuit`).
Returns:
`True` if this object represents multiple circuits; `False` otherwise.
Expand All @@ -152,14 +147,12 @@ def __repr__(self) -> str:
return (
f"CompilerOutput({self.circuit!r}, {self.initial_logical_to_physical!r}, "
f"{self.final_logical_to_physical!r}, {self.pulse_gate_circuit!r}, "
f"{self.pulse_sequence!r}, {self.seq!r}, {self.jaqal_program!r}, "
f"{self.pulse_list!r})"
f"{self.pulse_sequence!r}, {self.seq!r}, {self.jaqal_program!r})"
)
return (
f"CompilerOutput({self.circuits!r}, {self.initial_logical_to_physicals!r}, "
f"{self.final_logical_to_physicals!r}, {self.pulse_gate_circuits!r}, "
f"{self.pulse_sequences!r}, {self.seq!r}, {self.jaqal_programs!r}, "
f"{self.pulse_lists!r})"
f"{self.pulse_sequences!r}, {self.seq!r}, {self.jaqal_programs!r})"
)


Expand Down Expand Up @@ -260,8 +253,7 @@ def read_json_aqt(
Returns:
A `CompilerOutput` object with the compiled circuit(s). If `qtrl` is available locally,
the returned object also stores the pulse sequence in the .seq attribute and the
list(s) of cycles in the .pulse_list(s) attribute.
the returned object also stores the pulse sequence in the .seq attribute.
"""

compiled_circuits: list[cirq.Circuit] | list[list[cirq.Circuit]]
Expand All @@ -282,7 +274,6 @@ def read_json_aqt(
) = final_logical_to_physicals_list

seq = None
pulse_lists = None

if "state_jp" not in json_dict:
warnings.warn(
Expand All @@ -303,7 +294,6 @@ def _sequencer_from_state(state: dict[str, Any]) -> qtrl.sequencer.Sequence:
seq.compile()
return seq

pulse_lists = gss.serialization.deserialize(json_dict["pulse_lists_jp"])
state = gss.serialization.deserialize(json_dict["state_jp"])

if "readout_jp" in json_dict:
Expand Down Expand Up @@ -333,27 +323,20 @@ def _sequencer_from_state(state: dict[str, Any]) -> qtrl.sequencer.Sequence:
final_logical_to_physicals_list[i : i + num_eca_circuits]
for i in range(0, len(final_logical_to_physicals_list), num_eca_circuits)
]
pulse_lists = pulse_lists and [
pulse_lists[i : i + num_eca_circuits]
for i in range(0, len(pulse_lists), num_eca_circuits)
]

if circuits_is_list:
return CompilerOutput(
compiled_circuits,
initial_logical_to_physicals,
final_logical_to_physicals,
seq=seq,
pulse_lists=pulse_lists,
)

pulse_lists = pulse_lists[0] if pulse_lists is not None else None
return CompilerOutput(
compiled_circuits[0],
initial_logical_to_physicals[0],
final_logical_to_physicals[0],
seq=seq,
pulse_lists=pulse_lists,
)


Expand Down
24 changes: 6 additions & 18 deletions cirq-superstaq/cirq_superstaq/compiler_output_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ def test_compiler_output_repr() -> None:
qubit_map: dict[cirq.Qid, cirq.Qid] = {}
assert (
repr(css.compiler_output.CompilerOutput(circuit, qubit_map, qubit_map))
== f"CompilerOutput({circuit!r}, {{}}, {{}}, None, None, None, None, None)"
== f"CompilerOutput({circuit!r}, {{}}, {{}}, None, None, None, None)"
)

circuits = [circuit, circuit]
assert (
repr(css.compiler_output.CompilerOutput(circuits, [qubit_map], [qubit_map]))
== f"CompilerOutput({circuits!r}, [{{}}], [{{}}], None, None, None, None, None)"
== f"CompilerOutput({circuits!r}, [{{}}], [{{}}], None, None, None, None)"
)


Expand Down Expand Up @@ -248,14 +248,12 @@ def test_read_json_aqt() -> None:
qubits = cirq.LineQubit.range(4)
circuit = cirq.Circuit(cirq.H.on_each(*qubits), cirq.measure(*qubits))
state_str = gss.serialization.serialize({})
pulse_lists_str = gss.serialization.serialize([[[]]])
initial_logical_to_physical = {cirq.q(0): cirq.q(1)}
final_logical_to_physical = {cirq.q(0): cirq.q(4)}

json_dict = {
"cirq_circuits": css.serialization.serialize_circuits(circuit),
"state_jp": state_str,
"pulse_lists_jp": pulse_lists_str,
"initial_logical_to_physicals": cirq.to_json([list(initial_logical_to_physical.items())]),
"final_logical_to_physicals": cirq.to_json([list(final_logical_to_physical.items())]),
}
Expand Down Expand Up @@ -287,11 +285,9 @@ def test_read_json_aqt() -> None:
assert out.seq is None

# multiple circuits
pulse_lists_str = gss.serialization.serialize([[[]], [[]]])
json_dict = {
"cirq_circuits": css.serialization.serialize_circuits([circuit, circuit]),
"state_jp": state_str,
"pulse_lists_jp": pulse_lists_str,
"initial_logical_to_physicals": cirq.to_json(
2 * [list(initial_logical_to_physical.items())]
),
Expand Down Expand Up @@ -328,11 +324,9 @@ def test_read_json_with_qtrl() -> None: # pragma: no cover, b/c test requires q

circuit = cirq.Circuit(cirq.H(cirq.LineQubit(4)))
state_str = gss.serialization.serialize(seq.__getstate__())
pulse_lists_str = gss.serialization.serialize([[[]]])
json_dict = {
"cirq_circuits": css.serialization.serialize_circuits(circuit),
"state_jp": state_str,
"pulse_lists_jp": pulse_lists_str,
"initial_logical_to_physicals": cirq.to_json([list(initial_logical_to_physical.items())]),
"final_logical_to_physicals": cirq.to_json([list(final_logical_to_physical.items())]),
}
Expand All @@ -341,37 +335,32 @@ def test_read_json_with_qtrl() -> None: # pragma: no cover, b/c test requires q
assert out.circuit == circuit
assert isinstance(out.seq, qtrl.sequencer.Sequence)
assert pickle.dumps(out.seq) == pickle.dumps(seq)
assert out.pulse_list == [[]]
assert not hasattr(out.seq, "_readout")
assert not hasattr(out, "circuits") and not hasattr(out, "pulse_lists")
assert not hasattr(out, "circuits")

# Serialized readout attribute for aqt_zurich_qpu:
json_dict["readout_jp"] = state_str
json_dict["readout_qubits"] = "[4, 5, 6, 7]"
out = css.compiler_output.read_json_aqt(json_dict, circuits_is_list=False)
assert out.circuit == circuit
assert out.pulse_list == [[]]
assert isinstance(out.seq, qtrl.sequencer.Sequence)
assert isinstance(out.seq._readout, qtrl.sequencer.Sequence)
assert isinstance(out.seq._readout._readout, qtrl.sequence_utils.readout._ReadoutInfo)
assert out.seq._readout._readout.sequence is out.seq._readout
assert out.seq._readout._readout.qubits == [4, 5, 6, 7]
assert out.seq._readout._readout.n_readouts == 1
assert pickle.dumps(out.seq._readout) == pickle.dumps(out.seq) == pickle.dumps(seq)
assert not hasattr(out, "circuits") and not hasattr(out, "pulse_lists")
assert not hasattr(out, "circuits")

# Multiple circuits:
out = css.compiler_output.read_json_aqt(json_dict, circuits_is_list=True)
assert out.circuits == [circuit]
assert pickle.dumps(out.seq) == pickle.dumps(seq)
assert out.pulse_lists == [[[]]]
assert not hasattr(out, "circuit") and not hasattr(out, "pulse_list")
assert not hasattr(out, "circuit")

pulse_lists_str = gss.serialization.serialize([[[]], [[]]])
json_dict = {
"cirq_circuits": css.serialization.serialize_circuits([circuit, circuit]),
"state_jp": state_str,
"pulse_lists_jp": pulse_lists_str,
"readout_jp": state_str,
"readout_qubits": "[4, 5, 6, 7]",
"initial_logical_to_physicals": cirq.to_json(
Expand All @@ -382,14 +371,13 @@ def test_read_json_with_qtrl() -> None: # pragma: no cover, b/c test requires q
out = css.compiler_output.read_json_aqt(json_dict, circuits_is_list=True)
assert out.circuits == [circuit, circuit]
assert pickle.dumps(out.seq) == pickle.dumps(seq)
assert out.pulse_lists == [[[]], [[]]]
assert isinstance(out.seq, qtrl.sequencer.Sequence)
assert isinstance(out.seq._readout, qtrl.sequencer.Sequence)
assert isinstance(out.seq._readout._readout, qtrl.sequence_utils.readout._ReadoutInfo)
assert out.seq._readout._readout.sequence is out.seq._readout
assert out.seq._readout._readout.qubits == [4, 5, 6, 7]
assert out.seq._readout._readout.n_readouts == 2
assert not hasattr(out, "circuit") and not hasattr(out, "pulse_list")
assert not hasattr(out, "circuit")


def test_read_json_qscout() -> None:
Expand Down
6 changes: 2 additions & 4 deletions cirq-superstaq/cirq_superstaq/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,7 @@ def aqt_compile_eca(
Returns:
Object whose .circuits attribute is a list (or list of lists) of logically equivalent
circuits. If `qtrl` is installed, the object's .seq attribute is a qtrl Sequence object
containing pulse sequences for each compiled circuit, and its .pulse_list(s) attribute
contains the corresponding list(s) of cycles.
containing pulse sequences for each compiled circuit.
Raises:
ValueError: If `target` is not a valid AQT target.
Expand Down Expand Up @@ -515,8 +514,7 @@ def aqt_compile(
Object whose .circuit(s) attribute contains the optimized circuits(s). Alternatively for
ECA, an object whose .circuits attribute is a list (or list of lists) of logically
equivalent circuits. If `qtrl` is installed, the object's .seq attribute is a qtrl
Sequence object containing pulse sequences for each compiled circuit, and its
.pulse_list(s) attribute contains the corresponding list(s) of cycles.
Sequence object containing pulse sequences for each compiled circuit.
Raises:
ValueError: If `target` is not a valid AQT target.
Expand Down
10 changes: 3 additions & 7 deletions cirq-superstaq/cirq_superstaq/service_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ def test_service_create_job() -> None:
return_value={
"cirq_circuits": css.serialization.serialize_circuits(cirq.Circuit()),
"state_jp": gss.serialization.serialize({}),
"pulse_lists_jp": gss.serialization.serialize([[[]]]),
"initial_logical_to_physicals": cirq.to_json([[]]),
"final_logical_to_physicals": cirq.to_json([[]]),
},
Expand All @@ -268,7 +267,7 @@ def test_service_aqt_compile_single(mock_post_request: mock.MagicMock) -> None:
assert output.circuit == cirq.Circuit()
assert output.initial_logical_to_physical == {}
assert output.final_logical_to_physical == {}
assert not hasattr(output, "circuits") and not hasattr(output, "pulse_lists")
assert not hasattr(output, "circuits")
assert not hasattr(output, "initial_logical_to_physicals")
assert not hasattr(output, "final_logical_to_physicals")

Expand Down Expand Up @@ -300,7 +299,7 @@ def test_service_aqt_compile_single(mock_post_request: mock.MagicMock) -> None:
},
)
assert out.circuit == cirq.Circuit()
assert not hasattr(out, "circuits") and not hasattr(out, "pulse_lists")
assert not hasattr(out, "circuits")

with pytest.raises(ValueError, match="'ss_example_qpu' is not a valid AQT target."):
service.aqt_compile(cirq.Circuit(), target="ss_example_qpu")
Expand All @@ -311,7 +310,6 @@ def test_service_aqt_compile_single(mock_post_request: mock.MagicMock) -> None:
return_value={
"cirq_circuits": css.serialization.serialize_circuits([cirq.Circuit(), cirq.Circuit()]),
"state_jp": gss.serialization.serialize({}),
"pulse_lists_jp": gss.serialization.serialize([[[]], [[]]]),
"initial_logical_to_physicals": cirq.to_json([[], []]),
"final_logical_to_physicals": cirq.to_json([[], []]),
},
Expand All @@ -323,7 +321,7 @@ def test_service_aqt_compile_multiple(mock_post_request: mock.MagicMock) -> None
assert out.circuits == [cirq.Circuit(), cirq.Circuit()]
assert out.initial_logical_to_physicals == [{}, {}]
assert out.final_logical_to_physicals == [{}, {}]
assert not hasattr(out, "circuit") and not hasattr(out, "pulse_list")
assert not hasattr(out, "circuit")
assert not hasattr(out, "initial_logical_to_physical")
assert not hasattr(out, "final_logical_to_physical")

Expand All @@ -333,7 +331,6 @@ def test_service_aqt_compile_multiple(mock_post_request: mock.MagicMock) -> None
return_value={
"cirq_circuits": css.serialization.serialize_circuits([cirq.Circuit()]),
"state_jp": gss.serialization.serialize({}),
"pulse_lists_jp": gss.serialization.serialize([[[]]]),
"initial_logical_to_physicals": cirq.to_json([[]]),
"final_logical_to_physicals": cirq.to_json([[]]),
},
Expand All @@ -346,7 +343,6 @@ def test_service_aqt_compile_eca(mock_post_request: mock.MagicMock) -> None:
assert out.initial_logical_to_physicals == [{}]
assert out.final_logical_to_physicals == [{}]
assert not hasattr(out, "circuit")
assert not hasattr(out, "pulse_list")
assert not hasattr(out, "initial_logical_to_physical")
assert not hasattr(out, "final_logical_to_physical")

Expand Down
Loading

0 comments on commit d0e27e4

Please sign in to comment.