# The Ionizer
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13370396.svg)](https://doi.org/10.5281/zenodo.13370396)
<a href="https://ionizer.readthedocs.io/en/stable/" target="_blank"><img src="https://readthedocs.org/projects/ionizer/badge/?version=stable"></a>
Transpile and optimize your PennyLane circuits into
IonQ's native trapped-ion gate set (GPI, GPI2, MS) with just a single extra line
of code!
```python
from ionizer.transforms import ionize
@qml.qnode(dev)
@ionize
def circuit(x):
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
qml.RX(x, wires=1)
return qml.expval(qml.PauliZ(0))
```
```pycon
>>> qml.draw(circuit)(0.3)
0: ──GPI2(0.00)─╭MS──GPI2(-1.57)─────────────────────────┤ <Z>
1: ──GPI2(3.14)─╰MS──GPI2(1.57)───GPI(-1.42)──GPI2(1.57)─┤
```
## Installation
The Ionizer is available via PyPI:
```
pip install ionizer
```
The core requirement is [PennyLane](https://pennylane.ai/) 0.37.
Python versions 3.10-3.12 are supported and tested against.
To install from source, clone this repository and use
[Poetry](https://python-poetry.org/) to install the dependencies listed in the
`pyproject.toml` file.
## Examples
For more detailed explanations and usage examples, please check the full
[online documentation](https://ionizer.readthedocs.io/en/stable/).
The Ionizer is implemented using [quantum function
transforms](https://arxiv.org/abs/2202.13414), similar to PennyLane's [existing
compilation
tools](https://docs.pennylane.ai/en/stable/introduction/compiling_circuits.html). To
compile and execute the circuit using trapped ion gates, the
`@ionize` transform will
- Decompose all operations into Paulis/Pauli rotations, Hadamard, and CNOT
- Cancel inverses and merge single-qubit rotations
- Convert everything except RZ to GPI, GPI2, and MS gates
- Virtually apply RZ gates
- Repeatedly apply single-qubit gate fusion and commutation through MS gates,
and perform simplification based on a database of circuit identities.
```python
from ionizer.transforms import ionize
@qml.qnode(dev)
@ionize
def circuit_ionized(params):
for idx in range(5):
qml.Hadamard(wires=idx)
for idx in range(4):
qml.RY(params[idx], wires=idx)
qml.CNOT(wires=[idx + 1, idx])
for wire in dev.wires:
qml.PauliX(wires=wire)
return qml.expval(qml.PauliX(0))
```
```pycon
>>> circuit_ionized(params)
tensor(0.99500417, requires_grad=True)
>>> qml.draw(circuit_ionized)(params)
0: ──GPI2(-1.57)──GPI(-1.52)──GPI2(-3.04)─╭MS───────────────────────────────────────────────────
1: ──GPI2(-1.92)──GPI(3.14)───GPI2(-1.22)─╰MS──GPI2(2.36)──GPI(1.67)──GPI2(0.99)─╭MS────────────
2: ──GPI2(-1.92)──GPI(3.14)───GPI2(-1.22)────────────────────────────────────────╰MS──GPI2(2.36)
3: ──GPI2(-1.92)──GPI(3.14)───GPI2(-1.22)───────────────────────────────────────────────────────
4: ──GPI2(-1.92)──GPI(3.14)───GPI2(-1.22)───────────────────────────────────────────────────────
────────────────────────────────────────────────────────────────────────────────────────────┤ <X>
────────────────────────────────────────────────────────────────────────────────────────────┤
───GPI(1.72)──GPI2(1.09)─╭MS────────────────────────────────────────────────────────────────┤
─────────────────────────╰MS──GPI2(2.36)──GPI(1.77)──GPI2(1.19)─╭MS─────────────────────────┤
────────────────────────────────────────────────────────────────╰MS──GPI2(0.00)──GPI2(1.57)─┤
```
The consistuent transforms can also be accessed and used independently.
There is currently not direct support for other frameworks. However, if you
would like to apply the transforms to Qiskit circuits, this can be accomplished
using the
[`pennylane-qiskit`](https://github.com/PennyLaneAI/pennylane-qiskit) package as
shown belown.
```python
qiskit_circuit = QuantumCircuit(...)
# Turns a Qiskit circuit into a PennyLane quantum function
qfunc = qml.from_qiskit(qiskit_circuit)
@qml.qnode(dev)
@ionize
def pennylane_circuit():
qfunc()
return qml.expval(qml.PauliX(0))
```
## Notes
This package is a work in progress. While it has been verified to work on some
fairly large circuits, we still need to work on:
- finding circuit identities involving the 2-qubit gate
- ensuring differentiability of variational parameters
- writing more tests (compile at your own risk!)
## Resources
- [IonQ documentation](https://ionq.com/docs/getting-started-with-native-gates)
- [Basic circuit compilation techniques for an ion-trap quantum machine](https://arxiv.org/abs/1603.07678)
## Contributing
The Ionizer is available open source under the MIT License. Contributions are
welcome. Please open an issue if you are interested in contributing, or if you
encounter a bug.
## Reference
If you use the Ionizer as part of your workflow, we would appreciate if you cite it using the BibTeX below.
```
@software{di_matteo_2024_13370396,
author = {Di Matteo, Olivia},
title = {The Ionizer},
month = aug,
year = 2024,
publisher = {Zenodo},
version = {0.3},
doi = {10.5281/zenodo.13370396},
url = {https://doi.org/10.5281/zenodo.13370396}
}
```
Raw data
{
"_id": null,
"home_page": "https://github.com/QSAR-UBC/ionizer/",
"name": "ionizer",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "quantum-computing, quantum-software",
"author": "UBC Quantum Software and Algorithms Research Lab",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/a9/6e/ebb040ca32cd60b7ca18484d2d3487dbaa742db90d26e02a5b952db64393/ionizer-0.3.0.tar.gz",
"platform": null,
"description": "# The Ionizer\n\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13370396.svg)](https://doi.org/10.5281/zenodo.13370396)\n<a href=\"https://ionizer.readthedocs.io/en/stable/\" target=\"_blank\"><img src=\"https://readthedocs.org/projects/ionizer/badge/?version=stable\"></a>\n\nTranspile and optimize your PennyLane circuits into\nIonQ's native trapped-ion gate set (GPI, GPI2, MS) with just a single extra line\nof code!\n\n```python\nfrom ionizer.transforms import ionize\n\n\n@qml.qnode(dev)\n@ionize\ndef circuit(x):\n qml.Hadamard(wires=0)\n qml.CNOT(wires=[0, 1])\n qml.RX(x, wires=1)\n return qml.expval(qml.PauliZ(0))\n```\n\n```pycon\n>>> qml.draw(circuit)(0.3)\n0: \u2500\u2500GPI2(0.00)\u2500\u256dMS\u2500\u2500GPI2(-1.57)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 <Z>\n1: \u2500\u2500GPI2(3.14)\u2500\u2570MS\u2500\u2500GPI2(1.57)\u2500\u2500\u2500GPI(-1.42)\u2500\u2500GPI2(1.57)\u2500\u2524\n```\n\n## Installation\n\n\nThe Ionizer is available via PyPI:\n\n```\npip install ionizer\n```\n\nThe core requirement is [PennyLane](https://pennylane.ai/) 0.37.\n\nPython versions 3.10-3.12 are supported and tested against.\n\nTo install from source, clone this repository and use\n[Poetry](https://python-poetry.org/) to install the dependencies listed in the\n`pyproject.toml` file.\n\n## Examples\n\nFor more detailed explanations and usage examples, please check the full\n[online documentation](https://ionizer.readthedocs.io/en/stable/).\n\nThe Ionizer is implemented using [quantum function\ntransforms](https://arxiv.org/abs/2202.13414), similar to PennyLane's [existing\ncompilation\ntools](https://docs.pennylane.ai/en/stable/introduction/compiling_circuits.html). To\ncompile and execute the circuit using trapped ion gates, the\n`@ionize` transform will\n\n - Decompose all operations into Paulis/Pauli rotations, Hadamard, and CNOT\n - Cancel inverses and merge single-qubit rotations\n - Convert everything except RZ to GPI, GPI2, and MS gates\n - Virtually apply RZ gates\n - Repeatedly apply single-qubit gate fusion and commutation through MS gates,\n and perform simplification based on a database of circuit identities.\n\n```python\nfrom ionizer.transforms import ionize\n\n\n@qml.qnode(dev)\n@ionize\ndef circuit_ionized(params):\n for idx in range(5):\n qml.Hadamard(wires=idx)\n\n for idx in range(4):\n qml.RY(params[idx], wires=idx)\n qml.CNOT(wires=[idx + 1, idx])\n\n for wire in dev.wires:\n qml.PauliX(wires=wire)\n\n return qml.expval(qml.PauliX(0))\n```\n\n```pycon\n>>> circuit_ionized(params)\ntensor(0.99500417, requires_grad=True)\n>>> qml.draw(circuit_ionized)(params)\n0: \u2500\u2500GPI2(-1.57)\u2500\u2500GPI(-1.52)\u2500\u2500GPI2(-3.04)\u2500\u256dMS\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n1: \u2500\u2500GPI2(-1.92)\u2500\u2500GPI(3.14)\u2500\u2500\u2500GPI2(-1.22)\u2500\u2570MS\u2500\u2500GPI2(2.36)\u2500\u2500GPI(1.67)\u2500\u2500GPI2(0.99)\u2500\u256dMS\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n2: \u2500\u2500GPI2(-1.92)\u2500\u2500GPI(3.14)\u2500\u2500\u2500GPI2(-1.22)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570MS\u2500\u2500GPI2(2.36)\n3: \u2500\u2500GPI2(-1.92)\u2500\u2500GPI(3.14)\u2500\u2500\u2500GPI2(-1.22)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n4: \u2500\u2500GPI2(-1.92)\u2500\u2500GPI(3.14)\u2500\u2500\u2500GPI2(-1.22)\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 <X>\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2500\u2500\u2500GPI(1.72)\u2500\u2500GPI2(1.09)\u2500\u256dMS\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570MS\u2500\u2500GPI2(2.36)\u2500\u2500GPI(1.77)\u2500\u2500GPI2(1.19)\u2500\u256dMS\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2570MS\u2500\u2500GPI2(0.00)\u2500\u2500GPI2(1.57)\u2500\u2524\n\n```\n\nThe consistuent transforms can also be accessed and used independently.\n\nThere is currently not direct support for other frameworks. However, if you\nwould like to apply the transforms to Qiskit circuits, this can be accomplished\nusing the\n[`pennylane-qiskit`](https://github.com/PennyLaneAI/pennylane-qiskit) package as\nshown belown.\n\n```python\nqiskit_circuit = QuantumCircuit(...)\n\n# Turns a Qiskit circuit into a PennyLane quantum function\nqfunc = qml.from_qiskit(qiskit_circuit)\n\n\n@qml.qnode(dev)\n@ionize\ndef pennylane_circuit():\n qfunc()\n return qml.expval(qml.PauliX(0))\n```\n\n## Notes\n\nThis package is a work in progress. While it has been verified to work on some\nfairly large circuits, we still need to work on:\n\n- finding circuit identities involving the 2-qubit gate\n- ensuring differentiability of variational parameters\n- writing more tests (compile at your own risk!)\n\n## Resources\n\n- [IonQ documentation](https://ionq.com/docs/getting-started-with-native-gates)\n- [Basic circuit compilation techniques for an ion-trap quantum machine](https://arxiv.org/abs/1603.07678)\n\n\n## Contributing\n\nThe Ionizer is available open source under the MIT License. Contributions are\nwelcome. Please open an issue if you are interested in contributing, or if you\nencounter a bug.\n\n\n## Reference\n\nIf you use the Ionizer as part of your workflow, we would appreciate if you cite it using the BibTeX below.\n\n```\n@software{di_matteo_2024_13370396,\n author = {Di Matteo, Olivia},\n title = {The Ionizer},\n month = aug,\n year = 2024,\n publisher = {Zenodo},\n version = {0.3},\n doi = {10.5281/zenodo.13370396},\n url = {https://doi.org/10.5281/zenodo.13370396}\n}\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "PennyLane tools for compilation into trapped-ion native gates.",
"version": "0.3.0",
"project_urls": {
"Homepage": "https://github.com/QSAR-UBC/ionizer/",
"Repository": "https://github.com/QSAR-UBC/ionizer/"
},
"split_keywords": [
"quantum-computing",
" quantum-software"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1eb0a64a946492cc15bf0edda2f1abc9dfa7106397323b51d11d2634d6ba48a0",
"md5": "88c3eea97218b957f598114f3ecb30ab",
"sha256": "d78867a5209772adb8147e12bfe85d82f2c914cb1c09e080cb923f593660bd70"
},
"downloads": -1,
"filename": "ionizer-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "88c3eea97218b957f598114f3ecb30ab",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 28965,
"upload_time": "2024-08-24T22:11:24",
"upload_time_iso_8601": "2024-08-24T22:11:24.740523Z",
"url": "https://files.pythonhosted.org/packages/1e/b0/a64a946492cc15bf0edda2f1abc9dfa7106397323b51d11d2634d6ba48a0/ionizer-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a96eebb040ca32cd60b7ca18484d2d3487dbaa742db90d26e02a5b952db64393",
"md5": "3380052cbf89924a48005299d84a2853",
"sha256": "f4f6eb0449ed69682cfb5d0307f97c7f11b1738fcdf3605361d4b4844f85888b"
},
"downloads": -1,
"filename": "ionizer-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "3380052cbf89924a48005299d84a2853",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 28118,
"upload_time": "2024-08-24T22:11:26",
"upload_time_iso_8601": "2024-08-24T22:11:26.314993Z",
"url": "https://files.pythonhosted.org/packages/a9/6e/ebb040ca32cd60b7ca18484d2d3487dbaa742db90d26e02a5b952db64393/ionizer-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-24 22:11:26",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "QSAR-UBC",
"github_project": "ionizer",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "ionizer"
}