diff --git a/.gitignore b/.gitignore index f1899e4400..25e5e9fa19 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ __pycache__/ /source/fuzz/artifacts /source/fuzz/coverage /source/fuzz/Cargo.lock +/source/pip/doc /source/samples_test/src/tests/*_generated.rs .mypy_cache/ .pytest_cache/ @@ -22,3 +23,4 @@ __pycache__/ *.so samples/scratch/ *.pyd +/python_doc/ diff --git a/source/pip/qsharp/_adaptive_pass.py b/source/pip/qsharp/_adaptive_pass.py index 81c7c4b6f6..5a7a63ba55 100644 --- a/source/pip/qsharp/_adaptive_pass.py +++ b/source/pip/qsharp/_adaptive_pass.py @@ -292,13 +292,13 @@ def run( ) -> AdaptiveProgram: """Process module and return the AdaptiveProgram. - Args: - mod: The QIR module to process. - noise: Optional NoiseConfig. When provided, noise intrinsic calls - are resolved to correlated noise ops using the intrinsics table. - noise_intrinsics: Optional dict mapping noise intrinsic callee names - to noise table IDs. Takes precedence over ``noise`` if both are - given. + :param mod: The QIR module to process. + :param noise: Optional NoiseConfig. When provided, noise intrinsic calls + are resolved to correlated noise ops using the intrinsics table. + :param noise_intrinsics: Optional dict mapping noise intrinsic callee names + to noise table IDs. Takes precedence over ``noise`` if both are given. + :return: The processed adaptive program. + :rtype: AdaptiveProgram """ if mod.get_flag("arrays"): raise ValueError("QIR arrays are not currently supported.") diff --git a/source/pip/qsharp/_device/_atom/__init__.py b/source/pip/qsharp/_device/_atom/__init__.py index 6a8b0ae80c..bea15a145c 100644 --- a/source/pip/qsharp/_device/_atom/__init__.py +++ b/source/pip/qsharp/_device/_atom/__init__.py @@ -244,7 +244,7 @@ def simulate( If `None` (default), the GPU simulator will be tried first, falling back to CPU if a suitable GPU device could not be located. :param seed: An optional random seed for reproducibility. - :returns: The results of each shot of the simulation as a list. + :return: The results of each shot of the simulation as a list. """ from ._validate import ValidateNoConditionalBranches diff --git a/source/pip/qsharp/_device/_atom/_scheduler.py b/source/pip/qsharp/_device/_atom/_scheduler.py index 77282010fb..0b507c48f2 100644 --- a/source/pip/qsharp/_device/_atom/_scheduler.py +++ b/source/pip/qsharp/_device/_atom/_scheduler.py @@ -147,13 +147,11 @@ class MoveGroup: """ Represents a group of moves that can be done at the same time. - Attributes: - moves (set): A set of moves that can be performed in parallel. - scale_factor (Optional[tuple[Fraction, Fraction]]): A tuple of fractions - representing the scale factors in the row and col axes between - moves. `None`, if there is a single element in the move set. - ref_move (Move): A move used as a representative of the group, used - to test compatibility of other moves with the group. + ``moves`` is the set of moves that can be performed in parallel. + ``scale_factor`` is a tuple of fractions representing the scale factors in the + row and col axes between moves, or ``None`` if there is a single element in the set. + ``ref_move`` is a move used as a representative of the group to test compatibility + of other moves. """ __slots__ = ("moves", "scale_factor", "ref_move") @@ -170,8 +168,7 @@ def add(self, move: Move): """ Adds a move to this move group. - Args: - move (Move): The move to add. + :param move: The move to add. """ # A move group with a single move doesn't have an associated scale factor. @@ -193,23 +190,17 @@ class MoveGroupPool: """A data structure that takes individual moves as input and organizes them into groups of moves that can be executed in parallel. - Attributes: - moves: A set containing all the moves in the move-group pool. - move_group_candidates: A dict organizing the move-group candidates - by scale factor. - parity: The parity of source and destination columns of all the moves - in this pool. - direction: The up/down and left/right direction of all the moves - in this pool. + ``moves`` contains all moves in the pool. ``move_group_candidates`` is a dict + organizing the move-group candidates by scale factor. ``parity`` is the parity + of source and destination columns of all moves in the pool. ``direction`` is the + up/down and left/right direction of all moves in the pool. """ def __init__(self): - """Initializes a move-group pool for moves of the given `parity` and `direction`. - Args: - parity: The parity of source and destination columns of all the moves - in this pool. - direction: The up/down and left/right direction of all the moves - in this pool. + """Initializes a move-group pool for moves of the given ``parity`` and ``direction``. + + :param parity: The parity of source and destination columns of all the moves in this pool. + :param direction: The up/down and left/right direction of all the moves in this pool. """ self.moves: Optional[list[Move]] = [] self.move_group_candidates: dict[MoveGroupScaleFactor, list[MoveGroup]] = ( @@ -235,9 +226,9 @@ def largest_move_group_candidate(self) -> Optional[MoveGroup]: def add(self, move: Move): """Adds a move to the move-group pool. - Args: - move: The move to add. It must be of the same parity and direction as - the rest of the moves in this pool. + + :param move: The move to add. It must be of the same parity and direction as + the rest of the moves in this pool. """ assert self.moves is not None @@ -285,9 +276,9 @@ def add(self, move: Move): self.moves.append(move) def try_take(self, number_of_moves: int) -> list[Move]: - """Take up to `number_of_moves` from the largest move group candidate. - Args: - number_of_moves: The number of moves to take from this pool. + """Take up to ``number_of_moves`` from the largest move group candidate. + + :param number_of_moves: The number of moves to take from this pool. """ # Once we start taking moves from the MoveGroupPool, we don't need to add # new moves. So we set `self.moves` to `None` as a safety measure. @@ -352,12 +343,10 @@ class MoveScheduler: target zone and builds an iterator that returns groups of moves that can be executed in parallel. - Attributes: - device: An object containing information about the device. - zone: The zone the moves will be scheduled to. - available_dst_locations: The available destinations in the `zone`. - partial_moves: The moves that haven't been assigned a destination location. - disjoint_pools: A list containing one pool of move-groups for each parity and direction. + ``device`` contains information about the device. ``zone`` is the target zone. + ``available_dst_locations`` holds the available destinations in the zone. + ``partial_moves`` are moves not yet assigned a destination. ``disjoint_pools`` + is a list containing one pool of move-groups for each parity and direction. """ def __init__( @@ -368,10 +357,10 @@ def __init__( ): """Initializes the move scheduler from a device, a target zone, and a list of qubits to move to that target zone. - Args: - device: An object containing information about the device. - zone: The zone the moves will be scheduled to. - qubits_to_move: A list of qubits to move. + + :param device: An object containing information about the device. + :param zone: The zone the moves will be scheduled to. + :param qubits_to_move: A list of qubits to move. """ self.device = device self.zone = zone diff --git a/source/pip/qsharp/_device/_device.py b/source/pip/qsharp/_device/_device.py index 5cc091e71c..991dc46b24 100644 --- a/source/pip/qsharp/_device/_device.py +++ b/source/pip/qsharp/_device/_device.py @@ -58,11 +58,9 @@ def get_home_loc(self, qubit_id: int) -> tuple[int, int]: """ Get the home location (row, column) of the qubit with the given id. - Args: - qubit_id (int): The id of the qubit. - - Returns: - tuple[int, int]: The (row, column) location of the qubit. + :param qubit_id: The id of the qubit. + :return: The (row, column) location of the qubit. + :rtype: tuple[int, int] """ if qubit_id < 0 or qubit_id >= len(self.home_locs): raise ValueError(f"Qubit id {qubit_id} is out of range") @@ -72,11 +70,9 @@ def get_ordering(self, qubit_id: int) -> int: """ Get the ordering index of the qubit with the given id. - Args: - qubit_id (int): The id of the qubit. - - Returns: - int: The ordering index of the qubit. + :param qubit_id: The id of the qubit. + :return: The ordering index of the qubit. + :rtype: int """ if qubit_id < 0 or qubit_id >= len(self.home_locs): raise ValueError(f"Qubit id {qubit_id} is out of range") @@ -87,8 +83,8 @@ def get_register_zones(self) -> list[Zone]: """ Get the register zones in the device. - Returns: - list[Zone]: The register zones. + :return: The register zones. + :rtype: list[Zone] """ return [zone for zone in self.zones if zone.type == ZoneType.REG] @@ -96,8 +92,8 @@ def get_interaction_zones(self) -> list[Zone]: """ Get the interaction zones in the device. - Returns: - list[Zone]: The interaction zones. + :return: The interaction zones. + :rtype: list[Zone] """ return [zone for zone in self.zones if zone.type == ZoneType.INTER] @@ -105,8 +101,8 @@ def get_measurement_zones(self) -> list[Zone]: """ Get the measurement zones in the device. - Returns: - list[Zone]: The measurement zones. + :return: The measurement zones. + :rtype: list[Zone] """ return [zone for zone in self.zones if zone.type == ZoneType.MEAS] @@ -114,8 +110,7 @@ def compile(self, program: str) -> QirInputData: """ Compile the given program for the device. - Args: - program (str): The program to compile. + :param program: The program to compile. """ raise NotImplementedError("Subclasses must implement compile") @@ -123,8 +118,8 @@ def as_dict(self) -> dict: """ Get the device layout as a dictionary. - Returns: - dict: The device layout as a dictionary. + :return: The device layout as a dictionary. + :rtype: dict """ return { "cols": self.column_count, @@ -138,7 +133,7 @@ def get_layout(self) -> dict: """ Get the device layout as a dictionary. - Returns: - dict: The device layout as a dictionary. + :return: The device layout as a dictionary. + :rtype: dict """ return self.as_dict() diff --git a/source/pip/qsharp/_fs.py b/source/pip/qsharp/_fs.py index 3f14a01df3..c317007fd1 100644 --- a/source/pip/qsharp/_fs.py +++ b/source/pip/qsharp/_fs.py @@ -18,11 +18,9 @@ def read_file(path: str) -> Tuple[str, str]: """ Read the contents of a file. - Args: - path (str): The path to the file. - - Returns: - Tuple[str, str]: A tuple containing the path and the file contents. + :param path: The path to the file. + :return: A tuple containing the path and the file contents. + :rtype: Tuple[str, str] """ with open(path, mode="r", encoding="utf-8-sig") as f: return (path, f.read()) @@ -33,15 +31,13 @@ def list_directory(dir_path: str) -> List[Dict[str, str]]: Lists the contents of a directory and returns a list of dictionaries, where each dictionary represents an entry in the directory. - Args: - dir_path (str): The path of the directory to list. - - Returns: - List[Dict[str, str]]: A list of dictionaries representing the entries - in the directory. Each dictionary contains the following keys: - - "path": The full path of the entry. - - "entry_name": The name of the entry. - - "type": The type of the entry: "file", "folder", or "unknown". + :param dir_path: The path of the directory to list. + :return: A list of dictionaries representing the entries in the directory. + Each dictionary contains the following keys: + - ``"path"``: The full path of the entry. + - ``"entry_name"``: The name of the entry. + - ``"type"``: The type of the entry: ``"file"``, ``"folder"``, or ``"unknown"``. + :rtype: List[Dict[str, str]] """ def map_dir(e: str) -> Dict[str, str]: @@ -63,12 +59,10 @@ def resolve(base: str, path: str) -> str: """ Resolves a relative path with respect to a base path. - Args: - base (str): The base path. - path (str): The relative path. - - Returns: - str: The resolved path. + :param base: The base path. + :param path: The relative path. + :return: The resolved path. + :rtype: str """ return os.path.normpath(join(base, path)) @@ -77,11 +71,9 @@ def exists(path) -> bool: """ Check if a file or directory exists at the given path. - Args: - path (str): The path to the file or directory. - - Returns: - bool: True if the file or directory exists, False otherwise. + :param path: The path to the file or directory. + :return: ``True`` if the file or directory exists, ``False`` otherwise. + :rtype: bool """ return os.path.exists(path) @@ -90,11 +82,9 @@ def join(path: str, *paths) -> str: """ Joins one or more path components intelligently. - Args: - path (str): The base path. - *paths (str): Additional path components to be joined. - - Returns: - str: The concatenated path. + :param path: The base path. + :param *paths: Additional path components to be joined. + :return: The concatenated path. + :rtype: str """ return os.path.join(path, *paths) diff --git a/source/pip/qsharp/_http.py b/source/pip/qsharp/_http.py index 0969b0bb3f..240ddcc67f 100644 --- a/source/pip/qsharp/_http.py +++ b/source/pip/qsharp/_http.py @@ -13,18 +13,14 @@ def fetch_github(owner: str, repo: str, ref: str, path: str) -> str: """ Fetches the content of a file from a GitHub repository. - Args: - owner (str): The owner of the GitHub repository. - repo (str): The name of the GitHub repository. - ref (str): The reference (branch, tag, or commit) of the repository. - path (str): The path to the file within the repository. - - Returns: - str: The content of the file as a string. - - Raises: - urllib.error.HTTPError: If there is an error fetching the file from GitHub. - urllib.error.URLError: If there is an error with the URL. + :param owner: The owner of the GitHub repository. + :param repo: The name of the GitHub repository. + :param ref: The reference (branch, tag, or commit) of the repository. + :param path: The path to the file within the repository. + :return: The content of the file as a string. + :rtype: str + :raises urllib.error.HTTPError: If there is an error fetching the file from GitHub. + :raises urllib.error.URLError: If there is an error with the URL. """ import urllib.request diff --git a/source/pip/qsharp/_native.pyi b/source/pip/qsharp/_native.pyi index acb771a961..a84d950584 100644 --- a/source/pip/qsharp/_native.pyi +++ b/source/pip/qsharp/_native.pyi @@ -257,13 +257,13 @@ class Interpreter: :param entry_expr: An entry expression. - :param operation: The operation to synthesize. This can be a name of - an operation of a lambda expression. The operation must take only - qubits or arrays of qubits as parameters. + :keyword operation: The operation to synthesize. This can be a name of + an operation of a lambda expression. The operation must take only + qubits or arrays of qubits as parameters. - :param callable: The callable to synthesize the circuit for, if no entry expression is provided. + :keyword callable: The callable to synthesize the circuit for, if no entry expression is provided. - :param args: The arguments to pass to the callable, if any. + :keyword args: The arguments to pass to the callable, if any. :raises QSharpError: If there is an error synthesizing the circuit. """ @@ -327,7 +327,7 @@ class Interpreter: """ Returns the sparse state vector of the simulator as a StateDump object. - :returns: The state of the simulator. + :return: The state of the simulator. """ ... @@ -339,6 +339,8 @@ class Interpreter: in the simulator up to the current point. Requires the interpreter to be initialized with `trace_circuit=True`. + + :raises QSharpError: If the interpreter was not initialized with ``trace_circuit=True``. """ ... @@ -355,26 +357,21 @@ class Interpreter: """ Imports OpenQASM source code into the active Q# interpreter. - Args: - source (str): An OpenQASM program or fragment. - output_fn: The function to handle the output of the execution. - read_file: A callable that reads a file and returns its content and path. - list_directory: A callable that lists the contents of a directory. - resolve_path: A callable that resolves a file path given a base path and a relative path. - fetch_github: A callable that fetches a file from GitHub. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the program. This is used as the entry point for the program. - - search_path (Optional[str]): The optional search path for resolving file references. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - program_type (ProgramType, optional): The type of program compilation to perform. - - Returns: - value: The value returned by the last statement in the source code. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error compiling the program. - QSharpError: If there is an error evaluating the source code. + :param source: An OpenQASM program or fragment. + :param output_fn: The function to handle the output of the execution. + :param read_file: A callable that reads a file and returns its content and path. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a file path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: + + - ``name`` (str): The name of the program. + - ``search_path`` (str): The optional search path for resolving file references. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + - ``program_type`` (ProgramType): The type of program compilation to perform. + :return: The value returned by the last statement in the source code. + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error compiling or evaluating the program. """ ... @@ -432,6 +429,10 @@ class StateDumpData: def _repr_latex_(self) -> Optional[str]: ... class CircuitConfig: + """ + Configuration options for circuit generation. + """ + def __init__( self, *, @@ -442,10 +443,6 @@ class CircuitConfig: prune_classical_qubits: bool = False, ) -> None: ... - """ - Configuration options for circuit generation. - """ - max_operations: Optional[int] """ The maximum number of operations to include in the generated circuit. @@ -484,6 +481,12 @@ class CircuitGenerationMethod(Enum): """ class Circuit: + """ + A quantum circuit diagram generated from a Q# or OpenQASM program. + + Returned by :func:`qsharp.circuit` and :func:`qsharp.dump_circuit`. + """ + def json(self) -> str: ... def __repr__(self) -> str: ... def __str__(self) -> str: ... @@ -509,7 +512,8 @@ def physical_estimates(logical_resources: str, params: str) -> str: :param logical_resources: The logical resources to estimate from. :param params: The parameters to configure physical estimation. - :returns resources: The estimated resources. + :return: The estimated resources. + :rtype: str """ ... @@ -524,28 +528,24 @@ def circuit_qasm_program( """ Synthesizes a circuit for an OpenQASM program. - Note: + .. note:: This call while exported is not intended to be used directly by the user. It is intended to be used by the Python wrapper which will handle the callbacks and other Python specific details. - Args: - source (str): An OpenQASM program. Alternatively, a callable can be provided, - which must be an already imported global callable. - read_file (Callable[[str], Tuple[str, str]]): A callable that reads a file and returns its content and path. - list_directory (Callable[[str], List[Dict[str, str]]]): A callable that lists the contents of a directory. - resolve_path (Callable[[str, str], str]): A callable that resolves a file path given a base path and a relative path. - fetch_github (Callable[[str, str, str, str], str]): A callable that fetches a file from GitHub. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the program. This is used as the entry point for the program. - - search_path (Optional[str]): The optional search path for resolving file references. - Returns: - Circuit: The synthesized circuit. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error evaluating the program. - QSharpError: If there is an error synthesizing the circuit. + :param source: An OpenQASM program. + :param read_file: A callable that reads a file and returns its content and path. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a file path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: + + - ``name`` (str): The name of the program. + - ``search_path`` (str): The optional search path for resolving file references. + :return: The synthesized circuit. + :rtype: Circuit + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error evaluating or synthesizing the circuit. """ ... @@ -561,29 +561,26 @@ def compile_qasm_program_to_qir( Compiles the OpenQASM source code into a program that can be submitted to a target as QIR (Quantum Intermediate Representation). - Note: + .. note:: This call while exported is not intended to be used directly by the user. It is intended to be used by the Python wrapper which will handle the callbacks and other Python specific details. - Args: - source (str): The OpenQASM source code to estimate the resource requirements for. - read_file (Callable[[str], Tuple[str, str]]): A callable that reads a file and returns its content and path. - list_directory (Callable[[str], List[Dict[str, str]]]): A callable that lists the contents of a directory. - resolve_path (Callable[[str, str], str]): A callable that resolves a file path given a base path and a relative path. - fetch_github (Callable[[str, str, str, str], str]): A callable that fetches a file from GitHub. - **kwargs: Additional keyword arguments to pass to the compilation when source program is provided. - - name (str): The name of the circuit. This is used as the entry point for the program. - - target_profile (TargetProfile): The target profile to use for code generation. - - search_path (Optional[str]): The optional search path for resolving file references. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - Returns: - str: The converted QIR code as a string. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error compiling the program. + :param source: The OpenQASM source code to compile to QIR. + :param read_file: A callable that reads a file and returns its content and path. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a file path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: + + - ``name`` (str): The name of the circuit. + - ``target_profile`` (TargetProfile): The target profile to use for code generation. + - ``search_path`` (str): The optional search path for resolving file references. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + :return: The converted QIR code as a string. + :rtype: str + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error compiling the program. """ ... @@ -598,23 +595,22 @@ def compile_qasm_to_qsharp( """ Converts a OpenQASM program to Q#. - Note: + .. note:: This call while exported is not intended to be used directly by the user. It is intended to be used by the Python wrapper which will handle the callbacks and other Python specific details. - Args: - source (str): The OpenQASM source code to estimate the resource requirements for. - read_file (Callable[[str], Tuple[str, str]]): A callable that reads a file and returns its content and path. - list_directory (Callable[[str], List[Dict[str, str]]]): A callable that lists the contents of a directory. - resolve_path (Callable[[str, str], str]): A callable that resolves a file path given a base path and a relative path. - fetch_github (Callable[[str, str, str, str], str]): A callable that fetches a file from GitHub. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the circuit. This is used as the entry point for the program. - - search_path (Optional[str]): The optional search path for resolving file references. + :param source: The OpenQASM source code to convert. + :param read_file: A callable that reads a file and returns its content and path. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a file path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: - Returns: - str: The converted Q# code as a string. + - ``name`` (str): The name of the circuit. + - ``search_path`` (str): The optional search path for resolving file references. + :return: The converted Q# code as a string. + :rtype: str """ ... @@ -630,23 +626,23 @@ def resource_estimate_qasm_program( """ Estimates the resource requirements for executing OpenQASM source code. - Note: + .. note:: This call while exported is not intended to be used directly by the user. It is intended to be used by the Python wrapper which will handle the callbacks and other Python specific details. - Args: - source (str): The OpenQASM source code to estimate the resource requirements for. - job_params (str): The parameters for the job. - read_file (Callable[[str], Tuple[str, str]]): A callable that reads a file and returns its content and path. - list_directory (Callable[[str], List[Dict[str, str]]]): A callable that lists the contents of a directory. - resolve_path (Callable[[str, str], str]): A callable that resolves a file path given a base path and a relative path. - fetch_github (Callable[[str, str, str, str], str]): A callable that fetches a file from GitHub. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the circuit. This is used as the entry point for the program. Defaults to 'program'. - - search_path (str): The optional search path for resolving imports. - Returns: - str: The estimated resource requirements for executing the OpenQASM source code. + :param source: The OpenQASM source code to estimate resource requirements for. + :param job_params: The parameters for the job as a JSON string. + :param read_file: A callable that reads a file and returns its content and path. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a file path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: + + - ``name`` (str): The name of the circuit. Defaults to ``'program'``. + - ``search_path`` (str): The optional search path for resolving imports. + :return: The estimated resource requirements as a JSON string. + :rtype: str """ ... @@ -666,34 +662,32 @@ def run_qasm_program( Runs the given OpenQASM program for the given number of shots. Each shot uses an independent instance of the simulator. - Note: + .. note:: This call while exported is not intended to be used directly by the user. It is intended to be used by the Python wrapper which will handle the callbacks and other Python specific details. - Args: - source (str): The OpenQASM source code to execute. - output_fn (Callable[[Output], None]): The function to handle the output of the execution. - noise: The noise to use in simulation. - qubit_loss: The probability of qubit loss in simulation. - read_file (Callable[[str], Tuple[str, str]]): The function to read a file and return its contents. - list_directory (Callable[[str], List[Dict[str, str]]]): The function to list the contents of a directory. - resolve_path (Callable[[str, str], str]): The function to resolve a path given a base path and a relative path. - fetch_github (Callable[[str, str, str, str], str]): The function to fetch a file from GitHub. - **kwargs: Additional keyword arguments to pass to the execution. - - target_profile (TargetProfile): The target profile to use for execution. - - name (str): The name of the circuit. This is used as the entry point for the program. Defaults to 'program'. - - search_path (str): The optional search path for resolving imports. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - shots (int): The number of shots to run the program for. Defaults to 1. - - seed (int): The seed to use for the random number generator. - - Returns: - Any: The result of the execution. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error interpreting the input. + :param source: The OpenQASM source code to execute. + :param output_fn: The function to handle the output of the execution. + :param noise_config: Optional noise configuration for noisy simulation. + :param noise: Optional Pauli noise as a tuple of ``(x, y, z)`` probabilities. + :param qubit_loss: The probability of qubit loss in simulation. + :param read_file: A callable that reads a file and returns its contents. + :param list_directory: A callable that lists the contents of a directory. + :param resolve_path: A callable that resolves a path given a base path and a relative path. + :param fetch_github: A callable that fetches a file from GitHub. + :param **kwargs: Common options: + + - ``target_profile`` (TargetProfile): The target profile to use for execution. + - ``name`` (str): The name of the circuit. Defaults to ``'program'``. + - ``search_path`` (str): The optional search path for resolving imports. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + - ``shots`` (int): The number of shots to run. Defaults to ``1``. + - ``seed`` (int): The seed to use for the random number generator. + :return: The result of the execution. + :rtype: Any + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error interpreting the input. """ ... @@ -713,20 +707,28 @@ def estimate_custom( """ Estimates quantum resources for a given algorithm, qubit, and code. - Args: - algorithm: Python object representing the algorithm. - qubit: The qubit properties as a dictionary. - qec: Python object representing the quantum error correction code. - factories (List): List of python objects representing factories. Default: []. - error_budget (float): The total error budget, which is uniformly distributed. Default: 0.01. - max_factories (Optional[int]): Constrains the number of factories. Default: None. - logical_depth_factor (Optional[float]): Extends algorithmic logical depth by a factor >= 1. Default: None. - max_physical_qubits (Optional[int]): Forces estimator to not exceed provided number of physical qubits, may fail. Default: None. - max_duration (Optional[int]): Allows estimator to run for given runtime in nanoseconds, may fail. Default: None. - error_budget_pruning (bool): Will try to prune the error budget to increase magic state error budget. Default: False. - - Returns: - Dict: A dictionary with resource estimation results. + :param algorithm: Python object representing the algorithm. + :param qubit: The qubit properties as a dictionary. + :param qec: Python object representing the quantum error correction code. + :param factories: List of python objects representing factories. Defaults to ``[]``. + :type factories: List + :keyword error_budget: The total error budget, which is uniformly distributed. Defaults to ``0.01``. + :kwtype error_budget: float + :keyword max_factories: Constrains the number of factories. Defaults to ``None``. + :kwtype max_factories: int + :keyword logical_depth_factor: Extends algorithmic logical depth by a factor >= 1. Defaults to ``None``. + :kwtype logical_depth_factor: float + :keyword max_physical_qubits: Forces estimator to not exceed provided number of physical qubits, may fail. + Defaults to ``None``. + :kwtype max_physical_qubits: int + :keyword max_duration: Allows estimator to run for given runtime in nanoseconds, may fail. + Defaults to ``None``. + :kwtype max_duration: int + :keyword error_budget_pruning: Will try to prune the error budget to increase magic state error budget. + Defaults to ``False``. + :kwtype error_budget_pruning: bool + :return: A dictionary with resource estimation results. + :rtype: Dict """ ... @@ -861,7 +863,8 @@ class NoiseTable: The correlated pauli noise to use in simulation. Setting an element that was previously set overrides that entry with the new value. - Example: + Example:: + noise_table = NoiseTable(2) noise_table.set_pauli_noise([("XI", 1e-10), ("XZ", 1e-8)]) """ @@ -872,7 +875,8 @@ class NoiseTable: The correlated pauli noise to use in simulation. Setting an element that was previously set overrides that entry with the new value. - Example: + Example:: + noise_table = NoiseTable(2) noise_table.set_pauli_noise(["XI", "XZ"], [1e-10, 3.7e-8]) """ @@ -883,7 +887,8 @@ class NoiseTable: The correlated pauli noise to use in simulation. Setting an element that was previously set overrides that entry with the new value. - Example: + Example:: + noise_table = NoiseTable(2) noise_table.set_pauli_noise("XZ", 1e-10) """ diff --git a/source/pip/qsharp/_qsharp.py b/source/pip/qsharp/_qsharp.py index 50b0556fd6..a1a7d1ae37 100644 --- a/source/pip/qsharp/_qsharp.py +++ b/source/pip/qsharp/_qsharp.py @@ -143,11 +143,12 @@ def ipython_helper(): class Config: - _config: Dict[str, Any] """ Configuration hints for the language service. """ + _config: Dict[str, Any] + def __init__( self, target_profile: TargetProfile, @@ -205,6 +206,19 @@ class PauliNoise(Tuple[float, float, float]): """ def __new__(cls, x: float, y: float, z: float): + """ + Creates a new :class:`PauliNoise` instance with the given error probabilities. + + :param x: Probability of a Pauli-X (bit flip) error. Must be non-negative. + :type x: float + :param y: Probability of a Pauli-Y error. Must be non-negative. + :type y: float + :param z: Probability of a Pauli-Z (phase flip) error. Must be non-negative. + :type z: float + :return: A new :class:`PauliNoise` tuple ``(x, y, z)``. + :rtype: PauliNoise + :raises ValueError: If any probability is negative or if ``x + y + z > 1``. + """ if x < 0 or y < 0 or z < 0: raise ValueError("Pauli noise probabilities must be non-negative.") if x + y + z > 1: @@ -218,6 +232,18 @@ class DepolarizingNoise(PauliNoise): """ def __new__(cls, p: float): + """ + Creates a new :class:`DepolarizingNoise` instance. + + The depolarizing channel applies Pauli-X, Pauli-Y, or Pauli-Z errors each with + probability ``p / 3``. + + :param p: Total depolarizing error probability. Must satisfy ``0 ≤ p ≤ 1``. + :type p: float + :return: A new :class:`DepolarizingNoise` with equal X, Y, and Z error probabilities. + :rtype: DepolarizingNoise + :raises ValueError: If ``p`` is negative or ``p > 1``. + """ return super().__new__(cls, p / 3, p / 3, p / 3) @@ -227,6 +253,17 @@ class BitFlipNoise(PauliNoise): """ def __new__(cls, p: float): + """ + Creates a new :class:`BitFlipNoise` instance. + + The bit flip channel applies a Pauli-X error with probability ``p``. + + :param p: Probability of a bit flip (Pauli-X) error. Must satisfy ``0 ≤ p ≤ 1``. + :type p: float + :return: A new :class:`BitFlipNoise` with X error probability ``p``. + :rtype: BitFlipNoise + :raises ValueError: If ``p`` is negative or ``p > 1``. + """ return super().__new__(cls, p, 0, 0) @@ -236,6 +273,17 @@ class PhaseFlipNoise(PauliNoise): """ def __new__(cls, p: float): + """ + Creates a new :class:`PhaseFlipNoise` instance. + + The phase flip channel applies a Pauli-Z error with probability ``p``. + + :param p: Probability of a phase flip (Pauli-Z) error. Must satisfy ``0 ≤ p ≤ 1``. + :type p: float + :return: A new :class:`PhaseFlipNoise` with Z error probability ``p``. + :rtype: PhaseFlipNoise + :raises ValueError: If ``p`` is negative or ``p > 1``. + """ return super().__new__(cls, 0, 0, p) @@ -250,19 +298,30 @@ def init( """ Initializes the Q# interpreter. - :param target_profile: Setting the target profile allows the Q# + :keyword target_profile: Setting the target profile allows the Q# interpreter to generate programs that are compatible - with a specific target. See :py:class: `qsharp.TargetProfile`. + with a specific target. See :class:`TargetProfile`. - :param target_name: An optional name of the target machine to use for inferring the compatible + :keyword target_name: An optional name of the target machine to use for inferring the compatible target_profile setting. - :param project_root: An optional path to a root directory with a Q# project to include. + :keyword project_root: An optional path to a root directory with a Q# project to include. It must contain a qsharp.json project manifest. - :param trace_circuit: Enables tracing of circuit during execution. + :keyword language_features: An optional list of language feature flags to enable. + These correspond to experimental or preview Q# language features. + Valid values are: + + - ``"v2-preview-syntax"``: Enables Q# v2 preview syntax. This removes support for + the scoped qubit allocation block form (``use q = Qubit() { ... }``), requiring + the statement form instead (``use q = Qubit();``). It also removes the requirement + to use the ``set`` keyword for mutable variable assignments. + + :keyword trace_circuit: Enables tracing of circuit during execution. Passing `True` is required for the `dump_circuit` function to return a circuit. The `circuit` function is *NOT* affected by this parameter will always generate a circuit. + :return: The Q# interpreter configuration. + :rtype: Config """ from ._fs import read_file, list_directory, exists, join, resolve from ._http import fetch_github @@ -342,7 +401,8 @@ def get_interpreter() -> Interpreter: """ Returns the Q# interpreter. - :returns: The Q# interpreter. + :return: The Q# interpreter. + :rtype: Interpreter """ global _interpreter if _interpreter is None: @@ -355,7 +415,8 @@ def get_config() -> Config: """ Returns the Q# interpreter configuration. - :returns: The Q# interpreter configuration. + :return: The Q# interpreter configuration. + :rtype: Config """ global _config if _config is None: @@ -410,6 +471,8 @@ def check_eq( :param state: The state to check against, provided either as a dictionary of state indices to complex amplitudes, or as a list of real amplitudes. :param tolerance: The tolerance for the check. Defaults to 1e-10. + :return: ``True`` if the state dump is equal to the given state within the given tolerance, ignoring global phase. + :rtype: bool """ phase = None # Convert a dense list of real amplitudes to a dictionary of state indices to complex amplitudes @@ -436,6 +499,9 @@ def check_eq( def as_dense_state(self) -> List[complex]: """ Returns the state dump as a dense list of complex amplitudes. This will include zero amplitudes. + + :return: A dense list of complex amplitudes, one per computational basis state. + :rtype: List[complex] """ return [self.__inner.get(i, complex(0)) for i in range(2**self.qubit_count)] @@ -463,8 +529,9 @@ def eval( Output is printed to console. :param source: The Q# source code to evaluate. - :param save_events: If true, all output will be saved and returned. If false, they will be printed. - :returns value: The value returned by the last statement in the source code or the saved output if `save_events` is true. + :keyword save_events: If true, all output will be saved and returned. If false, they will be printed. + :return: The value returned by the last statement in the source code, or the saved output if ``save_events`` is true. + :rtype: Any :raises QSharpError: If there is an error evaluating the source code. """ ipython_helper() @@ -726,9 +793,8 @@ def run( :param qubit_loss: The probability of qubit loss in simulation. :param seed: The seed to use for the random number generator in simulation, if any. - :returns values: A list of results or runtime errors. If `save_events` is true, - a List of ShotResults is returned. - + :return: A list of results or runtime errors. If ``save_events`` is true, a list of ``ShotResult`` is returned. + :rtype: List[Any] :raises QSharpError: If there is an error interpreting the input. :raises ValueError: If the number of shots is less than 1. """ @@ -857,10 +923,10 @@ def compile( :param entry_expr: The Q# expression that will be used as the entrypoint for the program. Alternatively, a callable can be provided, which must be a Q# callable. + :param *args: The arguments to pass to the callable, if one is provided. - :returns QirInputData: The compiled program. - - To get the QIR string from the compiled program, use `str()`. + :return: The compiled program. Use ``str()`` to get the QIR string. + :rtype: QirInputData Example: @@ -905,13 +971,41 @@ def circuit( :param entry_expr: An entry expression. Alternatively, a callable can be provided, which must be a Q# callable. + :type entry_expr: str or Callable :param *args: The arguments to pass to the callable, if one is provided. - :param operation: The operation to synthesize. This can be a name of - an operation of a lambda expression. The operation must take only - qubits or arrays of qubits as parameters. - + :keyword operation: The operation to synthesize. This can be a name of + an operation or a lambda expression. The operation must take only + qubits or arrays of qubits as parameters. + :kwtype operation: str + + :keyword generation_method: The method to use for circuit generation. + :attr:`~qsharp.CircuitGenerationMethod.ClassicalEval` evaluates classical + control flow at circuit generation time. + :attr:`~qsharp.CircuitGenerationMethod.Simulate` runs a full simulation to + trace the circuit. + :attr:`~qsharp.CircuitGenerationMethod.Static` uses partial evaluation and + requires a non-``Unrestricted`` target profile. Defaults to ``None`` which + auto-selects the generation method. + :kwtype generation_method: :class:`~qsharp.CircuitGenerationMethod` + + :keyword max_operations: The maximum number of operations to include in the circuit. + Defaults to ``None`` which means no limit. + :kwtype max_operations: int + + :keyword source_locations: If ``True``, annotates each gate with its source location. + :kwtype source_locations: bool + + :keyword group_by_scope: If ``True``, groups operations by their containing scope, such as function declarations or loop blocks. + :kwtype group_by_scope: bool + + :keyword prune_classical_qubits: If ``True``, removes qubits that are never used in a quantum + gate (e.g. qubits only used as classical controls). + :kwtype prune_classical_qubits: bool + + :return: The synthesized circuit. + :rtype: :class:`~qsharp._native.Circuit` :raises QSharpError: If there is an error synthesizing the circuit. """ ipython_helper() @@ -956,7 +1050,8 @@ def estimate( which must be a Q# callable. :param params: The parameters to configure physical estimation. - :returns `EstimatorResult`: The estimated resources. + :return: The estimated resources. + :rtype: EstimatorResult """ ipython_helper() @@ -1015,7 +1110,8 @@ def logical_counts( :param entry_expr: The entry expression. Alternatively, a callable can be provided, which must be a Q# callable. - :returns `LogicalCounts`: Program resources in terms of logical gate counts. + :return: Program resources in terms of logical gate counts. + :rtype: LogicalCounts """ ipython_helper() @@ -1061,7 +1157,8 @@ def dump_machine() -> StateDump: """ Returns the sparse state vector of the simulator as a StateDump object. - :returns: The state of the simulator. + :return: The state of the simulator. + :rtype: StateDump """ ipython_helper() return StateDump(get_interpreter().dump_machine()) @@ -1075,6 +1172,10 @@ def dump_circuit() -> Circuit: in the simulator up to the current point. Requires the interpreter to be initialized with `trace_circuit=True`. + + :return: The current circuit trace. + :rtype: Circuit + :raises QSharpError: If the interpreter was not initialized with ``trace_circuit=True``. """ ipython_helper() return get_interpreter().dump_circuit() diff --git a/source/pip/qsharp/_simulation.py b/source/pip/qsharp/_simulation.py index 76621961f3..33e2e497da 100644 --- a/source/pip/qsharp/_simulation.py +++ b/source/pip/qsharp/_simulation.py @@ -696,20 +696,18 @@ def run_qir( """ Simulate the given QIR source. - Args: - input: The QIR source to simulate. - type: The type of simulator to use. - Use `"clifford"` if your QIR only contains Clifford gates and measurements. - Use `"gpu"` if you have a GPU available in your system. - Use `"cpu"` as a fallback option if you don't have a GPU in your system. - If `None` (default), the GPU simulator will be tried first, falling back to - CPU if a suitable GPU device could not be located. - shots: The number of shots to run. - noise: A noise model to use in the simulation. - seed: A seed for reproducibility. - - Returns: - A list of measurement results, in the order they happened during the simulation. + :param input: The QIR source to simulate. + :param type: The type of simulator to use. + Use ``"clifford"`` if your QIR only contains Clifford gates and measurements. + Use ``"gpu"`` if you have a GPU available in your system. + Use ``"cpu"`` as a fallback option if you don't have a GPU in your system. + If ``None`` (default), the GPU simulator will be tried first, falling back to + CPU if a suitable GPU device could not be located. + :param shots: The number of shots to run. + :param noise: A noise model to use in the simulation. + :param seed: A seed for reproducibility. + :return: A list of measurement results, in the order they happened during the simulation. + :rtype: List """ if type is None: try: diff --git a/source/pip/qsharp/estimator/_estimator.py b/source/pip/qsharp/estimator/_estimator.py index d3d48cab6b..2349862420 100644 --- a/source/pip/qsharp/estimator/_estimator.py +++ b/source/pip/qsharp/estimator/_estimator.py @@ -85,6 +85,13 @@ def validating_field(validation_func, default=None): class QubitParams: + """ + Predefined qubit model name constants for use with :class:`EstimatorQubitParams`. + + Pass one of these string constants as the ``name`` field to select a built-in + qubit model for resource estimation. + """ + GATE_US_E3 = "qubit_gate_us_e3" GATE_US_E4 = "qubit_gate_us_e4" GATE_NS_E3 = "qubit_gate_ns_e3" @@ -94,6 +101,14 @@ class QubitParams: class QECScheme: + """ + Predefined quantum error correction scheme name constants for use with + :class:`EstimatorQecScheme`. + + Pass one of these string constants as the ``name`` field to select a + built-in QEC scheme for resource estimation. + """ + SURFACE_CODE = "surface_code" FLOQUET_CODE = "floquet_code" @@ -128,12 +143,31 @@ def check_time(name, value): @dataclass class MeasurementErrorRate(AutoValidatingParams): + """ + Measurement error rate specified separately for process and readout errors. + + Used as the value of ``one_qubit_measurement_error_rate`` or + ``two_qubit_joint_measurement_error_rate`` in :class:`EstimatorQubitParams` + when process and readout error rates differ. + + :param process: Error rate during the measurement process. Must be in ``(0, 1)``. + :param readout: Error rate during readout. Must be in ``(0, 1)``. + """ + process: float = field(metadata={"validate": _check_error_rate}) readout: float = field(metadata={"validate": _check_error_rate}) @dataclass class EstimatorQubitParams(AutoValidatingParams): + """ + Physical qubit parameters for resource estimation. + + Specify a built-in qubit model by setting ``name`` to one of the + :class:`QubitParams` constants, or fully define a custom model by setting + ``instruction_set`` and all relevant timing and error-rate fields. + """ + @staticmethod def check_instruction_set(name, value): if value not in [ @@ -224,6 +258,14 @@ def as_dict(self, validate=True) -> Dict[str, Any]: @dataclass class EstimatorQecScheme(AutoValidatingParams): + """ + Quantum error correction scheme parameters for resource estimation. + + Specify a built-in scheme by setting ``name`` to one of the + :class:`QECScheme` constants, or define a custom scheme by setting + the threshold and code-distance parameters directly. + """ + name: Optional[str] = None error_correction_threshold: Optional[float] = validating_field(_check_error_rate) crossing_prefactor: Optional[float] = None @@ -235,6 +277,13 @@ class EstimatorQecScheme(AutoValidatingParams): @dataclass class ProtocolSpecificDistillationUnitSpecification(AutoValidatingParams): + """ + Protocol-specific specification for a magic-state distillation unit. + + Defines the number of physical qubits and the duration (in logical cycle + time units) for one round of distillation under a specific QEC code. + """ + num_unit_qubits: Optional[int] = None duration_in_qubit_cycle_time: Optional[int] = None @@ -248,6 +297,15 @@ def post_validation(self, result): @dataclass class DistillationUnitSpecification(AutoValidatingParams): + """ + Specification for a magic-state distillation unit. + + Either select a built-in unit by setting ``name``, or define a custom unit + by providing ``num_input_ts``, ``num_output_ts``, ``failure_probability_formula``, + ``output_error_rate_formula``, and optionally physical and logical qubit + specifications. + """ + name: Optional[str] = None display_name: Optional[str] = None num_input_ts: Optional[int] = None @@ -356,6 +414,17 @@ def as_dict(self, validate=True) -> Dict[str, Any]: @dataclass class ErrorBudgetPartition(AutoValidatingParams): + """ + Partition of the total error budget across algorithm components. + + The three fields must sum to the overall error budget. Defaults to equal + thirds of ``0.001`` (i.e. each component gets ``~3.33e-4``). + + :param logical: Budget allocated to logical errors in the algorithm. + :param t_states: Budget allocated to T-state distillation errors. + :param rotations: Budget allocated to rotation synthesis errors. + """ + logical: float = 0.001 / 3 t_states: float = 0.001 / 3 rotations: float = 0.001 / 3 @@ -363,6 +432,13 @@ class ErrorBudgetPartition(AutoValidatingParams): @dataclass class EstimatorConstraints(AutoValidatingParams): + """ + Optional runtime and resource constraints for resource estimation. + + At most one of ``max_duration`` or ``max_physical_qubits`` may be set + simultaneously. + """ + @staticmethod def at_least_one(name, value): if value < 1: @@ -382,9 +458,11 @@ def post_validation(self, result): class EstimatorInputParamsItem: """ - Input params for microsoft.estimator target + Input parameters for a single resource estimation job. - :ivar error_budget Total error budget for execution of the algorithm + Contains qubit model, QEC scheme, distillation unit specifications, constraints, + and error budget settings. Used directly for single-point estimation or as a + base class for batching via :class:`EstimatorParams`. """ def __init__(self): @@ -479,6 +557,18 @@ def as_dict(self, validate=True, additional_params=None) -> Dict[str, Any]: class EstimatorParams(EstimatorInputParamsItem): + """ + Top-level input parameters for the Microsoft Resource Estimator. + + Extends :class:`~qsharp.estimator.EstimatorInputParamsItem` with support for batching: pass + ``num_items`` to create a batching job where each item can override the + top-level parameters. + + :param num_items: Number of batching items. If ``None``, creates a + single-point estimation job. + :type num_items: int + """ + MAX_NUM_ITEMS: int = 1000 def __init__(self, num_items: Optional[int] = None): @@ -661,8 +751,10 @@ def _plot(self, **kwargs): Plots all result items in a space time plot, where the x-axis shows total runtime, and the y-axis shows total number of physical qubits. Both axes are in log-scale. - Attributes: - labels (list): List of labels for the legend. + + :param **kwargs: Common options: + + - ``labels`` (list): List of labels for the legend. Defaults to ``[]``. """ try: import matplotlib.pyplot as plt @@ -1070,10 +1162,9 @@ def estimate( Estimates resources for the current logical counts, using the Parallel Synthesis Sequential Pauli Computation (PSSPC) layout method. - :param logical_counts: The logical counts. :param params: The parameters to configure physical estimation. - - :returns resources: The estimated resources. + :return: The estimated resources. + :rtype: EstimatorResult """ if params is None: params = [{}] diff --git a/source/pip/qsharp/interop/__init__.py b/source/pip/qsharp/interop/__init__.py index 59e481eb93..379559deb5 100644 --- a/source/pip/qsharp/interop/__init__.py +++ b/source/pip/qsharp/interop/__init__.py @@ -1,2 +1,4 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. + +"""Interoperability modules for the Q# ecosystem.""" diff --git a/source/pip/qsharp/interop/cirq/__init__.py b/source/pip/qsharp/interop/cirq/__init__.py index d610e2bfd8..8a484fc8ab 100644 --- a/source/pip/qsharp/interop/cirq/__init__.py +++ b/source/pip/qsharp/interop/cirq/__init__.py @@ -3,11 +3,11 @@ """Cirq interoperability for the Q# ecosystem. -This module provides a :class:`NeutralAtomSampler` — a standard +This module provides a :class:`~qsharp.interop.cirq.NeutralAtomSampler` — a standard ``cirq.Sampler`` that runs Cirq circuits on the local NeutralAtomDevice simulator. -Usage:: +Usage: import cirq from qsharp.interop.cirq import NeutralAtomSampler diff --git a/source/pip/qsharp/interop/cirq/_neutral_atom.py b/source/pip/qsharp/interop/cirq/_neutral_atom.py index be45f12caf..8829e44b9d 100644 --- a/source/pip/qsharp/interop/cirq/_neutral_atom.py +++ b/source/pip/qsharp/interop/cirq/_neutral_atom.py @@ -29,23 +29,6 @@ class NeutralAtomSampler(cirq.Sampler): 3. QIR → ``NeutralAtomDevice.simulate()`` (decompose, schedule, simulate) 4. Raw shots → :class:`NeutralAtomCirqResult` - Args: - noise: Optional :class:`~qsharp._simulation.NoiseConfig` describing - per-gate noise. The device decomposes gates to the native set - ``{Rz, SX, CZ, MResetZ}``; configure noise on those native gates. - For example, a Cirq ``X`` gate arriving via QASM 2.0 is decomposed - to ``SX·SX``, so ``noise.sx`` is the relevant field. Defaults to - ``None`` (noiseless). - simulator_type: Force a particular simulator backend. - - ``"clifford"`` — Clifford-only, fast. Requires a Clifford circuit. - - ``"cpu"`` — Full state-vector on CPU. - - ``"gpu"`` — Full state-vector on GPU. - - ``None`` (default) — GPU if available, CPU otherwise. - seed: Optional integer seed for reproducibility. Defaults to ``None``. - device: An existing :class:`~qsharp._device._atom.NeutralAtomDevice` - instance to reuse across calls. A default-configured device is - created lazily on the first call when not provided. - Example:: import cirq @@ -70,6 +53,26 @@ class NeutralAtomSampler(cirq.Sampler): sampler = NeutralAtomSampler(noise=noise, seed=42) result = sampler.run(circuit, repetitions=1000) print(f"Accepted: {len(result.measurements['m'])} / {len(result.raw_shots)}") + + :keyword noise: Optional :class:`~qsharp._simulation.NoiseConfig` describing + per-gate noise. The device decomposes gates to the native set + ``{Rz, SX, CZ, MResetZ}``; configure noise on those native gates. + For example, a Cirq ``X`` gate arriving via QASM 2.0 is decomposed + to ``SX·SX``, so ``noise.sx`` is the relevant field. Defaults to + ``None`` (noiseless). + :kwtype noise: NoiseConfig + :keyword simulator_type: Force a particular simulator backend. + ``"clifford"`` — Clifford-only, fast. Requires a Clifford circuit. + ``"cpu"`` — Full state-vector on CPU. + ``"gpu"`` — Full state-vector on GPU. + ``None`` (default) — GPU if available, CPU otherwise. + :kwtype simulator_type: str + :keyword seed: Optional integer seed for reproducibility. Defaults to ``None``. + :kwtype seed: int + :keyword device: An existing :class:`~qsharp._device._atom.NeutralAtomDevice` + instance to reuse across calls. A default-configured device is + created lazily on the first call when not provided. + :kwtype device: NeutralAtomDevice """ def __init__( @@ -101,16 +104,19 @@ def run_sweep( ) -> List[NeutralAtomCirqResult]: """Run the circuit for each parameter resolver in the sweep. - Args: - program: The Cirq circuit to simulate. - params: A :class:`cirq.Sweepable` defining the parameter resolvers - to sweep over. Each resolver produces one result. - repetitions: Number of shots per parameter resolver. - - Returns: - A list of :class:`NeutralAtomCirqResult` objects, one per resolver. + :param program: The Cirq circuit to simulate. + :param params: A ``cirq.Sweepable`` defining the parameter resolvers + to sweep over. Each resolver produces one result. + :param repetitions: Number of shots per parameter resolver. + :type repetitions: int + :return: A list of :class:`NeutralAtomCirqResult` objects, one per resolver. + :rtype: List[NeutralAtomCirqResult] """ - resolvers = list(cirq.to_sweep(params)) if params is not None else [cirq.ParamResolver()] + resolvers = ( + list(cirq.to_sweep(params)) + if params is not None + else [cirq.ParamResolver()] + ) return [ self._run_once(program, resolver, repetitions) for resolver in resolvers ] diff --git a/source/pip/qsharp/interop/cirq/_result.py b/source/pip/qsharp/interop/cirq/_result.py index 6343c79f7d..d76bf8ecc3 100644 --- a/source/pip/qsharp/interop/cirq/_result.py +++ b/source/pip/qsharp/interop/cirq/_result.py @@ -26,16 +26,14 @@ class NeutralAtomCirqResult(cirq.ResultDict): which one or more qubits were lost during the simulation are excluded from ``measurements`` but are preserved in ``raw_shots``. - Attributes: - raw_shots: The full list of simulation results, one entry per shot, - in the native simulator output format (tuple, list, or scalar). - This includes shots that contain qubit-loss markers. - - Methods: - raw_measurements(): Return the full per-shot data (including loss markers) - in the same ``{key: 2D-array (shots x bits)}`` format as - ``measurements``, but with Unicode string dtype so that non-binary - markers are preserved. + The ``raw_shots`` attribute holds the full list of simulation results, one + entry per shot, in the native simulator output format (tuple, list, or + scalar). This includes shots that contain qubit-loss markers. + + Use :meth:`raw_measurements` to retrieve the full per-shot data (including + loss markers) in the same ``{key: 2D-array (shots x bits)}`` format as + ``measurements``, but with Unicode string dtype so that non-binary markers + are preserved. """ __slots__ = ("raw_shots", "_measurement_dict_data", "_raw_measurements_cache") @@ -119,12 +117,10 @@ def measurement_dict(circuit: cirq.Circuit) -> Dict[str, List[int]]: Qubit indices are determined by ``sorted(circuit.all_qubits())``, matching the ordering that Cirq's ``to_qasm()`` uses when it numbers the qubits. - Args: - circuit: The Cirq circuit to introspect. - - Returns: - An ordered dict mapping each measurement key to the list of global qubit + :param circuit: The Cirq circuit to introspect. + :return: An ordered dict mapping each measurement key to the list of global qubit indices that key covers, in the order they are measured. + :rtype: Dict[str, List[int]] """ ordered_qubits = sorted(circuit.all_qubits()) index_by_qubit = {q: i for i, q in enumerate(ordered_qubits)} @@ -188,12 +184,10 @@ def _qir_display_to_bitstring(obj: Any) -> str: def _split_registers(bitstring: str, key_lengths: List[int]) -> List[str]: """Split a flat or space-delimited bitstring into per-register chunks. - Args: - bitstring: The raw bitstring, possibly containing spaces between registers. - key_lengths: The expected width of each register, in order. - - Returns: - A list of register strings, one per key. + :param bitstring: The raw bitstring, possibly containing spaces between registers. + :param key_lengths: The expected width of each register, in order. + :return: A list of register strings, one per key. + :rtype: List[str] """ raw = str(bitstring).strip() @@ -229,13 +223,11 @@ def _shots_to_rows( Shots where any qubit returned a non-binary value (loss marker) are silently dropped. Only ``{0, 1}`` shots contribute to the returned arrays. - Args: - shots: Raw simulation output, one entry per shot. - measurement_dict_data: ``{key: [qubit_indices]}`` - the measurement - register layout. Defaults to a single key ``"m"`` with no qubits. - - Returns: - ``{key: list_of_rows}`` where each row is a list of 0/1 integers. + :param shots: Raw simulation output, one entry per shot. + :param measurement_dict_data: ``{key: [qubit_indices]}`` — the measurement + register layout. Defaults to a single key ``"m"`` with no qubits. + :return: ``{key: list_of_rows}`` where each row is a list of 0/1 integers. + :rtype: Dict[str, List[List[int]]] """ if measurement_dict_data is None: measurement_dict_data = {"m": []} @@ -286,16 +278,14 @@ def to_cirq_result( ) -> NeutralAtomCirqResult: """Build a :class:`NeutralAtomCirqResult` from raw simulation output. - Args: - raw_shots: The raw per-shot results from ``NeutralAtomDevice.simulate()``. - meas_dict: ``{key: [qubit_indices]}`` as returned by :func:`measurement_dict`. - param_resolver: Cirq parameter resolver for the circuit. Defaults to the - empty resolver. - - Returns: - A ``NeutralAtomCirqResult`` whose ``measurements`` field contains only + :param raw_shots: The raw per-shot results from ``NeutralAtomDevice.simulate()``. + :param meas_dict: ``{key: [qubit_indices]}`` as returned by :func:`measurement_dict`. + :param param_resolver: Cirq parameter resolver for the circuit. Defaults to the + empty resolver. + :return: A :class:`NeutralAtomCirqResult` whose ``measurements`` field contains only loss-free shots, and whose ``raw_shots`` / ``raw_measurements()`` retain all shots including those with loss markers. + :rtype: NeutralAtomCirqResult """ if param_resolver is None: param_resolver = cirq.ParamResolver({}) diff --git a/source/pip/qsharp/interop/qiskit/__init__.py b/source/pip/qsharp/interop/qiskit/__init__.py index a74d733456..9a6cd7a7c7 100644 --- a/source/pip/qsharp/interop/qiskit/__init__.py +++ b/source/pip/qsharp/interop/qiskit/__init__.py @@ -7,28 +7,28 @@ NeutralAtomDevice, allowing Qiskit circuits to be run locally without any cloud connection. -Available backends ------------------- -:class:`QSharpBackend` +Available backends: + +:class:`~qsharp.interop.qiskit.QSharpBackend` Runs any Qiskit ``QuantumCircuit`` using the Q# simulator. Supports noise-free simulation via QASM export and QIR compilation. -:class:`NeutralAtomBackend` +:class:`~qsharp.interop.qiskit.NeutralAtomBackend` Runs Qiskit circuits on the local NeutralAtomDevice simulator. Decomposes gates to the native ``{Rz, SX, CZ}`` gate set and optionally models per-gate noise (including qubit loss). Loss shots are exposed separately from accepted shots in the job result. -:class:`ResourceEstimatorBackend` +:class:`~qsharp.interop.qiskit.ResourceEstimatorBackend` Estimates quantum resources (qubits, T-gates, etc.) for a Qiskit circuit without running a full simulation. -:func:`estimate` +:func:`~qsharp.interop.qiskit.estimate` Convenience function that runs resource estimation on a Qiskit circuit - and returns an `EstimatorResult` directly, without needing to - construct a backend or job manually. + and returns an :class:`~qsharp.estimator.EstimatorResult` directly, without + needing to construct a backend or job manually. -Usage:: +Usage: from qiskit import QuantumCircuit from qsharp.interop.qiskit import NeutralAtomBackend @@ -73,14 +73,17 @@ def estimate( :param circuit: The input Qiskit QuantumCircuit object. :param params: The parameters to configure physical estimation. - :**options: Additional options for the execution. - - Any options for the transpiler, exporter, or Qiskit passes - configuration. Defaults to backend config values. Common - values include: 'optimization_level', 'basis_gates', - 'includes', 'search_path'. + :type params: EstimatorParams or dict or list + :param **options: Additional options for the transpiler, exporter, or Qiskit passes + configuration. Defaults to backend config values. Common options: + + - ``optimization_level`` (int): Transpiler optimization level. + - ``basis_gates`` (list): Basis gates for transpilation. + - ``includes`` (list): Include paths for QASM resolution. + - ``search_path`` (str): Search path for resolving file references. :raises QasmError: If there is an error generating or parsing QASM. - - :returns `EstimatorResult`: The estimated resources. + :return: The estimated resources. + :rtype: EstimatorResult """ from ..._qsharp import ipython_helper @@ -88,3 +91,18 @@ def estimate( backend = ResourceEstimatorBackend() job = backend.run(circuit, params=params, **options) return job.result() + + +__all__ = [ + "NeutralAtomBackend", + "QSharpBackend", + "ResourceEstimatorBackend", + "QirTarget", + "QsJob", + "QsSimJob", + "ReJob", + "QsJobSet", + "estimate", + "EstimatorParams", + "EstimatorResult", +] diff --git a/source/pip/qsharp/interop/qiskit/backends/backend_base.py b/source/pip/qsharp/interop/qiskit/backends/backend_base.py index a6400d73ee..8d24a45499 100644 --- a/source/pip/qsharp/interop/qiskit/backends/backend_base.py +++ b/source/pip/qsharp/interop/qiskit/backends/backend_base.py @@ -113,16 +113,14 @@ def __init__( transpile_options: Optional[Dict[str, Any]] = None, qasm_export_options: Optional[Dict[str, Any]] = None, skip_transpilation: bool = False, - **fields, + **options, ): """ - Parameters: - target (Target): The target to use for the backend. - qiskit_pass_options (Dict): Options for the Qiskit passes. - transpile_options (Dict): Options for the transpiler. - qasm_export_options (Dict): Options for the QASM3 exporter. - **options: Additional keyword arguments to pass to the - execution used by subclasses. + :param target: The target to use for the backend. + :param qiskit_pass_options: Options for the Qiskit passes. + :param transpile_options: Options for the transpiler. + :param qasm_export_options: Options for the QASM3 exporter. + :param **options: Additional keyword arguments passed to subclasses. """ super().__init__( name="QSharpBackend", @@ -130,18 +128,18 @@ def __init__( backend_version="0.0.1", ) - if fields is not None: + if options is not None: # we need to rename the seed_simulator to seed. This # is a convenience for aer users. # if the user passes in seed_simulator, we will rename it to seed # but only if the seed field is defined in the backend options. - if "seed_simulator" in fields and "seed" in self._options.data: + if "seed_simulator" in options and "seed" in self._options.data: warn("seed_simulator passed, but field is called seed.") - fields["seed"] = fields.pop("seed_simulator") + options["seed"] = options.pop("seed_simulator") # updates the options with the fields passed in, if the backend # doesn't have the field, it will raise an error. - self.set_options(**fields) + self.set_options(**options) self._qiskit_pass_options = Options( supports_barrier=False, @@ -227,12 +225,11 @@ def max_circuits(self): def _execute(self, programs: List[Compilation], **input_params) -> Dict[str, Any]: """Execute circuits on the backend. - Parameters: - programs (List of QuantumCompilation): simulator input. - input_params (Dict): configuration for simulation/compilation. - - Returns: - dict: return a dictionary of results. + :param programs: Simulator input circuits. + :type programs: List[Compilation] + :param **input_params: Configuration for simulation/compilation. + :return: A dictionary of results. + :rtype: dict """ @abstractmethod @@ -477,18 +474,13 @@ def transpile(self, circuit: QuantumCircuit, **options) -> QuantumCircuit: def _qasm(self, circuit: QuantumCircuit, **options) -> str: """Converts a Qiskit QuantumCircuit to QASM 3 for the current backend. - Args: - circuit (QuantumCircuit): The QuantumCircuit to be executed. - **options: Additional options for the execution. - - Any options for the transpiler, exporter, or Qiskit passes - configuration. Defaults to backend config values. Common - values include: 'optimization_level', 'basis_gates', - 'includes', 'search_path'. - - Returns: - str: The converted QASM code as a string. Any supplied includes - are emitted as include statements at the top of the program. - + :param circuit: The QuantumCircuit to be executed. + :param **options: Additional options for the transpiler, exporter, or Qiskit passes. + Common values include: ``optimization_level``, ``basis_gates``, ``includes``, + ``search_path``. Defaults to backend config values. + :return: The converted QASM code as a string. Any supplied includes + are emitted as ``include`` statements at the top of the program. + :rtype: str :raises QasmError: If there is an error generating or parsing QASM. """ transpiled_circuit = self.transpile(circuit, **options) @@ -513,18 +505,12 @@ def _qsharp(self, circuit: QuantumCircuit, **kwargs) -> str: The generated Q# code will not be idiomatic Q# code, but will be a direct translation of the Qiskit circuit. - Args: - circuit (QuantumCircuit): The QuantumCircuit to be executed. - **options: Additional options for the execution. Defaults to backend config values. - - Any options for the transpiler, exporter, or Qiskit passes - configuration. Defaults to backend config values. Common - values include: 'optimization_level', 'basis_gates', - 'includes', 'search_path'. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - Returns: - str: The converted QASM code as a string. Any supplied includes - are emitted as include statements at the top of the program. - + :param circuit: The QuantumCircuit to be executed. + :param **kwargs: Additional options for the transpiler, exporter, or Qiskit passes. + Common values include: ``optimization_level``, ``basis_gates``, ``includes``, + ``search_path``, ``output_semantics``. Defaults to backend config values. + :return: The converted Q# code as a string. + :rtype: str :raises QSharpError: If there is an error evaluating the source code. :raises QasmError: If there is an error generating, parsing, or compiling QASM. """ @@ -554,16 +540,14 @@ def qir( """ Converts a Qiskit QuantumCircuit to QIR (Quantum Intermediate Representation). - Args: - circuit ('QuantumCircuit'): The input Qiskit QuantumCircuit object. - **kwargs: Additional options for the execution. - - params (str, optional): The entry expression for the QIR conversion. Defaults to None. - - target_profile (TargetProfile, optional): The target profile for the backend. Defaults to backend config value. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. Defaults to backend config value. - - search_path (str, optional): The search path for the backend. Defaults to '.'. - Returns: - str: The converted QIR code as a string. + :param circuit: The input Qiskit QuantumCircuit object. + :param **kwargs: Common options: + - ``target_profile`` (TargetProfile): The target profile for the backend. Defaults to backend config value. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. Defaults to backend config value. + - ``search_path`` (str): The search path for the backend. Defaults to ``'.'``. + :return: The converted QIR code as a string. + :rtype: str :raises QSharpError: If there is an error evaluating the source code. :raises QasmError: If there is an error generating, parsing, or compiling QASM. :raises ValueError: If the backend configuration does not support QIR generation. diff --git a/source/pip/qsharp/interop/qiskit/backends/neutral_atom_backend.py b/source/pip/qsharp/interop/qiskit/backends/neutral_atom_backend.py index 6e176b7f0e..e78ac94d46 100644 --- a/source/pip/qsharp/interop/qiskit/backends/neutral_atom_backend.py +++ b/source/pip/qsharp/interop/qiskit/backends/neutral_atom_backend.py @@ -79,37 +79,37 @@ def __init__( transpile_options: Optional[Dict[str, Any]] = None, qasm_export_options: Optional[Dict[str, Any]] = None, skip_transpilation: bool = False, - **fields, + **options, ): """ - Parameters: - device (NeutralAtomDevice, optional): The NeutralAtomDevice instance to use - for compilation and simulation. A default-configured device is created - automatically if not provided. Pass a custom device to control the - qubit layout (column count, zone dimensions, etc.). - target (Target): Qiskit transpiler target. Defaults to the - NeutralAtomDevice native gate set ``{rz, sx, cz, measure, reset}``. - Override only if you need a custom decomposition strategy. - qiskit_pass_options (Dict): Options forwarded to Qiskit pre-transpilation - passes. - transpile_options (Dict): Options forwarded to ``qiskit.transpile()``. - qasm_export_options (Dict): Options forwarded to the Qiskit QASM3 exporter. - skip_transpilation (bool): Skip Qiskit transpilation. Useful when the - circuit is already expressed in terms of the target gate set. - **fields: Additional backend options. Common options: - - - ``name`` (str): Backend name for job metadata. Defaults to the circuit - name. - - ``shots`` (int): Number of shots. Defaults to 1024. - - ``seed`` (int): Random seed for reproducibility. Defaults to None. - - ``noise`` (NoiseConfig): Optional per-gate noise model. Defaults to - None (noiseless). - - ``simulator_type`` (str): Simulator to use — ``"clifford"`` (Clifford - only), ``"cpu"`` (CPU full-state), ``"gpu"`` (GPU full-state), or - None to auto-select (GPU if available, CPU otherwise). - - ``output_semantics`` (OutputSemantics): QIR output encoding. Defaults - to ``Qiskit``. - - ``executor``: Executor for async job submission. + :param device: The NeutralAtomDevice instance to use for compilation and simulation. + A default-configured device is created automatically if not provided. + Pass a custom device to control the qubit layout (column count, zone dimensions, etc.). + :type device: NeutralAtomDevice + :param target: Qiskit transpiler target. Defaults to the NeutralAtomDevice native + gate set ``{rz, sx, cz, measure, reset}``. Override only if you need a custom + decomposition strategy. + :param qiskit_pass_options: Options forwarded to Qiskit pre-transpilation passes. + :type qiskit_pass_options: Dict + :param transpile_options: Options forwarded to ``qiskit.transpile()``. + :type transpile_options: Dict + :param qasm_export_options: Options forwarded to the Qiskit QASM3 exporter. + :type qasm_export_options: Dict + :param skip_transpilation: Skip Qiskit transpilation. Useful when the circuit is + already expressed in terms of the target gate set. + :type skip_transpilation: bool + :param **options: Default option overrides. These can also be overridden per-call via + :meth:`run`. Common options: + + - ``name`` (str): Backend name for job metadata. Defaults to the circuit name. + - ``shots`` (int): Number of shots. Defaults to ``1024``. + - ``seed`` (int): Random seed for reproducibility. Defaults to ``None``. + - ``noise`` (NoiseConfig): Optional per-gate noise model. Defaults to ``None`` (noiseless). + - ``simulator_type`` (str): Simulator to use — ``"clifford"`` (Clifford only), + ``"cpu"`` (CPU full-state), ``"gpu"`` (GPU full-state), or ``None`` to + auto-select (GPU if available, CPU otherwise). + - ``output_semantics`` (OutputSemantics): QIR output encoding. Defaults to ``OutputSemantics.Qiskit``. + - ``executor``: Executor for async job submission. """ self._device = device super().__init__( @@ -118,7 +118,7 @@ def __init__( transpile_options, qasm_export_options, skip_transpilation, - **fields, + **options, ) def _get_device(self): @@ -157,17 +157,22 @@ def run( ) -> Union[QsSimJob, QsJobSet]: """Simulate the given circuit(s) using the NeutralAtomDevice pipeline. - Args: - run_input: A single ``QuantumCircuit`` or a list of them. - **options: Per-call option overrides (``shots``, ``seed``, ``noise``, - ``simulator_type``, etc.). See class docstring for the full list. - - Returns: - QsSimJob: A job object whose ``.result()`` returns a Qiskit ``Result``. - - Raises: - ValueError: If ``run_input`` is not a ``QuantumCircuit`` or list thereof, - or if a ``target_profile`` option is provided that is not ``TargetProfile.Base``. + :param run_input: A single ``QuantumCircuit`` or a list of them. + :param **options: Per-call option overrides. Common options: + + - ``name`` (str): Backend name for job metadata. Defaults to the circuit name. + - ``shots`` (int): Number of shots. Defaults to ``1024``. + - ``seed`` (int): Random seed for reproducibility. Defaults to ``None``. + - ``noise`` (NoiseConfig): Optional per-gate noise model. Defaults to ``None`` (noiseless). + - ``simulator_type`` (str): Simulator to use — ``"clifford"`` (Clifford only), + ``"cpu"`` (CPU full-state), ``"gpu"`` (GPU full-state), or ``None`` to + auto-select (GPU if available, CPU otherwise). + - ``output_semantics`` (OutputSemantics): QIR output encoding. Defaults to ``OutputSemantics.Qiskit``. + - ``executor``: Executor for async job submission. + :return: A job object whose ``.result()`` returns a Qiskit ``Result``. + :rtype: QsSimJob + :raises ValueError: If ``run_input`` is not a ``QuantumCircuit`` or list thereof, + or if a ``target_profile`` other than ``TargetProfile.Base`` is provided. """ run_input = self._validate_quantum_circuits(run_input) return self._run(run_input, **options) diff --git a/source/pip/qsharp/interop/qiskit/backends/neutral_atom_target.py b/source/pip/qsharp/interop/qiskit/backends/neutral_atom_target.py index aa30a1a71b..3502e95562 100644 --- a/source/pip/qsharp/interop/qiskit/backends/neutral_atom_target.py +++ b/source/pip/qsharp/interop/qiskit/backends/neutral_atom_target.py @@ -28,11 +28,8 @@ def build_target( ) -> Target: """Return a Qiskit ``Target`` with only the NeutralAtomDevice native gates. - Args: - num_qubits: Number of qubits. ``None`` means no limit (simulator). - - Returns: - A ``Target`` containing ``{rz, sx, cz, measure, reset}``. + :param num_qubits: Number of qubits. ``None`` means no limit (simulator). + :return: A ``Target`` containing ``{rz, sx, cz, measure, reset}``. """ target = Target(num_qubits=num_qubits) diff --git a/source/pip/qsharp/interop/qiskit/backends/qirtarget.py b/source/pip/qsharp/interop/qiskit/backends/qirtarget.py index 9305bc0995..b88f2056a1 100644 --- a/source/pip/qsharp/interop/qiskit/backends/qirtarget.py +++ b/source/pip/qsharp/interop/qiskit/backends/qirtarget.py @@ -83,19 +83,10 @@ def __getattr__(self, item): It forwards the attribute lookup to the internal _target object, effectively making this class act as a proxy or wrapper around the target. - Args: - item (str): The name of the attribute being accessed. - - Returns: - Any: The value of the requested attribute from the _target object. - - Raises: - AttributeError: If the requested item is "_target" or if the attribute - does not exist on the _target object. - - Note: - The special handling of "_target" prevents infinite recursion and - maintains proper encapsulation of the internal target object. + :param item: The name of the attribute being accessed. + :return: The value of the requested attribute from the ``_target`` object. + :raises AttributeError: If the requested item is ``"_target"`` or if the attribute + does not exist on the ``_target`` object. """ if item == "_target": raise AttributeError(item) @@ -120,33 +111,16 @@ def build_target( operations and gates that can be used when compiling Q#/OpenQASM code to QIR (Quantum Intermediate Representation) format. - Args: - num_qubits (Union[int, None], optional): The number of qubits for the target. - If None, the target will support any number of qubits. Defaults to None. - target_profile (TargetProfile, optional): The target profile that determines - which control flow operations are supported. If not TargetProfile.Base, - adds control flow operations like if_else, switch_case, and while_loop. - Defaults to TargetProfile.Base. - supports_barrier (bool, optional): Whether to include barrier operations - in the target. Defaults to False. - supports_delay (bool, optional): Whether to include delay operations - in the target. Defaults to False. - - Returns: - Target: A Qiskit Target object configured with quantum gates and operations - including: - - Basic single-qubit gates (X, Y, Z, H, S, T, SX, I) - - Rotation gates (RX, RY, RZ) with parameters - - Two-qubit gates (CX, CY, CZ, SWAP, controlled rotations) - - Three-qubit gates (CCX) - - Multi-qubit rotation gates (RXX, RYY, RZZ) - - Measurement and reset operations - - Control flow operations (when target_profile != Base) - - Optional barrier and delay operations - - Note: - The target includes reset operations even for base profile since the - compiler can implement workarounds using decompositions. + :param num_qubits: The number of qubits for the target. + If ``None``, the target will support any number of qubits. Defaults to ``None``. + :param target_profile: The target profile that determines which control flow operations + are supported. If not ``TargetProfile.Base``, adds control flow operations like + ``if_else``, ``switch_case``, and ``while_loop``. Defaults to ``TargetProfile.Base``. + :param supports_barrier: Whether to include barrier operations in the target. + Defaults to ``False``. + :param supports_delay: Whether to include delay operations in the target. + Defaults to ``False``. + :return: A Qiskit ``Target`` object configured with quantum gates and operations. """ target = Target(num_qubits=num_qubits) diff --git a/source/pip/qsharp/interop/qiskit/backends/qsharp_backend.py b/source/pip/qsharp/interop/qiskit/backends/qsharp_backend.py index 17f77b2f24..c23db5d849 100644 --- a/source/pip/qsharp/interop/qiskit/backends/qsharp_backend.py +++ b/source/pip/qsharp/interop/qiskit/backends/qsharp_backend.py @@ -34,26 +34,31 @@ def __init__( transpile_options: Optional[Dict[str, Any]] = None, qasm_export_options: Optional[Dict[str, Any]] = None, skip_transpilation: bool = False, - **fields, + **options, ): """ - Parameters: - target (Target): The target to use for the backend. - qiskit_pass_options (Dict): Options for the Qiskit passes. - transpile_options (Dict): Options for the transpiler. - qasm_export_options (Dict): Options for the QASM3 exporter. - **options: Additional options for the execution. - - name (str): The name of the circuit. This is used as the entry point for the program. - The circuit name will be used if not specified. - - target_profile (TargetProfile): The target profile to use for the compilation. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. Defaults to `Qiskit`. - - shots (int): The number of shots to run the program for. Defaults to `1024`. - - seed (int): The seed to use for the random number generator. Defaults to `None`. - - search_path (str): The path to search for imports. Defaults to '.'. - - output_fn (Callable[[Output], None]): A callback function to - receive the output of the circuit. Defaults to `None`. - - executor(ThreadPoolExecutor or other Executor): - The executor to be used to submit the job. Defaults to SynchronousExecutor. + :param target: The target to use for the backend. + :param qiskit_pass_options: Options for the Qiskit passes. + :type qiskit_pass_options: Dict + :param transpile_options: Options for the transpiler. + :type transpile_options: Dict + :param qasm_export_options: Options for the QASM3 exporter. + :type qasm_export_options: Dict + :param skip_transpilation: Skip Qiskit transpilation. + :type skip_transpilation: bool + :param **options: Default option overrides. These can also be overridden per-call via + :meth:`run`. Common options: + + - ``name`` (str): The name of the circuit used as the entry point. Defaults to the circuit name. + - ``target_profile`` (TargetProfile): The target profile to use for the compilation. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + Defaults to ``OutputSemantics.Qiskit``. + - ``shots`` (int): The number of shots to run the program for. Defaults to ``1024``. + - ``seed`` (int): The seed to use for the random number generator. Defaults to ``None``. + - ``search_path`` (str): The path to search for imports. Defaults to ``'.'``. + - ``output_fn`` (Callable): A callback function to receive the output of the circuit. + Defaults to ``None``. + - ``executor``: The executor to be used to submit the job. Defaults to ``SynchronousExecutor``. """ super().__init__( @@ -62,7 +67,7 @@ def __init__( transpile_options, qasm_export_options, skip_transpilation, - **fields, + **options, ) @classmethod @@ -87,28 +92,24 @@ def run( """ Runs the given QuantumCircuit using the Q# simulator. - Args: - run_input (QuantumCircuit): The QuantumCircuit to be executed. - **options: Additional options for the execution. Defaults to backend config values. - - name (str): The name of the circuit. This is used as the entry point for the program. - The circuit name will be used if not specified. - - params (Optional[str]): The entry expression to use for the program. Defaults to None. - - target_profile (TargetProfile): The target profile to use for the compilation. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - shots (int): The number of shots to run the program for. Defaults to 1024. - - seed (int): The seed to use for the random number generator. Defaults to None. - - search_path (str): The path to search for imports. Defaults to '.'. - - output_fn (Callable[[Output], None]): A callback function to - receive the output of the circuit. - - executor(ThreadPoolExecutor or other Executor): - The executor to be used to submit the job. - Returns: - QSharpJob: The simulation job - + :param run_input: The QuantumCircuit to be executed. + :param **options: Per-call option overrides. Common options: + + - ``name`` (str): The name of the circuit used as the entry point. Defaults to the circuit name. + - ``target_profile`` (TargetProfile): The target profile to use for the compilation. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + Defaults to ``OutputSemantics.Qiskit``. + - ``shots`` (int): The number of shots to run the program for. Defaults to ``1024``. + - ``seed`` (int): The seed to use for the random number generator. Defaults to ``None``. + - ``search_path`` (str): The path to search for imports. Defaults to ``'.'``. + - ``output_fn`` (Callable): A callback function to receive the output of the circuit. + Defaults to ``None``. + - ``executor``: The executor to be used to submit the job. Defaults to ``SynchronousExecutor``. + :return: The simulation job. + :rtype: QsSimJob :raises QSharpError: If there is an error evaluating the source code. :raises QasmError: If there is an error generating, parsing, or compiling QASM. - :raises ValueError: If the run_input is not a QuantumCircuit - or List[QuantumCircuit]. + :raises ValueError: If run_input is not a QuantumCircuit or List[QuantumCircuit]. """ run_input = self._validate_quantum_circuits(run_input) @@ -172,19 +173,18 @@ def _run_qasm( Any gates, such as matrix unitaries, that are not able to be transpiled will result in an error. - Parameters: - source (str): The input OpenQASM 3 string to be processed. - **options: Additional keyword arguments to pass to the execution. Defaults to backend config values. - - target_profile (TargetProfile): The target profile to use for the compilation. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - name (str): The name of the circuit. This is used as the entry point for the program. Defaults to 'program'. - - search_path (str): The optional search path for resolving qasm imports. - - shots (int): The number of shots to run the program for. Defaults to 1. - - seed (int): The seed to use for the random number generator. - - output_fn (Optional[Callable[[Output], None]]): A callback function that will be called with each output. Defaults to None. - - :returns values: A result or runtime errors. - + :param source: The input OpenQASM 3 string to be processed. + :param default_options: Default backend option values. + :param **options: Common options: + + - ``target_profile`` (TargetProfile): The target profile to use for the compilation. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + - ``name`` (str): The name of the circuit. Defaults to ``'program'``. + - ``search_path`` (str): The optional search path for resolving qasm imports. + - ``shots`` (int): The number of shots to run the program for. + - ``seed`` (int): The seed to use for the random number generator. + - ``output_fn`` (Callable): A callback for each output. Defaults to ``None``. + :return: A list of results or runtime errors. :raises QSharpError: If there is an error evaluating the source code. :raises QasmError: If there is an error generating, parsing, or compiling QASM. """ diff --git a/source/pip/qsharp/interop/qiskit/backends/re_backend.py b/source/pip/qsharp/interop/qiskit/backends/re_backend.py index aad5b0b6c4..9e523d2bc8 100644 --- a/source/pip/qsharp/interop/qiskit/backends/re_backend.py +++ b/source/pip/qsharp/interop/qiskit/backends/re_backend.py @@ -44,21 +44,25 @@ def __init__( transpile_options: Optional[Dict[str, Any]] = None, qasm_export_options: Optional[Dict[str, Any]] = None, skip_transpilation: bool = False, - **fields, + **options, ): """ - Parameters: - target (Target): The target to use for the backend. - qiskit_pass_options (Dict): Options for the Qiskit passes. - transpile_options (Dict): Options for the transpiler. - qasm_export_options (Dict): Options for the QASM3 exporter. - **options: Additional options for the execution. - - params (EstimatorParams): Configuration values for resource estimation. - - name (str): The name of the circuit. This is used as the entry point for the program. - The circuit name will be used if not specified. - - search_path (str): Path to search in for qasm imports. Defaults to '.'. - - executor(ThreadPoolExecutor or other Executor): - The executor to be used to submit the job. Defaults to SynchronousExecutor. + :param target: The target to use for the backend. + :param qiskit_pass_options: Options for the Qiskit passes. + :type qiskit_pass_options: Dict + :param transpile_options: Options for the transpiler. + :type transpile_options: Dict + :param qasm_export_options: Options for the QASM3 exporter. + :type qasm_export_options: Dict + :param skip_transpilation: Skip Qiskit transpilation. + :type skip_transpilation: bool + :param **options: Default option overrides. These can also be overridden per-call via + :meth:`run`. Common options: + + - ``params`` (EstimatorParams): Configuration values for resource estimation. + - ``name`` (str): The name of the circuit used as the entry point. Defaults to the circuit name. + - ``search_path`` (str): Path to search in for qasm imports. Defaults to ``'.'``. + - ``executor``: The executor to be used to submit the job. Defaults to ``SynchronousExecutor``. """ super().__init__( @@ -67,7 +71,7 @@ def __init__( transpile_options, qasm_export_options, skip_transpilation, - **fields, + **options, ) @property @@ -98,22 +102,21 @@ def run( Performs resource estimation on the supplied QuantumCircuit via conversion to OpenQASM 3. - Parameters: - run_input ('QuantumCircuit'): The input Qiskit QuantumCircuit object. - params (Optional EstimatorParams): Configuration values for resource estimation. - **options: Additional options for the execution. - - name (str): The name of the circuit. This is used as the entry point for the program. - The circuit name will be used if not specified. - - search_path (str): Path to search in for qasm imports. Defaults to '.'. - - target_profile (TargetProfile): The target profile to use for the backend. - - executor(ThreadPoolExecutor or other Executor): - The executor to be used to submit the job. - Returns: - ReJob: The resource estimation job - + :param run_input: The input Qiskit QuantumCircuit object. + :param params: Configuration values for resource estimation. + :type params: EstimatorParams + :param **options: Per-call option overrides. Common options: + + - ``params`` (EstimatorParams): Configuration values for resource estimation. + - ``name`` (str): The name of the circuit used as the entry point. Defaults to the circuit name. + - ``search_path`` (str): Path to search in for qasm imports. Defaults to ``'.'``. + - ``target_profile`` (TargetProfile): The target profile to use for the backend. + - ``executor``: The executor to be used to submit the job. Defaults to ``SynchronousExecutor``. + :return: The resource estimation job. + :rtype: ReJob :raises QSharpError: If there is an error evaluating the source code. :raises QasmError: If there is an error generating, parsing, or compiling QASM. - :raises ValueError: If the run_input is not a QuantumCircuit. + :raises ValueError: If run_input is not a QuantumCircuit. """ if isinstance(run_input, QuantumCircuit): run_input = [run_input] diff --git a/source/pip/qsharp/interop/qiskit/jobs/qsjob.py b/source/pip/qsharp/interop/qiskit/jobs/qsjob.py index 6304b58905..23c3f27281 100644 --- a/source/pip/qsharp/interop/qiskit/jobs/qsjob.py +++ b/source/pip/qsharp/interop/qiskit/jobs/qsjob.py @@ -25,6 +25,13 @@ class QsJob(JobV1, ABC): + """ + Abstract base class for Q# Qiskit jobs. + + Manages asynchronous execution of a quantum circuit via a callable submitted + to a thread pool. Concrete subclasses must implement :meth:`result` and + :meth:`_submit_duration`. + """ def __init__( self, @@ -36,7 +43,18 @@ def __init__( executor=None, **kwargs, ) -> None: - super().__init__(backend, job_id, **kwargs) + """ + :param backend: The backend on which the job is run. + :param job_id: A unique identifier for the job. + :type job_id: str + :param job_callable: The callable that executes the circuit and returns a result. + :param run_input: The quantum circuit to execute. + :param input_params: Parameters forwarded to ``job_callable`` at execution time. + :type input_params: Dict + :param executor: Thread pool executor. Uses a default single-threaded executor if + not provided. + :param **kwargs: Additional keyword arguments passed to ``qiskit.providers.JobV1``. + """ self._run_input = run_input self._input_params = input_params @@ -45,12 +63,12 @@ def __init__( self._job_callable = job_callable self._status = JobStatus.INITIALIZING self._submit_start_time: Optional[float] = None + super().__init__(backend, job_id, **kwargs) def submit(self): """Submit the job to the backend for execution. - Raises: - JobError: if trying to re-submit the job. + :raises JobError: If trying to re-submit the job. """ if self._future is not None: raise JobError("Job has already been submitted.") @@ -114,6 +132,12 @@ def add_done_callback(self, fn: Callable[[Future[Result]], object]) -> None: class QsSimJob(QsJob): + """ + A Qiskit job that runs a quantum circuit on the Q# simulator. + + Submits the circuit for simulation and returns a ``qiskit.result.Result`` + containing shot-level measurement outcomes. + """ def result(self, timeout: Optional[float] = None) -> Result: return self._result(timeout=timeout) @@ -121,8 +145,7 @@ def result(self, timeout: Optional[float] = None) -> Result: def submit(self): """Submit the job to the backend for execution. - Raises: - JobError: if trying to re-submit the job. + :raises JobError: If trying to re-submit the job. """ shots = self._input_params.get("shots", -1) telemetry_events.on_qiskit_run(shots, 1) @@ -141,6 +164,12 @@ def _submit_duration(self, _future: Future): class ReJob(QsJob): + """ + A Qiskit job that runs the Q# Resource Estimator. + + Submits the circuit to the resource estimator and returns an + :class:`~qsharp.estimator.EstimatorResult` with the computed resource estimates. + """ def result(self, timeout: Optional[float] = None) -> EstimatorResult: return self._result(timeout=timeout) @@ -148,8 +177,7 @@ def result(self, timeout: Optional[float] = None) -> EstimatorResult: def submit(self): """Submit the job to the backend for execution. - Raises: - JobError: if trying to re-submit the job. + :raises JobError: If trying to re-submit the job. """ telemetry_events.on_qiskit_run_re() diff --git a/source/pip/qsharp/interop/qiskit/jobs/qsjobset.py b/source/pip/qsharp/interop/qiskit/jobs/qsjobset.py index ef6120af75..0a20908079 100644 --- a/source/pip/qsharp/interop/qiskit/jobs/qsjobset.py +++ b/source/pip/qsharp/interop/qiskit/jobs/qsjobset.py @@ -24,6 +24,15 @@ class QsJobSet(Job): + """ + A Qiskit job set that runs multiple quantum circuits concurrently. + + Each circuit in ``run_input`` is submitted as an individual + :class:`~qsharp.interop.qiskit.jobs.qsjob.QsSimJob` and executed in a thread pool. + :meth:`result` blocks until all constituent + jobs are complete and aggregates their ``qiskit.result.Result`` objects into a single + combined result. + """ def __init__( self, @@ -49,8 +58,7 @@ def __init__( def submit(self): """Submit the job to the backend for execution. - Raises: - JobError: if trying to re-submit the job. + :raises JobError: If trying to re-submit the job. """ if len(self._jobs) > 0: raise JobError("Jobs have already been submitted.") diff --git a/source/pip/qsharp/noisy_simulator/_noisy_simulator.pyi b/source/pip/qsharp/noisy_simulator/_noisy_simulator.pyi index ce712aa0b0..cd740324b6 100644 --- a/source/pip/qsharp/noisy_simulator/_noisy_simulator.pyi +++ b/source/pip/qsharp/noisy_simulator/_noisy_simulator.pyi @@ -24,10 +24,11 @@ class Operation: """ Construct an operation from a list of Kraus operators. Matrices must be of dimension 2^k x 2^k, where k is an integer. - Raises a `NoisySimulatorError` if the Kraus matrices are ill formed. - Input: - kraus_operators: List[List[List[complex]]], can be a Python list or a numpy array. + :param kraus_operators: List of Kraus operators. Each operator is a 2D matrix stored as + a list of lists of complex numbers, or a numpy array. + :type kraus_operators: List[List[List[complex]]] + :raises NoisySimulatorError: If the Kraus matrices are ill formed. """ ... diff --git a/source/pip/qsharp/openqasm/_circuit.py b/source/pip/qsharp/openqasm/_circuit.py index bcd77707bf..eaed78cba8 100644 --- a/source/pip/qsharp/openqasm/_circuit.py +++ b/source/pip/qsharp/openqasm/_circuit.py @@ -25,20 +25,48 @@ def circuit( Synthesizes a circuit for an OpenQASM program. Either a program string or an operation must be provided. - Args: - source (str): An OpenQASM program. Alternatively, a callable can be provided, - which must be an already imported global callable. - *args: The arguments to pass to the callable, if one is provided. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the program. This is used as the entry point for the program. - - search_path (Optional[str]): The optional search path for resolving file references. - Returns: - Circuit: The synthesized circuit. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error evaluating the program. - QSharpError: If there is an error synthesizing the circuit. + :param source: An OpenQASM program. Alternatively, a callable can be provided, + which must be an already imported global callable. + :type source: str or Callable + + :param *args: The arguments to pass to the callable, if one is provided. + + :keyword generation_method: The method to use for circuit generation. + :attr:`~qsharp.CircuitGenerationMethod.ClassicalEval` evaluates classical + control flow at circuit generation time. + :attr:`~qsharp.CircuitGenerationMethod.Simulate` runs a full simulation to + trace the circuit. + :attr:`~qsharp.CircuitGenerationMethod.Static` uses partial evaluation and + requires a non-``Unrestricted`` target profile. Defaults to ``None`` which + auto-selects the generation method. + :kwtype generation_method: :class:`~qsharp.CircuitGenerationMethod` + + :keyword max_operations: The maximum number of operations to include in the circuit. + Defaults to ``None`` which means no limit. + :kwtype max_operations: int + + :keyword source_locations: If ``True``, annotates each gate with its source location. + Defaults to ``False``. + :kwtype source_locations: bool + + :keyword group_by_scope: If ``True``, groups operations by their containing scope, such as function declarations or loop blocks. + Defaults to ``True``. + :kwtype group_by_scope: bool + + :keyword prune_classical_qubits: If ``True``, removes qubits that are never used in a quantum + gate (e.g. qubits only used as classical controls). Defaults to ``False``. + :kwtype prune_classical_qubits: bool + + :keyword name: The name of the program. This is used as the entry point for the program. + :kwtype name: str + + :keyword search_path: The optional search path for resolving file references. + :kwtype search_path: str + + :return: The synthesized circuit. + :rtype: :class:`~qsharp._native.Circuit` + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error evaluating or synthesizing the circuit. """ ipython_helper() diff --git a/source/pip/qsharp/openqasm/_compile.py b/source/pip/qsharp/openqasm/_compile.py index 850b9621dc..8f34963eb1 100644 --- a/source/pip/qsharp/openqasm/_compile.py +++ b/source/pip/qsharp/openqasm/_compile.py @@ -29,24 +29,22 @@ def compile( target as QIR (Quantum Intermediate Representation). Either a full program or a callable with arguments must be provided. - Args: - source (str): An OpenQASM program. Alternatively, a callable can be provided, - which must be an already imported global callable. - *args: The arguments to pass to the callable, if one is provided. - **kwargs: Additional keyword arguments to pass to the compilation when source program is provided. - - name (str): The name of the circuit. This is used as the entry point for the program. - - target_profile (TargetProfile): The target profile to use for code generation. - - search_path (Optional[str]): The optional search path for resolving file references. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - Returns: - QirInputData: The compiled program. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error compiling the program. - - To get the QIR string from the compiled program, use `str()`. + :param source: An OpenQASM program. Alternatively, a callable can be provided, + which must be an already imported global callable. + :type source: str or Callable + :param *args: The arguments to pass to the callable, if one is provided. + :param **kwargs: Additional keyword arguments for compiling the source program. Common options: + + - ``name`` (str): The name of the circuit. This is used as the entry point for the program. + - ``target_profile`` (TargetProfile): The target profile to use for code generation. + - ``search_path`` (str): The optional search path for resolving file references. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + :return: The compiled program. Use ``str()`` to get the QIR string. + :rtype: QirInputData + :raises ValueError: If ``source`` is neither a string nor a callable with a + ``__global_callable`` attribute. + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error compiling the program. Example: @@ -91,7 +89,9 @@ def compile( **kwargs, ) else: - raise ValueError("source must be a string or a callable with __global_callable attribute") + raise ValueError( + "source must be a string or a callable with __global_callable attribute" + ) res = QirInputData("main", ll_str) durationMs = (monotonic() - start) * 1000 diff --git a/source/pip/qsharp/openqasm/_estimate.py b/source/pip/qsharp/openqasm/_estimate.py index 1555e58549..755f61eaec 100644 --- a/source/pip/qsharp/openqasm/_estimate.py +++ b/source/pip/qsharp/openqasm/_estimate.py @@ -29,22 +29,23 @@ def estimate( Estimates the resource requirements for executing OpenQASM source code. Either a full program or a callable with arguments must be provided. - Args: - source (str): An OpenQASM program. Alternatively, a callable can be provided, - which must be an already imported global callable. - params: The parameters to configure estimation. - callable: The callable to estimate resources for, if no entry expression is provided. - *args: The arguments to pass to the callable, if one is provided. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the circuit. This is used as the entry point for the program. Defaults to 'program'. - - search_path (str): The optional search path for resolving imports. + :param source: An OpenQASM program. Alternatively, a callable can be provided, + which must be an already imported global callable. + :type source: str or Callable + :param params: The parameters to configure estimation. + :type params: Dict, List, or EstimatorParams + :param *args: The arguments to pass to the callable, if one is provided. + :param **kwargs: Additional keyword arguments. Common options: - Returns: - EstimatorResult: The estimated resources. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error compiling the program. + - ``name`` (str): The name of the circuit. This is used as the entry point for the program. + Defaults to ``'program'``. + - ``search_path`` (str): The optional search path for resolving imports. + :return: The estimated resources. + :rtype: EstimatorResult + :raises ValueError: If ``source`` is neither a string nor a callable with a + ``__global_callable`` attribute. + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error compiling the program. """ ipython_helper() diff --git a/source/pip/qsharp/openqasm/_import.py b/source/pip/qsharp/openqasm/_import.py index 1129204309..e616ee0d39 100644 --- a/source/pip/qsharp/openqasm/_import.py +++ b/source/pip/qsharp/openqasm/_import.py @@ -19,31 +19,30 @@ def import_openqasm( **kwargs: Any, ) -> Any: """ - Imports OpenQASM source code into the active QDK interpreter. By default, import uses `ProgramType.Operation` such that - the source becomes a Q# operation in the global namespace with parameters for any declared classical inputs and - paramters for each of the declared qubits, while any explicit or implicit output declarations become the return - type of the operation. - Alternatively, specifying `ProgramType.File` will treat the input source as a stand-alone program and create an - operation in the `qasm_import` namespace that only takes classical parameters, allocates the required qubits + Imports OpenQASM source code into the active QDK interpreter. By default, import uses ``ProgramType.Operation`` + such that the source becomes a Q# operation in the global namespace with parameters for any declared classical + inputs and parameters for each of the declared qubits, while any explicit or implicit output declarations become + the return type of the operation. + Alternatively, specifying ``ProgramType.File`` will treat the input source as a stand-alone program and create + an operation in the ``qasm_import`` namespace that only takes classical parameters, allocates the required qubits internally and releases them at the end of the operation. - Finally, using `ProgramType.Fragments` executes the provided source in the current interactive interpreter, + Finally, using ``ProgramType.Fragments`` executes the provided source in the current interactive interpreter, defining any declared variables or operations in the current scope and returning the value of the last statement in the source. - Args: - source (str): An OpenQASM program or fragment. - **kwargs: Additional keyword arguments to pass to the execution. - - name (str): The name of the program. This is used as the entry point for the program. - - search_path (Optional[str]): The optional search path for resolving file references. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - program_type (ProgramType, optional): The type of program compilation to perform. Defaults to `ProgramType.Operation`. + :param source: An OpenQASM program or fragment. + :type source: str + :param **kwargs: Additional keyword arguments. Common options: - Returns: - value: The value returned by the last statement in the source code. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error compiling the program. + - ``name`` (str): The name of the program. This is used as the entry point for the program. + - ``search_path`` (str): The optional search path for resolving file references. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + - ``program_type`` (ProgramType): The type of program compilation to perform. + Defaults to ``ProgramType.Operation``. + :return: The value returned by the last statement in the source code. + :rtype: Any + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error compiling the program. """ ipython_helper() diff --git a/source/pip/qsharp/openqasm/_run.py b/source/pip/qsharp/openqasm/_run.py index e502bca7bb..1b82cb41ff 100644 --- a/source/pip/qsharp/openqasm/_run.py +++ b/source/pip/qsharp/openqasm/_run.py @@ -48,32 +48,37 @@ def run( Either a full program or a callable with arguments must be provided. Each shot uses an independent instance of the simulator. - Args: - source (str): An OpenQASM program. Alternatively, a callable can be provided, - which must be an already imported global callable. - shots: The number of shots to run, Defaults to 1024. - *args: The arguments to pass to the callable, if one is provided. - on_result: A callback function that will be called with each result. Only used when a callable is provided. - save_events: If true, the output of each shot will be saved. If false, they will be printed. Only used when a callable is provided. - noise: The noise to use in simulation. - qubit_loss: The probability of qubit loss in simulation. - as_bitstring: If true, the result registers will be converted to bitstrings. - **kwargs: Additional keyword arguments to pass to the compilation when source program is provided. - - name (str): The name of the circuit. This is used as the entry point for the program. - - target_profile (TargetProfile): The target profile to use for code generation. - - search_path (Optional[str]): The optional search path for resolving file references. - - output_semantics (OutputSemantics, optional): The output semantics for the compilation. - - seed (int): The seed to use for the random number generator. - - Returns: - values: A list of results or runtime errors. If `save_events` is true, - a List of ShotResults is returned. - - Raises: - QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. - QSharpError: If there is an error interpreting the input. - ValueError: If the number of shots is less than 1. - ValueError: If the `on_result` and `save_events` parameters are used when running OpenQASM programs. + :param source: An OpenQASM program. Alternatively, a callable can be provided, + which must be an already imported global callable. + :type source: str or Callable + :param shots: The number of shots to run. Defaults to ``1024``. + :type shots: int + :param *args: The arguments to pass to the callable, if one is provided. + :param on_result: A callback function that will be called with each result. + Only used when a callable is provided. + :type on_result: Callable + :param save_events: If true, the output of each shot will be saved. If false, they will be printed. + Only used when a callable is provided. + :type save_events: bool + :param noise: The noise to use in simulation. + :type noise: Union[Tuple[float, float, float], PauliNoise, BitFlipNoise, PhaseFlipNoise, DepolarizingNoise, NoiseConfig] + :param qubit_loss: The probability of qubit loss in simulation. + :type qubit_loss: float + :param as_bitstring: If true, the result registers will be converted to bitstrings. + :type as_bitstring: bool + :param **kwargs: Additional keyword arguments for compiling the source program. Common options: + + - ``name`` (str): The name of the circuit. This is used as the entry point for the program. + - ``target_profile`` (TargetProfile): The target profile to use for code generation. + - ``search_path`` (str): The optional search path for resolving file references. + - ``output_semantics`` (OutputSemantics): The output semantics for the compilation. + - ``seed`` (int): The seed to use for the random number generator. + :return: A list of results or runtime errors. If ``save_events`` is true, a list of ``ShotResult`` values is returned. + :rtype: List[Any] + :raises QasmError: If there is an error generating, parsing, or analyzing the OpenQASM source. + :raises QSharpError: If there is an error interpreting the input. + :raises ValueError: If the number of shots is less than 1. + :raises QasmError: If ``on_result`` or ``save_events`` are used when running OpenQASM programs. """ ipython_helper() diff --git a/source/pip/qsharp/utils/_utils.py b/source/pip/qsharp/utils/_utils.py index 6268c1801a..26984dc4db 100644 --- a/source/pip/qsharp/utils/_utils.py +++ b/source/pip/qsharp/utils/_utils.py @@ -13,7 +13,8 @@ def dump_operation(operation: str, num_qubits: int) -> List[List[complex]]: :param operation: The operation to be performed, which must operate on a list of qubits. :param num_qubits: The number of qubits to be used. - :returns: The matrix representing the operation. + :return: The matrix representing the operation. + :rtype: List[List[complex]] """ code = f"""{{ let op = {operation}; diff --git a/source/qdk_package/src/qdk/__init__.py b/source/qdk_package/src/qdk/__init__.py index ea3a13001e..8a14c157fa 100644 --- a/source/qdk_package/src/qdk/__init__.py +++ b/source/qdk_package/src/qdk/__init__.py @@ -3,15 +3,15 @@ """qdk bundling top-level package. -Design goals: - * Provide a single import root `qdk` that exposes bundled quantum tooling as - submodules (`qdk.qsharp`, `qdk.widgets`, etc.). - -Optional extras: - azure -> installs `azure-quantum`, available as `qdk.azure`. - qiskit -> installs `qiskit`, available as `qdk.qiskit`. - cirq -> installs `cirq-core` + `cirq-ionq`, available as `qdk.cirq`. - jupyter -> installs `qsharp-widgets` + `qsharp-jupyterlab`; exposes `qdk.widgets`. +Provides a single import root ``qdk`` that exposes bundled quantum tooling as +submodules (``qdk.qsharp``, ``qdk.widgets``, etc.). + +Optional extras install additional dependencies and submodules: + +- ``azure`` — installs ``azure-quantum``, available as ``qdk.azure``. +- ``qiskit`` — installs ``qiskit``, available as ``qdk.qiskit``. +- ``cirq`` — installs ``cirq-core`` + ``cirq-ionq``, available as ``qdk.cirq``. +- ``jupyter`` — installs ``qsharp-widgets`` + ``qsharp-jupyterlab``; exposes ``qdk.widgets``. """ diff --git a/source/qdk_package/src/qdk/azure/__init__.py b/source/qdk_package/src/qdk/azure/__init__.py index 8c5ba233ca..c3bef4cd8a 100644 --- a/source/qdk_package/src/qdk/azure/__init__.py +++ b/source/qdk_package/src/qdk/azure/__init__.py @@ -3,9 +3,10 @@ """qdk.azure package: re-export of azure.quantum namespaces. -Requires optional extra installation: `pip install qdk[azure]`. +Requires optional extra installation: ``pip install qdk[azure]``. + +Usage example:: -Usage examples: from qdk import azure ws = azure.Workspace(...) # if upstream exposes Workspace at top-level diff --git a/source/qdk_package/src/qdk/azure/cirq.py b/source/qdk_package/src/qdk/azure/cirq.py index 02d2b71b78..2a7a87fd3b 100644 --- a/source/qdk_package/src/qdk/azure/cirq.py +++ b/source/qdk_package/src/qdk/azure/cirq.py @@ -5,7 +5,8 @@ Requires installation: ``pip install \"qdk[azure,cirq]\"``. -Example: +Example:: + from qdk.azure.cirq import """ diff --git a/source/qdk_package/src/qdk/azure/qiskit.py b/source/qdk_package/src/qdk/azure/qiskit.py index 9a4fa98d0f..d97ce88839 100644 --- a/source/qdk_package/src/qdk/azure/qiskit.py +++ b/source/qdk_package/src/qdk/azure/qiskit.py @@ -5,7 +5,8 @@ Requires installation: ``pip install \"qdk[azure,qiskit]\"``. -Example: +Example:: + from qdk.azure.qiskit import """ diff --git a/source/qdk_package/src/qdk/cirq.py b/source/qdk_package/src/qdk/cirq.py index a1ae0c31be..fa4583d6ff 100644 --- a/source/qdk_package/src/qdk/cirq.py +++ b/source/qdk_package/src/qdk/cirq.py @@ -3,9 +3,12 @@ """Cirq interoperability for the Q# ecosystem. -This module provides a :class:`NeutralAtomSampler` — a standard -``cirq.Sampler`` that runs Cirq circuits on the local NeutralAtomDevice -simulator. +This module re-exports all public symbols from ``qsharp.interop.cirq``, +making them available under the ``qdk.cirq`` namespace. The primary export +is ``NeutralAtomSampler`` — a standard ``cirq.Sampler`` that runs Cirq +circuits on the local NeutralAtomDevice simulator. + +Requires the ``cirq`` extra: ``pip install qdk[cirq]``. Usage:: diff --git a/source/qdk_package/src/qdk/estimator.py b/source/qdk_package/src/qdk/estimator.py index de1899305a..6336977666 100644 --- a/source/qdk_package/src/qdk/estimator.py +++ b/source/qdk_package/src/qdk/estimator.py @@ -1,6 +1,22 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -"""Shim exposing qsharp.estimator as qdk.estimator.""" +"""Resource estimation utilities for the Q# ecosystem. + +This module re-exports all public symbols from ``qsharp.estimator``, +making them available under the ``qdk.estimator`` namespace. It provides +classes for configuring and interpreting Microsoft Resource Estimator jobs, +including qubit parameter models, QEC schemes, distillation unit +specifications, error budgets, and the result container. + +Key exports: + +- ``EstimatorParams`` — top-level input parameters for a resource estimation job. +- ``EstimatorResult`` — result container with formatted tables and diagrams. +- ``LogicalCounts`` — pre-calculated logical resource counts for physical estimation. +- ``QubitParams``, ``QECScheme`` — predefined model name constants. +- ``EstimatorQubitParams``, ``EstimatorQecScheme`` — custom model configuration. +- ``ErrorBudgetPartition``, ``EstimatorConstraints`` — budget and constraint settings. +""" from qsharp.estimator import * # pyright: ignore[reportWildcardImportFromLibrary] diff --git a/source/qdk_package/src/qdk/openqasm.py b/source/qdk_package/src/qdk/openqasm.py index 8a8dd10a04..1696d844ed 100644 --- a/source/qdk_package/src/qdk/openqasm.py +++ b/source/qdk_package/src/qdk/openqasm.py @@ -1,6 +1,20 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -"""Shim exposing qsharp.openqasm as qdk.openqasm.""" +"""OpenQASM interoperability for the Q# ecosystem. + +This module re-exports all public symbols from ``qsharp.openqasm``, +making them available under the ``qdk.openqasm`` namespace. It provides +functions for importing, compiling, running, and estimating resources for +OpenQASM 2.0 and 3.0 programs using the local Q# toolchain. + +Key exports: + +- ``import_openqasm`` — parse and import an OpenQASM program into the Q# interpreter. +- ``run`` — execute an OpenQASM program and return shot results. +- ``compile`` — compile an OpenQASM program to QIR. +- ``estimate`` — run the Microsoft Resource Estimator on an OpenQASM program. +- ``circuit`` — synthesize a circuit diagram from an OpenQASM program. +""" from qsharp.openqasm import * # pyright: ignore[reportWildcardImportFromLibrary] diff --git a/source/qdk_package/src/qdk/qiskit.py b/source/qdk_package/src/qdk/qiskit.py index aece2ce7f8..69c1b18db5 100644 --- a/source/qdk_package/src/qdk/qiskit.py +++ b/source/qdk_package/src/qdk/qiskit.py @@ -25,8 +25,8 @@ :func:`estimate` Convenience function that runs resource estimation on a Qiskit circuit - and returns an `EstimatorResult` directly, without needing to - construct a backend or job manually. + and returns an :class:`EstimatorResult` directly, without + needing to construct a backend or job manually. Usage:: diff --git a/source/qdk_package/src/qdk/qsharp.py b/source/qdk_package/src/qdk/qsharp.py index 8412b7beab..0bef6d4893 100644 --- a/source/qdk_package/src/qdk/qsharp.py +++ b/source/qdk_package/src/qdk/qsharp.py @@ -1,7 +1,18 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -"""Re-export of `qsharp` as `qdk.qsharp`.""" +"""Full re-export of the ``qsharp`` package as ``qdk.qsharp``. + +This module makes the entire ``qsharp`` public API available under the +``qdk.qsharp`` namespace, so code that imports from ``qdk.qsharp`` behaves +identically to importing from ``qsharp`` directly. It also pulls in +``dump_operation`` from ``qsharp.utils``. + +Key exports include ``init``, ``run``, ``eval``, ``compile``, ``circuit``, +``estimate``, ``dump_machine``, ``dump_circuit``, ``StateDump``, +``TargetProfile``, and the noise classes ``PauliNoise``, ``DepolarizingNoise``, +``BitFlipNoise``, and ``PhaseFlipNoise``. +""" from qsharp import * # pyright: ignore[reportWildcardImportFromLibrary] from qsharp.utils import dump_operation # pyright: ignore[reportUnusedImport] diff --git a/source/qdk_package/src/qdk/simulation.py b/source/qdk_package/src/qdk/simulation.py index 71a2acc0e1..ea01b936d3 100644 --- a/source/qdk_package/src/qdk/simulation.py +++ b/source/qdk_package/src/qdk/simulation.py @@ -1,5 +1,18 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. +"""Simulation utilities for the Q# ecosystem. + +This module exposes the core building blocks for noise-aware quantum simulation: + +- ``NeutralAtomDevice`` — models a neutral atom quantum device with configurable + zone layouts, qubit registers, and movement constraints. Used to compile + and simulate circuits on a realistic hardware topology. + +- ``NoiseConfig`` — configures per-gate Pauli noise (including qubit loss) for + use with the Q# simulator. Assign noise tables to individual gate intrinsics + to model depolarizing, bit-flip, phase-flip, or correlated noise channels. +""" + from qsharp._device._atom import NeutralAtomDevice from qsharp._simulation import NoiseConfig