A class using the builder pattern to make construction of circuits easy from Python.
Adds corresponding instruction when a method is called. Checks that instructions are known and
called with the right arguments.
Mainly here to allow for Qiskit-style circuit construction:
Parameters:
| Name |
Type |
Description |
Default |
qubit_register_size
|
int
|
Size of the qubit register
|
0
|
bit_register_size
|
int
|
|
0
|
Example
>>> CircuitBuilder(qubit_register_size=3, bit_register_size=3).H(0).CNOT(0, 1).CNOT(0, 2).to_circuit()
version 3.0
qubit[3] q
h q[0]
cnot q[0], q[1]
cnot q[0], q[2]
Source code in opensquirrel/circuit_builder.py
| class CircuitBuilder:
"""
A class using the builder pattern to make construction of circuits easy from Python.
Adds corresponding instruction when a method is called. Checks that instructions are known and
called with the right arguments.
Mainly here to allow for Qiskit-style circuit construction:
Args:
qubit_register_size (int): Size of the qubit register
bit_register_size (int): Size of the bit register
Example:
```python
>>> CircuitBuilder(qubit_register_size=3, bit_register_size=3).H(0).CNOT(0, 1).CNOT(0, 2).to_circuit()
```
```
version 3.0
qubit[3] q
h q[0]
cnot q[0], q[1]
cnot q[0], q[2]
```
"""
def __init__(
self,
qubit_register_size: int = 0,
bit_register_size: int = 0,
) -> None:
initial_qubit_registry = (
OrderedDict({DEFAULT_QUBIT_REGISTER_NAME: QubitRegister(qubit_register_size)})
if (qubit_register_size > 0)
else OrderedDict()
)
initial_bit_registry = (
OrderedDict({DEFAULT_BIT_REGISTER_NAME: BitRegister(bit_register_size)})
if (bit_register_size > 0)
else OrderedDict()
)
self.register_manager = RegisterManager(
initial_qubit_registry,
initial_bit_registry,
)
self.ir = IR()
def __dir__(self) -> list[str]:
return super().__dir__() + list(_builder_dynamic_attributes) # type: ignore
def __getattr__(self, attr: str) -> Any:
if attr in _builder_dynamic_attributes:
return partial(self._add_statement, attr)
# Default behaviour
return self.__getattribute__(attr)
def add_register(self, register: QubitRegister | BitRegister) -> None:
"""Add a (qu)bit register to the circuit builder.
Args:
register (QubitRegister | BitRegister): (Qu)bit register to add.
"""
self.register_manager.add_register(register)
def _check_qubit_out_of_bounds_access(self, qubit: QubitLike) -> None:
"""Throw error if qubit index is outside the qubit register range.
Args:
qubit: qubit to check.
"""
index = Qubit(qubit).index
qubit_register_size = self.register_manager.qubit_register_size
if index >= qubit_register_size:
msg = f"qubit index {index!r} is out of bounds: must be smaller than {qubit_register_size!r}"
raise IndexError(msg)
def _check_bit_out_of_bounds_access(self, bit: BitLike) -> None:
"""Throw error if bit index is outside the bit register range.
Args:
bit: bit to check.
"""
index = Bit(bit).index
bit_register_size = self.register_manager.bit_register_size
if index >= bit_register_size:
msg = f"bit index {index!r} is out of bounds: must be smaller than {bit_register_size!r}"
raise IndexError(msg)
def _check_out_of_bounds_access(self, instruction: Instruction) -> None:
for qubit in instruction.qubit_operands:
self._check_qubit_out_of_bounds_access(qubit)
for bit in instruction.bit_operands:
self._check_bit_out_of_bounds_access(bit)
def _add_statement(self, attr: str, *args: Any) -> Self:
if attr == "asm":
try:
asm_declaration = AsmDeclaration(*args)
self.ir.add_asm_declaration(asm_declaration)
except TypeError:
msg = f"trying to build {attr!r} with the wrong number or type of arguments: {args!r}"
raise TypeError(msg) from None
return self
if attr not in default_instruction_set:
msg = f"unknown instruction {attr!r}"
raise ValueError(msg)
try:
instruction = default_instruction_set[attr](*args)
except TypeError as e:
msg = f"trying to build {attr!r} with the wrong number or type of arguments: {args!r}: {e}"
raise TypeError(msg) from e
self._check_out_of_bounds_access(instruction)
self.ir.add_statement(instruction)
return self
def to_circuit(self) -> Circuit:
"""Build the circuit.
Returns:
Circuit: The built circuit.
"""
return Circuit(deepcopy(self.register_manager), deepcopy(self.ir))
|
add_register
add_register(register: QubitRegister | BitRegister) -> None
Add a (qu)bit register to the circuit builder.
Parameters:
Source code in opensquirrel/circuit_builder.py
| def add_register(self, register: QubitRegister | BitRegister) -> None:
"""Add a (qu)bit register to the circuit builder.
Args:
register (QubitRegister | BitRegister): (Qu)bit register to add.
"""
self.register_manager.add_register(register)
|
to_circuit
Build the circuit.
Returns:
| Name | Type |
Description |
Circuit |
Circuit
|
|
Source code in opensquirrel/circuit_builder.py
| def to_circuit(self) -> Circuit:
"""Build the circuit.
Returns:
Circuit: The built circuit.
"""
return Circuit(deepcopy(self.register_manager), deepcopy(self.ir))
|