Skip to content

Lazy implementation of costly parsing operations in the GlobalStatus#500

Open
dodu94 wants to merge 3 commits intodevelopingfrom
speed-up-jade-inint
Open

Lazy implementation of costly parsing operations in the GlobalStatus#500
dodu94 wants to merge 3 commits intodevelopingfrom
speed-up-jade-inint

Conversation

@dodu94
Copy link
Copy Markdown
Member

@dodu94 dodu94 commented Mar 24, 2026

This PR tries to address #488.

As expected, the main bottleneck is the parsing of the simulation folders and raw data.

After some experimentation it turns out the parsing itself cannot be sped up that much. At least, lazy implementations have been added for the parsing costly operations. This grants that the slow parsing will only be performed when absolutely necessary. (For instance, no parsing of simulation when post-processing).

Summary by CodeRabbit

  • Refactor

    • Transitioned application status initialization to lazy-loading to improve startup performance.
    • Refactored simulation success validation with improved code organization.
  • Tests

    • Updated test suite to accommodate lazy-loading behavior.

@dodu94 dodu94 requested a review from alexvalentine94 March 24, 2026 10:17
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Walkthrough

The pull request refactors status initialization in the JADE application from eager to lazy-loading with caching. Additionally, simulation success checkers are refactored from standalone functions to an object-oriented design with a SimulationChecker abstract base class and concrete implementations. Supporting static methods are added to simulation output classes to enable file-based success detection.

Changes

Cohort / File(s) Summary
Lazy-loaded Status Initialization
src/jade/app/app.py, src/jade/config/status.py
JadeApp.status converted to lazy-loading property that constructs GlobalStatus on first access. GlobalStatus now uses lazy properties for simulations and raw_data instead of eager initialization; update() method removed in favor of targeted update_raw_results() method.
Simulation Checker Refactoring
src/jade/helper/aux_functions.py
Standalone checker functions replaced with SimulationChecker abstract base class; concrete implementations (MCNPChecker, OpenMCChecker, SerpentChecker, D1SChecker) introduced. CODE_CHECKERS changed from function mapping to checker instance mapping.
Simulation Success Detection
src/jade/post/sim_output.py
Added is_successfully_simulated(files: list[str]) -> bool static methods to MCNPSimOutput and OpenMCSimOutput for file-based completion checking.
Checker Interface Updates
src/jade/run/benchmark.py
Updated checker invocation in _get_continue_run_command from function call with path to method call with directory listing: CODE_CHECKERS[code](path)CODE_CHECKERS[code].check_success(os.listdir(path)).
Test Updates
tests/app/test_app.py
Modified tests to trigger early status evaluation, replaced deprecated update() calls with update_raw_results() where appropriate.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • v4.3.0 additions #462: Modifies the JadeApp class in src/jade/app/app.py and related methods like run_benchmarks and raw_process, sharing overlapping structural changes with this lazy-loading refactor.

Suggested reviewers

  • alexvalentine94

Poem

🐰 Lazy bunny hops through code so spry,
Checkers class themselves, they multiply!
Status waits till needed, cached up tight,
Less eager work means faster flight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: converting costly GlobalStatus parsing operations from eager initialization to lazy loading.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch speed-up-jade-inint

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.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 96.77419% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/jade/helper/aux_functions.py 88.88% 2 Missing ⚠️
Files with missing lines Coverage Δ
src/jade/app/app.py 82.93% <100.00%> (+0.41%) ⬆️
src/jade/config/status.py 96.49% <100.00%> (+0.33%) ⬆️
src/jade/post/sim_output.py 93.56% <100.00%> (+0.13%) ⬆️
src/jade/run/benchmark.py 87.00% <100.00%> (ø)
src/jade/helper/aux_functions.py 95.18% <88.88%> (+1.27%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (3)
src/jade/helper/aux_functions.py (2)

112-118: Serpent checker raises NotImplementedError at runtime.

This is acceptable as a placeholder, but callers iterating over CODE_CHECKERS (e.g., in status.py) could encounter this exception if Serpent simulations exist in the folder structure.

Consider whether call sites need defensive handling, or document that Serpent support is not yet available.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/jade/helper/aux_functions.py` around lines 112 - 118, The SerpentChecker
currently raises NotImplementedError from SerpentChecker.check_success which can
bubble up when code iterates CODE_CHECKERS (e.g., in status.py); change
SerpentChecker.check_success to not raise—instead log a clear warning that
Serpent support is not implemented and return False (or an appropriate failure
value) so callers continue safely, and additionally harden the call sites that
iterate CODE_CHECKERS (for example the check loop in status.py) to catch
exceptions around checker.check_success and treat them as a failed check while
logging the exception and checker name.

121-126: Minor inefficiency: D1SChecker instantiates MCNPChecker on every call.

D1SChecker.check_success creates a new MCNPChecker() instance on each invocation. Since both classes are stateless, this could be simplified.

♻️ Suggested simplification
 class D1SChecker(SimulationChecker):
-    """Checker for D1S simulations."""
+    """Checker for D1S simulations (uses same logic as MCNP)."""
 
     def check_success(self, files: list[str]) -> bool:
         """Check if D1S run was successful (uses same logic as MCNP)."""
-        return MCNPChecker().check_success(files)
+        return MCNPSimOutput.is_successfully_simulated(files)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/jade/helper/aux_functions.py` around lines 121 - 126,
D1SChecker.check_success currently constructs a new MCNPChecker() on every call;
make it use a single shared instance to avoid repeated instantiation by creating
a module-level MCNPChecker instance (e.g., _mcnp_checker = MCNPChecker()) and
have D1SChecker.check_success call _mcnp_checker.check_success(files) instead of
instantiating a new MCNPChecker each time; reference: D1SChecker.check_success
and MCNPChecker.
src/jade/post/sim_output.py (1)

348-358: Minor inconsistency with retrieve_file method.

The is_successfully_simulated method checks for file.startswith("statepoint") and file.endswith(".h5"), but retrieve_file (line 332) only checks file.startswith("statepoint") without the .h5 extension requirement. While statepoint files are typically .h5, this inconsistency could cause a simulation to be considered successful by retrieve_file but fail the is_successfully_simulated check if a non-.h5 statepoint file exists.

Consider aligning the checks for consistency:

Option 1: Relax is_successfully_simulated to match retrieve_file
     `@staticmethod`
     def is_successfully_simulated(files: list[str]) -> bool:
         """Check if the simulation was successful by verifying output files exist."""
         statepoint_found = False
         output_found = False
         for file in files:
-            if file.startswith("statepoint") and file.endswith(".h5"):
+            if file.startswith("statepoint"):
                 statepoint_found = True
             elif file.endswith(".out"):
                 output_found = True
         return statepoint_found and output_found
Option 2: Tighten retrieve_file to match is_successfully_simulated
         for file_name in os.listdir(results_path):
             if file_name.endswith(".out"):
                 file1 = file_name
-            elif file_name.startswith("statepoint"):
+            elif file_name.startswith("statepoint") and file_name.endswith(".h5"):
                 file2 = file_name
             elif file_name == "volumes.json":
                 file3 = file_name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/jade/post/sim_output.py` around lines 348 - 358, The checks for
statepoint files are inconsistent: is_successfully_simulated requires files to
start with "statepoint" and end with ".h5" while retrieve_file only checks
startswith("statepoint"); update retrieve_file to the stricter check (require
file.startswith("statepoint") and file.endswith(".h5")) so both retrieve_file
and is_successfully_simulated use the same criteria, and ensure any code paths
relying on retrieve_file still behave correctly after adding the .h5 extension
check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/jade/helper/aux_functions.py`:
- Around line 112-118: The SerpentChecker currently raises NotImplementedError
from SerpentChecker.check_success which can bubble up when code iterates
CODE_CHECKERS (e.g., in status.py); change SerpentChecker.check_success to not
raise—instead log a clear warning that Serpent support is not implemented and
return False (or an appropriate failure value) so callers continue safely, and
additionally harden the call sites that iterate CODE_CHECKERS (for example the
check loop in status.py) to catch exceptions around checker.check_success and
treat them as a failed check while logging the exception and checker name.
- Around line 121-126: D1SChecker.check_success currently constructs a new
MCNPChecker() on every call; make it use a single shared instance to avoid
repeated instantiation by creating a module-level MCNPChecker instance (e.g.,
_mcnp_checker = MCNPChecker()) and have D1SChecker.check_success call
_mcnp_checker.check_success(files) instead of instantiating a new MCNPChecker
each time; reference: D1SChecker.check_success and MCNPChecker.

In `@src/jade/post/sim_output.py`:
- Around line 348-358: The checks for statepoint files are inconsistent:
is_successfully_simulated requires files to start with "statepoint" and end with
".h5" while retrieve_file only checks startswith("statepoint"); update
retrieve_file to the stricter check (require file.startswith("statepoint") and
file.endswith(".h5")) so both retrieve_file and is_successfully_simulated use
the same criteria, and ensure any code paths relying on retrieve_file still
behave correctly after adding the .h5 extension check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f864a29f-20e8-4ec3-b2fa-beaf9277b972

📥 Commits

Reviewing files that changed from the base of the PR and between a581978 and 8088251.

📒 Files selected for processing (6)
  • src/jade/app/app.py
  • src/jade/config/status.py
  • src/jade/helper/aux_functions.py
  • src/jade/post/sim_output.py
  • src/jade/run/benchmark.py
  • tests/app/test_app.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant