Skip to content

OsamaMIT/qitesse

Repository files navigation

qitesse

PyPI Version License Python Versions

qitesse is a high-throughput CPU backend for repeated evaluation of parameterized quantum circuits.

qitesse is built upon qitesse-sim, the high-performance CPU-based state-vector execution engine for quantum circuits, fully built in Rust.

This PyPI module provides a Python interface designed for hybrid quantum algorithms, repeated circuit evaluation, backend integration, and low-overhead CPU execution from Python.

Features

  • Rust-based CPU statevector simulator with a Python API
  • One-off circuit execution through Gate and Circuit
  • Compiled parameterized circuits through CircuitSpec, Parameter, and CompiledCircuit
  • Reusable zero-copy parameter buffers through ParamBuffer and ParamBatchBuffer
  • Expectation-value workflows for Pauli observables and Hamiltonians
  • Batch expectation execution for parameter sweeps and optimizer loops
  • Gradient APIs for compiled circuits via parameter-shift evaluation
  • Reusable ExecutionContext buffers for repeated scalar execution
  • Full statevector output for both one-off and compiled execution paths
  • Mid-circuit measure, reset, and barrier operations
  • Custom unitary operations with Gate.unitary(...)
  • Controlled custom unitaries with Gate.controlled_unitary(...)
  • Common single-, two-, and multi-qubit gates
  • Read the Docs documentation with autogenerated API reference pages

Installation

qitesse requires Python 3.8+. Install it via pip:

pip install qitesse

Or install from source:

git clone https://github.com/OsamaMIT/qitesse.git

pip install maturin

maturin develop --release

To run examples:

python examples/h_example.py

python examples/qft._example.py

python examples/custom_unitary.py

Documentation

The documentation is now set up for Read the Docs with automatic API generation.

To add a new public class to the API docs, add it once in docs/api/index.rst. Sphinx will generate the class page and include its methods and attributes automatically.

Current Capabilities

qitesse currently has two main usage modes:

  1. General-purpose simulation with Gate and Circuit for one-off execution.
  2. Compiled execution with CircuitSpec and CompiledCircuit for repeated parameterized workloads.

The compiled path currently supports:

  • reusable zero-copy parameter buffers
  • scalar expectation evaluation
  • batched expectation evaluation
  • scalar gradients
  • batched gradients
  • reusable execution contexts
  • statevector inspection when needed

The simulator path currently supports:

  • standard single-qubit gates
  • controlled and multi-qubit gates
  • custom unitaries
  • measurement, reset, and barrier operations

Compiled Circuits

import numpy as np
import qitesse

spec = qitesse.CircuitSpec(2)
theta = spec.param("theta")

spec.ry(0, theta)
spec.cx(0, 1)

compiled = spec.compile()
observable = qitesse.Observable.pauli_z(1)

value = compiled.expectation(np.array([0.4], dtype=np.float32), observable)
gradient = compiled.gradient(np.array([0.4], dtype=np.float32), observable)
value_again, grad_again = compiled.value_and_gradient(
    np.array([0.4], dtype=np.float32),
    observable,
)
state = compiled.statevector(np.array([0.4], dtype=np.float32))

params_batch = np.array([[0.1], [0.2], [0.3]], dtype=np.float32)
values = compiled.batch_expectation(params_batch, observable)
grads = compiled.batch_gradient(params_batch, observable)

context = compiled.execution_context()
value_again = context.expectation(compiled, np.array([0.5], dtype=np.float32), observable)
grad_again = context.gradient(compiled, np.array([0.5], dtype=np.float32), observable)

This execution path is intended for repeated evaluation of the same circuit structure with different parameter values.

Backend Integration

The compiled execution path is the primary integration surface for higher-level libraries.

The intended backend pattern is:

  1. Translate a framework circuit into CircuitSpec
  2. Compile once per circuit structure
  3. Keep parameters in contiguous numpy.float32 arrays
  4. Call expectation, batch_expectation, gradient, or value_and_gradient

For sequential scalar calls, reuse compiled.execution_context() to keep internal buffers alive.

For sweeps, minibatches, or optimizer batches, prefer batch_expectation(...) and batch_gradient(...) instead of looping in Python.

Supported Gates

Single-qubit gates:

  • i
  • x
  • y
  • z
  • h
  • s
  • sdg
  • t
  • tdg
  • rx
  • ry
  • rz
  • p / phase
  • u

Two-qubit gates:

  • cnot / cx
  • cy
  • cz
  • ch
  • swap
  • iswap
  • crx
  • cry
  • crz
  • cp / cphase
  • cu

Three-qubit and larger:

  • ccx / toffoli
  • cswap / fredkin
  • mcx
  • mcz
  • mcp / mcphase
  • controlled_unitary

Circuit operations:

  • measure
  • reset
  • barrier

Custom unitaries:

import numpy as np
import qitesse

hadamard = np.array([[1, 1], [1, -1]], dtype=np.complex64) / np.sqrt(2)

circuit = qitesse.Circuit([
    qitesse.Gate.unitary([0], hadamard),
    qitesse.Gate.controlled_unitary([0], [1], hadamard),
])

state = circuit.run(2)

Use run_with_measurements(num_qubits) if the circuit contains measurement gates and you want the observed bit values back.

Planned Features

  • Additional simulation backends

Contributing

Contributions are welcome! To contribute:

  1. Fork the repository
  2. Create a new branch (feature-branch)
  3. Commit your changes and open a pull request

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

Python API for high performance simulation of parameterized quantum circuits

Resources

License

Stars

Watchers

Forks

Contributors