File size: 1,641 Bytes
9f8cf99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""Contracts for acceleration backends and execution metadata."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Mapping, Protocol, runtime_checkable

import numpy as np


@dataclass(frozen=True)
class AccelerationMetadata:
    """Metadata describing one accelerator invocation."""

    name: str
    enabled: bool
    degraded: bool = False
    reason: str | None = None
    details: Mapping[str, Any] = field(default_factory=dict)

    def as_dict(self) -> dict[str, Any]:
        return {
            "name": self.name,
            "enabled": self.enabled,
            "degraded": self.degraded,
            "reason": self.reason,
            "details": dict(self.details),
        }


@dataclass(frozen=True)
class AcceleratorResult:
    """Return type for an accelerator call with execution metadata."""

    state: np.ndarray
    metadata: AccelerationMetadata


@runtime_checkable
class NoiseAccelerator(Protocol):
    """Protocol for one- and two-ket-path accelerator implementations."""

    name: str
    metadata: AccelerationMetadata

    def apply_pauli_channel(
        self,
        psi: np.ndarray,
        *,
        n_qubits: int,
        target_qubit: int,
        probs: list[float] | np.ndarray,
        seed: int = 42,
    ) -> AcceleratorResult:
        """Apply single-qubit Pauli channel to a statevector."""

    def apply_kraus_1q(
        self,
        rho: np.ndarray,
        *,
        n_qubits: int,
        target_qubit: int,
        kraus_ops: np.ndarray,
    ) -> AcceleratorResult:
        """Apply single-qubit Kraus channel to a density matrix."""