"""Verify compilation flow results."""from__future__importannotationsimportsysimportwarningsfromtypingimportTYPE_CHECKINGifTYPE_CHECKING:fromtyping_extensionsimportUnpackfrom.configurationimportConfigurationOptionsifTYPE_CHECKINGorsys.version_info<(3,10,0):importimportlib_resourcesasresourceselse:fromimportlibimportresourcesfromqiskitimportQuantumCircuitfromqiskit.transpiler.passesimportContainsInstructionfrom.importApplicationScheme,Configuration,EquivalenceCheckingManagerfrom.compilation_flow_profilesimportAncillaMode,generate_profile_namefrom.configurationimportaugment_config_from_kwargsfrom.verifyimportverifydef__check_if_circuit_contains_measurements(circuit:QuantumCircuit)->None:"""Check if the circuit contains measurements and emits a warning if it does not. Args: circuit: The circuit to check. """analysis_pass=ContainsInstruction("measure")analysis_pass(circuit)ifnotanalysis_pass.property_set["contains_measure"]:warnings.warn(UserWarning("One of the circuits does not contain any measurements. ""This may lead to unexpected results since the measurements are used ""to infer the output qubit permutation at the end of the circuit. ""Please consider adding measurements to the circuit _before_ compilation."),stacklevel=2,)
[docs]defverify_compilation(original_circuit:QuantumCircuit|str,compiled_circuit:QuantumCircuit|str,optimization_level:int=1,ancilla_mode:AncillaMode=AncillaMode.NO_ANCILLA,configuration:Configuration|None=None,**kwargs:Unpack[ConfigurationOptions],)->EquivalenceCheckingManager.Results:"""Verify compilation flow results. Similar to :func:`verify <.verify>`, but uses a dedicated compilation flow profile to guide the equivalence checking process. The compilation flow profile is determined by the ``optimization_level`` and ``ancilla_mode`` arguments. There are two (non-exclusive) ways of configuring the equivalence checking process: 1. Pass a :class:`Configuration <.Configuration>` instance as the ``configuration`` argument. 2. Pass keyword arguments to this function. These are directly incorporated into the :class:`Configuration <.Configuration>`. Any existing configuration is overridden by keyword arguments. Args: original_circuit: The original circuit. compiled_circuit: The compiled circuit. optimization_level: The optimization level used for compiling the circuit (0, 1, 2, or 3). Defaults to 1. ancilla_mode: The `ancilla mode <.AncillaMode>` used for realizing multi-controlled Toffoli gates, as available in Qiskit. Defaults to :attr:`.AncillaMode.NO_ANCILLA`. configuration: The configuration to use for the equivalence checking process. **kwargs: Keyword arguments to configure the equivalence checking process. Returns: The results of the equivalence checking process. """ifconfigurationisNone:configuration=Configuration()# prepare the configurationaugment_config_from_kwargs(configuration,kwargs)ifisinstance(original_circuit,QuantumCircuit):__check_if_circuit_contains_measurements(original_circuit)ifisinstance(compiled_circuit,QuantumCircuit):__check_if_circuit_contains_measurements(compiled_circuit)# use the gate_cost scheme for the verificationconfiguration.application.construction_scheme=ApplicationScheme.gate_costconfiguration.application.simulation_scheme=ApplicationScheme.gate_costconfiguration.application.alternating_scheme=ApplicationScheme.gate_cost# get the pre-defined profile for the gate_cost schemeprofile_name=generate_profile_name(optimization_level=optimization_level,mode=ancilla_mode)ref=resources.files("mqt.qcec")/"profiles"/profile_namewithresources.as_file(ref)aspath:configuration.application.profile=str(path)returnverify(original_circuit,compiled_circuit,configuration=configuration)