Skip to content
Open
50 changes: 35 additions & 15 deletions src/braket/circuits/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

from __future__ import annotations

import warnings
from collections import Counter
from collections.abc import Callable, Iterable, Sequence
from numbers import Number
Expand Down Expand Up @@ -57,7 +56,9 @@
QubitReferenceType,
SerializationProperties,
)
from braket.circuits.text_diagram_builders.unicode_circuit_diagram import UnicodeCircuitDiagram
from braket.circuits.text_diagram_builders.unicode_circuit_diagram import (
UnicodeCircuitDiagram,
)
from braket.circuits.unitary_calculation import calculate_unitary_big_endian
from braket.pulse.ast.qasm_parser import ast_to_qasm
from braket.pulse.frame import Frame
Expand All @@ -67,7 +68,11 @@
from braket.registers.qubit_set import QubitSet, QubitSetInput

SubroutineReturn = TypeVar(
"SubroutineReturn", Iterable[Instruction], Instruction, ResultType, Iterable[ResultType]
"SubroutineReturn",
Iterable[Instruction],
Instruction,
ResultType,
Iterable[ResultType],
)
SubroutineCallable = TypeVar("SubroutineCallable", bound=Callable[..., SubroutineReturn])
AddableTypes = TypeVar("AddableTypes", SubroutineReturn, SubroutineCallable)
Expand Down Expand Up @@ -153,6 +158,13 @@ def __init__(self, addable: AddableTypes | None = None, *args, **kwargs):
if addable is not None:
self.add(addable, *args, **kwargs)

def count(self, operator_name: str | None = None) -> int | Counter[str]:
"""Count istructions in a circuit"""
count = Counter(instr.operator.name.lower() for instr in self.instructions)
if operator_name is not None:
return count[operator_name.lower()]
return count

@property
def depth(self) -> int:
"""int: Get the circuit depth."""
Expand Down Expand Up @@ -1110,7 +1122,8 @@ def _use_parameter_value(self, param_values: dict[str, Number]) -> Circuit:
if self._check_for_params(instruction):
fixed_circ.add(
Instruction(
instruction.operator.bind_values(**param_values), target=instruction.target
instruction.operator.bind_values(**param_values),
target=instruction.target,
)
)
else:
Expand Down Expand Up @@ -1312,7 +1325,7 @@ def diagram(self, circuit_diagram_class: type = UnicodeCircuitDiagram) -> str:

def to_ir(
self,
ir_type: IRType = IRType.OPENQASM,
ir_type: IRType = IRType.JAQCD,
serialization_properties: SerializationProperties | None = None,
gate_definitions: dict[tuple[Gate, QubitSet], PulseSequence] | None = None,
) -> OpenQasmProgram | JaqcdProgram:
Expand All @@ -1338,10 +1351,6 @@ def to_ir(
"""
gate_definitions = gate_definitions or {}
if ir_type == IRType.JAQCD:
warnings.warn(
"The JAQCD action type is deprecated. Please use OpenQASM 3 programs instead.",
stacklevel=2,
)
return self._to_jaqcd()
if ir_type == IRType.OPENQASM:
if serialization_properties and not isinstance(
Expand Down Expand Up @@ -1411,15 +1420,17 @@ def _to_openqasm(
openqasm_ir_type = IRType.OPENQASM
ir_instructions.extend([
instruction.to_ir(
ir_type=openqasm_ir_type, serialization_properties=serialization_properties
ir_type=openqasm_ir_type,
serialization_properties=serialization_properties,
)
for instruction in self.instructions
])

if self.result_types:
ir_instructions.extend([
result_type.to_ir(
ir_type=openqasm_ir_type, serialization_properties=serialization_properties
ir_type=openqasm_ir_type,
serialization_properties=serialization_properties,
)
for result_type in self.result_types
])
Expand Down Expand Up @@ -1525,12 +1536,15 @@ def _generate_frame_wf_defcal_declarations(
for param in calibration.parameters:
self._parameters.add(param)
arguments = [
param._to_oqpy_expression() if isinstance(param, FreeParameter) else param
(param._to_oqpy_expression() if isinstance(param, FreeParameter) else param)
for param in arguments
]

with oqpy.defcal(
program, [oqpy.PhysicalQubits[int(k)] for k in qubits], gate_name, arguments
program,
[oqpy.PhysicalQubits[int(k)] for k in qubits],
gate_name,
arguments,
):
program += calibration._program

Expand Down Expand Up @@ -1622,7 +1636,11 @@ def _add_fixed_argument_calibrations(
)
additional_calibrations[bound_key] = calibration(**{
p.name if isinstance(p, FreeParameterExpression) else p: v
for p, v in zip(gate.parameters, instruction.operator.parameters, strict=True)
for p, v in zip(
gate.parameters,
instruction.operator.parameters,
strict=True,
)
})
return additional_calibrations

Expand Down Expand Up @@ -1760,7 +1778,9 @@ def subroutine(register: bool = False) -> Callable:
Instruction('operator': 'H', 'target': QubitSet(Qubit(1),))
"""

def _subroutine_function_wrapper(func: Callable[..., SubroutineReturn]) -> SubroutineReturn:
def _subroutine_function_wrapper(
func: Callable[..., SubroutineReturn],
) -> SubroutineReturn:
if register:
Circuit.register_subroutine(func)
return func
Expand Down
Loading
Loading