diff --git a/qdao/circuit.py b/qdao/circuit.py index 38483e3..f370b96 100644 --- a/qdao/circuit.py +++ b/qdao/circuit.py @@ -56,8 +56,8 @@ class BasePartitioner: Base class for circuit partitioning. Attributes: - np (int): Number of partitions. - nl (int): Number of layers. + np (int): Number of primary qubits. + nl (int): Number of local qubits. backend (str): The backend used for the partitioning process. """ @@ -68,22 +68,22 @@ def __init__(self, np=4, nl=2, backend="qiskit") -> None: @property def np(self): - """Gets the number of partitions.""" + """Gets the number of primary qubits.""" return self._np @np.setter def np(self, n): - """Sets the number of partitions.""" + """Sets the number of primary qubits.""" self._np = n @property def nl(self): - """Sets the number of layers.""" + """Sets the number of local qubits.""" return self._nl @nl.setter def nl(self, n): - """Sets the number of layers.""" + """Sets the number of local qubits.""" self._nl = n def run(self, circuit: Any) -> List[QdaoCircuit]: diff --git a/qdao/executor.py b/qdao/executor.py index d49cf52..d0d5da7 100644 --- a/qdao/executor.py +++ b/qdao/executor.py @@ -108,7 +108,7 @@ class ConstantPoolParallelExecutor: """ Executes a function in parallel using a constant-sized thread pool. - When the number of qubits (NQ) is much larger than the number of layers (NL), + When the number of qubits (NQ) is much larger than the number of local qubits (NL), there will be excessive overhead. This class tries to run a thread pool group by group with each group of CPU_COUNT size. """ @@ -154,7 +154,7 @@ class AsyncIoExecutor: """ Executes a function in parallel using asyncio for asynchronous I/O operations. - When the number of qubits (NQ) is much larger than the number of layers (NL), + When the number of qubits (NQ) is much larger than the number of local qubits (NL), there will be excessive overhead. This class tries to run thread pool group by group with each group of CPU_COUNT size. """ diff --git a/qdao/qiskit/annotated_operation.py b/qdao/qiskit/annotated_operation.py index f2351bd..57d7e29 100644 --- a/qdao/qiskit/annotated_operation.py +++ b/qdao/qiskit/annotated_operation.py @@ -10,30 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Annotated Operations -==================== - -This module defines the `AnnotatedOperation` class and various modifier classes -used to create annotated operations in Qiskit. Annotated operations allow the -addition of modifiers to base operations, enabling more abstract representations -and optimizations during transpilation. - -Classes: --------- - -- Modifier: Base class for all modifiers. -- InverseModifier: Modifier to specify that the operation is inverted. -- ControlModifier: Modifier to specify that the operation is controlled. -- PowerModifier: Modifier to specify that the operation is raised to a power. -- AnnotatedOperation: Class representing an annotated operation. - -Functions: ----------- - -- _canonicalize_modifiers: Returns the canonical representative of the modifier list. - -""" +"""Annotated Operations.""" from __future__ import annotations @@ -107,8 +84,8 @@ def __init__(self, base_op: Operation, modifiers: Union[Modifier, List[Modifier] that is immediately followed by its inverse. Args: - base_op (Operation): base operation being modified - modifiers (Union[Modifier, List[Modifier]]): ordered list of modifiers. Supported modifiers include + base_op: base operation being modified + modifiers: ordered list of modifiers. Supported modifiers include ``InverseModifier``, ``ControlModifier`` and ``PowerModifier``. Examples:: @@ -192,14 +169,14 @@ def control( Implemented as an annotated operation, see :class:`.AnnotatedOperation`. Args: - num_ctrl_qubits (int): number of controls to add to gate (default: ``1``) - label (str | None): ignored (used for consistency with other control methods) - ctrl_state (int | str | None): The control state in decimal or as a bitstring + num_ctrl_qubits: number of controls to add to gate (default: ``1``) + label: ignored (used for consistency with other control methods) + ctrl_state: The control state in decimal or as a bitstring (e.g. ``'111'``). If ``None``, use ``2**num_ctrl_qubits-1``. - annotated (bool): ignored (used for consistency with other control methods) + annotated: ignored (used for consistency with other control methods) Returns: - AnnotatedOperation: Controlled version of the given operation. + Controlled version of the given operation. """ # pylint: disable=unused-argument extended_modifiers = self.modifiers.copy() @@ -215,10 +192,10 @@ def inverse(self, annotated: bool = True): Implemented as an annotated operation, see :class:`.AnnotatedOperation`. Args: - annotated (bool): ignored (used for consistency with other inverse methods) + annotated: ignored (used for consistency with other inverse methods) Returns: - AnnotatedOperation: Inverse version of the given operation. + Inverse version of the given operation. """ # pylint: disable=unused-argument extended_modifiers = self.modifiers.copy() @@ -234,12 +211,6 @@ def _canonicalize_modifiers(modifiers): of control qubits / control state and the total power. The InverseModifier will be present if total power is negative, whereas the power modifier will be present only with positive powers different from 1. - - Args: - modifiers (List[Modifier]): List of modifiers to canonicalize. - - Returns: - List[Modifier]: Canonical list of modifiers. """ power = 1 num_ctrl_qubits = 0 @@ -266,4 +237,4 @@ def _canonicalize_modifiers(modifiers): if num_ctrl_qubits > 0: canonical_modifiers.append(ControlModifier(num_ctrl_qubits, ctrl_state)) - return canonical_modifiers + return canonical_modifiers \ No newline at end of file diff --git a/qdao/qiskit/gate.py b/qdao/qiskit/gate.py index d5304de..00a74f1 100644 --- a/qdao/qiskit/gate.py +++ b/qdao/qiskit/gate.py @@ -10,50 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Unitary Gate Module -==================== - -This module provides a `Gate` class to represent unitary gates in quantum circuits. -It includes methods for matrix conversion, exponentiation, control, and argument broadcasting. - -Modules: --------- -- qiskit.circuit.exceptions: Contains exceptions related to quantum circuits. -- qiskit.circuit.parameterexpression: Handles parameter expressions in quantum circuits. -- .annotated_operation: Provides classes for annotated operations. -- .instruction: Defines the base `Instruction` class. - -Classes: --------- -- Gate: Represents a unitary gate in a quantum circuit. - -Methods: --------- -- __init__(self, name: str, num_qubits: int, params: list, label: str | None = None, duration: Any = None, unit: str = "dt") - Create a new gate. -- to_matrix(self) -> np.ndarray - Return a Numpy.array for the gate unitary matrix. -- power(self, exponent: float) - Creates a unitary gate as `gate^exponent`. -- __pow__(self, exponent: float) -> "Gate" - Allows exponentiation using the `**` operator. -- _return_repeat(self, exponent: float) -> "Gate" - Returns a repeated version of the gate. -- control(self, num_ctrl_qubits: int = 1, label: str | None = None, ctrl_state: int | str | None = None, annotated: bool = False) - Return the controlled version of itself. -- _broadcast_single_argument(qarg: list) -> Iterator[tuple[list, list]] - Expands a single argument for broadcasting. -- _broadcast_2_arguments(qarg0: list, qarg1: list) -> Iterator[tuple[list, list]] - Expands two arguments for broadcasting. -- _broadcast_3_or_more_args(qargs: list) -> Iterator[tuple[list, list]] - Expands three or more arguments for broadcasting. -- broadcast_arguments(self, qargs: list, cargs: list) -> Iterable[tuple[list, list]] - Validation and handling of the arguments and their relationships. -- validate_parameter(self, parameter: Any) - Gate parameters should be int, float, or ParameterExpression. - -""" +"""Unitary gate.""" from __future__ import annotations @@ -82,12 +39,10 @@ def __init__( """Create a new gate. Args: - name (str): The Qobj name of the gate. - num_qubits (int): The number of qubits the gate acts on. - params (list): A list of parameters. - label (str | None): An optional label for the gate. - duration (Any): The duration of the gate. - unit (str): The unit of the gate duration. + name: The Qobj name of the gate. + num_qubits: The number of qubits the gate acts on. + params: A list of parameters. + label: An optional label for the gate. """ self.definition = None super().__init__( @@ -154,13 +109,13 @@ def control( Implemented either as a controlled gate (ref. :class:`.ControlledGate`) or as an annotated operation (ref. :class:`.AnnotatedOperation`). - Args: - num_ctrl_qubits (int): number of controls to add to gate (default: ``1``) - label (str | None): optional gate label. Ignored if implemented as an annotated + Args: + num_ctrl_qubits: number of controls to add to gate (default: ``1``) + label: optional gate label. Ignored if implemented as an annotated operation. - ctrl_state (int | str | None): the control state in decimal or as a bitstring + ctrl_state: the control state in decimal or as a bitstring (e.g. ``'111'``). If ``None``, use ``2**num_ctrl_qubits-1``. - annotated (bool): indicates whether the controlled gate can be implemented + annotated: indicates whether the controlled gate can be implemented as an annotated gate. Returns: @@ -184,13 +139,7 @@ def control( @staticmethod def _broadcast_single_argument(qarg: list) -> Iterator[tuple[list, list]]: """Expands a single argument. - - Args: - qarg (list): List of qubit arguments. - - Returns: - Iterator[tuple[list, list]]: Iterator of expanded arguments. - + For example: [q[0], q[1]] -> [q[0]], [q[1]] """ # [q[0], q[1]] -> [q[0]] @@ -200,18 +149,6 @@ def _broadcast_single_argument(qarg: list) -> Iterator[tuple[list, list]]: @staticmethod def _broadcast_2_arguments(qarg0: list, qarg1: list) -> Iterator[tuple[list, list]]: - """Expands two arguments for broadcasting. - - Args: - qarg0 (list): First list of qubit arguments. - qarg1 (list): Second list of qubit arguments. - - Returns: - Iterator[tuple[list, list]]: Iterator of expanded arguments. - - Raises: - CircuitError: If the arguments cannot be combined. - """ if len(qarg0) == len(qarg1): # [[q[0], q[1]], [r[0], r[1]]] -> [q[0], r[0]] # -> [q[1], r[1]] @@ -234,18 +171,6 @@ def _broadcast_2_arguments(qarg0: list, qarg1: list) -> Iterator[tuple[list, lis @staticmethod def _broadcast_3_or_more_args(qargs: list) -> Iterator[tuple[list, list]]: - """Expands three or more arguments for broadcasting. - - Args: - qargs (list): List of lists of qubit arguments. - - Returns: - Iterator[tuple[list, list]]: Iterator of expanded arguments. - - Raises: - CircuitError: If the arguments cannot be combined. - """ - if all(len(qarg) == len(qargs[0]) for qarg in qargs): for arg in zip(*qargs): yield list(arg), [] @@ -283,16 +208,15 @@ def broadcast_arguments( [q[0], q[1]], [r[0], r[1]], ...] -> [q[0], r[0], ...], [q[1], r[1], ...] Args: - qargs (list): List of quantum bit arguments. - cargs (list): List of classical bit arguments. + qargs: List of quantum bit arguments. + cargs: List of classical bit arguments. Returns: - Iterable[tuple[list, list]]: A tuple with single arguments. + A tuple with single arguments. Raises: CircuitError: If the input is not valid. For example, the number of arguments does not match the gate expectation. - """ if len(qargs) != self.num_qubits or cargs: raise CircuitError( @@ -317,14 +241,7 @@ def broadcast_arguments( raise CircuitError("This gate cannot handle %i arguments" % len(qargs)) def validate_parameter(self, parameter): - """Gate parameters should be int, float, or ParameterExpression - - Args: - parameter (Any): Parameter to validate. - - Raises: - CircuitError: If the parameter is invalid. - """ + """Gate parameters should be int, float, or ParameterExpression""" if isinstance(parameter, ParameterExpression): if len(parameter.parameters) > 0: return ( @@ -341,4 +258,4 @@ def validate_parameter(self, parameter): else: raise CircuitError( f"Invalid param type {type(parameter)} for gate {self.name}." - ) + ) \ No newline at end of file diff --git a/qdao/qiskit/instruction.py b/qdao/qiskit/instruction.py index 560a378..c191eaa 100644 --- a/qdao/qiskit/instruction.py +++ b/qdao/qiskit/instruction.py @@ -11,10 +11,7 @@ # that they have been altered from the originals. """ -Qiskit Instruction Module -========================== - -This module contains the definition and functionality of a generic quantum instruction. +A generic quantum instruction. Instructions can be implementable on hardware (u, cx, etc.) or in simulation (snapshot, noise, etc.). @@ -681,4 +678,4 @@ def _compare_parameters(self, other): except TypeError: if x != y: return False - return True + return True \ No newline at end of file diff --git a/qdao/qiskit/simulator.py b/qdao/qiskit/simulator.py index 84fe6d2..7eb4679 100644 --- a/qdao/qiskit/simulator.py +++ b/qdao/qiskit/simulator.py @@ -1,24 +1,3 @@ -""" -Qiskit Simulator Module -======================== - -This module provides a `QiskitSimulator` class to interface with Qiskit's Aer simulator and other -potential simulators. It includes methods for initialization and running simulations. - -Modules: --------- -- logging: Provides logging capabilities. -- typing: Includes the Optional type hint. -- numpy: Handles numerical operations and arrays. -- qiskit_aer: Provides access to Qiskit's Aer simulator. -- qdao.exceptions: Contains custom exceptions for the quantum DAO (Qdao) module. - -Classes: --------- -- QiskitSimulator: Interfaces with Qiskit simulators for running quantum circuit simulations. - - -""" import logging from typing import Optional @@ -28,36 +7,12 @@ class QiskitSimulator: - """ - A class to interface with Qiskit's Aer simulator and other potential simulators. - - Attributes: - ----------- - _sim : Backend - The backend simulator used for running quantum simulations. - - Methods: - -------- - __init__(self, provider: Optional[str] = None, fusion: Optional[bool] = False, device: str = "CPU") -> None - Initializes the simulator with the specified provider, fusion option, and device type. - - run(self, simobj) -> np.ndarray - Runs a simulation on the provided simulation object and returns the resulting state vector. - """ def __init__( self, provider: Optional[str] = None, fusion: Optional[bool] = False, device: str = "CPU", ) -> None: - """ - Initialize the QiskitSimulator. - - Args: - provider (Optional[str]): The simulator provider to use (e.g., 'ddsim'). Defaults to None. - fusion (Optional[bool]): Whether to enable fusion optimizations. Defaults to False. - device (str): The device to use for simulation ('CPU' or 'GPU'). Defaults to 'CPU'. - """ if provider: if provider == "ddsim": from mqt import ddsim @@ -71,18 +26,6 @@ def __init__( self._sim.set_options(device=device) def run(self, simobj) -> np.ndarray: - """ - Run a simulation on the provided simulation object. - - Args: - simobj: The simulation object containing the quantum circuit to simulate. - - Returns: - np.ndarray: The resulting state vector from the simulation. - - Raises: - QdaoError: If the simulation fails. - """ res = self._sim.run(simobj.circ).result() if not res.success: raise QdaoError( @@ -93,4 +36,4 @@ def run(self, simobj) -> np.ndarray: except Exception as e: sv = np.zeros(1 << simobj.circ.num_qubits) logging.info(f"No state vector for this sub-circuit: {e}") - return sv + return sv \ No newline at end of file diff --git a/qdao/qiskit/utils.py b/qdao/qiskit/utils.py index a976c93..93020ec 100644 --- a/qdao/qiskit/utils.py +++ b/qdao/qiskit/utils.py @@ -10,23 +10,7 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -""" -Utility Functions for Generating Random Circuits -================================================= - -This module provides utility functions for generating random quantum circuits. - -Modules: --------- -- numpy: Handles numerical operations and arrays. -- qiskit.circuit: Provides the QuantumCircuit, QuantumRegister, ClassicalRegister, and exceptions for quantum circuits. -- qiskit.circuit.library.standard_gates: Contains standard gates for quantum circuits. - -Functions: ----------- -- random_circuit(num_qubits: int, depth: int, max_operands: int = 3, measure: bool = False, conditional: bool = False, reset: bool = False, seed: int = None) -> QuantumCircuit - Generate a random quantum circuit with the specified parameters. -""" +"""Utility functions for generating random circuits.""" import numpy as np from qiskit.circuit import ClassicalRegister, QuantumCircuit, QuantumRegister, Reset @@ -82,20 +66,20 @@ def random_circuit( circ = random_circuit(2, 2, measure=True) circ.draw(output='mpl') - Args: - num_qubits (int): Number of quantum wires. - depth (int): Layers of operations (i.e. critical path length). - max_operands (int): Maximum operands of each gate (between 1 and 3). Defaults to 3. - measure (bool): If True, measure all qubits at the end. Defaults to False. - conditional (bool): If True, insert middle measurements and conditionals. Defaults to False. - reset (bool): If True, insert middle resets. Defaults to False. - seed (int): Sets random seed (optional). Defaults to None. + Args: + num_qubits (int): number of quantum wires + depth (int): layers of operations (i.e. critical path length) + max_operands (int): maximum operands of each gate (between 1 and 3) + measure (bool): if True, measure all qubits at the end + conditional (bool): if True, insert middle measurements and conditionals + reset (bool): if True, insert middle resets + seed (int): sets random seed (optional) Returns: - QuantumCircuit: Constructed random quantum circuit. + QuantumCircuit: constructed circuit Raises: - CircuitError: When invalid options are given. + CircuitError: when invalid options given """ if max_operands < 1 or max_operands > 3: raise CircuitError("max_operands must be between 1 and 3") @@ -174,4 +158,4 @@ def random_circuit( if measure: qc.measure(qr, cr) - return qc + return qc \ No newline at end of file diff --git a/qdao/simulator.py b/qdao/simulator.py index 851312b..be3bca0 100644 --- a/qdao/simulator.py +++ b/qdao/simulator.py @@ -35,10 +35,6 @@ class QdaoSimObj: This class encapsulates the quantum circuit and any additional options required to run the simulation. - Attributes: - _objs (tuple): Tuple containing the simulation objects. - _circ (Any): The quantum circuit object. - _run_options (dict): Options for running the simulation. """ def __init__(self, *objs, **options) -> None: @@ -82,8 +78,6 @@ class SimulatorProvider: Methods: get_simulator: Returns an instance of the specified simulator backend. - Attributes: - SIMS (dict): Dictionary mapping backend names to simulator classes. """ @classmethod