Skip to content

Conversation

@swernli
Copy link
Collaborator

@swernli swernli commented Dec 4, 2025

This change adds a parameter to Q# and OpenQASM circuit generation called prune_classical_qubits that will generate a simplified circuit diagram where qubits that are unused or purely classical (never enter superposition) are removed. This can be handy for places where the program comes from generated logic that may use more qubits than strictly needed. This is purely for visualizing the simplified circuit and does not perform any kind of execution optimization.

So a program like this that has nine qubits but doesn't really use all of them:
image

will by default show the full circuit as it does today:
image

but with prune_classical_qubits = True will remove the purely classical q1, q2, q4, q5, and q8:
image

@DmitryVasilevsky
Copy link
Contributor

DmitryVasilevsky commented Dec 4, 2025

I'm a bit uneasy about this feature as it is. The trimmed circuit is not equivalent to the original and it may be confusing. For example, I can create this circuit:

operation Foo() : Result {
    use qs = Qubit[2];
    X(qs[0]);
    CNOT(qs[0], qs[1]);
    H(qs[1]);
    Ry(Std.Math.PI() / 2.0, qs[1]);
    X(qs[0]);
    MResetZ(qs[1])
}

In this circuit the first qubit is trimmable, but the second is not. We can compare original and resulting circuits.
Original:
image
Trimmed:
image
For the original circuit the result is always Zero. But for the trimmed circuit the result is always One.
I would rather see CNOT replaced with X in the resulting diagram, but that would not be easy. I think the feature still has merits as it is, but then I don't like the name of the parameter 'trim'. It feels like the diagrams should be equivalent. I think we need a scarier name for this parameter.
@minestarks already mentioned a different name would be better, but it was only from the 'trimming' point. I think the fact that the circuit becomes not equivalent should also be reflected in the name.

@swernli swernli changed the title Add optional trim setting for circuit generation Add optional prune_classical_qubits setting for circuit generation Dec 6, 2025
@swernli swernli force-pushed the swernli/circuit-trimming branch from 920cd6c to 260bf32 Compare December 6, 2025 03:01
@swernli
Copy link
Collaborator Author

swernli commented Dec 6, 2025

... I would rather see CNOT replaced with X in the resulting diagram, but that would not be easy. I think the feature still has merits as it is, but then I don't like the name of the parameter 'trim'. It feels like the diagrams should be equivalent.

@DmitryVasilevsky, I believe the new logic handles this appopriately. Using your same sample code, the output now looks the way you were hoping, keeping the circuit equivalent:
image

I'll need more tests to ensure this across different inputs though!

This change adds a parameter to Q# and OpenQASM circuit generation called `trim` that will generate a simplified circuit diagram where qubits that are unused or purely classical (never enter superposition) are removed. This can be handy for places where the program comes from generated logic that may use more qubits than strictly needed. This is purely for visualizing the simplified circuit and does not perform any kind of execution optimization.
@swernli swernli force-pushed the swernli/circuit-trimming branch from 260bf32 to 88b2c87 Compare December 8, 2025 21:28
@swernli
Copy link
Collaborator Author

swernli commented Dec 8, 2025

@DmitryVasilevsky @minestarks This is now ready for review with the updated behavior based on your feedback. No rush to get this in soon though.

Copy link
Member

@minestarks minestarks left a comment

Choose a reason for hiding this comment

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

Looks good, but lots of little suggestions

@msoeken
Copy link
Member

msoeken commented Dec 16, 2025

... I would rather see CNOT replaced with X in the resulting diagram, but that would not be easy. I think the feature still has merits as it is, but then I don't like the name of the parameter 'trim'. It feels like the diagrams should be equivalent.

@DmitryVasilevsky, I believe the new logic handles this appopriately. Using your same sample code, the output now looks the way you were hoping, keeping the circuit equivalent: image

I'll need more tests to ensure this across different inputs though!

This is better than the original approach after including @DmitryVasilevsky's feedback, but I still find this confusing. I do like the underlying motivation for the feature though. Could one alternative highlight qubits that are 100% "classical" (either in |0> or |1> state) with some color. Their value might affect different gates/operations in different ways, e.g., |0> on a CNOT's control removes the gate, |1> on a CNOT's control removes the control (other gates behave differently). Further, not meant to be part of this PR, but if we have logic to determine these values, we could also apply the optimization to the circuit and then visualize it (and have the same benefits for other tasks, to, e.g., speed up simulation, reduce resources, ...)

@swernli
Copy link
Collaborator Author

swernli commented Dec 17, 2025

This is better than the original approach after including @DmitryVasilevsky's feedback, but I still find this confusing. I do like the underlying motivation for the feature though. Could one alternative highlight qubits that are 100% "classical" (either in |0> or |1> state) with some color. Their value might affect different gates/operations in different ways, e.g., |0> on a CNOT's control removes the gate, |1> on a CNOT's control removes the control (other gates behave differently). Further, not meant to be part of this PR, but if we have logic to determine these values, we could also apply the optimization to the circuit and then visualize it (and have the same benefits for other tasks, to, e.g., speed up simulation, reduce resources, ...)

Thanks, @msoeken. @DmitryVasilevsky has similar suggestions about keeping the classical lines visible but distinct. That said, for now this is is intended to be an opt-in, Python only feature rather than anything that happens by default. I think the different ways of visualizing the full circuit, pruned circuit, and the difference between them could be something we investigate if/when we extend this into the UI. For now, this is meant to assist users who are visualizing circuits from chemistry Hamiltonians, which often end up getting programmatically generated with more qubits and gates than are strictly needed to capture the relationships between the states. So the approach was adapted from those chemistry tools and meant (for now) just for that scenario.

@swernli swernli enabled auto-merge December 18, 2025 01:38
@swernli swernli added this pull request to the merge queue Dec 18, 2025
Merged via the queue into main with commit fb71248 Dec 18, 2025
18 checks passed
@swernli swernli deleted the swernli/circuit-trimming branch December 18, 2025 02:29
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.

5 participants