Skip to content

Commit

Permalink
Merge pull request #134 from eclipse-qrisp/catalyst_integration
Browse files Browse the repository at this point in the history
Merge Catalyst integration into main
  • Loading branch information
positr0nium authored Feb 5, 2025
2 parents fed0eb4 + 9ef537c commit 4fb522a
Show file tree
Hide file tree
Showing 193 changed files with 19,297 additions and 984 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/qrisp_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
build:

runs-on: ubuntu-latest
timeout-minutes: 30
timeout-minutes: 60
strategy:
matrix:
python-version: ["3.9.16"]
Expand All @@ -24,8 +24,11 @@ jobs:
pip install -e ./
pip install pennylane
pip install qiskit-aer
pip install jax==0.4.28
pip install jaxlib==0.4.28
pip install pyscf
pip install qiskit-iqm
pip install stim
- name: Test with pytest
run: |
pytest
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ before_script:
- pip install pennylane
- pip install pytket
- pip install pytket-qiskit
- pip install jax


# isort:
Expand Down
263 changes: 263 additions & 0 deletions .ipynb_checkpoints/jisp_demo-checkpoint.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "9918bf03-b930-4c7f-adec-a9bafcc102de",
"metadata": {},
"source": [
"jasp, a dynamic Pythonic low-level IR\n",
"-------------------------------------\n",
"\n",
"Within this notebook we demonstrate the latest feature of the Jax Integration.\n",
"\n",
"We introduce a jasp, a new IR that represents hybrid programs embedded into the Jaxpr IR.\n",
"\n",
"Creating a jasp program is simple:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "c770249c-137c-4b45-9263-7f77726571bc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; a\u001b[35m:i32[]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mb\u001b[35m:QuantumCircuit\u001b[39m = qdef \n",
" c\u001b[35m:QuantumCircuit\u001b[39m d\u001b[35m:QubitArray\u001b[39m = create_qubits b a\n",
" e\u001b[35m:QuantumCircuit\u001b[39m = q_env[stage=enter type=inversionenvironment] c\n",
" f\u001b[35m:Qubit\u001b[39m = get_qubit d 0\n",
" g\u001b[35m:QuantumCircuit\u001b[39m = x e f\n",
" h\u001b[35m:Qubit\u001b[39m = get_qubit d 0\n",
" i\u001b[35m:Qubit\u001b[39m = get_qubit d 2\n",
" j\u001b[35m:QuantumCircuit\u001b[39m = cx g h i\n",
" _\u001b[35m:QuantumCircuit\u001b[39m = q_env[stage=exit type=inversionenvironment] j\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m() }\n",
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; a\u001b[35m:i32[]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mb\u001b[35m:QuantumCircuit\u001b[39m = qdef \n",
" c\u001b[35m:QuantumCircuit\u001b[39m d\u001b[35m:QubitArray\u001b[39m = create_qubits b a\n",
" _\u001b[35m:QuantumCircuit\u001b[39m = q_env[\n",
" jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22md\u001b[35m:QubitArray\u001b[39m; e\u001b[35m:QuantumCircuit\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mf\u001b[35m:Qubit\u001b[39m = get_qubit d 0\n",
" g\u001b[35m:QuantumCircuit\u001b[39m = x e f\n",
" h\u001b[35m:Qubit\u001b[39m = get_qubit d 0\n",
" i\u001b[35m:Qubit\u001b[39m = get_qubit d 2\n",
" j\u001b[35m:QuantumCircuit\u001b[39m = cx g h i\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(j,) }\n",
" stage=collected\n",
" ] c d\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m() }\n"
]
}
],
"source": [
"from qrisp import *\n",
"from jax import make_jaxpr\n",
"\n",
"def test_f(i):\n",
" a = QuantumFloat(i)\n",
" with invert():\n",
" x(a[0])\n",
" cx(a[0], a[2])\n",
" return \n",
"\n",
"jasp_program = make_jaxpr(test_f)(5)\n",
"\n",
"\n",
"print(jasp_program)\n",
"print(collect_environments(jasp_program.jaxpr))\n",
"#print(to_qc(jasp_program)(5)[0])"
]
},
{
"cell_type": "markdown",
"id": "644dbc01-036b-4d33-8ac3-c85a41b0e252",
"metadata": {},
"source": [
"jasp programs can be executed with the jasp interpreter:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b02aeffb-7e93-4ec0-bca6-7e226fadcfd5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5 \u001b[2K\n"
]
}
],
"source": [
"compiled_test_f = jasp_interpreter(jasp_program)\n",
"\n",
"print(compiled_test_f(5))"
]
},
{
"cell_type": "markdown",
"id": "2223d289-965f-4f91-a508-d07332433978",
"metadata": {},
"source": [
"One of the most powerful features of this IR is that it is fully dynamic, allowing many functions to be cached and reused."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b0a49866-6d82-4906-941e-36b646102079",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.0111033916473389\n",
"let inner_function = { \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; a\u001b[35m:QuantumCircuit\u001b[39m b\u001b[35m:QubitArray\u001b[39m c\u001b[35m:i32[]\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22md\u001b[35m:Qubit\u001b[39m = get_qubit b 0\n",
" e\u001b[35m:Qubit\u001b[39m = get_qubit b 1\n",
" f\u001b[35m:QuantumCircuit\u001b[39m = cx a d e\n",
" g\u001b[35m:Qubit\u001b[39m = get_qubit b c\n",
" h\u001b[35m:QuantumCircuit\u001b[39m = h f g\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(h,) } in\n",
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; . \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mi\u001b[35m:QuantumCircuit\u001b[39m = qdef \n",
" j\u001b[35m:QuantumCircuit\u001b[39m k\u001b[35m:QubitArray\u001b[39m = create_qubits i 5\n",
" l\u001b[35m:QuantumCircuit\u001b[39m = pjit[name=inner_function jaxpr=inner_function] j k 0\n",
" m\u001b[35m:QuantumCircuit\u001b[39m = pjit[name=inner_function jaxpr=inner_function] l k 1\n",
" n\u001b[35m:QuantumCircuit\u001b[39m = pjit[name=inner_function jaxpr=inner_function] m k 2\n",
" _\u001b[35m:QuantumCircuit\u001b[39m o\u001b[35m:i32[]\u001b[39m = measure n k\n",
" p\u001b[35m:i32[]\u001b[39m = mul o 1\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(p,) }\n"
]
}
],
"source": [
"import time\n",
"\n",
"@qache\n",
"def inner_function(qv, i):\n",
" cx(qv[0], qv[1])\n",
" h(qv[i])\n",
" # Complicated compilation, that takes a lot of time\n",
" time.sleep(1)\n",
"\n",
"def outer_function():\n",
" qv = QuantumFloat(5)\n",
"\n",
" inner_function(qv, 0)\n",
" inner_function(qv, 1)\n",
" inner_function(qv, 2)\n",
"\n",
" return measure(qv)\n",
"\n",
"t0 = time.time()\n",
"jasp_program = make_jaxpr(outer_function)()\n",
"print(time.time()- t0)\n",
"\n",
"print(jasp_program)\n"
]
},
{
"cell_type": "markdown",
"id": "82fcdc22-737e-475a-bc68-1837e1663a5d",
"metadata": {},
"source": [
"Furthermore jasp programs are seamlessly hybrid:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "851a0a3f-64ef-453d-8bab-e6e6b7d8ffe8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25.5 \u001b[2K\n",
"{ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; . \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22ma\u001b[35m:QuantumCircuit\u001b[39m = qdef \n",
" b\u001b[35m:QuantumCircuit\u001b[39m c\u001b[35m:QubitArray\u001b[39m = create_qubits a 6\n",
" d\u001b[35m:i32[]\u001b[39m = get_size c\n",
" _\u001b[35m:i32[]\u001b[39m _\u001b[35m:i32[]\u001b[39m _\u001b[35m:QubitArray\u001b[39m e\u001b[35m:QuantumCircuit\u001b[39m = while[\n",
" body_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; f\u001b[35m:i32[]\u001b[39m g\u001b[35m:i32[]\u001b[39m h\u001b[35m:QubitArray\u001b[39m i\u001b[35m:QuantumCircuit\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mj\u001b[35m:i32[]\u001b[39m = add f 1\n",
" k\u001b[35m:i32[]\u001b[39m = shift_left 1 f\n",
" l\u001b[35m:i32[]\u001b[39m = and k 22\n",
" m\u001b[35m:Qubit\u001b[39m = get_qubit h f\n",
" n\u001b[35m:bool[]\u001b[39m = ne l 0\n",
" o\u001b[35m:i32[]\u001b[39m = convert_element_type[new_dtype=int32 weak_type=False] n\n",
" p\u001b[35m:QuantumCircuit\u001b[39m = cond[\n",
" branches=(\n",
" { \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; q\u001b[35m:QuantumCircuit\u001b[39m r\u001b[35m:i32[]\u001b[39m s\u001b[35m:Qubit\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\u001b[39m\u001b[22m\u001b[22m \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(q,) }\n",
" { \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; t\u001b[35m:QuantumCircuit\u001b[39m u\u001b[35m:i32[]\u001b[39m v\u001b[35m:Qubit\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mw\u001b[35m:QuantumCircuit\u001b[39m = x t v\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(w,) }\n",
" )\n",
" linear=(False, False, False)\n",
" ] o i l m\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(j, g, h, p) }\n",
" body_nconsts=0\n",
" cond_jaxpr={ \u001b[34m\u001b[22m\u001b[1mlambda \u001b[39m\u001b[22m\u001b[22m; x\u001b[35m:i32[]\u001b[39m y\u001b[35m:i32[]\u001b[39m z\u001b[35m:QubitArray\u001b[39m ba\u001b[35m:QuantumCircuit\u001b[39m. \u001b[34m\u001b[22m\u001b[1mlet\n",
" \u001b[39m\u001b[22m\u001b[22mbb\u001b[35m:bool[]\u001b[39m = lt x y\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(bb,) }\n",
" cond_nconsts=0\n",
" ] 0 d c b\n",
" _\u001b[35m:QuantumCircuit\u001b[39m bc\u001b[35m:i32[]\u001b[39m = measure e c\n",
" bd\u001b[35m:f32[]\u001b[39m = convert_element_type[new_dtype=float32 weak_type=True] bc\n",
" be\u001b[35m:f32[]\u001b[39m = mul bd 0.25\n",
" bf\u001b[35m:f32[]\u001b[39m = add be 20.0\n",
" \u001b[34m\u001b[22m\u001b[1min \u001b[39m\u001b[22m\u001b[22m(bf,) }\n"
]
}
],
"source": [
"\n",
"def test_f():\n",
"\n",
" a = QuantumFloat(6, -2)\n",
" a[:] = 5.5\n",
"\n",
" b = measure(a)\n",
"\n",
" b += 10\n",
"\n",
" return b\n",
"\n",
"jasp_program = make_jaxpr(test_f)()\n",
"\n",
"print(jasp_interpreter(jasp_program)())\n",
"print(jasp_program)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
22 changes: 22 additions & 0 deletions documentation/.ipynb_checkpoints/README-checkpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Documentation for qrisp project
This README gives an overview of the relevant files of the documentation page development.\
The documentation is build with sphinx. For further information I recommend the following tutorial:\
[How to Document using Sphinx: Part 1—Setting up](https://www.youtube.com/watch?v=WcUhGT4rs5o)

# Installing sphinx and extensions
pip install -U sphinx
pip install sphinx_fontawesome
pip install sphinx-toolbox

# Setup page
Every page of the documentation website is designed in the related .rst file inside the source folder.\
Each page needs to be integrated via index.rst file.\
Of further interest is the conf.py, check out the recommended tutorial for its functionality.

# Creating the actual html page
make html
The make html command generates the html pages inside the build/html folder.\
Opening the index.html file in the browser displays the build version of the documentation page.


sphinx-apidoc --separate -o source/srcfolder ../src/qrisp
Loading

0 comments on commit 4fb522a

Please sign in to comment.