[QDP] Collapse the per-encoder matrix into one generic encode path

qdp-core
- New `gpu::kernels` module: a `Kernel` trait with one `launch` on
  device-resident data, `Input` (host f64/f32 slice, or a device pointer
  on a stream), `Shape`, and a single `encode` driver that validates,
  uploads (dual-stream pipeline for large host batches), allocates and
  launches. A single sample is a batch of one.
- Launches are asynchronous: `launch` returns a `Pending` holding the
  buffers the queued kernels read and checks that need device results
  (validation flags, norm flags), settled after one stream sync. The
  Parquet streaming path therefore keeps copy/compute overlap for every
  encoding.
- One descriptor per encoding (amplitude, angle, basis, iqp, phase),
  each launching its kernels through `qdp_kernels::registry`. The
  amplitude and IQP host launch orchestration moved into the
  descriptors. Amplitude uses the wide single-sample reduction for one
  sample and a CPU norm with one kernel for small single host samples;
  its finalize kernel raises a flag and writes 0 for zero or non-finite
  norms. Basis casts host indices on the CPU and uploads int64. The angle
  encoder went from 868 lines to under 90.
- `QdpEngine::encode(input, shape, num_qubits, encoding)` replaces the
  24 named encode methods. Host-batch and f64/int64 device-pointer
  shorthands live on in `compat.rs`. Float32 host input under a float64
  engine is widened on the CPU first.
- The streaming Parquet path is generic over `Kernel`, supports every
  encoding, and encodes into the engine's precision through a bounded
  float64 staging buffer. Samples that cannot be normalised stay zero
  rows, as before.
- `gpu::validation` queues flag kernels through the registry; basis
  indices can be cast on the device from float64 as well as float32.
- `Encoding::vector_len` delegates to `Kernel::sample_size`.
- `QuantumEncoder`, `gpu/encodings/*` and `encoding/{amplitude,angle,
  basis}.rs` are deleted. The transitional host launchers pass a null
  flag to the finalize kernel.

qdp-python
- `PyInput::from_py` converts lists, NumPy (f64 and f32), CPU tensors
  and CUDA tensors into an `Input`; `QdpEngine.encode` is one call.
  CUDA tensor dtype acceptance is derived from `Kernel::supports`, so
  phase now encodes from a CUDA tensor and basis accepts float64 indices.

Tests
- Rust tests use `encode_single`, `encode_batch` or the generic path;
  device-pointer tests call `encode` with `Input::Device`. Parquet tests
  that download complex128 use a float64 engine, since streaming now
  honours engine precision. NumPy float32 input is accepted; the dtype
  error test uses float16. The parity grid covers phase on the device.
44 files changed
tree: 032deb683614449e85ea0b5b33c457f75822a29d
  1. .devcontainer/
  2. .github/
  3. dev/
  4. docs/
  5. examples/
  6. qdp/
  7. qumat/
  8. testing/
  9. website/
  10. .asf.yaml
  11. .cherry_picker.toml
  12. .dockerignore
  13. .gitignore
  14. .pre-commit-config.yaml
  15. CONTRIBUTING.md
  16. doap_Mahout.rdf
  17. Dockerfile.qdp-amd
  18. KEYS
  19. LICENSE
  20. lychee.toml
  21. Makefile
  22. NOTICE
  23. pyproject.toml
  24. README.md
  25. uv.lock
README.md

Apache Mahout

License PyPI version PyPI - Python Version GitHub Stars GitHub Contributors

The goal of the Apache Mahoutâ„¢ project is to build an environment for quickly creating scalable, performant machine learning applications.
For additional information about Mahout, visit the Mahout Home Page

Qumat

Qumat is a high-level Python library for quantum computing that provides:

  • Quantum Circuit Abstraction - Build quantum circuits with standard gates (Hadamard, CNOT, Pauli, etc.) and run them on Qiskit, Cirq, or Amazon Braket with a single unified API. Write once, execute anywhere. Check out basic gates for a quick introduction to the basic gates supported across all backends.
  • QDP (Quantum Data Plane) - Encode classical data into quantum states using GPU-accelerated kernels. Zero-copy tensor transfer via DLPack lets you move data between PyTorch, NumPy, and TensorFlow without overhead.

Quick Start

pip install qumat

with QDP (Quantum Data Plane) support

pip install qumat[qdp]

Qumat: Run a Quantum Circuit

from qumat import QuMat

qumat = QuMat({"backend_name": "qiskit", "backend_options": {"simulator_type": "aer_simulator"}})
qumat.create_empty_circuit(num_qubits=2)
qumat.apply_hadamard_gate(0)
qumat.apply_cnot_gate(0, 1)
qumat.execute_circuit()

QDP: Encode data for Quantum ML

import qumat.qdp as qdp

engine = qdp.QdpEngine(device_id=0)
qtensor = engine.encode([1.0, 2.0, 3.0, 4.0], num_qubits=2, encoding_method="amplitude")

Roadmap

2024

  • [x] Transition of Classic to maintenance mode
  • [x] Integration of Qumat with hardened (tests, docs, CI/CD) Cirq, Qiskit, and Braket backends
  • [x] Integration with Amazon Braket
  • [x] Public talk about Qumat

2025

  • [x] FOSDEM talk
  • [x] QDP: Foundation & Infrastructure (Rust workspace, build configuration)
  • [x] QDP: Core Implementation (CUDA kernels, CPU preprocessing, GPU memory management)
  • [x] QDP: Zero-copy and Safety (DLManagedTensor, DLPack structures)
  • [x] QDP: Python Binding (PyO3 wrapping, DLPack protocol)

Q1 2026

  • [ ] QDP: Input Format Support (PyTorch, NumPy, TensorFlow integration)
  • [ ] QDP: Verification and Testing (device testing, benchmarking)
  • [ ] QDP: Additional Encoders (angle/basis encoding, multi-GPU optimization)
  • [ ] QDP: Integration & Release (documentation, example notebooks, PyPI publishing)

Legal

Please see the NOTICE.txt included in this directory for more information.