Skip to content

fixed potential memory leak in parallelization#336

Merged
aaronleesander merged 7 commits intomainfrom
imports
Feb 17, 2026
Merged

fixed potential memory leak in parallelization#336
aaronleesander merged 7 commits intomainfrom
imports

Conversation

@aaronleesander
Copy link
Member

Description

This pull request fixes issues related to each trajectory duplicating unneeded information which would need to memory usage exploding for heavy simulations.

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@aaronleesander aaronleesander added the bug Something isn't working label Feb 17, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 17, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Fixed memory leak in parallel simulation execution
  • New Features

    • Introduced YAQS_MAX_WORKERS environment variable to customize parallel worker threads
    • Added progress tracking during parallel simulations
    • Improved retry handling for transient failures

Walkthrough

The changes refactor parallel task execution in the simulator using a worker-context model, replacing direct parameter passing with shared context objects. This includes thread-limiting logic, worker initializers, and progress tracking across digital and analog simulation paths. A memory leak fix is documented in the changelog.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Added "Fixed" section documenting memory leak resolution and PR reference [#336].
Parallel Execution Refactoring
src/mqt/yaqs/simulator.py
Introduced worker-context model with global _WORKER_CTX, per-worker initializers, and context-aware worker wrappers (_digital_strong_worker, _digital_weak_worker, _analog_worker, _mcwf_worker). Added thread-capping logic, bounded task execution, progress bars via tqdm, and retry logic. Extended CPU detection with YAQS_MAX_WORKERS environment override. Reworked serial and parallel execution paths to use new context model.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Poem

🐰 A context shared among workers swift,
No memory leaks—a welcome gift!
Threads now capped, tasks bounded tight,
Progress bars glow through the night. 🌙✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing a memory leak in parallelization. It is concise and clearly summarizes the primary objective of the changeset.
Description check ✅ Passed The description includes a summary of the change and addresses the issue of memory duplication in trajectories. However, it lacks a specific issue reference (e.g., 'Fixes #336') and the motivation could be more detailed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch imports

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/mqt/yaqs/simulator.py (2)

349-383: 🧹 Nitpick | 🔵 Trivial

Duplicate section number in comments — both sections labeled "8)".

Line 350 and Line 383 both use section number 8). Likely a copy-paste oversight.

✏️ Fix section numbering
 # ---------------------------------------------------------------------------
-# 8) MULTIPROCESS "spawn" CONTEXT
+# 9) MULTIPROCESS "spawn" CONTEXT
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/mqt/yaqs/simulator.py` around lines 349 - 383, The comment headers have a
duplicated section number "8)" around the _call_backend function; update the
comment numbering to be sequential and unique (e.g., change this section to "8)"
and the following "8) MULTIPROCESS \"spawn\" CONTEXT" to "9) MULTIPROCESS
\"spawn\" CONTEXT" or vice versa) so section labels are not duplicated; locate
the section header string containing "_call_backend" and the next header text
"MULTIPROCESS \"spawn\" CONTEXT" and adjust the numeral to maintain proper
ordering.

41-51: 🧹 Nitpick | 🔵 Trivial

Duplicate import of Callable.

Callable is imported at runtime on Line 41 (from collections.abc import Callable) and again inside the if TYPE_CHECKING: block on Line 51. The TYPE_CHECKING import is redundant since the runtime import already makes Callable available everywhere.

♻️ Remove the redundant import
 if TYPE_CHECKING:
-    from collections.abc import Callable
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/mqt/yaqs/simulator.py` around lines 41 - 51, Remove the redundant
type-only import of Callable inside the TYPE_CHECKING block: since Callable is
already imported at runtime (from collections.abc import Callable), delete the
duplicate "from collections.abc import Callable" line inside the if
TYPE_CHECKING: block so Callable is only imported once and type checks still
work; verify no other TYPE_CHECKING-only imports rely on that duplicate before
committing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/mqt/yaqs/simulator.py`:
- Around line 838-844: Initialize ctx before the conditional to avoid the
"potentially unbound" warning: declare ctx = None (with an appropriate Optional
type annotation) above the if sim_params.solver == "MCWF": block, keep the
existing assignment inside that block, and leave the later use in args as-is
(it's still guarded by the same MCWF branch so no runtime change); update
imports/annotations if needed to reference typing.Optional and the actual ctx
type.
- Around line 834-835: The serial fallback currently sets n_threads =
available_cpus() which ignores the sim_params.num_threads setting; change the
serial path to respect the num_threads attribute on the simulation params (e.g.,
use sim_params.num_threads or default to 1) instead of available_cpus(). Update
the block that assigns n_threads (and any downstream use of n_threads) to read
sim_params.num_threads (falling back to 1 if unset) so StrongSimParams and
AnalogSimParams controls are honored. Ensure available_cpus() continues to be
used only for the parallel path, and keep variable name n_threads unchanged.
- Around line 586-598: The serial execution paths currently set n_threads =
available_cpus(), which overrides the user's StrongSimParams.num_threads
preference; change the serial-path thread selection to use
sim_params.num_threads (falling back to available_cpus() only if num_threads is
missing or None) so BLAS/LAPACK threading honors the user's setting—update the
occurrence in this loop (where n_threads is used with _call_backend(backend,
arg, n_threads=n_threads)) and mirror the same change in the other serial
branches for weak and analog simulations so all serial code uses
sim_params.num_threads instead of unconditionally calling available_cpus().

---

Outside diff comments:
In `@src/mqt/yaqs/simulator.py`:
- Around line 349-383: The comment headers have a duplicated section number "8)"
around the _call_backend function; update the comment numbering to be sequential
and unique (e.g., change this section to "8)" and the following "8) MULTIPROCESS
\"spawn\" CONTEXT" to "9) MULTIPROCESS \"spawn\" CONTEXT" or vice versa) so
section labels are not duplicated; locate the section header string containing
"_call_backend" and the next header text "MULTIPROCESS \"spawn\" CONTEXT" and
adjust the numeral to maintain proper ordering.
- Around line 41-51: Remove the redundant type-only import of Callable inside
the TYPE_CHECKING block: since Callable is already imported at runtime (from
collections.abc import Callable), delete the duplicate "from collections.abc
import Callable" line inside the if TYPE_CHECKING: block so Callable is only
imported once and type checks still work; verify no other TYPE_CHECKING-only
imports rely on that duplicate before committing.

@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

❌ Patch coverage is 72.22222% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/mqt/yaqs/simulator.py 72.2% 15 Missing ⚠️

📢 Thoughts on this report? Let us know!

@aaronleesander aaronleesander merged commit 840d33b into main Feb 17, 2026
14 of 15 checks passed
@aaronleesander aaronleesander deleted the imports branch February 17, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments