Source code for qbraid.runtime.qperfect.device

# Copyright 2026 qBraid
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Module defining QPerfect (MIMIQ) device class.

"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from qbraid.runtime.device import QuantumDevice
from qbraid.runtime.enums import DeviceStatus

from .job import QPerfectJob

if TYPE_CHECKING:
    from mimiqcircuits import Circuit as MimiqCircuit

    import qbraid.runtime
    import qbraid.runtime.qperfect.provider

# MIMIQ ``MimiqConnection.submit`` options that may be forwarded as runtime options. ``nsamples``
# (shots) and ``label`` (name) are set explicitly, so they are excluded here.
_SUBMIT_OPTIONS = frozenset(
    {
        "algorithm",
        "bitstrings",
        "timelimit",
        "bonddim",
        "entdim",
        "mpscutoff",
        "remove_swaps",
        "canonicaldecompose",
        "fuse",
        "reorderqubits",
        "reorderqubits_seed",
        "seed",
        "qasmincludes",
        "mpsmethod",
        "mpotraversal",
        "noisemodel",
        "streaming",
    }
)


[docs] class QPerfectDevice(QuantumDevice): """QPerfect (MIMIQ) simulator device interface."""
[docs] def __init__( self, profile: qbraid.runtime.TargetProfile, provider: qbraid.runtime.qperfect.provider.QPerfectProvider, ): super().__init__(profile=profile) self._provider = provider
def __str__(self): return f"{self.__class__.__name__}('{self.id}')" def status(self) -> DeviceStatus: """Return the device status based on connection health. MIMIQ exposes no device-status endpoint; the emulator is ``ONLINE`` when the provider can authenticate a connection to the cloud, and ``OFFLINE`` otherwise. """ try: connection = self._provider.connection if connection.connection.isOpen(): return DeviceStatus.ONLINE return DeviceStatus.OFFLINE except Exception: # pylint: disable=broad-except return DeviceStatus.OFFLINE # pylint: disable-next=arguments-differ def submit( self, run_input: MimiqCircuit | list[MimiqCircuit], shots: int = 100, *, name: str | None = None, **options: Any, ) -> QPerfectJob: """Submit one or more native MIMIQ circuits to the emulator. Args: run_input: A native ``mimiqcircuits.Circuit`` (or a list of them for a batch), as produced by the ``qiskit -> mimiqcircuits`` conversion during ``run``. A batch is executed as a single job; results come back per circuit in submission order. shots: Number of samples per circuit (MIMIQ ``nsamples``). Defaults to 100. name: Optional human-readable label for the job. **options: MIMIQ submit options forwarded to the emulator, e.g. ``algorithm`` (``"auto"`` / ``"statevector"`` / ``"mps"``), ``timelimit``, ``bonddim``, ``entdim``, ``seed``, ``bitstrings``, or ``noisemodel``. ``algorithm`` defaults to ``"auto"`` for a single circuit and to ``"mps"`` for a batch. Returns: QPerfectJob: A handle to the submitted job. Raises: ValueError: If an unsupported submit option is passed. """ unknown = set(options) - _SUBMIT_OPTIONS if unknown: raise ValueError( f"Unsupported MIMIQ submit option(s): {sorted(unknown)}. " f"Supported: {sorted(_SUBMIT_OPTIONS)}." ) connection = self._provider.connection kwargs: dict[str, Any] = {"nsamples": shots, "label": name or "qbraid", **options} # MIMIQ refuses algorithm="auto" for a batch. "mps" is what "auto" resolves to past toy # widths and runs at every width the device advertises; "statevector" fails above ~30. kwargs.setdefault("algorithm", "auto" if not isinstance(run_input, list) else "mps") execution = connection.submit(run_input, **kwargs) return QPerfectJob(job_id=str(execution), connection=connection, device=self, shots=shots)