Metadata-Version: 2.2
Name: qilisdk
Version: 0.3.1
Summary: QiliSDK is a Python framework for writing digital and analog quantum algorithms and executing them across multiple quantum backends. Its modular design streamlines the development process and enables easy integration with a variety of quantum platforms.
Keywords: qilimanjaro,quantum computing,digital quantum computing,analog quantum computing
Author-Email: Qilimanjaro Quantum Tech <info@qilimanjaro.tech>
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Quantum Computing
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Project-URL: Homepage, https://github.com/qilimanjaro-tech/qilisdk
Project-URL: Documentation, https://qilimanjaro-tech.github.io/qilisdk/
Project-URL: Source, https://github.com/qilimanjaro-tech/qilisdk
Project-URL: Issues, https://github.com/qilimanjaro-tech/qilisdk/issues
Project-URL: Changelog, https://github.com/qilimanjaro-tech/qilisdk/blob/main/CHANGELOG.md
Requires-Python: >=3.11
Requires-Dist: dill>=0.3.9
Requires-Dist: numpy>=2.3.2
Requires-Dist: ruamel-yaml>=0.18.7
Requires-Dist: scipy>=1.16.1
Requires-Dist: pydantic>=2.12.0
Requires-Dist: pydantic-settings>=2.14.2
Requires-Dist: loguru>=0.7.3
Requires-Dist: matplotlib>=3.10.5
Requires-Dist: py-cpuinfo>=9.0.0
Requires-Dist: rustworkx>=0.16.0
Requires-Dist: psutil>=6.1.0
Requires-Dist: packaging>=24.2
Provides-Extra: cuda
Requires-Dist: qilisdk[cuda12]; extra == "cuda"
Provides-Extra: cuda12
Requires-Dist: nvidia-cuda-runtime-cu12; extra == "cuda12"
Requires-Dist: nvidia-cublas-cu12; extra == "cuda12"
Requires-Dist: nvidia-cusolver-cu12; extra == "cuda12"
Requires-Dist: nvidia-cusparse-cu12; extra == "cuda12"
Requires-Dist: nvidia-nvjitlink-cu12; extra == "cuda12"
Provides-Extra: cuda13
Requires-Dist: nvidia-cuda-runtime; extra == "cuda13"
Requires-Dist: nvidia-cublas; extra == "cuda13"
Requires-Dist: nvidia-cusolver; extra == "cuda13"
Requires-Dist: nvidia-cusparse; extra == "cuda13"
Requires-Dist: nvidia-nvjitlink; extra == "cuda13"
Provides-Extra: speqtrum
Requires-Dist: httpx==0.28.1; extra == "speqtrum"
Requires-Dist: keyring>=25.6.0; extra == "speqtrum"
Requires-Dist: keyrings-alt>=5.0.2; extra == "speqtrum"
Provides-Extra: openfermion
Requires-Dist: openfermion>=1.7.1; extra == "openfermion"
Provides-Extra: qir
Requires-Dist: pyqir>=0.12.0; extra == "qir"
Provides-Extra: openqasm
Requires-Dist: openqasm3[parser]>=1.0.1; extra == "openqasm"
Provides-Extra: scip
Requires-Dist: pyscipopt>=5.7.0; extra == "scip"
Provides-Extra: all
Requires-Dist: qilisdk[cuda12]; extra == "all"
Requires-Dist: qilisdk[speqtrum]; extra == "all"
Requires-Dist: qilisdk[openfermion]; extra == "all"
Requires-Dist: qilisdk[qir]; extra == "all"
Requires-Dist: qilisdk[openqasm]; extra == "all"
Requires-Dist: qilisdk[scip]; extra == "all"
Provides-Extra: all-cu12
Requires-Dist: qilisdk[cuda12]; extra == "all-cu12"
Requires-Dist: qilisdk[speqtrum]; extra == "all-cu12"
Requires-Dist: qilisdk[openfermion]; extra == "all-cu12"
Requires-Dist: qilisdk[qir]; extra == "all-cu12"
Requires-Dist: qilisdk[openqasm]; extra == "all-cu12"
Requires-Dist: qilisdk[scip]; extra == "all-cu12"
Provides-Extra: all-cu13
Requires-Dist: qilisdk[cuda13]; extra == "all-cu13"
Requires-Dist: qilisdk[speqtrum]; extra == "all-cu13"
Requires-Dist: qilisdk[openfermion]; extra == "all-cu13"
Requires-Dist: qilisdk[qir]; extra == "all-cu13"
Requires-Dist: qilisdk[openqasm]; extra == "all-cu13"
Requires-Dist: qilisdk[scip]; extra == "all-cu13"
Description-Content-Type: text/markdown

<img src="docs/_static/QiliSDK_wht.svg" alt="QiliSDK" height="80">

[![Python Versions](https://img.shields.io/pypi/pyversions/qilisdk.svg)](https://pypi.org/project/qilisdk/)
[![PyPI Version](https://img.shields.io/pypi/v/qilisdk.svg)](https://pypi.org/project/qilisdk/)
[![Code Coverage](https://codecov.io/gh/qilimanjaro-tech/qilisdk/graph/badge.svg?token=iUMp8nKCqJ)](https://codecov.io/gh/qilimanjaro-tech/qilisdk)
[![License](https://img.shields.io/pypi/l/qilisdk.svg)](#license)
[![Docs](https://img.shields.io/badge/docs-latest-pink.svg)](https://qilimanjaro-tech.github.io/qilisdk/)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17819870.svg)](https://doi.org/10.5281/zenodo.17819870)

**QiliSDK** is [Qilimanjaro Quantum Tech's](https://qilimanjaro.tech/) open-source Python framework for designing and executing **analog, digital, and hybrid quantum algorithms**. Its modular structure unifies circuit-based and Hamiltonian-based workflows within a single API. It provides high-level abstractions for gates, circuits, Hamiltonians, and more, while remaining fully backend-agnostic allowing a seamless switch between CPU, GPU, or QPU execution. Fast CPU simulation can be done locally using **QiliSim**, our quantum simulator written in C++.

## Why QiliSDK?

There are several other quantum frameworks out there, but QiliSDK has many unique advantages:

 - We use a single framework for digital, analog and hybrid workflows, running on CPU, GPU or a Qilimanjaro QPU. Everything is one unified stack.
 - All core functionality is included in the package, with performance critical parts pre-compiled from C++, all easily installable with a single `pip install` command.
 - At the highest level we have our Model class, which lets you write problems in their simplest form and simplify the conversion to quantum jobs.
 - At a slightly lower level we have our functionals, describing specific quantum tasks: VariationalProgram, AnalogEvolution, DigitalPropagation and even QuantumReservoirs.
 - Meanwhile, on the more fundamental side, we have symbolic Hamiltonians and Expression classes, fully customizable analog Schedules, all standard quantum gates, parametrizable objects, our quantum object class QTensor which has a wide range of quantum information utilities, and many more.

## Installation

QiliSDK is available via [PyPI](https://pypi.org/project/qilisdk/):

```bash
pip install qilisdk
```

For other installaton options, see the [docs](https://qilimanjaro-tech.github.io/qilisdk).

## Usage

Here are just a few examples to get you started, for tutorials and full documentation, please see the [docs](https://qilimanjaro-tech.github.io/qilisdk).

### Digital Circuits

To create a simple quantum circuit and simulate it on your CPU:

```python
from qilisdk.digital import Circuit, H, RX, CNOT
from qilisdk.functionals import DigitalPropagation
from qilisdk.readout import Readout
from qilisdk.backends import QiliSim

# Create a simple two-qubit circuit
circuit = Circuit(2)
circuit.add(H(0))
circuit.add(RX(1, theta=3.14))
circuit.add(CNOT(0, 1))

# Set up the quantum task
functional = DigitalPropagation(circuit)
readout = Readout().with_sampling(1000)

# Simulate it with CPU
backend = QiliSim()
results = backend.execute(functional, readout)
print(results)
```

### Analog Evolution

To create a linear interpolation between an initial and final Hamiltonian, then simulate it using your GPU:

```python
from qilisdk.analog import Schedule, X, Z
from qilisdk.functionals import AnalogEvolution
from qilisdk.readout import Readout
from qilisdk.core import InitialState
from qilisdk.backends import QiliSim, AnalogMethod, ExecutionConfig

# Construct the interpolation between Hamiltonians
initial_hamiltonian = -X(0) - X(1)
final_hamiltonian = Z(0) + Z(1) + 0.5 * Z(0) * Z(1)
schedule = Schedule.linear(initial_hamiltonian, final_hamiltonian, total_time=10.0, dt=0.5)

# Set up the quantum task
functional = AnalogEvolution(schedule, initial_state=InitialState.UNIFORM)
readout = Readout().with_expectation([final_hamiltonian])

# Simulate it with GPU
config = ExecutionConfig(gpu=True)
method = AnalogMethod.variational_annealing()
backend = QiliSim(execution_config=config, analog_simulation_method=method)
results = backend.execute(functional, readout)
print(results)
```

### Quantum Reservoirs

```python
import numpy as np
from qilisdk.backends import QiliSim
from qilisdk.core import ket
from qilisdk.digital import Circuit, U2
from qilisdk.functionals.quantum_reservoirs import QuantumReservoir, ReservoirInput, ReservoirLayer
from qilisdk.analog import Schedule, X, Z
from qilisdk.readout import Readout

# Set up the quantum reservoir
pre_processing = Circuit(2)
pre_processing.add(U2(1, phi=ReservoirInput("phi_1", 0.1), gamma=ReservoirInput("gamma_1", 0.1)))
res_layer = ReservoirLayer(
    evolution_dynamics=Schedule(
        hamiltonians={"h": Z(0) + Z(1) + Z(0) * Z(1) + 0.5 * (X(0) + X(1))},
        total_time=1.0,
        dt=0.1,
    ),
    input_encoding=pre_processing,
    qubits_to_reset=[1],
)
reservoir = QuantumReservoir(
    initial_state=(np.random.rand() * ket(0, 0) + np.random.rand() * ket(1, 1)).unit(),
    reservoir_layer=res_layer,
    input_per_layer=[
        {"phi_1": 0.2, "gamma_1": 0.1},
        {"phi_1": 0.3, "gamma_1": 0.2},
        {"phi_1": 0.4, "gamma_1": 0.3},
    ],
)

# Simulate it with CPU
results = QiliSim().execute(
    reservoir,
    Readout().with_expectation(observables=[Z(0), Z(1), Z(0) * Z(1)]),
)
print(results.get_expectation_values())
```

## Benchmarks

<img src="docs/_static/benchmark_digital.png" alt="QiliSDK">

## Development Guide

This section covers how to set up a local development environment for qilisdk, run tests, enforce code style, manage dependencies, and contribute to the project. We use a number of tools to maintain code quality and consistency:

- **[uv](https://pypi.org/project/uv/)** for dependency management and packaging.
- **[ruff](https://docs.astral.sh/ruff/)** for linting and code formatting.
- **[ty](https://docs.astral.sh/ty/)** for language server and static type checking.
- **[towncrier](https://github.com/twisted/towncrier)** for automated changelog generation.

### Setup & Dependency Management

For instructions on how to compile from source and set up the development environment, see the [docs](https://qilimanjaro-tech.github.io/qilisdk/main/getting_started/installation#compiling-from-source). Following those instructions will setup a virtual environment (venv) in which you can run all other development tools (e.g. tests, linting).

### Testing

We use **pytest** for the test suite. Once you have your venv set up, run the Python unit tests using:

```bash
pytest tests/unit_python
```

To run the integration tests (bigger tests which use the full QiliSDK stack and might take a bit longer):
```bash
pytest tests/integration
```

To run the CUDA, qutip, and SpeQtrum backend tests, install the optional dependencies first (e.g., `uv sync --all-groups --extra all-cu13`).

To run the C++ tests, you first need to recompile with C++ testing enabled:
```bash
uv sync --reinstall -Ccmake.define.tests=ON
```
The C++ testing suite can then be ran using:
```bash
./tests/unit_cpp/test_cpp
```

### Linting & Formatting

We enforce code style and best practices using [**ruff**](https://beta.ruff.rs/docs/). ruff handles:

- Lint checks (similar to flake8, pylint).
- Formatting (similar to black or isort).
- Automated fixes for certain issues.

To check linting:

```bash
ruff check
```

To automatically fix lint issues (where possible):

```bash
ruff check --fix
```

To automatically format your code:

```bash
ruff format
```

*(We recommend running `ruff check --fix` and `ruff format` before committing any changes.)*

To check the C++ code, compile with the tidy flag:
```bash
uv pip install -v -e ./ -Ccmake.build-type=Debug -Ccmake.define.tidy=ON
```
This will run clang-tidy as well as a number of C++ compiler flags for debugging. For this you will need clang-tidy installed, which can be done on Debian/Ubuntu with:
```bash
sudo apt-get install clang-tidy
```
It may also throw an error about not being able to find `omp.h`, if so, try:
```bash
sudo apt-get install libomp-dev
```
For ease of use there are also a number of bash scripts in the "scripts" folder, for instance to generate coverage reports or to run all pre-commit checks.

### Type Checking

We use [**ty**](https://docs.astral.sh/ty/) for static type checking. This helps ensure our code is type-safe and maintainable.

```bash
ty check
```

*(We encourage developers to annotate new functions, classes, and methods with type hints.)*

### Helpful Scripts

For ease of use there are also a number of scripts in the `scripts/` directory. Each of these generates a .log file with the same name as the script (`checks.sh` generates `checks.log` and so on).

To run all pre-commit checks (e.g. linting/tests):
```bash
bash scripts/checks.sh
```

To check all of the code blocks in the documentaton:
```bash
bash scripts/docs.sh
```

To generate a full coverage report of all code, run:
```bash
bash scripts/coverage.sh
```
This will generate a html file which you can open in your browser to see which lines (in both the C++ and Python) are covered by the tests. We aim for 100% coverage!

### Changelog Management

We manage our changelog using [**towncrier**](https://github.com/twisted/towncrier). Instead of editing `CHANGELOG.md` directly, **each pull request** includes a small *news fragment* file in the `changes/` directory describing the user-facing changes.

For example, if you create a PR with id #123 adding a new feature, you add:
```
changes/123.feature.md
```
Inside this file, you briefly describe the new feature:
```markdown
Added a new `cool_feature` in the `qilisdk.backends` module.
```
These change fragments should be written in Markdown, so use standard Markdown syntax.
Also, instead of manually creating the file, you can run:
```bash
towncrier create --no-edit
```
When we cut a new release, we update the version in `pyproject.toml` file and run:
```bash
towncrier
```
This aggregates all the news fragments into the `CHANGELOG.md` under the new version and removes the used fragments.

### Contributing

We welcome contributions! Here’s the workflow:

1. **Fork** this repository and create a feature branch.
2. **Write** your changes (code, docs, or tests).
3. **Add a news fragment** in `changes/` describing the user-facing impact.
4. **Run** the following checks locally:
   ```bash
   bash scripts/checks.sh
   ```
5. **Commit** and push your branch to your fork.
6. **Open a Pull Request** against the `main` branch here.

Our CI will run tests, linting, and type checks. Please make sure your branch passes these checks before requesting a review.

## License

This project is licensed under the [Apache License](LICENSE).

## Acknowledgments

- Thanks to all the contributors who help develop qilisdk!
- [uv](https://docs.astral.sh/uv/) for making dependency management smoother.
- [ruff](https://docs.astral.sh/ruff/), [ty](https://docs.astral.sh/ty/), and [towncrier](https://github.com/twisted/towncrier) for their amazing tooling.

---

Feel free to open [issues](https://github.com/qilimanjaro-tech/qilisdk/issues) or [pull requests](https://github.com/qilimanjaro-tech/qilisdk/pulls) if you have questions or contributions. Happy quantum coding!
