:py:mod:`pygsti.protocols.mirror_edesign` ========================================= .. py:module:: pygsti.protocols.mirror_edesign .. autoapi-nested-parse:: Functions for creating mirror experiment designs for mirror circuit fidelity estimation (MCFE) Module Contents --------------- Functions ~~~~~~~~~ .. autoapisummary:: pygsti.protocols.mirror_edesign.qiskit_circuits_to_mirror_edesign pygsti.protocols.mirror_edesign.qiskit_circuits_to_fullstack_mirror_edesign pygsti.protocols.mirror_edesign.qiskit_circuits_to_subcircuit_mirror_edesign pygsti.protocols.mirror_edesign.make_mirror_edesign pygsti.protocols.mirror_edesign.compute_inverse pygsti.protocols.mirror_edesign.init_layer .. py:function:: qiskit_circuits_to_mirror_edesign(qk_circs: Union[Dict[Any, qiskit.QuantumCircuit], List[qiskit.QuantumCircuit]], mirroring_kwargs_dict: Dict[str, Any] = {}) -> Tuple[pygsti.protocols.protocol.FreeformDesign, pygsti.protocols.protocol.CombinedExperimentDesign] Create a noise benchmark from transpiled Qiskit circuits. Parameters ---------- qk_circs : List[qiskit.QuantumCircuit] | Dict[qiskit.QuantumCircuit] Qiskit QuantumCircuits from which a noise benchmark is to be created. If a dictionary is provided, those keys are used. If a list is provided, default integer keys are used. mirroring_kwargs_dict : dict, optional dictionary of keyword arguments to be used in circuit mirroring. If an arg is not provided, a default value is used. The args are: 'mirror_circuits_per_circ': default 10. The number of mirror circuits of the test-exact and exact-exact varieties to be used for the process fidelity estimation of each provided Qiskit circuit. 'num_ref_per_qubit_subset': default 10. The number of SPAM reference circuits to use for each qubit subset that is represented among the provided Qiskit circuits. 'rand_state': default None. np.random.RandomState to be used for circuit mirroring. Returns --------- Tuple pygsti.protocols.FreeformDesign Experiment design containing the pyGSTi conversion of all Qiskit circuits that were passed in. Does not need executed, but is needed for fidelity calculations. pygsti.protocols.CombinedExperimentDesign Experiment design containing all mirror circuits that must be executed in order to perform mirror circuit fidelity estimation. .. py:function:: qiskit_circuits_to_fullstack_mirror_edesign(qk_circs: Union[Dict[Any, qiskit.QuantumCircuit], List[qiskit.QuantumCircuit]], qk_backend: Optional[qiskit.providers.BackendV2] = None, coupling_map: Optional[qiskit.transpiler.CouplingMap] = None, basis_gates: Optional[List[str]] = None, transpiler_kwargs_dict: Dict[str, Any] = {}, mirroring_kwargs_dict: Dict[str, Any] = {}, num_transpilation_attempts: int = 100, return_qiskit_time: bool = False) -> Tuple[pygsti.protocols.protocol.FreeformDesign, pygsti.protocols.protocol.CombinedExperimentDesign] Create a full-stack benchmark from high-level Qiskit circuits. Parameters ---------- qk_circs : List[qiskit.QuantumCircuit] | Dict[qiskit.QuantumCircuit] Qiskit QuantumCircuits from which a full-stack benchmark is to be created. If a dictionary is provided, those keys are used. If a list is provided, default integer keys are used. qk_backend : qiskit-ibm-runtime.IBMBackend, optional IBM backend whose native gate set, connectivity, and error rates are to be targeted when doing a full-stack transpilation. Fake backends are also acceptable. If not provided, both `coupling_map` and `basis_gates` must be provided, and certain transpiler optimizations that depend on backend error rates may not be accessible. coupling_map : qiskit.transpiler.CouplingMap, optional couplinp map for a target backend that must be provided if `qk_backend` is None. This argument is ignored if `qk_backend` is not None. basis_gates : list[str], optional list of native gates for a target backend that must be provided if `qk_backend` is None. This argument is ignored if `qk_backend` is not None. transpiler_kwargs_dict : dict, optional keyword arguments that are passed to the Qiskit transpiler for full-stack transpilation. Please see the Qiskit transpiler documentation for a comprehensive list of options. If any or all of the following keys are not provided, the listed defaults are used: 'optimization_level': default 3 'approximation_degree': default 1.0 'seed_transpiler': default None mirroring_kwargs_dict : dict, optional dictionary of keyword arguments to be used in circuit mirroring. If an arg is not provided, a default value is used. The args are: 'mirror_circuits_per_circ': default 10. The number of mirror circuits of the test-exact and exact-exact varieties to be used for the process fidelity estimation of each provided Qiskit circuit. 'num_ref_per_qubit_subset': default 10. The number of SPAM reference circuits to use for each qubit subset that is represented among the provided Qiskit circuits. 'rand_state': default None. np.random.RandomState to be used for circuit mirroring. num_transpilation_attempts : int, optional number of times to attempt full-stack circuit transpilation. Circuit mirroring requires that the transpilation not use ancilla qubits, which is difficult to enforce with the other transpiler options. Instead, we adopt a try-until-success strategy, which may fail if an insufficient number of attempts are allowed. Increase this number if you are having issues with the transpilation. If not provided, the default is 100 attempts. return_qiskit_time : bool, optional Debug flag that sets whether or not to report the time spent in the Qiskit transpiler. Qiskit transpilation is often the most costly part of benchmark creation and it can be helpful to know how much time it is consuming. Returns --------- Tuple pygsti.protocols.FreeformDesign Experiment design containing the pyGSTi conversion of all Qiskit circuits that were passed in. Does not need executed, but is needed for fidelity calculations. pygsti.protocols.CombinedExperimentDesign Experiment design containing all mirror circuits that must be executed in order to perform mirror circuit fidelity estimation. float, optional amount of time spent in Qiskit transpiler. .. py:function:: qiskit_circuits_to_subcircuit_mirror_edesign(qk_circs: Union[Dict[Any, qiskit.QuantumCircuit], List[qiskit.QuantumCircuit]], aggregate_subcircs: bool, width_depth_dict: Dict[int, List[int]], coupling_map: qiskit.transpiler.CouplingMap, instruction_durations: qiskit.transpiler.InstructionDurations, subcirc_kwargs_dict: Dict[str, Any] = {}, mirroring_kwargs_dict: Dict[str, Any] = {}) -> Tuple[pygsti.protocols.protocol.FreeformDesign, pygsti.protocols.protocol.CombinedExperimentDesign] Create a subcircuit benchmark from transpiled Qiskit circuits. Parameters ---------- qk_circs : List[qiskit.QuantumCircuit] | Dict[qiskit.QuantumCircuit] Qiskit QuantumCircuits from which a subcircuit benchmark is to be created. If a dictionary is provided, those keys are used. If a list is provided, default integer keys are used. aggregate_subcircs : bool Whether or not the provided Qiskit circuits should be used to create one combined subcircuit experiment design or kept separate. Circuit aggregration can be useful if the provided circuits are all instances of the same 'family' of the circuit, e.g., all Bernstein-Vazirani circuits with different secret keys. width_depth_dict : dict[int, list[int]] dictionary whose keys are subcircuit widths and whose values are lists of depths to snip out for that width. coupling_map : str or qiskit.transpiler.CouplingMap coupling map for the device the Qiskit circuits were transpiled to. If 'all-to-all', an all-to-all coupling map is used. If 'linear', a linear topology is used. instruction_durations : qiskit.transpiler.InstructionDurations instruction durations for each gate in the target device. These durations are needed to calculate the appropriate delay time when only idling qubits are sampled out from a full circuit layer. subcirc_kwargs_dict : dict, optional dictionary of keyword arguments to be used in subcircuit selection. If an arg is not provided, a default value is used. The args are: 'num_samples_per_width_depth': default 10. number of subcircuits to sample from each full circuit. if `aggregate_subcircuits` is set to True, `num_samplse_per_width_depth` subcircuits are drawn from each full circuit and combined into one experiment design. 'rand_state': default None. np.random.RandomState to be used for subcircuit selection. mirroring_kwargs_dict : dict, optional dictionary of keyword arguments to be used in circuit mirroring If an arg is not provided, a default value is used. The args are: 'mirror_circuits_per_circ': default 10. The number of mirror circuits of the test-exact and exact-exact varieties to be used for the process fidelity estimation of each provided Qiskit circuit. 'num_ref_per_qubit_subset': default 10. The number of SPAM reference circuits to use for each qubit subset that is represented among the provided Qiskit circuits. 'rand_state': default None. np.random.RandomState to be used for circuit mirroring. Returns --------- Tuple dict[hashable, pygsti.protocols.FreeformDesign] or pygsti.protocols.FreeformDesign Experiment design(s) containing the pyGSTi conversion of all Qiskit circuits that were passed in. Does not need executed, but is needed for fidelity calculations. A dictionary is returned if `aggregate_subcircs` is False, otherwise a FreeformDesign is returned. dict[hashable, pygsti.protocols.CombinedExperimentDesign] or pygsti.protocols.CombinedExperimentDesign Experiment design(s) containing all mirror circuits that must be executed in order to perform mirror circuit fidelity estimation. A dictionary is returned if `aggregate_subcircs` is False, otherwise a FreeformDesign is returned. .. py:function:: make_mirror_edesign(test_edesign: pygsti.protocols.protocol.FreeformDesign, account_for_routing: bool, ref_edesign: Optional[pygsti.protocols.protocol.FreeformDesign] = None, ref_id_lookup_dict: Optional[dict] = None, num_mcs_per_circ: int = 10, num_ref_per_qubit_subset: int = 10, mirroring_strategy: Literal['pauli_rc', 'central_pauli'] = 'pauli_rc', gate_set: str = 'u3_cx_cz', inverse: Optional[Callable[[pygsti.circuits.circuit.Circuit], pygsti.circuits.circuit.Circuit]] = None, inv_kwargs: Optional[dict] = None, rc_function: Optional[Callable[[pygsti.circuits.circuit.Circuit], Tuple[pygsti.circuits.circuit.Circuit, str]]] = None, rc_kwargs: Optional[dict] = None, state_initialization: Optional[Union[str, Callable[Ellipsis, pygsti.circuits.circuit.Circuit]]] = None, state_init_kwargs: Optional[dict] = None, rand_state: Optional[numpy.random.RandomState] = None) -> pygsti.protocols.protocol.CombinedExperimentDesign Creates an experiment design containing the mirror circuits needed for mirror circuit fidelity estimation (MCFE). Parameters ---------- test_edesign : pygsti.protocols.FreeformDesign The experiment design containing the test circuits. account_for_routing : bool Indicates whether to account for routing in the design. ref_edesign : Optional[pygsti.protocols.FreeformDesign], optional The experiment design containing the reference circuits. Default is None. ref_id_lookup_dict : Optional[dict], optional A lookup dictionary for matching test circuits with reference circuits. Default is None. num_mcs_per_circ : int, optional The number of mirror circuits to generate for each test circuit. Default is 10. num_ref_per_qubit_subset : int, optional The number of SPAM reference circuits to use for each qubit subset. Default is 10. mirroring_strategy : Literal['pauli_rc', 'central_pauli'], optional The strategy to use for mirroring ('pauli_rc' or 'central_pauli'). Default is 'pauli_rc'. gate_set : str, optional The set of gates to be used in the design. Default is 'u3_cx_cz'. inverse : Optional[Callable[[_Circuit], _Circuit]], optional A custom function to compute the inverse of a circuit. Default is None. Signature: inverse(circ: pygsti.circuits.Circuit, ...) -> pygsti.circuits.Circuit If providing a custom inverse function, 'circ' must be the circuit parameter name. inv_kwargs : Optional[dict], optional Additional keyword arguments for a custom inverse function. Default is None. rc_function : Optional[Callable[[_Circuit], Tuple[_Circuit, str]]], optional A custom function for random compilation. Default is None. Signature: rc_function(circ: pygsti.circuits.Circuit, rand_state: Optional[_np.random.RandomState] = None, ...) -> Tuple[pygsti.circuits.Circuit, str] The user-defined function must return the randomized circuit, along with the expected bitstring measurement given the randomization. This function is called twice: 1) On the reverse half of the circuit, when creating the init-test-ref_inv-init_inv circuit. ref_inv and init_inv are randomized. The bitstring should be the expected measurement *for the full circuit*, *not* ref_inv-init_inv in isolation from the forward half of the circuit. Pass the forward half of the circuit as a kwarg in rc_kwargs if necessary. 2) On the entire circuit, when creating the init-ref-ref_inv-init_inv circuit. All four pieces are randomized. The bitstring should again be the expected measurement for the full circuit, but it is more clear in this case than in the previous. rc_kwargs : Optional[dict], optional Additional keyword arguments for the random compilation function. Default is None. state_initialization : Optional[Union[str, Callable[..., _Circuit]]], optional A function or string for state initialization. Default is None. Signature: state_initialization(qubits, rand_state: Optional[_np.random.RandomState] = None, ...) -> pygsti.circuits.Circuit If providing a custom state initialization, the parameter names must be 'qubits' (list of the qubits being used) and 'rand_state'. state_init_kwargs : Optional[dict], optional Additional keyword arguments for a custom state initialization function. Default is None. rand_state : Optional[_np.random.RandomState], optional A random state for reproducibility. Default is None. Returns -------- pygsti.protocols.CombinedExperimentDesign A combined experiment design containing the MCFE circuits. .. py:function:: compute_inverse(circ: pygsti.circuits.circuit.Circuit, gate_set: str, inverse: Optional[Callable[[pygsti.circuits.circuit.Circuit], pygsti.circuits.circuit.Circuit]] = None, inv_kwargs: Optional[dict] = None) -> pygsti.circuits.circuit.Circuit Computes the inverse of a given circuit based on the specified gate set. Parameters ---------- circ : pygsti.circuits.Circuit The circuit for which to compute the inverse. gate_set : str The set of gates used in the circuit (e.g., 'u3_cx_cz'). inverse : Optional[Callable[[_Circuit], _Circuit]], optional A custom function to compute the inverse of the circuit. Default is None. inv_kwargs : Optional[dict], optional Additional keyword arguments for the custom inverse function. Default is None. Returns -------- pygsti.circuits.Circuit A new circuit that is the inverse of the input circuit. .. py:function:: init_layer(qubits: List[str], gate_set: str, state_initialization: Optional[Union[str, Callable[Ellipsis, pygsti.circuits.circuit.Circuit]]] = None, state_init_kwargs: Optional[dict] = None, rand_state: Optional[numpy.random.RandomState] = None) -> pygsti.circuits.circuit.Circuit Create initial layer for mirror circuit. Parameters ---------- qubits : list A list of qubit labels for the layer. gate_set : str The gate set for the mirror circuit (e.g., 'u3_cx_cz'). state_initialization : Optional[Union[str, Callable[..., _Circuit]]], optional Custom function for creating initial layer, or the string 'none'. If 'none' is provided, then an empty initial layer is created, i.e., there is no state preparation layer. Default is None, which prepares an initial layer according to the gate set. state_init_kwargs : Optional[dict], optional Additional keyword arguments for the state initialization function. Default is None. rand_state : Optional[_np.random.RandomState], optional A random state for reproducibility. Default is None. Returns -------- pygsti.circuits.Circuit A new circuit representing the initial layer of gates.