-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Ensure unused classical registers are not omitted #238
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
from .phirgen import PHIR_HEADER, append_cmd, arg_to_bit, get_decls, tket_gate_to_phir | ||
|
||
if TYPE_CHECKING: | ||
from pytket.circuit import Circuit | ||
from pytket.unit_id import UnitID | ||
|
||
from .machine import Machine | ||
|
@@ -310,12 +311,15 @@ def adjust_phir_transport_time(ops: list["JsonDict"], machine: "Machine") -> Non | |
|
||
|
||
def genphir_parallel( | ||
inp: list[tuple["Ordering", "ShardLayer", "Cost"]], machine: "Machine" | ||
inp: list[tuple["Ordering", "ShardLayer", "Cost"]], | ||
circuit: "Circuit", | ||
machine: "Machine", | ||
) -> str: | ||
"""Convert a list of shards to the equivalent PHIR with parallel gating. | ||
|
||
Args: | ||
inp: list of shards | ||
circuit: corresponding tket Circuit | ||
machine: a QTM machine on which to simulate the circuit | ||
""" | ||
max_parallel_tq_gates = len(machine.tq_options) // 2 | ||
|
@@ -325,8 +329,6 @@ def genphir_parallel( | |
phir["metadata"]["strict_parallelism"] = True | ||
ops: list[JsonDict] = [] | ||
|
||
qbits = set() | ||
cbits = set() | ||
for _orders, shard_layer, layer_cost in inp: | ||
# within each shard layer, create groups of parallelizable shards | ||
# squash all the sub-commands into the first shard in the group | ||
|
@@ -335,8 +337,6 @@ def genphir_parallel( | |
) | ||
for group in shard_groups.values(): | ||
for shard in group: | ||
qbits |= shard.qubits_used | ||
cbits |= shard.bits_read | shard.bits_written | ||
if shard.sub_commands.values(): | ||
# sub-commands are always sq gates | ||
subcmd_groups = process_sub_commands( | ||
|
@@ -353,7 +353,7 @@ def genphir_parallel( | |
) | ||
adjust_phir_transport_time(ops, machine) | ||
|
||
decls = get_decls(qbits, cbits) | ||
decls = get_decls(circuit.q_registers, circuit.c_registers) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A possible "gotcha" here is that if a pytket circuit contains bits that do not form part of a full register -- for example, if it contains a bit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @cqc-alec. My guess without working with an example is that as long as pytket commands applying operations are referring to the right bits, we will generate correct PHIR commands for them. The only chance of error here, from what I can gather from your comment, is that the declaration command may mismatch the dimension of a register. Would you be able to provide an example to help make this change more robust? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, how about this: from pytket.circuit import Circuit, Qubit, Bit
from pytket.phir.api import pytket_to_phir
circ = Circuit()
circ.add_qubit(Qubit(1))
circ.add_bit(Bit(1))
circ.H(1)
circ.Measure(1, 1)
phir = pytket_to_phir(circ)
print(phir) Currently this produces the following: {
"format": "PHIR/JSON",
"version": "0.1.0",
"metadata": { "source": "pytket-phir v0.8.1" },
"ops": [
{
"data": "qvar_define",
"data_type": "qubits",
"variable": "q",
"size": 1
},
{ "data": "cvar_define", "data_type": "i64", "variable": "c", "size": 1 },
{ "//": "H q[1];" },
{ "qop": "H", "angles": null, "args": [["q", 1]] },
{ "//": "Measure q[1] --> c[1];" },
{ "qop": "Measure", "returns": [["c", 1]], "args": [["q", 1]] }
]
} This looks incorrect, since it seems to be indexing With the change in this PR, I suspect it will be differently wrong, since the qubit and bit registers would not be declared at all? I think it would be OK to reject circuits with incomplete registers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
One would think that these operations should not be allowed by What's the rationale behind supporting them in pytket? In general, I agree we should reject this circuit in either of the cases -- with or without this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fundamental entities in pytket are not registers but As for the original rationale -- I'm afraid I don't know! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I will update the PR to reject such programs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, equally happy for that to be a separate PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me make another PR then. #242 |
||
|
||
phir["ops"] = decls + ops | ||
PHIRModel.model_validate(phir) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(See other comment.)