-
-
Notifications
You must be signed in to change notification settings - Fork 21
Refined MDP for RL #449
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?
Refined MDP for RL #449
Changes from all commits
129b60f
08889bd
e2ff3fe
1c32d15
78dc1aa
a3ba836
5935e6f
f71fb29
3c7592b
6db5c27
47841c5
b1ac8ce
5f8473c
7491ec0
3346842
6f7a73c
6c67349
2692b96
f4874e6
54eec91
845f7de
3418936
ae870cc
861bc62
fa989b6
405bd39
7b2f321
b67d0a6
bf7c9ee
6d2733f
878185a
eae11a2
68306ec
fcba8fa
e5b7518
907ce2b
70dcd7d
e0364b1
eb27098
2688c0e
840d23d
ac406ac
97c81bb
470365d
caaf224
468da2e
737a9f2
94c25ab
3ff922e
782caf8
44e0e40
350bae5
91208d1
622d409
fa008a6
0c98e56
34a1c7c
a8d069a
114b79b
aaf14b1
e39cd7e
e7b4174
fcab4fa
cb4d0fb
988a8f7
a3d4baa
ea40f6a
148d8d3
914192c
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 |
|---|---|---|
|
|
@@ -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
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 TODO comment references issue #471 for qiskit-ibm-runtime constraint. The upper bound 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 |
||
| "sb3_contrib>=2.0.0", | ||
| "stable-baselines3>=2.7.0", | ||
| "tqdm>=4.66.0", | ||
| "rich>=12.6.0", | ||
| "scikit-learn>=1.5.1", | ||
|
|
@@ -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
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 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 -5Repository: munich-quantum-toolkit/predictor Length of output: 208 🌐 Web query:
💡 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: 🌐 Web query:
💡 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: 🌐 Web query:
💡 Result: Relevant security advisories / CVEs affecting Qiskit (including QPY/Qiskit SDK / IBM runtime components):
If you want, I can fetch official vendor advisory pages, NVD entries, and exact fixed versions/mitigations for each CVE. Citations:
🌐 Web query:
💡 Result: Short answer: I found no public CVE that specifically names qiskit-ibm-ai-local-transpiler. Related/nearby Qiskit security advisories you should watch:
Sources: 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:
💡 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:
🌐 Web query:
💡 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:
Update
🤖 Prompt for AI Agents |
||
| ] | ||
|
|
||
| classifiers = [ | ||
|
|
@@ -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', | ||
flowerthrower marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ] | ||
|
|
||
| [tool.coverage] | ||
|
|
@@ -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] | ||
|
|
@@ -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
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 Scope of The uv Please check uv’s documentation for 🤖 Prompt for AI Agents |
||
| ] | ||
|
Comment on lines
+261
to
264
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 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 -VRepository: munich-quantum-toolkit/predictor Length of output: 208 🌐 Web query:
💡 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:
🌐 Web query:
💡 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):
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: 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., 🤖 Prompt for AI Agents
Comment on lines
+261
to
264
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: 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:
Notes:
Sources: 🏁 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:
💡 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:
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: 🌐 Web query:
💡 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
References
🏁 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 -100Repository: 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:
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: 🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -61,6 +61,8 @@ | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| logger = logging.getLogger("mqt-predictor") | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| NO_PARALLEL = sys.platform == "win32" and sys.version_info >= (3, 13) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
Shaobo-Zhou marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def setup_device_predictor( | ||||||||||||||||||||||
| devices: list[Target], | ||||||||||||||||||||||
|
|
@@ -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
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 Consistent use of NO_PARALLEL; consider a tiny helper to avoid repetition The conditional 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 |
||||||||||||||||||||||
| delayed(self._compile_all_circuits_devicewise)( | ||||||||||||||||||||||
| device, timeout, path_uncompiled_circuits, path_compiled_circuits, logger.level | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
|
|
@@ -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
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 Add explanatory comment for consistency. The parallelization logic is correct and matches the pattern in 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| delayed(self._generate_training_sample)( | ||||||||||||||||||||||
| filename.name, | ||||||||||||||||||||||
| path_uncompiled_circuits, | ||||||||||||||||||||||
|
|
@@ -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): | ||||||||||||||||||||||
|
|
@@ -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
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 Correct implementation, but consider adding explanatory comment. The conditional parallelization logic is correct and implements the past review feedback. However, like 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
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| joblib_dump(mdl, save_mdl_path) | ||||||||||||||||||||||
| logger.info("Random Forest model is trained and saved.") | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
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.
We should definitely add these (and some other major) changes to the changelog.
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.
Could you please do so in
CHANGELOG.md.