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 get_results() when process_circuits() given circuits of different sizes #422

Merged
merged 4 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- Revert a change made in release v0.59.0 where users are warned about implicit qubit permutations in {py:func}`tk_to_qiskit`. This avoids spamming the user with unhelpful warnings when using pytket-qiskit backends. These backends handle implicit permutations automatically.
- Add new level 3 optimisation that uses `GreedyPauliSimp`
- Fix `get_results()` for Aer backends when circuits with different numbers of qubits or postprocessing circuits submitted together.

## 0.59.0 (November 2024)

Expand Down
8 changes: 7 additions & 1 deletion pytket/extensions/qiskit/backends/aer.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ class _AerBaseBackend(Backend):
_has_arch: bool = False
_needs_transpile: bool = False

# Map from (job ID, circuit index) to (number of qubits, postprocessing circuit),
# i.e. from the first two components of the ResultHandle to the last two.
_circuit_data: dict[tuple[str, int], tuple[int, str]] = {}

@property
def required_predicates(self) -> list[Predicate]:
return self._required_predicates
Expand Down Expand Up @@ -327,6 +331,7 @@ def process_circuits(
for i, ind in enumerate(indices):
handle = ResultHandle(jobid, i, tkc_qubits_count[i], ppcirc_strs[i])
handle_list[ind] = handle
self._circuit_data[(jobid, i)] = (tkc_qubits_count[i], ppcirc_strs[i])
self._cache[handle] = {"job": job}
return cast(list[ResultHandle], handle_list)

Expand All @@ -346,7 +351,7 @@ def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResul
try:
return super().get_result(handle)
except CircuitNotRunError:
jobid, _, qubit_n, ppc = handle
jobid = handle[0]
try:
job: AerJob = self._cache[handle]["job"]
except KeyError:
Expand All @@ -362,6 +367,7 @@ def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResul
include_density_matrix=self._supports_density_matrix,
)
for circ_index, backres in enumerate(backresults):
qubit_n, ppc = self._circuit_data[(jobid, circ_index)]
self._cache[ResultHandle(jobid, circ_index, qubit_n, ppc)][
"result"
] = backres
Expand Down
10 changes: 10 additions & 0 deletions tests/backend_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1541,3 +1541,13 @@ def test_optimisation_level_3_serialisation() -> None:
},
)
assert p_dict == passlist.to_dict()


def test_process_circuits_n_qubits() -> None:
# https://github.com/CQCL/pytket-qiskit/issues/420
circs = [Circuit(1).X(0).measure_all(), Circuit(2).X(0).measure_all()]
b = AerBackend()
hs = b.process_circuits(circs, n_shots=10)
rs = b.get_results(hs)
assert rs[0].get_counts() == Counter({(1,): 10})
assert rs[1].get_counts() == Counter({(1, 0): 10})
Loading