Skip to main content
Version: master

API Reference

Use the QDP Python guide for backend selection and complete workflows. Use this generated reference for signatures, parameters, return values, and exceptions.

Key entry points​

Benchmark API: throughput and latency benchmarks for the CUDA and AMD backends.

Usage:

from qumat_qdp import QdpBenchmark, ThroughputResult, LatencyResult

# CUDA backend (default, Rust pipeline):
result = (QdpBenchmark(device_id=0).qubits(16).encoding("amplitude")
.batches(100, size=64).warmup(2).run_throughput())

# AMD backend (Triton, ROCm):
result = (QdpBenchmark(device_id=0).backend("amd").qubits(16)
.encoding("amplitude").batches(100, size=64).run_throughput())

ThroughputResult​

@dataclass
class ThroughputResult()

Throughput benchmark measurement.

Returned by QdpBenchmark.run_throughput(). duration_sec is the measured timed section after any configured warmup batches. vectors_per_sec is computed over total_batches * batch_size encoded input vectors.

LatencyResult​

@dataclass
class LatencyResult()

Latency benchmark measurement.

Returned by QdpBenchmark.run_latency(). duration_sec is the same timed interval used for throughput, and latency_ms_per_vector is the average milliseconds per encoded input vector across the measured batches.

QdpBenchmark​

class QdpBenchmark()

Builder for throughput/latency benchmarks.

Supports two backends:

  • "cuda" (default): Rust-optimized pipeline (no Python for-loop, GIL released).
  • "amd": Triton AMD engine on a ROCm device.

qubits​

def qubits(n: int) -> QdpBenchmark

Set the number of qubits for benchmarked encodings.

Arguments:

  • n: Number of qubits in each encoded output state.

Returns:

This builder for fluent chaining.

encoding​

def encoding(method: str) -> QdpBenchmark

Set the encoding method to benchmark.

Arguments:

  • method: Encoding name, for example "amplitude", "angle", "basis", "iqp", or "iqp-z".

Returns:

This builder for fluent chaining.

batches​

def batches(total: int, size: int = 64) -> QdpBenchmark

Set the number and size of benchmark batches.

Arguments:

  • total: Number of timed batches to process.
  • size: Number of vectors in each batch.

Returns:

This builder for fluent chaining.

prefetch​

def prefetch(n: int) -> QdpBenchmark

Accept a prefetch setting for fluent API compatibility.

The current Rust benchmark pipeline manages work internally and the AMD path does not use a Python-side prefetch queue, so n is intentionally ignored.

Arguments:

  • n: Requested prefetch depth; currently unused.

Returns:

self for fluent builder chaining.

warmup​

def warmup(n: int) -> QdpBenchmark

Set the number of warmup batches run before timing.

Arguments:

  • n: Number of batches to execute before measurements begin.

Returns:

This builder for fluent chaining.

backend​

def backend(name: str) -> QdpBenchmark

Select the benchmark execution backend.

"cuda" (the default) uses the native optimized pipeline exposed by the _qdp extension and raises at run time if that extension or entry point is unavailable. "amd" runs the Triton AMD engine on the selected ROCm device and raises at run time if no ROCm runtime is available.

Arguments:

  • name: "cuda" or "amd".

Raises:

  • ValueError: If name is not a supported backend.

Returns:

self for fluent builder chaining.

dtype​

def dtype(dtype: str) -> QdpBenchmark

Set pipeline element dtype: 'f32' (default) or 'f64'.

'f32' uses the float32 batch path where the encoding supports it (amplitude, angle, basis); for other encodings the Rust pipeline falls back to f64.

run_throughput​

def run_throughput() -> ThroughputResult

Run the configured throughput benchmark.

qubits() and batches() must be configured before calling this method. The default "cuda" backend calls the native _qdp pipeline with any configured warmup batches; "amd" runs a Python encoder loop and synchronizes GPU timing.

Raises:

  • ValueError: If required benchmark parameters are missing.
  • RuntimeError: If the selected GPU backend is unavailable.

Returns:

A ThroughputResult containing elapsed seconds and encoded vectors per second.

run_latency​

def run_latency() -> LatencyResult

Run the configured latency benchmark.

qubits() and batches() must be configured before calling this method. The CUDA backend reports latency from the native pipeline; the AMD backend derives average latency from its throughput run.

Raises:

  • ValueError: If required benchmark parameters are missing.
  • RuntimeError: If the selected GPU backend is unavailable.

Returns:

A LatencyResult containing elapsed seconds and mean milliseconds per encoded vector.

Unified Python facade for explicit QDP backend selection.

QdpEngine​

class QdpEngine()

Select and delegate to a native QDP encoding backend.

QdpEngine is the small public Python facade used by callers that want explicit backend selection. backend="cuda" routes to the Rust/CUDA extension-backed engine. backend="amd" and backend="triton_amd" route to the AMD/Triton implementation. The selected backend is exposed as self.backend ("cuda" or "amd") and all encode() calls are forwarded to that engine.

Arguments:

  • device_id: GPU device ordinal to use.
  • precision: Numeric precision requested from the backend, such as "float32" or "float64" when supported by that backend.
  • backend: Backend selector. Valid values are "cuda", "amd", and "triton_amd".

Raises:

  • ValueError: If backend is not one of the supported selectors.

__init__​

def __init__(device_id: int = 0,
precision: str = "float32",
backend: str = "cuda") -> None

Create a backend-selecting QDP engine facade.

Arguments:

  • device_id: GPU device ordinal to use.
  • precision: Numeric precision requested from the backend.
  • backend: Backend selector, either "cuda", "amd", or "triton_amd".

Raises:

  • ValueError: If backend is not supported.

encode​

def encode(data: Any,
num_qubits: int,
encoding_method: str = "amplitude") -> QdpTensor

Encode input samples with the configured backend.

Arguments:

  • data: Input samples accepted by the selected backend.
  • num_qubits: Number of qubits in the output state vector.
  • encoding_method: Encoding strategy, such as "amplitude", "angle", "basis", "iqp", "iqp-z", or "phase" when supported by the backend.

Raises:

  • ValueError: If the backend does not support encoding_method.

Returns:

A QdpTensor wrapping the backend-native result; convert with torch.from_dlpack(result) or result.to_torch().

Unified tensor facade for backend-native QDP results.

QdpTensor​

@dataclass
class QdpTensor()

DLPack-compatible wrapper for backend-native QDP tensor results.

The Rust/CUDA path and other native backends may return objects whose concrete tensor type is backend-specific. QdpTensor preserves that object in value while exposing __dlpack__ and __dlpack_device__ so consumers such as PyTorch can import it without a copy.

Arguments:

  • value: Backend-native tensor-like object. It must implement the DLPack protocol when converted with to_torch() or torch.from_dlpack.
  • backend: Human-readable backend name used in error messages.

Raises:

  • RuntimeError: If value does not implement the required DLPack methods when conversion is attempted.

__dlpack__​

def __dlpack__(stream: int | None = None, **kwargs: Any) -> Any

Return a DLPack capsule for the wrapped backend tensor.

Arguments:

  • stream: Optional consumer stream to pass through to the wrapped tensor's __dlpack__ implementation.
  • kwargs: Further DLPack keyword arguments (such as max_version) passed through unchanged.

Raises:

  • RuntimeError: If the wrapped value does not implement __dlpack__.

Returns:

A DLPack capsule representing value.

__dlpack_device__​

def __dlpack_device__() -> Any

Return the DLPack device descriptor for the wrapped tensor.

Raises:

  • RuntimeError: If the wrapped value does not implement __dlpack_device__.

Returns:

The (device_type, device_id) tuple reported by value.

to_torch​

def to_torch() -> Any

Convert the wrapped tensor to a PyTorch tensor via DLPack.

Returns:

A torch.Tensor sharing storage with the backend tensor when the backend's DLPack producer supports zero-copy exchange.

QuantumTensor​

Backward-compatible alias for QdpTensor.

Quantum Data Loader: Python builder for Rust-backed batch iterator.

Usage:

from qumat_qdp import QuantumDataLoader

loader = (QuantumDataLoader(device_id=0).qubits(16).encoding("amplitude")
.batches(100, size=64).source_synthetic())
for qt in loader:
batch = torch.from_dlpack(qt)
...

QuantumDataLoader​

class QuantumDataLoader()

Builder for batched QDP encoding iterators.

QuantumDataLoader can generate synthetic input samples or read supported file formats, then encode each batch with the selected backend. Every backend yields QdpTensor batches; batch.value is the backend-native object (a Rust _qdp.QuantumTensor for "cuda", a torch.Tensor for "amd"). The "auto" backend picks the GPU backend for the host ("cuda" on NVIDIA, "amd" on AMD ROCm) and raises when neither is usable.

__init__​

def __init__(device_id: int = 0,
num_qubits: int = 16,
batch_size: int = 64,
total_batches: int = 100,
encoding_method: str = "amplitude",
seed: int | None = None) -> None

Create a loader builder with default synthetic batching settings.

Arguments:

  • device_id: GPU device ordinal (CUDA or ROCm, per the backend).
  • num_qubits: Number of qubits in each encoded output state.
  • batch_size: Number of samples per emitted batch.
  • total_batches: Maximum number of batches to emit.
  • encoding_method: Encoding method name.
  • seed: Optional synthetic data seed.

Raises:

  • ValueError: If any initial setting is invalid.

qubits​

def qubits(n: int) -> QuantumDataLoader

Set the number of qubits used by subsequent encodings.

n must be a positive integer. The value controls the encoded state size (for example, amplitude and phase-style encodings produce vectors of length 2**n) and the expected input width for encodings such as "angle" and "iqp-z".

Arguments:

  • n: Positive qubit count.

Raises:

  • ValueError: If n is not a positive integer.

Returns:

self for fluent builder chaining.

encoding​

def encoding(method: str) -> QuantumDataLoader

Set the quantum feature encoding method.

Valid values are "amplitude", "angle", "basis", "iqp", "iqp-z", and "phase". Names are matched case-insensitively and normalized to the canonical lowercase spelling before they reach the selected backend.

Arguments:

  • method: Encoding method name.

Raises:

  • ValueError: If method is empty, not a string, or not a supported encoding.

Returns:

self for fluent builder chaining.

batches​

def batches(total: int, size: int = 64) -> QuantumDataLoader

Set the number of batches to produce and samples per batch.

Both total and size must be positive integers. For synthetic sources, total is the exact number of generated batches. For file sources loaded in memory by the AMD backend, iteration stops at the smaller of total and the number of complete/partial batches available from the loaded file.

Arguments:

  • total: Positive maximum number of batches to emit.
  • size: Positive number of samples per encoded batch.

Raises:

  • ValueError: If either argument is not a positive integer.

Returns:

self for fluent builder chaining.

source_synthetic​

def source_synthetic(total_batches: int | None = None) -> QuantumDataLoader

Select the synthetic data source.

Synthetic data is the default when no file source is configured, but calling this method records the source choice explicitly. Use seed() to make generated samples reproducible where the selected backend supports seeded generation. If total_batches is provided, it overrides the current batch count and must be a positive integer. Selecting both source_synthetic() and source_file() on the same loader is rejected when iteration starts.

Arguments:

  • total_batches: Optional positive replacement for the configured number of batches.

Raises:

  • ValueError: If total_batches is provided but is not a positive integer.

Returns:

self for fluent builder chaining.

source_file​

def source_file(path: str, streaming: bool = False) -> QuantumDataLoader

Use a file data source.

Non-streaming native loading accepts .parquet, .arrow, .feather, .ipc, .npy, .pt, .pth, and .pb files. The AMD backend supports only .npy, .pt, and .pth inputs because it loads the full tensor into memory before encoding. Streaming mode is native-only and currently accepts .parquet files. Remote s3:// and gs:// paths are accepted when the native remote I/O feature is enabled; remote query strings and fragments are rejected.

Element precision is controlled by dtype(). By default file input is loaded as float64 (lossless). Selecting dtype("float32") narrows f64 file contents to f32 on load; values outside the f32 range become ±Inf. basis encoding is exempt: its values are integer state indices, so it is always loaded as f64 and an explicit float32 request is rejected when an index exceeds f32's exact integer range (2**24).

Arguments:

  • path: Local or supported remote input path.
  • streaming: Whether to request native streaming file loading.

Raises:

  • ValueError: If path is empty, includes an unsupported remote query/fragment, or requests streaming for an unsupported extension.

Returns:

self for fluent builder chaining.

dtype​

def dtype(name: str) -> QuantumDataLoader

Set the element precision used when loading file sources.

Applies to source_file() sources. "float64" (the default) loads file contents losslessly; "float32" narrows them to f32 on load. See source_file() for the cast caveats, including the basis exemption on the native path.

Arguments:

  • name: "float32"/"f32" or "float64"/"f64" (case-insensitive).

Raises:

  • ValueError: If name is not a recognized dtype.

Returns:

self for fluent builder chaining.

seed​

def seed(s: int | None = None) -> QuantumDataLoader

Set or clear the synthetic data seed.

None leaves the loader unseeded for the native Rust path and maps to the AMD backend's default deterministic seed. Integer seeds must fit Rust u64 so the same configuration can be passed to the native backend.

Arguments:

  • s: None or an integer in [0, 2**64 - 1].

Raises:

  • ValueError: If s is not None or a valid Rust u64.

Returns:

self for fluent builder chaining.

null_handling​

def null_handling(policy: str) -> QuantumDataLoader

Set how nullable file inputs are handled by the native loader.

Valid policies are "fill_zero" (replace nulls with zero before encoding) and "reject" (fail on null input). The policy is passed through to Rust file and synthetic loader creation when available. The AMD backend loaders do not consume this setting because supported .npy/.pt/.pth inputs are loaded as dense tensors.

Arguments:

  • policy: Null handling policy, either "fill_zero" or "reject".

Raises:

  • ValueError: If policy is not supported.

Returns:

self for fluent builder chaining.

backend​

def backend(name: str) -> QuantumDataLoader

Set the GPU backend: 'cuda', 'amd', or 'auto'.

'cuda' (the default) uses the Rust/CUDA extension on NVIDIA and raises if the extension is missing. 'amd' uses the Triton AMD engine and raises if no ROCm runtime is available.

'auto' picks the GPU backend for this host: 'cuda' when the extension reports a usable CUDA device, otherwise 'amd' when a ROCm runtime is available. If neither GPU backend is usable, iteration raises RuntimeError. Returns self for chaining.

as_torch_dataset​

def as_torch_dataset()

Wrap this loader as a torch.utils.data.IterableDataset.

Returns a dataset that yields one encoded batch (torch.Tensor) per iteration step, compatible with torch.utils.data.DataLoader.

Example::

from qumat_qdp import QuantumDataLoader import torch

dataset = (QuantumDataLoader() .qubits(16).encoding("amplitude") .batches(100, size=64) .source_synthetic() .as_torch_dataset()) loader = torch.utils.data.DataLoader(dataset, batch_size=None, num_workers=0) for batch in loader: ... # batch is torch.Tensor, shape (64, 2**16)

Note: batch_size=None in DataLoader disables DataLoader's own batching; num_workers=0 is required because the Rust backend holds GPU state that cannot be pickled for multi-process workers.

__iter__​

def __iter__() -> Iterator[object]

Return iterator that yields one encoded batch per step.

Yields QdpTensor batches on every backend; convert with torch.from_dlpack(batch) or batch.to_torch().

Triton AMD backend for QDP encodings on ROCm.

is_triton_amd_available​

def is_triton_amd_available() -> bool

Return whether the Triton AMD backend appears usable.

Returns:

True when PyTorch reports a ROCm device, Triton imports, and the active Triton target is HIP or cannot be queried reliably.

TritonAmdEngine​

@dataclass
class TritonAmdEngine()

ROCm/Triton implementation of the QDP encoder interface.

This engine targets AMD GPUs through a PyTorch ROCm runtime plus the Triton Python package. encode() accepts "amplitude", "angle", "basis", "iqp", "iqp-z", and "phase". The phase encoder uses a fused Triton HIP kernel for float32 and 1 <= num_qubits <= 32; other supported cases fall back to vectorized PyTorch operations on the same ROCm device.

precision accepts "float32"/"f32"/"float" and "float64"/"f64"/"double". Runtime availability is checked when encode() is called and raises a descriptive RuntimeError if PyTorch ROCm or Triton is unavailable.

Arguments:

  • device_id: ROCm device ordinal, addressed through PyTorch as cuda:{device_id}.
  • precision: Floating-point precision for real inputs and complex outputs.

check_runtime​

def check_runtime() -> None

Validate that the process can use the Triton AMD backend.

Raises:

  • RuntimeError: If PyTorch ROCm support or Triton is unavailable.

encode_amplitude​

def encode_amplitude(data: Any, num_qubits: int) -> Any

Encode real-valued samples as normalized amplitudes.

Arguments:

  • data: One- or two-dimensional samples with width at most 2**num_qubits.
  • num_qubits: Number of qubits in the encoded state.

Raises:

  • ValueError: If the sample width exceeds the state length.

Returns:

Complex tensor of shape (batch, 2**num_qubits).

encode_angle​

def encode_angle(data: Any, num_qubits: int) -> Any

Encode samples with product-state angle encoding.

Arguments:

  • data: One- or two-dimensional angle samples with exactly num_qubits values per sample.
  • num_qubits: Number of qubits in the encoded state.

Raises:

  • ValueError: If the sample width is not num_qubits.

Returns:

Complex tensor of shape (batch, 2**num_qubits).

encode_basis​

def encode_basis(data: Any, num_qubits: int) -> Any

Encode integer basis-state indices as one-hot quantum states.

Arguments:

  • data: One-dimensional indices or a two-dimensional column of indices in [0, 2**num_qubits - 1].
  • num_qubits: Number of qubits in the encoded state.

Raises:

  • ValueError: If indices are empty, malformed, or out of range.

Returns:

Complex one-hot tensor of shape (batch, 2**num_qubits).

encode_iqp​

def encode_iqp(data: Any, num_qubits: int, *, enable_zz: bool = True) -> Any

Encode samples with the IQP feature map.

Arguments:

  • data: IQP parameters. With enable_zz=True, each sample must contain num_qubits + num_qubits * (num_qubits - 1) // 2 values; otherwise each sample must contain num_qubits values.
  • num_qubits: Number of qubits in the encoded state.
  • enable_zz: Include pairwise ZZ interactions when True.

Raises:

  • ValueError: If the parameter width does not match the IQP variant.

Returns:

Complex tensor of shape (batch, 2**num_qubits).

encode_phase​

def encode_phase(data: Any, num_qubits: int) -> Any

Encode samples as equal-magnitude states with data-dependent phase.

Arguments:

  • data: One- or two-dimensional phase samples with exactly num_qubits values per sample.
  • num_qubits: Number of qubits in the encoded state.

Raises:

  • ValueError: If the sample width is not num_qubits.

Returns:

Complex tensor of shape (batch, 2**num_qubits).

encode​

def encode(data: Any,
num_qubits: int,
encoding_method: str = "amplitude") -> Any

Encode input samples using a named Triton AMD encoding.

Arguments:

  • data: Input samples for the selected encoding method.
  • num_qubits: Number of qubits in the encoded state.
  • encoding_method: One of "amplitude", "angle", "basis", "iqp", "iqp-z", or "phase".

Raises:

  • RuntimeError: If the Triton AMD runtime is unavailable.
  • ValueError: If encoding_method is unsupported or inputs are invalid for the selected encoder.

Returns:

Complex tensor of shape (batch, 2**num_qubits).