Skip to content

Rework circuit measurement handling - #1532

Open
sorewachigauyo wants to merge 23 commits into
mainfrom
circuit-measurement-rework
Open

Rework circuit measurement handling#1532
sorewachigauyo wants to merge 23 commits into
mainfrom
circuit-measurement-rework

Conversation

@sorewachigauyo

@sorewachigauyo sorewachigauyo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

As described in #1530, we relax the condition that assigns only one qubit per measurement register and provide handling of multiple qubits per measurement register.

From the normal flow of circuit execution, we get a map of measurement registers/gates to pulse sequences. The qubits in these registers are logical indices, so we can map them back onto the physical qubit IDs thanks to the platform mapping being available. We then reuse the original result handling but assign the state counts to the physical qubit IDs instead of the logical IDs.

TODO

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.74%. Comparing base (2bc632a) to head (5e77837).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1532      +/-   ##
==========================================
- Coverage   91.83%   91.74%   -0.10%     
==========================================
  Files         147      147              
  Lines       11745    11724      -21     
==========================================
- Hits        10786    10756      -30     
- Misses        959      968       +9     
Flag Coverage Δ
unittests 91.74% <100.00%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/qibocal/auto/transpile.py 94.84% <100.00%> (+2.80%) ⬆️
...qibocal/protocols/randomized_benchmarking/utils.py 91.54% <100.00%> (-0.13%) ⬇️
...cal/protocols/readout/readout_mitigation_matrix.py 97.61% <100.00%> (-2.39%) ⬇️
...qibocal/protocols/tomographies/state_tomography.py 92.09% <100.00%> (-0.09%) ⬇️
...otocols/tomographies/two_qubit_state_tomography.py 99.28% <100.00%> (ø)
...l/protocols/two_qubit_interaction/chsh/circuits.py 100.00% <100.00%> (ø)
...l/protocols/two_qubit_interaction/chsh/protocol.py 98.41% <100.00%> (+0.83%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sorewachigauyo
sorewachigauyo marked this pull request as ready for review June 18, 2026 05:02
@sorewachigauyo
sorewachigauyo requested review from a team June 18, 2026 05:02
@RoyStegeman
RoyStegeman self-requested a review June 18, 2026 05:52

@RoyStegeman RoyStegeman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks again @sorewachigauyo, this is nice improvement. Since I don't have a platform available to check myself, did you run the protocols to make sure the results are still sensible?

Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
Comment thread src/qibocal/auto/transpile.py Outdated
@sorewachigauyo

Copy link
Copy Markdown
Contributor Author

Thanks again @sorewachigauyo, this is nice improvement. Since I don't have a platform available to check myself, did you run the protocols to make sure the results are still sensible?

Yes, I ran all the protocols on my QPU and attached the results in original comment #1532 (comment)

@sorewachigauyo
sorewachigauyo marked this pull request as draft June 23, 2026 09:21
@sorewachigauyo
sorewachigauyo marked this pull request as ready for review July 13, 2026 03:24
@RoyStegeman

RoyStegeman commented Jul 13, 2026

Copy link
Copy Markdown
Member

Thanks @sorewachigauyo I'll have a look. Did you notice the test failing? Nvm, seems it was a fluke

@sorewachigauyo

Copy link
Copy Markdown
Contributor Author

It seems to be on an unrelated test on windows py312, the other tests were passing by then.

I checked on my end before I pushed.

@RoyStegeman RoyStegeman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, I think it looks good up to a few issues with inconsistent use of types.

Comment thread tests/test_transpile.py
true_circuit.add(gates.Z(1))
true_circuit.add(gates.Z(2))
assert np.all(true_circuit.unitary() == transpiled_circuit.unitary())
qubit_map = [0, 1]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
qubit_map = [0, 1]
qubit_map: QubitMap = [0, 1]

if len(measure.qubits) == 1:
qid = platform_qubit_map[measure.qubits[0]]
else:
qid = tuple([platform_qubit_map[qubit_id] for qubit_id in measure.qubits])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
qid = tuple([platform_qubit_map[qubit_id] for qubit_id in measure.qubits])
len(measure.qubits) == 2
qid = (
platform_qubit_map[measure.qubits[0]],
platform_qubit_map[measure.qubits[1]],
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

assert?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah yes indeed

Comment on lines +564 to +565
result = indexed_result.result
qubit_pair: QubitPairId = indexed_result.target

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
result = indexed_result.result
qubit_pair: QubitPairId = indexed_result.target
result = indexed_result.result
assert isinstance(indexed_result.target, tuple)
qubit_pair: QubitPairId = indexed_result.target

"""An array where the elements are physical qubit IDs (str/int) and the indices are
logical qubit IDs
"""
ResultMap = dict[QubitId | QubitPairId, list[Counter[str]]]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
ResultMap = dict[QubitId | QubitPairId, list[Counter[str]]]
ResultMap = dict[QubitId | QubitPairId | tuple[QubitId,...], list[Counter[str]]]

Can't this also be tuple[QubitId,...] for the readout mitigation matrix protocol?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

results = execute_circuits(
circuits,
[list(pair)] * len(circuits),
[pair],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

execute_circuits now expects a list[QubitMap], so which is not what [pair] is. in principle this should be fine since you want to use the pair as a list of QubitMap, but you may want to explicitly cast it to a list list(pair).

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.

Circuit execution pipeline Replace repeated qubit_maps list with a single qubit_map in execute_circuits

3 participants