Source code for braket.emulation.passes.circuit_passes.gate_validator

# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
#     http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

from collections.abc import Iterable

from braket.circuits import Circuit
from braket.circuits.compiler_directives import EndVerbatimBox, StartVerbatimBox
from braket.circuits.gate import Gate
from braket.circuits.translations import BRAKET_GATES
from braket.emulation.passes import ValidationPass
from braket.program_sets import ProgramSet


[docs] class GateValidator(ValidationPass): def __init__( self, supported_gates: Iterable[str] | None = None, native_gates: Iterable[str] | None = None, ): """ A GateValidator instance validates that a circuit uses the supported gates of the device, or native gates within a verbatim box if any. Args: supported_gates (Iterable[str] | None): A list of gates supported outside of verbatim modeby the emulator. A gate is a Braket gate name. native_gates (Iterable[str] | None): A list of gates supported inside of verbatim mode by the emulator. Raises: ValueError: If supported_gates and native_gates are empty or any of the provided gate are not supported by the Braket BDK. """ supported_gates, native_gates = (supported_gates or []), (native_gates or []) if not supported_gates and not native_gates: raise ValueError("Supported gate set or native gate set must be provided.") try: self._supported_gates = frozenset( BRAKET_GATES[gate.lower()] for gate in supported_gates ) except KeyError as e: raise ValueError( f"Input {e!s} in supported_gates is not a valid Braket gate name." ) from e try: self._native_gates = frozenset(BRAKET_GATES[gate.lower()] for gate in native_gates) except KeyError as e: raise ValueError(f"Input {e!s} in native_gates is not a valid Braket gate name.") from e self._supported_specifications = Circuit | ProgramSet
[docs] def validate(self, circuit: Circuit | ProgramSet) -> None: """ Checks that all non-verbatim gates used in the circuit are in this validator's supported gate set and that all verbatim gates used in the circuit are in this validator's native gate set. Args: circuit (Circuit): The Braket circuit whose gates to validate. Raises: ValueError: If a gate operation or verbatim gate operation is not in this validator's supported or native gate set, respectively. """ if isinstance(circuit, ProgramSet): for item in circuit: self.validate(item) return in_verbatim = False for instruction in circuit.instructions: operator = instruction.operator if isinstance(operator, Gate): self._validate_gate(in_verbatim, operator) elif isinstance(operator, StartVerbatimBox): if in_verbatim: raise ValueError("Already in verbatim box") in_verbatim = True elif isinstance(operator, EndVerbatimBox): if not in_verbatim: raise ValueError("Already outside of verbatim box") in_verbatim = False # Check for unclosed verbatim box if in_verbatim: raise ValueError("No end verbatim box found for the circuit.")
def _validate_gate(self, in_verbatim: bool, operator: Gate) -> None: if in_verbatim: if type(operator) not in self._native_gates: raise ValueError(f"Gate {operator.name} is not a native gate for this device.") elif type(operator) not in self._supported_gates: raise ValueError(f"Gate {operator.name} is not a supported gate for this device.")