-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Parallel XEB: Add option to specify pairs #6787
Merged
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
9b4765d
update test
eliottrosenberg 9a48e3c
add option to specify pairs for parallel two-qubit xeb
eliottrosenberg d526de4
remove unrelated changes
eliottrosenberg 4aff27f
fix test, nits
eliottrosenberg b82338c
Merge branch 'main' into u/eliottrosenberg/parallel_xeb_pairs
NoureldinYosri 5259715
Update cirq-core/cirq/experiments/two_qubit_xeb.py
NoureldinYosri 00917c0
Make `qubits_and_pairs` public
NoureldinYosri File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
add option to specify pairs for parallel two-qubit xeb
- Loading branch information
commit 9a48e3cd763c9633dce3cd1032390f7b58d3b658
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -351,20 +351,23 @@ def plot_histogram( | |||||
def parallel_xeb_workflow( | ||||||
sampler: 'cirq.Sampler', | ||||||
qubits: Optional[Sequence['cirq.GridQubit']] = None, | ||||||
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None, | ||||||
entangling_gate: 'cirq.Gate' = ops.CZ, | ||||||
n_repetitions: int = 10**4, | ||||||
n_combinations: int = 10, | ||||||
n_circuits: int = 20, | ||||||
cycle_depths: Sequence[int] = (5, 25, 50, 100, 200, 300), | ||||||
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None, | ||||||
ax: Optional[plt.Axes] = None, | ||||||
pool: Optional['multiprocessing.pool.Pool'] = None, | ||||||
**plot_kwargs, | ||||||
) -> Tuple[pd.DataFrame, Sequence['cirq.Circuit'], pd.DataFrame]: | ||||||
"""A utility method that runs the full XEB workflow. | ||||||
|
||||||
Args: | ||||||
sampler: The quantum engine or simulator to run the circuits. | ||||||
qubits: Qubits under test. If none, uses all qubits on the sampler's device. | ||||||
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits. | ||||||
entangling_gate: The entangling gate to use. | ||||||
n_repetitions: The number of repetitions to use. | ||||||
n_combinations: The number of combinations to generate. | ||||||
|
@@ -373,6 +376,7 @@ def parallel_xeb_workflow( | |||||
random_state: The random state to use. | ||||||
ax: the plt.Axes to plot the device layout on. If not given, | ||||||
no plot is created. | ||||||
pool: An optional multiprocessing pool. | ||||||
**plot_kwargs: Arguments to be passed to 'plt.Axes.plot'. | ||||||
|
||||||
Returns: | ||||||
|
@@ -389,13 +393,23 @@ def parallel_xeb_workflow( | |||||
rs = value.parse_random_state(random_state) | ||||||
|
||||||
if qubits is None: | ||||||
qubits = _grid_qubits_for_sampler(sampler) | ||||||
if qubits is None: | ||||||
raise ValueError("Couldn't determine qubits from sampler. Please specify them.") | ||||||
|
||||||
graph = nx.Graph( | ||||||
pair for pair in itertools.combinations(qubits, 2) if _manhattan_distance(*pair) == 1 | ||||||
) | ||||||
if pairs is None: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extract this logic into a method and use it here and in the other methods def qubits_and_pairs(
sampler: 'cirq.Sampler',
qubits: Optional[Sequence['cirq.GridQubit']] = None,
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
) -> Tuple[Sequence['cirq.GridQubit'], Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]]:
"""Extract qubits and pairs from sampler.
If qubits are not provided, then they are extracted from the pairs (if given) or the sampler.
If pairs are not provided then all pairs of adjacent qubits are used.
Args:
sampler: The quantum engine or simulator to run the circuits.
qubits: Optional list of qubits.
pairs: Optional list of pair to use.
Returns:
- Qubits to use.
- Pairs of qubits to use.
Raises:
ValueError: If qubits are not specified and can't be deduced from other arguments.
"""
if qubits is None:
if pairs is None:
qubits = _grid_qubits_for_sampler(sampler)
if qubits is None:
raise ValueError("Couldn't determine qubits from sampler. Please specify them.")
else:
qubits_set = set(itertools.chain(*pairs))
qubits = list(qubits_set)
if pairs is None:
pairs = [
pair for pair in itertools.combinations(qubits, 2) if _manhattan_distance(*pair) == 1
]
return qubits, pairs |
||||||
qubits = _grid_qubits_for_sampler(sampler) | ||||||
if qubits is None: | ||||||
raise ValueError("Couldn't determine qubits from sampler. Please specify them.") | ||||||
else: | ||||||
qubits_set = set() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
for pair in pairs: | ||||||
qubits_set.add(pair[0]) | ||||||
qubits_set.add(pair[1]) | ||||||
qubits = list(qubits_set) | ||||||
|
||||||
if pairs is None: | ||||||
pairs = [ | ||||||
pair for pair in itertools.combinations(qubits, 2) if _manhattan_distance(*pair) == 1 | ||||||
] | ||||||
|
||||||
graph = nx.Graph(pairs) | ||||||
|
||||||
if ax is not None: | ||||||
nx.draw_networkx(graph, pos={q: (q.row, q.col) for q in qubits}, ax=ax) | ||||||
|
@@ -426,7 +440,7 @@ def parallel_xeb_workflow( | |||||
) | ||||||
|
||||||
fids = benchmark_2q_xeb_fidelities( | ||||||
sampled_df=sampled_df, circuits=circuit_library, cycle_depths=cycle_depths | ||||||
sampled_df=sampled_df, circuits=circuit_library, cycle_depths=cycle_depths, pool=pool | ||||||
) | ||||||
|
||||||
return fids, circuit_library, sampled_df | ||||||
|
@@ -435,6 +449,7 @@ def parallel_xeb_workflow( | |||||
def parallel_two_qubit_xeb( | ||||||
sampler: 'cirq.Sampler', | ||||||
qubits: Optional[Sequence['cirq.GridQubit']] = None, | ||||||
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None, | ||||||
entangling_gate: 'cirq.Gate' = ops.CZ, | ||||||
n_repetitions: int = 10**4, | ||||||
n_combinations: int = 10, | ||||||
|
@@ -449,6 +464,7 @@ def parallel_two_qubit_xeb( | |||||
Args: | ||||||
sampler: The quantum engine or simulator to run the circuits. | ||||||
qubits: Qubits under test. If none, uses all qubits on the sampler's device. | ||||||
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits. | ||||||
entangling_gate: The entangling gate to use. | ||||||
n_repetitions: The number of repetitions to use. | ||||||
n_combinations: The number of combinations to generate. | ||||||
|
@@ -466,6 +482,7 @@ def parallel_two_qubit_xeb( | |||||
fids, *_ = parallel_xeb_workflow( | ||||||
sampler=sampler, | ||||||
qubits=qubits, | ||||||
pairs=pairs, | ||||||
entangling_gate=entangling_gate, | ||||||
n_repetitions=n_repetitions, | ||||||
n_combinations=n_combinations, | ||||||
|
@@ -481,6 +498,7 @@ def parallel_two_qubit_xeb( | |||||
def run_rb_and_xeb( | ||||||
sampler: 'cirq.Sampler', | ||||||
qubits: Optional[Sequence['cirq.GridQubit']] = None, | ||||||
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None, | ||||||
repetitions: int = 10**3, | ||||||
num_circuits: int = 20, | ||||||
num_clifford_range: Sequence[int] = tuple( | ||||||
|
@@ -496,6 +514,7 @@ def run_rb_and_xeb( | |||||
Args: | ||||||
sampler: The quantum engine or simulator to run the circuits. | ||||||
qubits: Qubits under test. If none, uses all qubits on the sampler's device. | ||||||
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits. | ||||||
repetitions: The number of repetitions to use for RB and XEB. | ||||||
num_circuits: The number of circuits to generate for RB and XEB. | ||||||
num_clifford_range: The different numbers of Cliffords in the RB study. | ||||||
|
@@ -527,6 +546,7 @@ def run_rb_and_xeb( | |||||
xeb = parallel_two_qubit_xeb( | ||||||
sampler=sampler, | ||||||
qubits=qubits, | ||||||
pairs=pairs, | ||||||
entangling_gate=entangling_gate, | ||||||
n_repetitions=repetitions, | ||||||
n_circuits=num_circuits, | ||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
usually new arguments go to the end