Skip to content

Commit 2ba516a

Browse files
NoureldinYosriBichengYing
authored andcommitted
Add ability to pass tags to XEB and related methods (quantumlib#6836)
1 parent 3755f08 commit 2ba516a

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

cirq-core/cirq/experiments/random_quantum_circuit_generation.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ def generate_library_of_2q_circuits(
250250
q0: 'cirq.Qid' = devices.LineQubit(0),
251251
q1: 'cirq.Qid' = devices.LineQubit(1),
252252
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
253+
tags: Sequence[Any] = (),
253254
) -> List['cirq.Circuit']:
254255
"""Generate a library of two-qubit Circuits.
255256
@@ -266,6 +267,7 @@ def generate_library_of_2q_circuits(
266267
q0: The first qubit to use when constructing the circuits.
267268
q1: The second qubit to use when constructing the circuits
268269
random_state: A random state or seed used to deterministically sample the random circuits.
270+
tags: Tags to add to the two qubit operations.
269271
"""
270272
rs = value.parse_random_state(random_state)
271273
exponents = np.linspace(0, 7 / 4, 8)
@@ -278,7 +280,7 @@ def generate_library_of_2q_circuits(
278280
q0,
279281
q1,
280282
depth=max_cycle_depth,
281-
two_qubit_op_factory=lambda a, b, _: two_qubit_gate(a, b),
283+
two_qubit_op_factory=lambda a, b, _: two_qubit_gate(a, b).with_tags(*tags),
282284
single_qubit_gates=single_qubit_gates,
283285
seed=rs,
284286
)

cirq-core/cirq/experiments/random_quantum_circuit_generation_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,20 @@ def add_pair(neighbor: 'cirq.GridQubit'):
457457
add_pair(cirq.GridQubit(qubit.row + 1, qubit.col))
458458

459459
return pairs
460+
461+
462+
def test_generate_library_of_2q_circuits_with_tags():
463+
circuits = generate_library_of_2q_circuits(
464+
n_library_circuits=5,
465+
two_qubit_gate=cirq.FSimGate(3, 4),
466+
max_cycle_depth=13,
467+
random_state=9,
468+
tags=('test_tag',),
469+
)
470+
assert len(circuits) == 5
471+
for circuit in circuits:
472+
for op in circuit.all_operations():
473+
if cirq.num_qubits(op) == 1:
474+
continue
475+
assert op.tags == ('test_tag',)
476+
assert op.gate == cirq.FSimGate(3, 4)

cirq-core/cirq/experiments/two_qubit_xeb.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
"""Provides functions for running and analyzing two-qubit XEB experiments."""
16-
from typing import Sequence, TYPE_CHECKING, Optional, Tuple, Dict, cast, Mapping
16+
from typing import Sequence, TYPE_CHECKING, Optional, Tuple, Dict, cast, Mapping, Any
1717

1818
from dataclasses import dataclass
1919
from types import MappingProxyType
@@ -402,6 +402,7 @@ def parallel_xeb_workflow(
402402
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
403403
pool: Optional['multiprocessing.pool.Pool'] = None,
404404
batch_size: int = 9,
405+
tags: Sequence[Any] = (),
405406
**plot_kwargs,
406407
) -> Tuple[pd.DataFrame, Sequence['cirq.Circuit'], pd.DataFrame]:
407408
"""A utility method that runs the full XEB workflow.
@@ -422,6 +423,7 @@ def parallel_xeb_workflow(
422423
batch_size: We call `run_batch` on the sampler, which can speed up execution in certain
423424
environments. The number of (circuit, cycle_depth) tasks to be run in each batch
424425
is given by this number.
426+
tags: Tags to add to two qubit operations.
425427
**plot_kwargs: Arguments to be passed to 'plt.Axes.plot'.
426428
427429
Returns:
@@ -450,6 +452,7 @@ def parallel_xeb_workflow(
450452
two_qubit_gate=entangling_gate,
451453
random_state=rs,
452454
max_cycle_depth=max(cycle_depths),
455+
tags=tags,
453456
)
454457

455458
combs_by_layer = rqcg.get_random_combinations_for_device(
@@ -488,6 +491,7 @@ def parallel_two_qubit_xeb(
488491
ax: Optional[plt.Axes] = None,
489492
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
490493
batch_size: int = 9,
494+
tags: Sequence[Any] = (),
491495
**plot_kwargs,
492496
) -> TwoQubitXEBResult:
493497
"""A convenience method that runs the full XEB workflow.
@@ -507,6 +511,7 @@ def parallel_two_qubit_xeb(
507511
batch_size: We call `run_batch` on the sampler, which can speed up execution in certain
508512
environments. The number of (circuit, cycle_depth) tasks to be run in each batch
509513
is given by this number.
514+
tags: Tags to add to two qubit operations.
510515
**plot_kwargs: Arguments to be passed to 'plt.Axes.plot'.
511516
Returns:
512517
A TwoQubitXEBResult object representing the results of the experiment.
@@ -525,6 +530,7 @@ def parallel_two_qubit_xeb(
525530
random_state=random_state,
526531
ax=ax,
527532
batch_size=batch_size,
533+
tags=tags,
528534
**plot_kwargs,
529535
)
530536
return TwoQubitXEBResult(fit_exponential_decays(fids))
@@ -544,6 +550,7 @@ def run_rb_and_xeb(
544550
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
545551
pairs: Optional[Sequence[tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
546552
batch_size: int = 9,
553+
tags: Sequence[Any] = (),
547554
) -> InferredXEBResult:
548555
"""A convenience method that runs both RB and XEB workflows.
549556
@@ -561,6 +568,7 @@ def run_rb_and_xeb(
561568
batch_size: We call `run_batch` on the sampler, which can speed up execution in certain
562569
environments. The number of (circuit, cycle_depth) tasks to be run in each batch
563570
is given by this number.
571+
tags: Tags to add to two qubit operations.
564572
565573
Returns:
566574
An InferredXEBResult object representing the results of the experiment.
@@ -590,6 +598,7 @@ def run_rb_and_xeb(
590598
n_combinations=xeb_combinations,
591599
random_state=random_state,
592600
batch_size=batch_size,
601+
tags=tags,
593602
)
594603

595604
return InferredXEBResult(rb, xeb)

cirq-core/cirq/experiments/z_phase_calibration.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
"""Provides a method to do z-phase calibration for excitation-preserving gates."""
16-
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING
16+
from typing import Union, Optional, Sequence, Tuple, Dict, TYPE_CHECKING, Any
1717
import multiprocessing
1818
import multiprocessing.pool
1919

@@ -41,6 +41,8 @@ def z_phase_calibration_workflow(
4141
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
4242
atol: float = 1e-3,
4343
num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
44+
pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
45+
tags: Sequence[Any] = (),
4446
) -> Tuple[xeb_fitting.XEBCharacterizationResult, 'pd.DataFrame']:
4547
"""Perform z-phase calibration for excitation-preserving gates.
4648
@@ -77,6 +79,8 @@ def z_phase_calibration_workflow(
7779
A zero value means no multiprocessing.
7880
A positive integer value will create a pool with the given number of workers.
7981
A negative value will create pool with maximum number of workers.
82+
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits.
83+
tags: Tags to add to two qubit operations.
8084
Returns:
8185
- An `XEBCharacterizationResult` object that contains the calibration result.
8286
- A `pd.DataFrame` comparing the before and after fidelities.
@@ -100,6 +104,8 @@ def z_phase_calibration_workflow(
100104
n_combinations=n_combinations,
101105
random_state=random_state,
102106
pool=pool,
107+
tags=tags,
108+
pairs=pairs,
103109
)
104110

105111
if options is None:
@@ -148,6 +154,8 @@ def calibrate_z_phases(
148154
random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
149155
atol: float = 1e-3,
150156
num_workers_or_pool: Union[int, 'multiprocessing.pool.Pool'] = -1,
157+
pairs: Optional[Sequence[Tuple['cirq.GridQubit', 'cirq.GridQubit']]] = None,
158+
tags: Sequence[Any] = (),
151159
) -> Dict[Tuple['cirq.Qid', 'cirq.Qid'], 'cirq.PhasedFSimGate']:
152160
"""Perform z-phase calibration for excitation-preserving gates.
153161
@@ -184,6 +192,8 @@ def calibrate_z_phases(
184192
A zero value means no multiprocessing.
185193
A positive integer value will create a pool with the given number of workers.
186194
A negative value will create pool with maximum number of workers.
195+
pairs: Pairs to use. If not specified, use all pairs between adjacent qubits.
196+
tags: Tags to add to two qubit operations.
187197
188198
Returns:
189199
- A dictionary mapping qubit pairs to the calibrated PhasedFSimGates.
@@ -210,6 +220,8 @@ def calibrate_z_phases(
210220
random_state=random_state,
211221
atol=atol,
212222
num_workers_or_pool=num_workers_or_pool,
223+
tags=tags,
224+
pairs=pairs,
213225
)
214226

215227
gates = {}

0 commit comments

Comments
 (0)