Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
129b60f
Update predictor(adding callbacks)
Mar 29, 2025
08889bd
Update
Apr 10, 2025
e2ff3fe
Restore helper.py and predictor.py to match upstream
Jul 29, 2025
1c32d15
Merge remote-tracking branch 'upstream/main'
Jul 29, 2025
78dc1aa
Implement new mapping actions
Jul 29, 2025
a3ba836
Fix: resolve pre-commit issues and add missing annotations
Jul 29, 2025
5935e6f
Fix: resolve pre-commit issues and add missing annotations
Jul 29, 2025
f71fb29
Fix: resolve pre-commit issues and add missing annotations
Jul 30, 2025
3c7592b
Fix: resolve pre-commit issues and add missing annotations
Jul 30, 2025
6db5c27
Fix mypy errors
Aug 1, 2025
47841c5
Fix mypy errors
Aug 1, 2025
b1ac8ce
Fix dependencies issues
Aug 3, 2025
5f8473c
Fix dependency issues
Aug 3, 2025
7491ec0
Add missing zip file
Aug 3, 2025
3346842
Fix issue with Python 3.13
Aug 3, 2025
6f7a73c
Merge branch 'main' into hybrid-mapping
Shaobo-Zhou Aug 3, 2025
6c67349
Remove Python 3.13 from noxfile.py due to compatibility issue
Aug 3, 2025
2692b96
Skip minimums session on Windows due to CI slowness
Aug 4, 2025
f4874e6
Fix bugs
Aug 5, 2025
54eec91
Fix bugs
Aug 5, 2025
845f7de
Use default Qiskit settings for VF2Layout and add assertion for nativ…
Shaobo-Zhou Aug 7, 2025
3418936
Debug
Shaobo-Zhou Aug 7, 2025
ae870cc
Fix missing argument
Shaobo-Zhou Aug 7, 2025
861bc62
Fix warning issues
Shaobo-Zhou Aug 7, 2025
fa989b6
Fix window runtime warning problem
Shaobo-Zhou Aug 7, 2025
405bd39
Fix window runtime warning problem
Shaobo-Zhou Aug 7, 2025
7b2f321
Add time limit for VF2PostLayout
Shaobo-Zhou Aug 7, 2025
b67d0a6
Fix windows runtime warning problem
Shaobo-Zhou Aug 7, 2025
bf7c9ee
Add new actions
Shaobo-Zhou Aug 29, 2025
6d2733f
Add new actions
Shaobo-Zhou Aug 29, 2025
878185a
Add evaluation code for baseline model
Shaobo-Zhou Sep 3, 2025
eae11a2
Set up code for testing new model
Shaobo-Zhou Sep 5, 2025
68306ec
Reset
Shaobo-Zhou Sep 5, 2025
fcba8fa
Add new actions
Shaobo-Zhou Sep 6, 2025
e5b7518
Fix dependencies
Shaobo-Zhou Sep 8, 2025
907ce2b
Fix dependencies
Shaobo-Zhou Sep 8, 2025
70dcd7d
Fix dependencies
Shaobo-Zhou Sep 8, 2025
e0364b1
Merge branch 'main' into new_structure
Shaobo-Zhou Sep 8, 2025
eb27098
🎨 pre-commit fixes
pre-commit-ci[bot] Sep 8, 2025
2688c0e
Fix dependencies
Shaobo-Zhou Sep 8, 2025
840d23d
Fix multiprocessing on Python 3.13
Shaobo-Zhou Sep 9, 2025
ac406ac
Fix timeout watcher
Shaobo-Zhou Sep 9, 2025
97c81bb
Update comments and restructure
Shaobo-Zhou Sep 15, 2025
470365d
Adjust test circuits from ALG to INDEP
Shaobo-Zhou Sep 15, 2025
caaf224
Update max synthesis size for bqskit
Shaobo-Zhou Sep 15, 2025
468da2e
Add tests for more coverage
Shaobo-Zhou Sep 17, 2025
737a9f2
Update tests
Shaobo-Zhou Sep 18, 2025
94c25ab
Update override
Shaobo-Zhou Sep 18, 2025
3ff922e
Update comments
Shaobo-Zhou Sep 18, 2025
782caf8
Update noxfile.py and CHANGELOG.md
Shaobo-Zhou Sep 22, 2025
44e0e40
Clean up venv after each session to free up space
Shaobo-Zhou Sep 23, 2025
350bae5
Clean up venv after each session to free up space
Shaobo-Zhou Sep 23, 2025
91208d1
Clean up venv after each session to free up space
Shaobo-Zhou Sep 23, 2025
622d409
Clean up venv after each session to free up space
Shaobo-Zhou Sep 23, 2025
fa008a6
Update noxfile
Shaobo-Zhou Sep 25, 2025
0c98e56
Update ibm runtime dependency
Shaobo-Zhou Sep 25, 2025
34a1c7c
Update noxfile
Shaobo-Zhou Sep 25, 2025
a8d069a
Update noxfile
Shaobo-Zhou Sep 25, 2025
114b79b
Update noxfile
Shaobo-Zhou Sep 25, 2025
aaf14b1
Fetch update from main
Shaobo-Zhou Sep 26, 2025
e39cd7e
Merge remote-tracking branch 'upstream/main' into new_structure
Shaobo-Zhou Nov 20, 2025
e7b4174
Fix ruff checks
Shaobo-Zhou Nov 20, 2025
fcab4fa
Update action space and add normalized gate counts as RL features
Shaobo-Zhou Nov 20, 2025
cb4d0fb
Fix FOM comparison logic
Shaobo-Zhou Nov 20, 2025
988a8f7
Remove 3-qubit gates from dict
Shaobo-Zhou Nov 21, 2025
a3d4baa
Update docs and comments
Shaobo-Zhou Nov 27, 2025
ea40f6a
Minor Fixes
Shaobo-Zhou Nov 27, 2025
148d8d3
Merge branch 'main' into new_structure
Shaobo-Zhou Nov 27, 2025
914192c
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Changed

- 🔧 Changed test circuit level for RL predictor from ALG to INDEP ([#449]) ([**@Shaobo-Zhou**])
- ✨ Remove support for custom names of trained models ([#489]) ([**@bachase**])
- 🔥 Drop support for x86 macOS systems ([#421]) ([**@denialhaag**])

Expand Down
2 changes: 1 addition & 1 deletion docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ After setup, any quantum circuit can be compiled for the most suitable device wi
from mqt.predictor import qcompile
from mqt.bench import get_benchmark, BenchmarkLevel

uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.ALG, circuit_size=5)
uncompiled_qc = get_benchmark("ghz", level=BenchmarkLevel.INDEP, circuit_size=5)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely add these (and some other major) changes to the changelog.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please do so in CHANGELOG.md.

compiled_qc, compilation_info, selected_device = qcompile(
uncompiled_qc, figure_of_merit="expected_fidelity"
)
Expand Down
20 changes: 15 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ dependencies = [
"mqt.bench>=2.0.0",
"qiskit>=1.3.3",
"pytket>=1.29.0", # lowest version that supports the used pytket AutoRebase pass instead of auto_rebase
"pytket_qiskit>=0.61.0",
"qiskit-ibm-runtime>=0.30.0",
"pytket_qiskit>=0.71.0",
# TODO(denialhaag): Remove once pytket_qiskit is updated
# https://github.com/munich-quantum-toolkit/predictor/issues/471
"qiskit-ibm-runtime>=0.30.0,<0.42.0",
Comment on lines +36 to +38
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

TODO comment references issue #471 for qiskit-ibm-runtime constraint.

The upper bound <0.42.0 on qiskit-ibm-runtime is intentional (with a TODO for issue #471). Ensure this constraint is tracked and revisited once the underlying issue is resolved to allow future versions.

If you'd like, I can help monitor or generate a reminder to revisit this constraint when issue #471 is addressed.

🤖 Prompt for AI Agents
In pyproject.toml around lines 36 to 38, the qiskit-ibm-runtime upper bound
(<0.42.0) is intentionally pinned with a TODO referencing issue #471; keep the
version constraint as-is but update the TODO to include the full issue URL and a
clear action (e.g., "remove upper bound when issue #471 is resolved"), and add a
tracking reminder (create a GitHub issue/board card or calendar reminder) so
this constraint is revisited and removed/relaxed once the referenced issue is
closed.

"sb3_contrib>=2.0.0",
"stable-baselines3>=2.7.0",
"tqdm>=4.66.0",
"rich>=12.6.0",
"scikit-learn>=1.5.1",
Expand All @@ -45,6 +48,8 @@ dependencies = [
"numpy>=1.24; python_version >= '3.11'",
"numpy>=1.22",
"typing-extensions>=4.1", # for `assert_never`
"qiskit-ibm-transpiler==0.13.1; python_version < '3.13'", # Do not support python 3.13 yet
"qiskit-ibm-ai-local-transpiler==0.4.2; python_version < '3.13'",
Comment on lines +51 to +52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check latest versions for the pinned transpiler packages

echo "=== Checking qiskit-ibm-transpiler ==="
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | \
  jq -r '"Version pinned: 0.13.1\nLatest version: " + .info.version'

echo -e "\n=== Checking qiskit-ibm-ai-local-transpiler ==="
curl -s https://pypi.org/pypi/qiskit-ibm-ai-local-transpiler/json | \
  jq -r '"Version pinned: 0.4.2\nLatest version: " + .info.version'

echo -e "\n=== Checking release dates ==="
echo "qiskit-ibm-transpiler releases:"
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | \
  jq -r '.releases | keys[] | select(. == "0.13.1" or startswith("0.14") or startswith("0.15") or startswith("1."))' | head -5

echo -e "\nqiskit-ibm-ai-local-transpiler releases:"
curl -s https://pypi.org/pypi/qiskit-ibm-ai-local-transpiler/json | \
  jq -r '.releases | keys[] | select(. == "0.4.2" or startswith("0.5") or startswith("1."))' | head -5

Repository: munich-quantum-toolkit/predictor

Length of output: 208


🌐 Web query:

qiskit-ibm-transpiler latest version PyPI

💡 Result:

The latest PyPI release is qiskit-ibm-transpiler 0.14.5 — published on Nov 21, 2025. [1]

You can install it with: pip install qiskit-ibm-transpiler. [1]

Sources:
[1] PyPI project page for qiskit-ibm-transpiler.


🌐 Web query:

qiskit-ibm-ai-local-transpiler latest version PyPI

💡 Result:

Latest PyPI version: 0.4.2 (released Jul 2, 2025). [1]

Install: pip install qiskit-ibm-ai-local-transpiler==0.4.2. [1]

Sources:
[1] PyPI project page — qiskit-ibm-ai-local-transpiler (release history).


🌐 Web query:

qiskit-ibm-transpiler security advisories CVE

💡 Result:

Relevant security advisories / CVEs affecting Qiskit (including QPY/Qiskit SDK / IBM runtime components):

  • CVE‑2025‑2000 — Arbitrary code execution when deserializing QPY format < 13 (qiskit.qpy.load). Fixed by requiring QPY v13+ / patches. (ibm.com)
  • CVE‑2025‑1403 — DoS via maliciously crafted QPY (malformed symengine serialization causes segfault). CVSS 8.6. (ibm.com)
  • CVE‑2024‑29032 — qiskit-ibm-runtime RuntimeDecoder unsafe deserialization leading to possible arbitrary code execution (fixed in qiskit-ibm-runtime 0.21.2+). (wiz.io)
  • GHSA/GitHub advisories (e.g., unsafe eval in qiskit-ibm-runtime Options.get_program_inputs) — patched in point releases (see package advisories). (wiz.io)

If you want, I can fetch official vendor advisory pages, NVD entries, and exact fixed versions/mitigations for each CVE.

Citations:


🌐 Web query:

qiskit-ibm-ai-local-transpiler security advisories CVE

💡 Result:

Short answer: I found no public CVE that specifically names qiskit-ibm-ai-local-transpiler. Related/nearby Qiskit security advisories you should watch:

  • IBM security bulletin for CVE‑2025‑1403 (Qiskit SDK QPY deserialization → remote DoS). [1]
  • CVE‑2024‑29032 (qiskit‑ibm‑runtime JSON deserialization issue) — affects runtime components, not the ai-local-transpiler package itself. [2]
  • The qiskit-ibm-ai-local-transpiler package page / releases (for tracking updates). [3]

Sources:
[1] IBM Security Bulletin — Qiskit SDK vulnerability (CVE‑2025‑1403). [turn0search1]
[2] CVE‑2024‑29032 entry / advisory references (qiskit‑ibm‑runtime). [turn0search5]
[3] qiskit-ibm-ai-local-transpiler PyPI / release info. [turn0search4]

If you want, I can: (a) monitor for new CVEs for that package and alert you, or (b) search specific GitHub security advisories/issue trackers for the repo. Which do you prefer?


🌐 Web query:

qiskit-ibm-transpiler 0.14.5 Python 3.13 support compatibility

💡 Result:

Yes — qiskit-ibm-transpiler 0.14.5 is published for Python 3 (built/uploaded with CPython 3.13.7), so it supports Python 3.13. [1][2]

Sources:

  • PyPI package details for qiskit-ibm-transpiler 0.14.5 (upload metadata shows twine/CPython/3.13.7). [1]
  • Qiskit Transpiler Service release notes (latest 0.14.x series). [2]

🌐 Web query:

qiskit-ibm-transpiler 0.14.0 release notes Python version requirements

💡 Result:

qiskit-ibm-transpiler 0.14.0 (released 2025-08-21) supports Python 3.9 and newer (the package wheels are published as py3 / py3-none-any). [1][2]

Sources:

  • Release notes (0.14.0 — Aug 21, 2025). [1]
  • piwheels / package wheel listings showing py3 wheels for 0.14.0. [2]

Update qiskit-ibm-transpiler — pinned version is outdated and Python 3.13 support now available.

qiskit-ibm-transpiler 0.13.1 is behind the current release (0.14.5, published Nov 21, 2025). Newer versions now support Python 3.13, so the python_version < '3.13' constraint can be removed or updated. Consider upgrading to 0.14.5 or verifying compatibility with the specific features in use.

qiskit-ibm-ai-local-transpiler 0.4.2 is already the latest version (released Jul 2, 2025) and has no known security advisories. The Python < 3.13 constraint for this package should be verified separately to determine if it still applies.

🤖 Prompt for AI Agents
In pyproject.toml around lines 51-52, the qiskit-ibm-transpiler entry is pinned
to 0.13.1 with a python_version < '3.13' constraint that is now outdated; update
the dependency to "qiskit-ibm-transpiler==0.14.5" and remove the ";
python_version < '3.13'" marker (or relax it) so Python 3.13 is allowed, then
run CI/tests to verify compatibility and adjust code if any API changes surface;
also verify whether the python_version constraint on
qiskit-ibm-ai-local-transpiler is still necessary and remove or update it if
not.

]

classifiers = [
Expand Down Expand Up @@ -126,6 +131,8 @@ filterwarnings = [
'ignore:.*qiskit.providers.models is deprecated since Qiskit 1.2*:DeprecationWarning:',
'ignore:.*The class ``qiskit.qobj.*`` is deprecated as of Qiskit 1.3.*:DeprecationWarning:',
'ignore:.*The property ``qiskit.circuit.instruction.Instruction.*`` is deprecated as of qiskit 1.3.0.*:DeprecationWarning:',
'ignore:.*Timeout is not supported on Windows\\.:RuntimeWarning',

]

[tool.coverage]
Expand Down Expand Up @@ -163,7 +170,7 @@ implicit_reexport = true
# recent versions of `gym` are typed, but stable-baselines3 pins a very old version of gym.
# qiskit is not yet marked as typed, but is typed mostly.
# the other libraries do not have type stubs.
module = ["qiskit.*", "joblib.*", "sklearn.*", "matplotlib.*", "gymnasium.*", "mqt.bench.*", "sb3_contrib.*", "bqskit.*", "qiskit_ibm_runtime.*", "networkx.*", "stable_baselines3.*"]
module = ["qiskit.*", "joblib.*", "sklearn.*", "matplotlib.*", "gymnasium.*", "mqt.bench.*", "sb3_contrib.*", "bqskit.*", "qiskit_ibm_runtime.*", "networkx.*", "stable_baselines3.*","qiskit_ibm_transpiler.*"]
ignore_missing_imports = true

[tool.ruff]
Expand Down Expand Up @@ -249,6 +256,9 @@ aer = "aer"
fom = "fom"

[tool.repo-review]
ignore = [
"GH200",
ignore = ["GH200"]

[tool.uv]
override-dependencies = [
"networkx==2.8.5", # Required by `qiskit-ibm-transpiler`
Comment on lines +259 to +263
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Scope of networkx==2.8.5 override may be broader than needed

The uv override-dependencies pin of networkx==2.8.5 is justified for qiskit-ibm-transpiler, but it applies unconditionally to all environments, including those where qiskit-ibm-transpiler isn’t installed (e.g., Python ≥3.13). That may unnecessarily constrain networkx for other tools. If uv supports environment markers here, consider mirroring the Python guard you use for qiskit-ibm-transpiler so the override only activates where that dependency is present.

Please check uv’s documentation for override-dependencies to confirm whether environment markers (e.g., "; python_version < '3.13'") are supported, and, if so, adjust this entry to match the qiskit-ibm-transpiler Python constraint.

🤖 Prompt for AI Agents
In pyproject.toml around lines 259 to 263, the unconditional
override-dependencies pin "networkx==2.8.5" applies to all environments even
where qiskit-ibm-transpiler is not used; check uv's documentation to confirm
whether override-dependencies supports environment markers (for example ;
python_version < "3.13"), and if it does, change the override entry to include
the same Python guard used for qiskit-ibm-transpiler so the pin only applies in
environments where that package is present; if uv does not support markers,
document this limitation in a comment and consider moving the pin into the
specific environment or constraint file where qiskit-ibm-transpiler is declared.

]
Comment on lines +261 to 264
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check qiskit-ibm-transpiler's networkx dependency requirements

echo "=== Checking qiskit-ibm-transpiler dependencies ==="
# Get the package info - try multiple versions to see requirements
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | jq -r '.releases | keys[]' | grep -E '^0\.(13|12|14)' | sort -V | tail -3

echo -e "\n=== Fetching latest qiskit-ibm-transpiler info ==="
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | jq -r '.info | "\(.version): requires_dist=\(.requires_dist)"' | head -20

echo -e "\n=== Checking networkx requirements from qiskit-ibm-transpiler ==="
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | jq -r '.info.requires_dist[]? | select(. | contains("networkx"))' 

echo -e "\n=== Checking networkx releases around 2.8.5 ==="
curl -s https://pypi.org/pypi/networkx/json | jq -r '.releases | keys[] | select(startswith("2.8") or startswith("2.9") or startswith("3."))' | sort -V

echo -e "\n=== Checking if 2.8.5 exists ==="
curl -s https://pypi.org/pypi/networkx/2.8.5/json | jq -r '.info.version // "NOT_FOUND"'

Repository: munich-quantum-toolkit/predictor

Length of output: 208


🏁 Script executed:

#!/bin/bash
# Check qiskit-ibm-transpiler's networkx dependency requirements

echo "=== Checking qiskit-ibm-transpiler latest version ==="
LATEST_QIT=$(curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | jq -r '.info.version')
echo "Latest version: $LATEST_QIT"

echo -e "\n=== Checking networkx requirements from qiskit-ibm-transpiler ==="
curl -s https://pypi.org/pypi/qiskit-ibm-transpiler/json | jq -r '.info.requires_dist[]? | select(. | contains("networkx"))' 

echo -e "\n=== Checking networkx release history around 2.8.5 ==="
curl -s https://pypi.org/pypi/networkx/json | jq -r '.releases | keys[] | select(startswith("2.8") or startswith("2.9") or startswith("3.0") or startswith("3.1"))' | sort -V | tail -10

echo -e "\n=== Verifying networkx 2.8.5 exists ==="
curl -s https://pypi.org/pypi/networkx/2.8.5/json 2>/dev/null | jq -r '.info.version // .info // "NOT_FOUND"' | head -1

echo -e "\n=== Checking networkx compatibility across versions ==="
curl -s https://pypi.org/pypi/networkx/json | jq -r '.releases | keys[] | select(startswith("2.8") or startswith("2.9"))' | sort -V

Repository: munich-quantum-toolkit/predictor

Length of output: 208


🌐 Web query:

qiskit-ibm-transpiler networkx version requirement pypi

💡 Result:

On PyPI qiskit-ibm-transpiler declares networkx as a dependency but without a pinned version specifier (i.e. it requires "networkx" generically). [1][2]

Sources:

  • qiskit-ibm-transpiler PyPI project page (dependency: networkx). [1]
  • qiskit-ibm-transpiler release notes (added networkx to requirements in 0.11.1). [2]

🌐 Web query:

networkx 2.8.5 qiskit compatibility requirements

💡 Result:

Short answer: Qiskit no longer requires networkx for most core functionality, but some parts still need it — so networkx 2.8.5 is fine to use if you install it when needed.

Details (sources):

  • Since qiskit-terra's move to retworkx, networkx is not a mandatory dependency for Terra; only a few methods that convert DAGCircuit to/from networkx require you to install networkx manually. [1]
  • Some Qiskit subpackages (e.g., older Ignis modules / topological_codes) explicitly listed networkx as a dependency in earlier releases; if you use those subpackages or any API that converts to networkx, install networkx 2.8.x. [2][3]

Recommendation: If your code calls qiskit.dagcircuit.DAGCircuit.to_networkx / from_networkx or uses qiskit-ignis/topological code, pip-install networkx (pip install "networkx==2.8.5" or a compatible 2.8.x). Otherwise you can rely on the default qiskit installation which uses retworkx for graph operations. [1][2]

Sources:
[1] Qiskit release notes (qiskit 0.25) — networkx no longer required for qiskit-terra; DAGCircuit conversions remain.
[2] Qiskit release notes (0.18) — retworkx introduced as requirement replacing networkx for performance.
[3] Qiskit Ignis notes / earlier releases — networkx explicitly listed for Ignis topological modules.


The networkx==2.8.5 pin is unnecessarily restrictive and not actually required by qiskit-ibm-transpiler.

qiskit-ibm-transpiler declares networkx as a dependency without specifying a version constraint—it accepts any networkx version. Pinning to exactly 2.8.5 is overly strict and likely a legacy requirement that will cause unnecessary dependency conflicts. Consider using a more flexible constraint (e.g., networkx>=2.8 or removing the override entirely) unless there's a specific compatibility issue with newer versions.

🤖 Prompt for AI Agents
In pyproject.toml around lines 261 to 264, the hard pin "networkx==2.8.5" is
unnecessarily restrictive; update the override to a flexible constraint (for
example "networkx>=2.8" or "networkx>=2.8,<3" depending on compatibility) or
remove the override entirely so qiskit-ibm-transpiler can use its declared
networkx range; apply the change and run dependency resolution/tests to ensure
no regressions.

Comment on lines +261 to 264
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

uv override-dependencies syntax Python version constraints

💡 Result:

Short answer: override-dependencies entries use standard PEP 508 dependency specifiers (name, optional extras, version specifier, optional environment marker). To constrain by Python version put the marker after a semicolon and quote the version. Examples:

  • Force exact version for all Pythons:
    override-dependencies = ["werkzeug==2.3.0"]. [1]

  • Only override for older Pythons:
    override-dependencies = [
    "numpy<1.24; python_version < "3.10"",
    "numpy>=1.24; python_version >= "3.10"",
    ]. [1][2]

Notes:

  • Version specifiers (outside markers) follow PEP 440 and are unquoted; marker version literals (inside the marker) must be quoted strings. [2]
  • uv treats override-dependencies as absolute replacements during resolution and reads them from [tool.uv] in pyproject.toml at the workspace root. [1]

Sources:
[1] uv settings / override-dependencies docs.
[2] uv dependency specifiers / PEP 508 markers (packaging) docs.


🏁 Script executed:

# Check the pyproject.toml around lines 51-52 to see transpiler dependency format
cat -n pyproject.toml | sed -n '40,65p'

Repository: munich-quantum-toolkit/predictor

Length of output: 208


🌐 Web query:

networkx 2.8.5 Python 3.13 compatibility constraint qiskit-ibm-transpiler

💡 Result:

Short answer: NetworkX 2.8.5 is not compatible with Python 3.13 (it supports Python 3.8–3.10), so if qiskit-ibm-transpiler requires or installs networkx==2.8.5 you cannot use that combo on Python 3.13. [1][2][3]

Details & sources:

  • NetworkX 2.8.5 supports Python 3.8–3.10 (release notes). [1]
  • NetworkX newer 3.x releases add support for Python 3.11–3.13 (e.g. NetworkX 3.4+ support 3.13). If you need Python 3.13 install a NetworkX 3.x release. [3]
  • qiskit-ibm-transpiler release notes indicate NetworkX was added to its requirements in recent releases (so the transpiler can pull in networkx from your environment). Check which networkx version qiskit-ibm-transpiler requests in your installed package/pyproject to confirm whether it pins 2.8.x. [2]

Recommendation: either use Python 3.10 (to keep networkx 2.8.5), or upgrade NetworkX to a 3.x release that supports Python 3.13 and ensure qiskit-ibm-transpiler is compatible with that NetworkX version (check the transpiler’s dependency metadata or test in a venv). [2][3]

Sources:
[1] NetworkX 2.8.5 release notes (supported Python versions).
[2] qiskit-ibm-transpiler release notes (networkx added to requirements).
[3] NetworkX 3.4/3.x release notes (Python 3.13 support).


🌐 Web query:

qiskit-ibm-transpiler networkx version Python 3.13

💡 Result:

Short answer: Yes — qiskit-ibm-transpiler depends on networkx (but does not pin a restrictive networkx version), and networkx releases (3.4+) support Python 3.13, while recent Qiskit releases add official Python 3.13 support. So you can run qiskit-ibm-transpiler on Python 3.13 after installing a networkx release that supports 3.13 (e.g. networkx 3.4+). [1][2][3]

Sources

  • qiskit-ibm-transpiler (package + release notes showing networkx listed as a dependency). [1]
  • Qiskit release notes stating Python 3.13 support added. [2]
  • NetworkX release notes / install docs showing support for Python 3.13 (networkx 3.4+). [3]

References

  1. qiskit-ibm-transpiler package / PyPI & release notes.
  2. Qiskit SDK / release notes (Python 3.13 support).
  3. NetworkX release notes / install docs (supports Python 3.13).

🏁 Script executed:

# Try to fetch raw file from GitHub
curl -s "https://raw.githubusercontent.com/munich-quantum-toolkit/predictor/HEAD/pyproject.toml" | sed -n '40,280p' | cat -n | grep -A 20 -B 5 "networkx\|qiskit-ibm-transpiler" | head -100

Repository: munich-quantum-toolkit/predictor

Length of output: 208


Based on the web search results, I can now provide a conclusive verification:

The review comment's concern is valid and the suggested fix is necessary.

Key findings:

  1. uv DOES support Python version constraints via PEP 508 environment markers (syntax: "package==version; python_version < \"X.Y\"")
  2. NetworkX 2.8.5 supports ONLY Python 3.8–3.10 — it is incompatible with Python 3.13
  3. The current code lacks the version constraint, which means projects targeting Python 3.13 would fail when trying to use networkx==2.8.5

The correct implementation should be:

[tool.uv]
override-dependencies = [
  "networkx==2.8.5; python_version < \"3.13\"",  # Required by `qiskit-ibm-transpiler`
]

Add a Python version constraint to the networkx override dependency.

NetworkX 2.8.5 supports only Python 3.8–3.10 and is incompatible with Python 3.13. Without the constraint, users on Python 3.13 will encounter resolution failures. Update the override to: "networkx==2.8.5; python_version < \"3.13\"".

🤖 Prompt for AI Agents
In pyproject.toml around lines 261 to 264, the override for networkx pins 2.8.5
but lacks a Python-version constraint so it will be applied on Python 3.13
(where that release is incompatible); update the override entry to use a PEP 508
environment marker restricting it to Python versions older than 3.13 (i.e., add
`; python_version < "3.13"` to the networkx override) so the override only
applies for Python < 3.13.

17 changes: 13 additions & 4 deletions src/mqt/predictor/ml/predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@

logger = logging.getLogger("mqt-predictor")

NO_PARALLEL = sys.platform == "win32" and sys.version_info >= (3, 13)


def setup_device_predictor(
devices: list[Target],
Expand Down Expand Up @@ -227,7 +229,10 @@ def compile_training_circuits(
with zipfile.ZipFile(str(path_zip), "r") as zip_ref:
zip_ref.extractall(path_uncompiled_circuits)

Parallel(n_jobs=num_workers, verbose=100)(
# On Windows + Python 3.13, joblib's default "loky" process backend is broken
# (missing `_posixsubprocess`). Fall back to no multiprocessing.
num_jobs = 1 if NO_PARALLEL else num_workers
Parallel(n_jobs=num_jobs, verbose=100)(
Comment on lines +232 to +235
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consistent use of NO_PARALLEL; consider a tiny helper to avoid repetition

The conditional num_jobs = 1 if NO_PARALLEL else ... pattern is applied consistently across compilation, data generation, and model training and correctly funnels all parallelism through the same platform guard.

If you want to reduce duplication and make future changes (e.g., tweaking behavior or adding logging) easier, you could factor this into a small helper:

+def _effective_num_jobs(requested: int) -> int:
+    return 1 if NO_PARALLEL else requested
+
 ...
-        num_jobs = 1 if NO_PARALLEL else num_workers
+        num_jobs = _effective_num_jobs(num_workers)
 ...
-        num_jobs = 1 if NO_PARALLEL else num_workers
+        num_jobs = _effective_num_jobs(num_workers)
 ...
-        num_jobs = 1 if NO_PARALLEL else 8
+        num_jobs = _effective_num_jobs(8)

Not mandatory, but it would centralize the logic if this workaround needs revisiting later.

Also applies to: 277-287, 417-420

🤖 Prompt for AI Agents
In src/mqt/predictor/ml/predictor.py around lines 234-237 (and also apply to
ranges 277-287 and 417-420), the code repeats the pattern `num_jobs = 1 if
NO_PARALLEL else num_workers` before Parallel calls; create a small helper
function (e.g., _resolve_num_jobs(num_workers) or get_num_jobs) near the top of
the module that returns 1 when NO_PARALLEL is true otherwise returns the
provided num_workers, then replace the repeated inline conditional with calls to
that helper in all three locations; keep behavior identical but centralize logic
so future changes or logging can be added in one place.

delayed(self._compile_all_circuits_devicewise)(
device, timeout, path_uncompiled_circuits, path_compiled_circuits, logger.level
)
Expand Down Expand Up @@ -267,7 +272,8 @@ def generate_training_data(
names_list = []
scores_list = []

results = Parallel(n_jobs=num_workers, verbose=100)(
num_jobs = 1 if NO_PARALLEL else num_workers
results = Parallel(n_jobs=num_jobs, verbose=100)(
Comment on lines +275 to +276
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Add explanatory comment for consistency.

The parallelization logic is correct and matches the pattern in compile_training_circuits. However, this location lacks the explanatory comment present at lines 232-233, creating an inconsistency. Adding the same comment here would improve code maintainability.

Apply this diff:

+        # On Windows + Python 3.13, joblib's default "loky" process backend is broken
+        # (missing `_posixsubprocess`). Fall back to no multiprocessing.
         num_jobs = 1 if NO_PARALLEL else num_workers
         results = Parallel(n_jobs=num_jobs, verbose=100)(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
num_jobs = 1 if NO_PARALLEL else num_workers
results = Parallel(n_jobs=num_jobs, verbose=100)(
# On Windows + Python 3.13, joblib's default "loky" process backend is broken
# (missing `_posixsubprocess`). Fall back to no multiprocessing.
num_jobs = 1 if NO_PARALLEL else num_workers
results = Parallel(n_jobs=num_jobs, verbose=100)(
🤖 Prompt for AI Agents
In src/mqt/predictor/ml/predictor.py around lines 275 to 276, the Parallel call
lacks the explanatory comment that appears at lines 232-233; add the same
comment immediately above the lines setting num_jobs and calling Parallel to
explain why num_jobs is set to 1 when NO_PARALLEL is true and to document the
parallelization behaviour for consistency and maintainability.

delayed(self._generate_training_sample)(
filename.name,
path_uncompiled_circuits,
Expand All @@ -276,6 +282,7 @@ def generate_training_data(
)
for filename in path_uncompiled_circuits.glob("*.qasm")
)

for sample in results:
training_sample, circuit_name, scores = sample
if all(score == -1 for score in scores):
Expand Down Expand Up @@ -405,8 +412,10 @@ def train_random_forest_model(
if not training_data:
training_data = self._get_prepared_training_data()
num_cv = min(len(training_data.y_train), 5)
mdl = GridSearchCV(mdl, tree_param, cv=num_cv, n_jobs=8).fit(training_data.X_train, training_data.y_train)

num_jobs = 1 if NO_PARALLEL else 8
mdl = GridSearchCV(mdl, tree_param, cv=num_cv, n_jobs=num_jobs).fit(
training_data.X_train, training_data.y_train
)
Comment on lines +415 to +418
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Correct implementation, but consider adding explanatory comment.

The conditional parallelization logic is correct and implements the past review feedback. However, like generate_training_data, this lacks the explanatory comment present in compile_training_circuits (lines 232-233).

Consider adding the same explanatory comment for consistency:

+        # On Windows + Python 3.13, joblib's default "loky" process backend is broken
+        # (missing `_posixsubprocess`). Fall back to no multiprocessing.
         num_jobs = 1 if NO_PARALLEL else 8
         mdl = GridSearchCV(mdl, tree_param, cv=num_cv, n_jobs=num_jobs).fit(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
num_jobs = 1 if NO_PARALLEL else 8
mdl = GridSearchCV(mdl, tree_param, cv=num_cv, n_jobs=num_jobs).fit(
training_data.X_train, training_data.y_train
)
# On Windows + Python 3.13, joblib's default "loky" process backend is broken
# (missing `_posixsubprocess`). Fall back to no multiprocessing.
num_jobs = 1 if NO_PARALLEL else 8
mdl = GridSearchCV(mdl, tree_param, cv=num_cv, n_jobs=num_jobs).fit(
training_data.X_train, training_data.y_train
)
🤖 Prompt for AI Agents
In src/mqt/predictor/ml/predictor.py around lines 415 to 418, the conditional
parallelization (num_jobs = 1 if NO_PARALLEL else 8) is correct but missing an
explanatory comment for consistency; add a short comment above the num_jobs line
mirroring the style of the comment used in compile_training_circuits (lines
232-233) explaining that NO_PARALLEL forces single-threaded execution for
debugging/CI/resource reasons and otherwise uses 8 parallel jobs for
GridSearchCV, so future readers understand the rationale.

joblib_dump(mdl, save_mdl_path)
logger.info("Random Forest model is trained and saved.")

Expand Down
3 changes: 3 additions & 0 deletions src/mqt/predictor/reward.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,15 @@ def estimated_success_probability(qc: QuantumCircuit, device: Target, precision:
if first_qubit_idx not in active_qubits:
continue

dt = device.dt # discrete time unit used in duration
res *= np.exp(
-instruction.duration
* dt
/ min(device.qubit_properties[first_qubit_idx].t1, device.qubit_properties[first_qubit_idx].t2)
)
continue
res *= 1 - device[gate_type][first_qubit_idx,].error

else:
second_qubit_idx = calc_qubit_index(qargs, qc.qregs, 1)
res *= 1 - device[gate_type][first_qubit_idx, second_qubit_idx].error
Expand Down
Loading
Loading