Skip to content
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

Merged

Conversation

qartik
Copy link
Member

@qartik qartik commented Oct 4, 2024

Description

Fixes #237

Also refactor get_decls to use the info from pytket Circuit.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog with any user-facing changes

@qartik qartik force-pushed the 237-unused-classical-registers-omitted-from-generated-phir branch from 18d1b46 to 84a1cbf Compare October 7, 2024 15:33
@qartik qartik changed the title fix: Esnure unused classical registers are not omitted fix: Ensure unused classical registers are not omitted Oct 7, 2024
Also refactor get_decls to use the info from pytket Circuit
@qartik qartik marked this pull request as ready for review October 7, 2024 17:15
Copy link
Collaborator

@peter-campora peter-campora left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The 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 c[1] but not c[0] -- then these bits are ignored by circuit.c_registers (similarly for qubits). I am not sure how phirgen handles this case currently (maybe an error, maybe add missing bits?) -- but if such a circuit were passed to this function it would presumably generate invalid PHIR.

Copy link
Member Author

Choose a reason for hiding this comment

The 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?

Copy link
Collaborator

@cqc-alec cqc-alec Oct 8, 2024

Choose a reason for hiding this comment

The 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 q[1] in a size-1 register. I am not sure what pecos will do with this, probably error?

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.

Copy link
Member Author

@qartik qartik Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

circ.add_qubit(Qubit(1))
circ.add_bit(Bit(1))

One would think that these operations should not be allowed by pytket as they seem inherently unsafe, and no backend may be able to simulate/run such a circuit.

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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fundamental entities in pytket are not registers but Qubits and Bits -- and each of these is identified by the combination of a string and an index. There's nothing inherently wrong with this but it is confusing because most other languages and representations have the register as their fundamental entity, and in pytket this is a secondary concept.

As for the original rationale -- I'm afraid I don't know!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will update the PR to reject such programs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, equally happy for that to be a separate PR.

Copy link
Member Author

@qartik qartik Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me make another PR then. #242

@@ -612,7 +605,7 @@ def genphir(
},
)

decls = get_decls(qbits, cbits)
decls = get_decls(circuit.q_registers, circuit.c_registers)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(See other comment.)

@qartik qartik merged commit 13246af into main Oct 8, 2024
6 checks passed
@qartik qartik deleted the 237-unused-classical-registers-omitted-from-generated-phir branch October 8, 2024 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unused classical registers omitted from generated PHIR
4 participants