-
Notifications
You must be signed in to change notification settings - Fork 155
Show source code locations on circuit diagrams #2761
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
Conversation
d8ca28c to
991ff11
Compare
…tarks/circuit-source-links
|
Found a bug where going to source from a circuit element causes unexpected/inconsistent behavior when the source of that element is found in a circuit file ( |
swernli
left a comment
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.
Gave some feedback on dyn vs impl in person, otherwise just this nitpick on naming.
…tarks/circuit-source-links
This PR adds a feature to circuit diagrams to display Q#/QASM source code locations for each qubit and gate as clickable links in VS Code. They can also be displayed as hover text in the Python circuit widget.
2025-10-31_14-28-26.mp4
Notes
Operation call sites
Operation boxes are clickable and show hover text with the location of the call site.
We always show the nearest user code location to the actual call site.
For example, if the user code shows
ForEach(MResetZ, qs), even though the actualMResetZgate is applied in the Std library, the location in the circuit diagram will point to theForEachexpression.In Python, "user code" includes both cell contents and any real files pulled via
qsharp.init(project_root=...)Qubit declaration sites
Qubit labels are clickable and show hover text with a location.
This location corresponds to the
usestatement that allocated the qubit. Example:There is an exception to this when the circuit diagram is generated for an operation which takes qubit input arguments.
In this case, the declaration locations are the input arguments to the operation. Example:
Here,
q0is declared at 1:16 andq1is declared at 1:27.Qubits can have multiple declaration sites. Example:
The circuit diagram for this code only shows one qubit wire, but it maps to both
q1andq2. So clicking on that qubit label will show both locations:Circuit JSON schema
Components now have a
sourcefield.Qubits have a
declarationsfield.These fields don't exist in the .qsc file schema. Even though we don't have a user scenario that writes circuits out to editable .qsc files yet, if we ever do, these fields should be excluded as they lose their meaning when the generated circuit is divorced from its originating source code.
VS Code
In VS code, clicking on an element with a source code location will navigate to the source code.
Python
Source code locations can be enabled in Python by passing in
source_locations=Trueintoqsharp.circuit().While the hover text shows the location, clicking on the gates does nothing.
Source code locations are not enabled by default in Python. This is because today, the locations for Q#/QASM code evaluated via
qsharp.evaldon't look very meaningful (line_1:4:2etc). If aqsharp.jsonis used, then the files will have proper disk locations, but this is a relatively uncommon scenario.ASCII art update to show source code location labels, e.g.
ASCII art update to show source code location labels, e.g.
These labels are disabled in the Python string rendering (the only place this ASCII art would be shown to the user) . It's useful in test snapshots (see
circuit_tests.rs), but at the moment they look too ugly for public consumption.Configuration and enablement
Since there is a perf cost to capturing call stacks during circuit tracing, we have to be conservative about when to enable circuit tracing.
At this point circuit tracing is only enabled when:
circuit()API in Pythontrace_circuit=TrueAdditionally source location capturing is configurable via a user setting. When it's disabled, the Q#/QASM evaluator skips call stack captures.
In VS Code, new
settings.jsonconfigurations have been added to tweak circuit generation options.While
maxOperationsandgenerationMethodare not new features, they weren't configurable by the user.In Python, these configuration options are exposed in the
circuit()function:Internals
Evaluator and circuit tracer changes
Introduced a
Tracertrait, now implemented by the circuit tracer (a.k.a. the circuit builder). This trait diverges fromBackendmainly in that it takes a call stack parameter (stack: &[Frame]), which allows the circuit tracer implementation to capture source code metadata in the circuit. TheTracingBackendcomposes a regularBackend, aTracer, or both, so backends that do not care about tracing remain unchanged.Every time the evaluator makes an intrinsic call, it captures the call stack and passes it to tracer (unless source location capturing is disabled).
Also removed
Resultassociated type fromBackendas it made passing this type around needlessly complicated. Implementors can simply returnval::Result, as theimpl Into<Result>was enforced everywhere anyway.The mechanics of the circuit tracer is largely unchanged, but it is refactored to make way for future changes.
WireMapBuilderandOperationBuilderare separated out for manageability; these will continue evolving as we implement further circuit diagram features.Entry expressions for operation circuits
Note that when we generate an circuit for an operation that takes qubits (as opposed to an Entrypoint, which has no input parameters), we have to do some additional processing to figure out qubit declaration locations.
Since in this scenario we use a generated entry expression, the real qubit declarations would live there. Example:
We can't use these as the qubit declaration locations since they don't map to user code, and don't provide any meaningful insight to the user.
VS Code command
A new generic
qsharp-vscode.gotoLocationscommand was added to jump to a specific location in source. The built-in VS Code commands didn't play nicely with our UX.Circuit rendering
If operations or gate labels contain source code locations, they are rendered as clickable SVG elements. The hover text should show the source code location as well.
Minor fixes in rendering and CSS (dashed lines were invisible, SWAP gates had an error in the bounding box calculation.)
Changed the signature of
drawto better organize the increasing number of options.