99import warnings
1010from collections import defaultdict
1111from collections .abc import Callable , Iterable , Mapping , Sequence
12+ from dataclasses import dataclass
1213from math import inf , pi , prod
1314from numbers import Number
1415from typing import TypeVar
@@ -982,7 +983,21 @@ def _restore_verbatim_boxes(
982983 return reconstructed_circuit
983984
984985
985- def to_braket (
986+ @dataclass (frozen = True )
987+ class _CompilationContext :
988+ """Internal result from _compile containing compiled circuits and resolved state."""
989+
990+ circuits : list [QuantumCircuit ]
991+ single_instance : bool
992+ target : Target | None
993+ qubit_labels : Sequence [int ] | None
994+ verbatim : bool | None
995+ basis_gates : Sequence [str ] | None
996+ angle_restrictions : Mapping [str , Mapping [int , set [float ] | tuple [float , float ]]] | None
997+ pass_manager : PassManager | None
998+
999+
1000+ def _compile (
9861001 circuits : _Translatable | Iterable [_Translatable ] = None ,
9871002 * args ,
9881003 qubit_labels : Sequence [int ] | None = None ,
@@ -1002,77 +1017,9 @@ def to_braket(
10021017 verbatim_box_name : str = _BRAKET_VERBATIM_BOX_NAME ,
10031018 layout_method : str | None = None ,
10041019 routing_method : str | None = None ,
1005- ) -> Circuit | list [Circuit ]:
1006- """Converts a single or list of Qiskit QuantumCircuits to a single or list of Braket Circuits.
1007-
1008- The recommended way to use this method is to minimally pass in qubit labels and a target
1009- (instead of basis gates and coupling map). This ensures that the translated circuit is actually
1010- supported by the device (and doesn't, for example, include unsupported parameters for gates).
1011- The latter guarantees that the output Braket circuit uses the qubit labels of the Braket device,
1012- which are not necessarily contiguous.
1020+ seed_transpiler : int | None = None ,
1021+ ) -> _CompilationContext :
10131022
1014- Args:
1015- circuits (QuantumCircuit | Circuit | Program | str | Iterable): Qiskit or Braket
1016- circuit(s) or OpenQASM 3 program(s) to transpile and translate to Braket.
1017- qubit_labels (Sequence[int] | None): A list of (not necessarily contiguous) indices of
1018- qubits in the underlying Amazon Braket device. If not supplied, then the indices are
1019- assumed to be contiguous. Default: ``None``.
1020- target (Target | None): A backend transpiler target. Can only be provided
1021- if basis_gates is ``None``. Default: ``None``.
1022- verbatim (bool): Whether to translate the circuit without any modification, in other
1023- words without transpiling it. Default: ``False``.
1024- basis_gates (Sequence[str] | None): The gateset to transpile to. Can only be provided
1025- if target is ``None``. If ``None`` and target is ``None``, the transpiler will use
1026- all gates defined in the Braket SDK. Default: ``None``.
1027- coupling_map (list[list[int]] | None): If provided, will transpile to a circuit
1028- with this coupling map. Default: ``None``.
1029- angle_restrictions (Mapping[str, Mapping[int, set[float] | tuple[float, float]]] | None):
1030- Mapping of gate names to parameter angle constraints used to
1031- validate numeric parameters. Default: ``None``.
1032- optimization_level (int | None): The optimization level to pass to ``qiskit.transpile``.
1033- From Qiskit:
1034-
1035- * 0: no optimization - basic translation, no optimization, trivial layout
1036- * 1: light optimization - routing + potential SaberSwap, some gate cancellation
1037- and 1Q gate folding
1038- * 2: medium optimization - better routing (noise aware) and commutative cancellation
1039- * 3: high optimization - gate resynthesis and unitary-breaking passes
1040-
1041- Default: 0.
1042- callback (Callable | None): A callback function that will be called after each transpiler
1043- pass execution. Default: ``None``.
1044- num_processes (int | None): The maximum number of parallel transpilation processes for
1045- multiple circuits. Default: ``None``.
1046- pass_manager (PassManager): `PassManager` to transpile the circuit; will raise an error if
1047- used in conjunction with a target, basis gates, or connectivity. Default: ``None``.
1048- braket_device (Device): Braket device to transpile to. Can only be provided if `target`
1049- and ``basis_gates`` are ``None``. Default: ``None``.
1050- add_measurements (bool): Whether to add measurements when translating Braket circuits.
1051- Default: True.
1052- circuit (QuantumCircuit | Circuit | Program | str | Iterable | None): Qiskit or Braket
1053- circuit(s) or OpenQASM 3 program(s) to transpile and translate to Braket.
1054- Default: ``None``. DEPRECATED: use first positional argument or ``circuits`` instead.
1055- connectivity (list[list[int]] | None): If provided, will transpile to a circuit
1056- with this connectivity. Default: ``None``. DEPRECATED: use ``coupling_map`` instead.
1057- verbatim_box_name (str): The label name used to identify verbatim BoxOp operations
1058- in Qiskit circuits. When circuits contain BoxOp operations with this label, they
1059- will be preserved during transpilation by temporarily replacing them with barriers.
1060- Default: ``"verbatim"``.
1061- layout_method (str | None): The layout method to use during transpilation. If ``None``
1062- and the circuit contains verbatim boxes, defaults to ``'trivial'`` to preserve
1063- physical qubit mappings. Otherwise uses Qiskit's default. Default: ``None``.
1064- routing_method (str | None): The routing method to use during transpilation. If ``None``
1065- and the circuit contains verbatim boxes, defaults to ``'none'`` to disable routing
1066- and preserve physical qubit structure. Otherwise uses Qiskit's default. Default: ``None``.
1067-
1068- Raises:
1069- ValueError: If more than one of `target`, ``basis_gates``
1070- or ``coupling_map``/``connectivity``, ``pass_manager``, and ``braket_device``
1071- are passed together, or if `qubit_labels` is passed with ``braket_device``.
1072-
1073- Returns:
1074- Circuit | list[Circuit]: Braket circuit or circuits
1075- """
10761023 circuits , single_instance = _get_circuits (circuits , circuit , add_measurements )
10771024 if len (args ) > 4 :
10781025 raise ValueError (f"Unknown arguments passed: { args [4 :]} " )
@@ -1166,6 +1113,7 @@ def to_braket(
11661113 num_processes = num_processes ,
11671114 layout_method = effective_layout_method ,
11681115 routing_method = effective_routing_method ,
1116+ seed_transpiler = seed_transpiler ,
11691117 )
11701118 if isinstance (target , _SubstitutedTarget ):
11711119 circuits = target ._substitute (circuits )
@@ -1176,13 +1124,131 @@ def to_braket(
11761124 for circ , verbatim_boxes in zip (circuits , all_verbatim_boxes )
11771125 ]
11781126
1127+ return _CompilationContext (
1128+ circuits = circuits ,
1129+ single_instance = single_instance ,
1130+ target = target ,
1131+ qubit_labels = qubit_labels ,
1132+ verbatim = verbatim ,
1133+ basis_gates = basis_gates ,
1134+ angle_restrictions = angle_restrictions ,
1135+ pass_manager = pass_manager ,
1136+ )
1137+
1138+
1139+ def to_braket (
1140+ circuits : _Translatable | Iterable [_Translatable ] = None ,
1141+ * args ,
1142+ qubit_labels : Sequence [int ] | None = None ,
1143+ target : Target | None = None ,
1144+ verbatim : bool | None = None ,
1145+ basis_gates : Sequence [str ] | None = None ,
1146+ coupling_map : list [list [int ]] | None = None ,
1147+ angle_restrictions : Mapping [str , Mapping [int , set [float ] | tuple [float , float ]]] | None = None ,
1148+ optimization_level : int = 0 ,
1149+ callback : Callable | None = None ,
1150+ num_processes : int | None = None ,
1151+ pass_manager : PassManager | None = None ,
1152+ braket_device : Device | None = None ,
1153+ add_measurements : bool = True ,
1154+ circuit : _Translatable | Iterable [_Translatable ] | None = None ,
1155+ connectivity : list [list [int ]] | None = None ,
1156+ verbatim_box_name : str = _BRAKET_VERBATIM_BOX_NAME ,
1157+ layout_method : str | None = None ,
1158+ routing_method : str | None = None ,
1159+ seed_transpiler : int | None = None ,
1160+ ) -> Circuit | list [Circuit ]:
1161+ """Converts a single or list of Qiskit QuantumCircuits to a single or list of Braket Circuits.
1162+
1163+ The recommended way to use this method is to minimally pass in qubit labels and a target
1164+ (instead of basis gates and coupling map). This ensures that the translated circuit is actually
1165+ supported by the device (and doesn't, for example, include unsupported parameters for gates).
1166+ The latter guarantees that the output Braket circuit uses the qubit labels of the Braket device,
1167+ which are not necessarily contiguous.
1168+
1169+ Args:
1170+ circuits (QuantumCircuit | Circuit | Program | str | Iterable): Qiskit or Braket
1171+ circuit(s) or OpenQASM 3 program(s) to transpile and translate to Braket.
1172+ qubit_labels (Sequence[int] | None): A list of (not necessarily contiguous) indices of
1173+ qubits in the underlying Amazon Braket device. If not supplied, then the indices are
1174+ assumed to be contiguous. Default: ``None``.
1175+ target (Target | None): A backend transpiler target. Can only be provided
1176+ if basis_gates is ``None``. Default: ``None``.
1177+ verbatim (bool): Whether to translate the circuit without any modification, in other
1178+ words without transpiling it. Default: ``False``.
1179+ basis_gates (Sequence[str] | None): The gateset to transpile to. Can only be provided
1180+ if target is ``None``. If ``None`` and target is ``None``, the transpiler will use
1181+ all gates defined in the Braket SDK. Default: ``None``.
1182+ coupling_map (list[list[int]] | None): If provided, will transpile to a circuit
1183+ with this coupling map. Default: ``None``.
1184+ angle_restrictions (Mapping[str, Mapping[int, set[float] | tuple[float, float]]] | None):
1185+ Mapping of gate names to parameter angle constraints used to
1186+ validate numeric parameters. Default: ``None``.
1187+ optimization_level (int | None): The optimization level to pass to ``qiskit.transpile``.
1188+ From Qiskit:
1189+
1190+ * 0: no optimization - basic translation, no optimization, trivial layout
1191+ * 1: light optimization - routing + potential SaberSwap, some gate cancellation
1192+ and 1Q gate folding
1193+ * 2: medium optimization - better routing (noise aware) and commutative cancellation
1194+ * 3: high optimization - gate resynthesis and unitary-breaking passes
1195+
1196+ Default: 0.
1197+ callback (Callable | None): A callback function that will be called after each transpiler
1198+ pass execution. Default: ``None``.
1199+ num_processes (int | None): The maximum number of parallel transpilation processes for
1200+ multiple circuits. Default: ``None``.
1201+ pass_manager (PassManager): `PassManager` to transpile the circuit; will raise an error if
1202+ used in conjunction with a target, basis gates, or connectivity. Default: ``None``.
1203+ braket_device (Device): Braket device to transpile to. Can only be provided if `target`
1204+ and ``basis_gates`` are ``None``. Default: ``None``.
1205+ add_measurements (bool): Whether to add measurements when translating Braket circuits.
1206+ Default: True.
1207+ circuit (QuantumCircuit | Circuit | Program | str | Iterable | None): Qiskit or Braket
1208+ circuit(s) or OpenQASM 3 program(s) to transpile and translate to Braket.
1209+ Default: ``None``. DEPRECATED: use first positional argument or ``circuits`` instead.
1210+ connectivity (list[list[int]] | None): If provided, will transpile to a circuit
1211+ with this connectivity. Default: ``None``. DEPRECATED: use ``coupling_map`` instead.
1212+ verbatim_box_name (str): The label name used to identify verbatim BoxOp operations
1213+ in Qiskit circuits. When circuits contain BoxOp operations with this label, they
1214+ will be preserved during transpilation by temporarily replacing them with barriers.
1215+ Default: ``"verbatim"``.
1216+ layout_method (str | None): The layout method to use during transpilation. If ``None``
1217+ and the circuit contains verbatim boxes, defaults to ``'trivial'`` to preserve
1218+ physical qubit mappings. Otherwise uses Qiskit's default. Default: ``None``.
1219+ routing_method (str | None): The routing method to use during transpilation. If ``None``
1220+ and the circuit contains verbatim boxes, defaults to ``'none'`` to disable routing
1221+ and preserve physical qubit structure. Otherwise uses Qiskit's default. Default: ``None``.
1222+ seed_transpiler (int | None): This specifies a seed used for the stochastic parts
1223+ of the transpiler. Default: ``None``.
1224+
1225+ Raises:
1226+ ValueError: If more than one of `target`, ``basis_gates``
1227+ or ``coupling_map``/``connectivity``, ``pass_manager``, and ``braket_device``
1228+ are passed together, or if `qubit_labels` is passed with ``braket_device``.
1229+
1230+ Returns:
1231+ Circuit | list[Circuit]: Braket circuit or circuits
1232+ """
1233+ result = _compile (
1234+ circuits , * args ,
1235+ qubit_labels = qubit_labels , target = target , verbatim = verbatim ,
1236+ basis_gates = basis_gates , coupling_map = coupling_map ,
1237+ angle_restrictions = angle_restrictions , optimization_level = optimization_level ,
1238+ callback = callback , num_processes = num_processes , pass_manager = pass_manager ,
1239+ braket_device = braket_device , add_measurements = add_measurements ,
1240+ circuit = circuit , connectivity = connectivity , verbatim_box_name = verbatim_box_name ,
1241+ layout_method = layout_method , routing_method = routing_method ,
1242+ seed_transpiler = seed_transpiler ,
1243+ )
11791244 translated = [
11801245 _translate_to_braket (
1181- circ , target , qubit_labels , verbatim , basis_gates , angle_restrictions , pass_manager
1246+ circ , result .target , result .qubit_labels , result .verbatim ,
1247+ result .basis_gates , result .angle_restrictions , result .pass_manager ,
11821248 )
1183- for circ in circuits
1249+ for circ in result . circuits
11841250 ]
1185- return translated [0 ] if single_instance else translated
1251+ return translated [0 ] if result . single_instance else translated
11861252
11871253
11881254def _get_circuits (
0 commit comments