-
Notifications
You must be signed in to change notification settings - Fork 17
feat: add qbraid_qir.qiskit module for Qiskit to QIR conversion #271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
07af47d
a44cba2
9f30903
b69c5d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Third Party Notices | ||
|
|
||
| This software includes code derived from third party sources. | ||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use “Third-Party” hyphenation for consistency with markdown grammar checks. Line 1 and Line 3 should use “Third-Party” / “third-party”. ✏️ Proposed wording update-# Third Party Notices
+# Third-Party Notices
...
-This software includes code derived from third party sources.
+This software includes code derived from third-party sources.🧰 Tools🪛 LanguageTool[grammar] ~1-~1: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) [grammar] ~3-~3: Use a hyphen to join words. (QB_NEW_EN_HYPHEN) 🤖 Prompt for AI Agents |
||
|
|
||
| ## qiskit-qir | ||
|
|
||
| The `qbraid_qir.qiskit` module contains code derived from [microsoft/qiskit-qir](https://github.com/microsoft/qiskit-qir). | ||
|
|
||
| ``` | ||
| MIT License | ||
|
|
||
| Copyright (c) Microsoft Corporation. | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE | ||
| ``` | ||
|
|
||
| The qiskit-qir codebase has been adapted to: | ||
| - Work with Qiskit 2.x (updated for new QuantumCircuit API) | ||
| - Follow qbraid-qir conventions and coding style | ||
| - Support both pyqir 0.10.x and 0.12+ (typed and opaque pointers) | ||
| - Integrate with the qbraid-qir module structure | ||
|
Comment on lines
+33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a single trailing newline at end of file.
🧰 Tools🪛 markdownlint-cli2 (0.21.0)[warning] 35-35: Files should end with a single newline character (MD047, single-trailing-newline) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,8 @@ | ||||||||||||||||
| :orphan: | ||||||||||||||||
|
|
||||||||||||||||
| qbraid_qir.qiskit | ||||||||||||||||
| ================== | ||||||||||||||||
|
|
||||||||||||||||
| .. automodule:: qbraid_qir.qiskit | ||||||||||||||||
| :undoc-members: | ||||||||||||||||
| :show-inheritance: | ||||||||||||||||
|
Comment on lines
+6
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check automodule directive patterns in API docs
fd --glob '*.rst' docs/api | head -20Repository: qBraid/qbraid-qir Length of output: 204 🏁 Script executed: #!/bin/bash
# Examine the specific file and surrounding context
if [ -f "docs/api/qbraid_qir.qiskit.rst" ]; then
cat -n "docs/api/qbraid_qir.qiskit.rst"
else
echo "File not found, searching for qiskit.rst files:"
find . -name "*qiskit.rst" -type f 2>/dev/null
fiRepository: qBraid/qbraid-qir Length of output: 239 🏁 Script executed: #!/bin/bash
# Check all automodule directives in docs/api to see the pattern
fd --glob '*.rst' docs/api | xargs grep -l "automodule" | while read file; do
echo "=== $file ==="
grep -A 3 "automodule" "$file"
doneRepository: qBraid/qbraid-qir Length of output: 567 🏁 Script executed: #!/bin/bash
# Check Sphinx configuration for automodule settings
find docs -name "conf.py" -o -name "conf.rst" | head -5Repository: qBraid/qbraid-qir Length of output: 73 🏁 Script executed: #!/bin/bash
# Check if there's any documentation or comments about why members aren't included
rg -B2 -A2 "undoc-members|:members:" docs/ --type rstRepository: qBraid/qbraid-qir Length of output: 849 🌐 Web query:
💡 Result: In Sphinx
Example: .. automodule:: noodles
:members:
:undoc-members:This includes members with docstrings (because of Source: Sphinx autodoc options documentation. [1] [1] https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html 🏁 Script executed: #!/bin/bash
# Check the Sphinx configuration for autodoc settings
cat -n docs/conf.py | head -100Repository: qBraid/qbraid-qir Length of output: 4288 🏁 Script executed: #!/bin/bash
# Look for autodoc_default_options or any special autodoc configuration
rg -n "autodoc|automodule" docs/conf.pyRepository: qBraid/qbraid-qir Length of output: 414 Add The This pattern affects all module API documentation files (qbraid_qir.cirq.rst, qbraid_qir.qasm3.rst, qbraid_qir.qiskit.rst, and qbraid_qir.squin.rst). Add Proposed fix .. automodule:: qbraid_qir.qiskit
+ :members:
:undoc-members:
:show-inheritance:📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,7 +9,7 @@ description = "qBraid-SDK extension providing support for QIR conversions." | |||||
| readme = "README.md" | ||||||
| authors = [{name = "qBraid Development Team"}, {email = "contact@qbraid.com"}] | ||||||
| license = "Apache-2.0" | ||||||
| keywords = ["qbraid", "quantum", "qir", "llvm", "cirq", "openqasm", "squin"] | ||||||
| keywords = ["qbraid", "quantum", "qir", "llvm", "cirq", "openqasm", "qiskit", "squin"] | ||||||
| classifiers = [ | ||||||
| "Development Status :: 5 - Production/Stable", | ||||||
| "Intended Audience :: Developers", | ||||||
|
|
@@ -40,10 +40,11 @@ Discord = "https://discord.gg/TPBU2sa8Et" | |||||
| [project.optional-dependencies] | ||||||
| cirq = ["cirq-core>=1.3.0,<1.6.0"] | ||||||
| qasm3 = ["pyqasm>=0.4.0,<1.1.0", "numpy"] | ||||||
| qiskit = ["qiskit>=2.0"] | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result:
Sources: [1] PyPI Consider constraining the Qiskit extra to 2.x as defensive major-version pinning. While 📦 Suggested fix-qiskit = ["qiskit>=2.0"]
+qiskit = ["qiskit>=2.0,<3.0"]📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| squin = ["kirin-toolchain>=0.17.33", "bloqade-circuit>=0.9.1"] | ||||||
|
|
||||||
| [tool.setuptools] | ||||||
| packages = ["qbraid_qir", "qbraid_qir.cirq", "qbraid_qir.qasm3", "qbraid_qir.squin"] | ||||||
| packages = ["qbraid_qir", "qbraid_qir.cirq", "qbraid_qir.qasm3", "qbraid_qir.qiskit", "qbraid_qir.squin"] | ||||||
|
|
||||||
| [tool.setuptools.dynamic] | ||||||
| version = {attr = "qbraid_qir.__version__"} | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -51,13 +51,15 @@ | |||||||||||||
| "dumps", | ||||||||||||||
| "qasm3_to_qir", | ||||||||||||||
| "cirq_to_qir", | ||||||||||||||
| "qiskit_to_qir", | ||||||||||||||
| ] | ||||||||||||||
|
|
||||||||||||||
| _lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir"} | ||||||||||||||
| _lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir", "qiskit": "qiskit_to_qir"} | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normalize Current 💡 Proposed fix-_lazy = {"cirq": "cirq_to_qir", "qasm3": "qasm3_to_qir", "qiskit": "qiskit_to_qir"}
+_lazy = {
+ "cirq": ("cirq_to_qir",),
+ "qasm3": ("qasm3_to_qir",),
+ "qiskit": ("qiskit_to_qir",),
+}
@@
- if name in objects:
+ if name in objects:
module = importlib.import_module(f".{mod_name}", __name__)
obj = getattr(module, name)
globals()[name] = obj
return obj📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| if TYPE_CHECKING: | ||||||||||||||
| from .cirq import cirq_to_qir | ||||||||||||||
| from .qasm3 import qasm3_to_qir | ||||||||||||||
| from .qiskit import qiskit_to_qir | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def __getattr__(name): | ||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Copyright 2025 qBraid | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # pylint: disable=line-too-long | ||
| # Portions of this module are adapted from microsoft/qiskit-qir | ||
| # (https://github.com/microsoft/qiskit-qir), with modifications by qBraid. | ||
| # The original MIT license notice is reproduced in NOTICE.md. | ||
| # pylint: enable=line-too-long | ||
|
|
||
| """ | ||
| Module containing Qiskit QIR functionality. | ||
|
|
||
| .. currentmodule:: qbraid_qir.qiskit | ||
|
|
||
| Functions | ||
| ----------- | ||
|
|
||
| .. autosummary:: | ||
| :toctree: ../stubs/ | ||
|
|
||
| qiskit_to_qir | ||
|
|
||
|
|
||
| Classes | ||
| --------- | ||
|
|
||
| .. autosummary:: | ||
| :toctree: ../stubs/ | ||
|
|
||
| QiskitModule | ||
| BasicQiskitVisitor | ||
|
|
||
| Exceptions | ||
| ----------- | ||
|
|
||
| .. autosummary:: | ||
| :toctree: ../stubs/ | ||
|
|
||
| QiskitConversionError | ||
|
|
||
| """ | ||
|
|
||
| from .convert import qiskit_to_qir | ||
| from .elements import QiskitModule | ||
| from .exceptions import QiskitConversionError | ||
| from .visitor import BasicQiskitVisitor | ||
|
|
||
| __all__ = ["qiskit_to_qir", "QiskitModule", "QiskitConversionError", "BasicQiskitVisitor"] | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Optional: sort No functional issue, but sorting avoids recurring lint churn. 🧰 Tools🪛 Ruff (0.15.2)[warning] 59-59: Apply an isort-style sorting to (RUF022) 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| # Copyright 2025 qBraid | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # pylint: disable=line-too-long | ||
| # Portions of this module are adapted from microsoft/qiskit-qir | ||
| # (https://github.com/microsoft/qiskit-qir), with modifications by qBraid. | ||
| # The original MIT license notice is reproduced in NOTICE.md. | ||
| # pylint: enable=line-too-long | ||
|
|
||
| """ | ||
| Module containing Qiskit to QIR conversion functions. | ||
|
|
||
| """ | ||
|
|
||
| from typing import Optional | ||
|
|
||
| from pyqir import Context, Module, qir_module | ||
| from qiskit.circuit import QuantumCircuit | ||
|
|
||
| from .elements import QiskitModule, generate_module_id | ||
| from .exceptions import QiskitConversionError | ||
| from .visitor import BasicQiskitVisitor | ||
|
|
||
|
|
||
| def qiskit_to_qir(circuit: QuantumCircuit, name: Optional[str] = None, **kwargs) -> Module: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Type the visitor kwargs for API clarity.
🧰 Tools🪛 Ruff (0.15.2)[warning] 36-36: Missing type annotation for (ANN003) 🤖 Prompt for AI Agents |
||
| """ | ||
| Converts a Qiskit QuantumCircuit to a PyQIR module. | ||
|
|
||
| Args: | ||
| circuit: The Qiskit QuantumCircuit to convert. | ||
| name: Identifier for created QIR module. Auto-generated if not provided. | ||
|
|
||
| Keyword Args: | ||
| initialize_runtime (bool): Whether to perform quantum runtime environment initialization, | ||
| default `True`. | ||
| record_output (bool): Whether to record output calls for registers, default `True`. | ||
| emit_barrier_calls (bool): Whether to emit barrier calls in the QIR, default `False`. | ||
|
|
||
| Returns: | ||
| The QIR ``pyqir.Module`` representation of the input Qiskit circuit. | ||
|
|
||
| Raises: | ||
| TypeError: If the input is not a valid Qiskit QuantumCircuit. | ||
| ValueError: If the input circuit is empty. | ||
| QiskitConversionError: If the conversion fails. | ||
|
|
||
| Example: | ||
| >>> from qiskit import QuantumCircuit | ||
| >>> from qbraid_qir.qiskit import qiskit_to_qir | ||
| >>> | ||
| >>> qc = QuantumCircuit(2, 2) | ||
| >>> qc.h(0) | ||
| >>> qc.cx(0, 1) | ||
| >>> qc.measure([0, 1], [0, 1]) | ||
| >>> | ||
| >>> module = qiskit_to_qir(qc, name="bell") | ||
| >>> ir = str(module) | ||
| """ | ||
| if not isinstance(circuit, QuantumCircuit): | ||
| raise TypeError("Input quantum program must be of type qiskit.QuantumCircuit.") | ||
|
|
||
| if len(circuit.data) == 0: | ||
| raise ValueError("Input quantum circuit must consist of at least one operation.") | ||
|
|
||
| if name is None: | ||
| name = generate_module_id(circuit) | ||
|
|
||
| llvm_module = qir_module(Context(), name) | ||
| module = QiskitModule.from_circuit(circuit, llvm_module) | ||
|
|
||
| visitor = BasicQiskitVisitor(**kwargs) | ||
| module.accept(visitor) | ||
|
|
||
| error = llvm_module.verify() | ||
| if error is not None: | ||
| raise QiskitConversionError(error) | ||
|
|
||
| return llvm_module | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the documented function signature for
qiskit_to_qir.The changelog currently implies
nameis required, but implementation usesname=None(optional). Please align docs to avoid API confusion.🤖 Prompt for AI Agents