Metadata-Version: 2.4
Name: parityos-cudaq
Version: 0.1.0
Summary: CudaQ extension for ParityOS
Project-URL: Homepage, https://parityqc.com/
Author-email: ParityQC <parityos@parityqc.com>
License-Expression: BSD-3-Clause
License-File: LICENSE.txt
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: attrs
Requires-Dist: parityos>=3.0.0
Description-Content-Type: text/markdown

# ParityOS CudaQ

ParityOS extension adding an interface to [cudaq](https://developer.nvidia.com/cuda-q).

## Installation

It is recommended to install this package in a separate Python virtual environment. For example:

```shell
# To create a standard Python virtual environment:
python -m venv my_new_venv && source my_new_venv/bin/activate
# Alternatively, to create a Anaconda/Miniconda environment:
conda create --name my_new_conda_env python=<version> && conda activate my_new_conda_env
# or a pyenv environment
pyenv virtualenv <version> my_new_venv && pyenv activate my_new_venv
# or a uv managed environment
uv venv -p <version>
```
where `<version>` is a python version and one of `[3.11, 3.12, 3.13]`.

After activating the virtual environment, install via your favorite package manager, e.g.:

```shell
# using pip
pip install parityos-cudaq
# using uv
uv pip install parityos-cudaq
```

## Exporter

`parityos-cudaq` offers an exporter of ParityOS to quantum circuits to the 
[Quake dialect](https://nvidia.github.io/cuda-quantum/latest/specification/quake-dialect.html) .

```python
from parityos.bits import get_q
from parityos.operators.circuit import Circuit
from parityos.operators.controlled_operator import CNOT
from parityos.operators.elementary_operator import H, Z
from parityos.operators.rotation_operator import RX
from parityos_cudaq.exporter import export_parityos_to_quake

# Create circuit qubits.
qubits = [get_q(name) for name in ("a", "b", "c")]

# Create the following circuit as sequence of gates, followed by a measurement of all qubits.
#     ┌───────┐┌───┐┌───┐   ┌─┐
# qa: ┤ Rx(2) ├┤ H ├┤ Z ├───┤M├
#     └───────┘├───┤└┬─┬┘   └╥┘
# qb: ─────────┤ X ├─┤M├─────╫─
#       ┌───┐  └─┬─┘ └╥┘ ┌─┐ ║ 
# qc: ──┤ H ├────■────╫──┤M├─╫─
#       └───┘         ║  └╥┘ ║ 
# c: 3/═══════════════╩═══╩══╩═
#                     1   2  0 
circuit = Circuit(
    [
        RX(qubits[0], 2),
        H(qubits[0]),
        H(qubits[2]),
        CNOT(qubits[2], qubits[1]),
        Z(qubits[0]),
    ]
).measure_all()

# Export to quake. 
qiskit_result = export_parityos_to_quake(circuit, False)

print(qiskit_result.module)
# // Generated by ParityOS
# module {
#   func.func @parityos_circuit() {
#     // Allocate register
#     %n_qubits = arith.constant 3 : i64
#     %register = quake.alloca !quake.veq<?>[%n_qubits : i64]
#     %q_0 = quake.extract_ref %register[0] : (!quake.veq<?>) -> !quake.ref
#     %q_1 = quake.extract_ref %register[1] : (!quake.veq<?>) -> !quake.ref
#     %q_2 = quake.extract_ref %register[2] : (!quake.veq<?>) -> !quake.ref
#    
#     %angle_0 = arith.constant 2.0 : f64
#     quake.rx (%angle_0) %q_0 : (f64, !quake.ref) -> ()
#     quake.h %q_0 : (!quake.ref) -> ()
#     quake.h %q_2 : (!quake.ref) -> ()
#     quake.x [%q_2] %q_1 : (!quake.ref, !quake.ref) -> ()
#     quake.z %q_0 : (!quake.ref) -> ()
#     %m_result_0 = quake.mz %q_0 : (!quake.ref) -> !quake.measure
#    
#     %m_result_1 = quake.mz %q_1 : (!quake.ref) -> !quake.measure
#    
#     %m_result_2 = quake.mz %q_2 : (!quake.ref) -> !quake.measure
#    
#     return
#   }
# }

print(qiskit_result.qubit_map)  # Maps ParityOS qubits to quake Qubit integer labels
# {Qubit(id='a'): 0, Qubit(id='b'): 1, Qubit(id='c'): 2}
```

## License

This software package is made available under the 3-Clause BSD License. 
See `License.txt` for details.
