Skip to content

Test cores#37

Merged
rbx merged 3 commits into
FairRootGroup:masterfrom
enlorenz:test_cores
Mar 24, 2026
Merged

Test cores#37
rbx merged 3 commits into
FairRootGroup:masterfrom
enlorenz:test_cores

Conversation

@enlorenz

Copy link
Copy Markdown
Collaborator

No description provided.

Enis Lorenz added 2 commits March 20, 2026 13:50
…ries for different seeds.

Othterwise it would rewrite in the same model directory.
@coderabbitai

coderabbitai Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The diff adds array-based power accounting and moves job wait-time metric updates to job completion. It extends APIs to pass metrics/baseline flags, updates environment/baseline to use node/cores arrays for cost/power, and adds CLI seed-path/sweep options with session-dir changes and related test coverage for completion metrics.

Changes

Cohort / File(s) Summary
Power & reward logic
src/reward_calculation.py
Introduce array-aware power functions (_power_consumption_from_state_mwh), generalize power_consumption_mwh and power_cost to accept node/cores arrays with include_idle_nodes, and extend RewardCalculator.calculate(...) to accept nodes/cores_available.
Job lifecycle & metrics
src/job_management.py, test/test_job_completion_metrics.py
process_ongoing_jobs signature gains metrics and is_baseline; completion-time metrics update moved from assignment to job completion. assign_jobs_to_available_nodes stores wait_time on running jobs. Tests added to assert metrics increment only on completion.
Environment & baseline integration
src/environment.py, src/baseline.py
Environment and baseline now pass metrics/is_baseline into process_ongoing_jobs; reward calculation and step-level power/cost use node-array + cores_available inputs; baseline cost recalculated from power*price and off-mode calls set include_idle_nodes=False.
CLI / orchestration (seed handling & sessions)
analyze_seed_occupancy.py, train.py, train_iter.py
Add --seed-path and --seed-sweep handling; session directory and model/log/plot outputs now use a session_root that can include seed-derived suffixes; train_iter forwards --seed-sweep when multiple seeds provided.
Tests
test/test_job_completion_metrics.py
New tests verifying that job completion metrics (baseline and non-baseline) increment only when jobs finish; helper _empty_cluster() added.

Sequence Diagram(s)

sequenceDiagram
  participant Orchestrator as Train/Env Loop
  participant Scheduler as Job Manager
  participant Cluster as Nodes State
  participant Metrics as MetricsTracker
  participant Reward as RewardCalculator
  participant Baseline as BaselineStep

  Orchestrator->>Scheduler: assign_jobs_to_available_nodes(job_queue, Cluster.nodes, Cluster.cores)
  Scheduler->>Cluster: mark nodes used, add running_jobs {wait_time:int(job_age)}
  Orchestrator->>Scheduler: process_ongoing_jobs(Cluster.nodes, Cluster.cores, running_jobs, metrics, is_baseline)
  Scheduler->>Cluster: detect finished jobs -> return completed_job_ids
  Scheduler->>Metrics: if metrics and jobs finished -> increment completed counters & aggregate wait_time (baseline vs non-baseline)
  Orchestrator->>Reward: calculate(..., nodes=Cluster.nodes, cores_available=Cluster.cores)
  Reward->>Reward: compute power via _power_consumption_from_state_mwh(nodes, cores_available, include_idle_nodes)
  Reward->>Orchestrator: return cost, power, reward
  Orchestrator->>Baseline: baseline_step calls process_ongoing_jobs(..., is_baseline=True) and uses Reward outputs for baseline cost/power
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Test cores' is vague and does not clearly summarize the main changes, which involve significant refactoring of power consumption calculations, job metrics tracking, and CLI argument additions across multiple files. Revise the title to be more descriptive, such as 'Refactor power consumption to use array-based node state' or 'Update job completion metrics to track at job finish rather than start'.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether the description relates to the changeset. Add a detailed pull request description explaining the purpose, scope, and impact of the changes, including the motivation for the refactoring.

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


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
analyze_seed_occupancy.py (1)

902-902: Minor style: missing space before help keyword argument.

For consistency with other argument definitions in this file, add a space before help=.

🧹 Suggested fix
-    parser.add_argument("--seed-path", default="",help="Path if models are saved by seed (forwarded to train.py)")
+    parser.add_argument("--seed-path", default="", help="Path if models are saved by seed (forwarded to train.py)")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@analyze_seed_occupancy.py` at line 902, The parser.add_argument call for
"--seed-path" is missing a space before the help keyword; update the line with
the function call (parser.add_argument("--seed-path", default="", help="Path if
models are saved by seed (forwarded to train.py)")) so it matches the file's
argument formatting; locate the parser.add_argument("--seed-path",
default="",help="...") occurrence and insert the space before help= to maintain
consistent style.
src/reward_calculation.py (1)

67-96: Note: Semantic difference between scalar and array power computation paths.

The scalar path (lines 85-88) uses a discrete model where nodes are either "idle" (COST_IDLE_MW) or "used" (COST_USED_MW), while the array path (lines 90-96) uses utilization-based interpolation where partially-utilized nodes consume proportional power.

For a node with 50% core utilization:

  • Scalar: Counts as "used" → full COST_USED_MW
  • Array: COST_IDLE_MW + 0.5 * (COST_USED_MW - COST_IDLE_MW)

This is likely intentional for the transition to finer-grained power modeling, but ensure all callers use the appropriate path consistently. The issues flagged in environment.py and baseline.py show mixing of both paths.

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

In `@src/reward_calculation.py` around lines 67 - 96, power_consumption_mwh
currently has two different semantics for scalar vs array inputs (scalar branch
uses discrete COST_IDLE_MW/COST_USED_MW while array branch uses utilization
interpolation via _power_consumption_from_state_mwh), which causes inconsistent
results when callers in environment.py and baseline.py mix both styles; fix by
choosing one consistent behavior: either (A) update callers (environment.py,
baseline.py) to always pass node-state arrays and cores-available arrays so
power_consumption_mwh always follows the interpolation path, or (B) change
power_consumption_mwh to canonicalize scalar inputs into the array form before
computing (e.g., expand num_used_nodes and num_idle_nodes into boolean/node-util
arrays and call _power_consumption_from_state_mwh) so both code paths yield the
same utilization-based result—locate the code in power_consumption_mwh and
modify the scalar-handling branch or update the callers accordingly.
🤖 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/baseline.py`:
- Around line 140-148: The baseline code currently overwrites the array-based
power/cost with a scalar computation: restore consistent array-based accounting
by using power_consumption_mwh(num_used_nodes, num_idle_nodes) and
power_consumption_mwh(num_used_nodes, 0) for baseline_power_mwh and
baseline_power_off_mwh (and derive baseline_cost/baseline_cost_off from those)
instead of the scalar num_used_cores/CORES_PER_NODE calls; remove or revert the
scalar assignments that assign baseline_power_mwh and baseline_power_off_mwh
from num_used_cores and delete the leftover commented-out lines so
baseline_power_mwh, baseline_power_off_mwh, baseline_cost, and baseline_cost_off
are computed only from the array-based power_consumption_mwh results to match
src/environment.py.

In `@src/environment.py`:
- Around line 487-498: The power/cost calculation is inconsistent:
step_power_mwh is computed twice (once as scalar using
num_used_cores/CORES_PER_NODE and again as an array using
power_consumption_mwh(self.state['nodes'], self.cores_available)), but step_cost
is computed from the scalar while metrics are updated from the array. Fix by
computing step_power_mwh exactly once using the array-based call
power_consumption_mwh(self.state['nodes'], self.cores_available) (or convert
that array to the scalar aggregate you intend), then compute step_cost =
step_power_mwh * current_price using that same value, and update
self.metrics.total_cost and self.metrics.episode_total_cost from that same
step_cost; remove the redundant scalar computation and leftover commented-out
lines (references: power_consumption_mwh, CORES_PER_NODE, num_used_cores,
num_idle_nodes, self.state['nodes'], self.cores_available,
self.metrics.total_cost, self.metrics.episode_total_cost).

---

Nitpick comments:
In `@analyze_seed_occupancy.py`:
- Line 902: The parser.add_argument call for "--seed-path" is missing a space
before the help keyword; update the line with the function call
(parser.add_argument("--seed-path", default="", help="Path if models are saved
by seed (forwarded to train.py)")) so it matches the file's argument formatting;
locate the parser.add_argument("--seed-path", default="",help="...") occurrence
and insert the space before help= to maintain consistent style.

In `@src/reward_calculation.py`:
- Around line 67-96: power_consumption_mwh currently has two different semantics
for scalar vs array inputs (scalar branch uses discrete
COST_IDLE_MW/COST_USED_MW while array branch uses utilization interpolation via
_power_consumption_from_state_mwh), which causes inconsistent results when
callers in environment.py and baseline.py mix both styles; fix by choosing one
consistent behavior: either (A) update callers (environment.py, baseline.py) to
always pass node-state arrays and cores-available arrays so
power_consumption_mwh always follows the interpolation path, or (B) change
power_consumption_mwh to canonicalize scalar inputs into the array form before
computing (e.g., expand num_used_nodes and num_idle_nodes into boolean/node-util
arrays and call _power_consumption_from_state_mwh) so both code paths yield the
same utilization-based result—locate the code in power_consumption_mwh and
modify the scalar-handling branch or update the callers accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c610fce8-722f-4dc5-ae09-557fb38101e0

📥 Commits

Reviewing files that changed from the base of the PR and between 95c564e and 9d073f9.

📒 Files selected for processing (8)
  • analyze_seed_occupancy.py
  • src/baseline.py
  • src/environment.py
  • src/job_management.py
  • src/reward_calculation.py
  • test/test_job_completion_metrics.py
  • train.py
  • train_iter.py

Comment thread src/baseline.py
Comment thread src/environment.py Outdated
@enlorenz enlorenz force-pushed the test_cores branch 2 times, most recently from ffe59c6 to 0b3dfc7 Compare March 24, 2026 09:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/baseline.py (1)

140-148: ⚠️ Potential issue | 🟠 Major

Power/cost values computed twice; scalar version overwrites array version.

Lines 123-137 compute baseline_cost, baseline_power_mwh, etc. using the array-based method, then lines 143-147 overwrite these with scalar-based computation using num_used_cores/CORES_PER_NODE. This creates:

  1. Redundant computation - the array-based values are discarded
  2. Semantic mismatch - scalar path treats fractional nodes (num_used_cores/CORES_PER_NODE) differently than array path (per-node utilization interpolation)
  3. Inconsistency with environment.py - the agent uses array-based power accounting via RewardCalculator.calculate(nodes=..., cores_available=...)

The commented-out lines 141-142 indicate incomplete refactoring.

Proposed fix: Remove the redundant scalar recomputation
     num_used_cores = num_on_nodes * CORES_PER_NODE - np.sum(baseline_cores_available)
-    
-    `#baseline_power_mwh` = power_consumption_mwh(num_used_nodes , num_idle_nodes)
-    `#baseline_power_off_mwh` = power_consumption_mwh(num_used_nodes, 0)
-    baseline_power_mwh = power_consumption_mwh(num_used_cores/CORES_PER_NODE, num_idle_nodes)
-    baseline_power_off_mwh = power_consumption_mwh(num_used_cores/CORES_PER_NODE, 0)
-    
-    baseline_cost = baseline_power_mwh * current_price
-    baseline_cost_off = baseline_power_off_mwh * current_price
-
+    # baseline_cost, baseline_cost_off, baseline_power_mwh, baseline_power_off_mwh
+    # are already computed above using array-based method (lines 123-137)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/baseline.py` around lines 140 - 148, Remove the redundant scalar
recomputation that overwrites the array-based baseline values: keep the
array-based calls to power_consumption_mwh and baseline_cost/baseline_cost_off
(the ones computed earlier, which align with RewardCalculator.calculate and
per-node utilization), and delete the subsequent assignments that use
num_used_cores/CORES_PER_NODE (the lines assigning baseline_power_mwh and
baseline_power_off_mwh using num_used_cores). Ensure only the array-based
baseline_power_mwh, baseline_power_off_mwh, baseline_cost, and baseline_cost_off
remain so the semantics match the rest of the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/baseline.py`:
- Around line 140-148: Remove the redundant scalar recomputation that overwrites
the array-based baseline values: keep the array-based calls to
power_consumption_mwh and baseline_cost/baseline_cost_off (the ones computed
earlier, which align with RewardCalculator.calculate and per-node utilization),
and delete the subsequent assignments that use num_used_cores/CORES_PER_NODE
(the lines assigning baseline_power_mwh and baseline_power_off_mwh using
num_used_cores). Ensure only the array-based baseline_power_mwh,
baseline_power_off_mwh, baseline_cost, and baseline_cost_off remain so the
semantics match the rest of the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9a6788c4-cd30-45fe-98c3-227980e2c83d

📥 Commits

Reviewing files that changed from the base of the PR and between 9d073f9 and 0b3dfc7.

📒 Files selected for processing (3)
  • src/baseline.py
  • src/environment.py
  • src/reward_calculation.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/environment.py

- switch agent and baseline power/cost accounting from binary idle/used nodes to per-node core utilization
- keep baseline_off semantics by excluding idle powered-on nodes from power/cost
- add regression tests for completion timing and partial-utilization power accounting

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/baseline.py (1)

123-143: Remove redundant cost computation: baseline_cost and baseline_cost_off are computed twice.

Lines 123–130 compute costs via power_cost(), used only for logging. Lines 141–142 then overwrite both variables by multiplying power_mwh * current_price. Since power_cost() internally calls power_consumption_mwh() * price, the two approaches are mathematically equivalent, making lines 123–130 wasteful duplicate computation.

Refactor to compute power first, then derive cost once:

♻️ Proposed refactor
-    baseline_cost = power_cost(baseline_state['nodes'], baseline_cores_available, current_price)
-    env_print(f"    > baseline_cost: €{baseline_cost:.4f} | used nodes: {num_used_nodes}, idle nodes: {num_idle_nodes}")
-    baseline_cost_off = power_cost(
-        baseline_state['nodes'],
-        baseline_cores_available,
-        current_price,
-        include_idle_nodes=False,
-    )
-    env_print(f"    > baseline_cost_off: €{baseline_cost_off:.4f} | used nodes: {num_used_nodes}, idle nodes: 0")
     baseline_power_mwh = power_consumption_mwh(baseline_state['nodes'], baseline_cores_available)
     baseline_power_off_mwh = power_consumption_mwh(
         baseline_state['nodes'],
         baseline_cores_available,
         include_idle_nodes=False,
     )
 
     num_used_cores = num_on_nodes * CORES_PER_NODE - np.sum(baseline_cores_available)
     baseline_cost = baseline_power_mwh * current_price
     baseline_cost_off = baseline_power_off_mwh * current_price
+    env_print(f"    > baseline_cost: €{baseline_cost:.4f} | used nodes: {num_used_nodes}, idle nodes: {num_idle_nodes}")
+    env_print(f"    > baseline_cost_off: €{baseline_cost_off:.4f} | used nodes: {num_used_nodes}, idle nodes: 0")
 

Greedy scheduler guideline is satisfied (docstring confirms all nodes stay online, jobs scheduled greedily).

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

In `@src/baseline.py` around lines 123 - 143, The code redundantly calls
power_cost() to compute baseline_cost and baseline_cost_off and then overwrites
them by multiplying baseline_power_mwh and baseline_power_off_mwh by
current_price; remove the initial power_cost() calls and instead compute power
once via power_consumption_mwh() (baseline_power_mwh, baseline_power_off_mwh)
and derive baseline_cost = baseline_power_mwh * current_price and
baseline_cost_off = baseline_power_off_mwh * current_price, updating the
env_print() lines to use those derived values (refer to baseline_cost,
baseline_cost_off, baseline_power_mwh, baseline_power_off_mwh, power_cost(),
power_consumption_mwh(), num_used_nodes, num_idle_nodes).
🤖 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/baseline.py`:
- Around line 123-143: The code redundantly calls power_cost() to compute
baseline_cost and baseline_cost_off and then overwrites them by multiplying
baseline_power_mwh and baseline_power_off_mwh by current_price; remove the
initial power_cost() calls and instead compute power once via
power_consumption_mwh() (baseline_power_mwh, baseline_power_off_mwh) and derive
baseline_cost = baseline_power_mwh * current_price and baseline_cost_off =
baseline_power_off_mwh * current_price, updating the env_print() lines to use
those derived values (refer to baseline_cost, baseline_cost_off,
baseline_power_mwh, baseline_power_off_mwh, power_cost(),
power_consumption_mwh(), num_used_nodes, num_idle_nodes).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91314391-7e05-42af-ab59-cddb8c807255

📥 Commits

Reviewing files that changed from the base of the PR and between 0b3dfc7 and 9505a79.

📒 Files selected for processing (3)
  • src/baseline.py
  • src/environment.py
  • src/reward_calculation.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/environment.py
  • src/reward_calculation.py

@rbx rbx merged commit 77d00ea into FairRootGroup:master Mar 24, 2026
4 checks passed
@enlorenz enlorenz deleted the test_cores branch March 24, 2026 11:58
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.

2 participants