Skip to content

Commit cbc2308

Browse files
committed
CostPowerAnalysis added
1 parent 42ce30d commit cbc2308

File tree

6 files changed

+636
-71
lines changed

6 files changed

+636
-71
lines changed

docs/reference/api-full.md

Lines changed: 117 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Quick links:
1212
- [CLI Reference](cli.md)
1313
- [DSL Reference](dsl.md)
1414

15-
Generated from source code on: August 15, 2025 at 11:31 UTC
15+
Generated from source code on: August 15, 2025 at 17:27 UTC
1616

17-
Modules auto-discovered: 72
17+
Modules auto-discovered: 73
1818

1919
---
2020

@@ -2388,9 +2388,13 @@ Attributes:
23882388
Bandwidth-Availability Curve (BAC) from ``flow_results``.
23892389

23902390
Supports both MaxFlow and TrafficMatrixPlacement steps. For each failure
2391-
iteration, aggregate delivered bandwidth (sum of `placed` over all DC-DC pairs).
2392-
Compute the empirical availability curve and summary quantiles. Optionally,
2393-
overlay Placement vs MaxFlow when a sibling step with the same failure_id set is found.
2391+
iteration, aggregate delivered bandwidth (sum of ``placed`` over all DC-DC
2392+
pairs). Compute the empirical availability curve and summary quantiles.
2393+
2394+
This enhanced version optionally normalizes the x-axis by the offered demand
2395+
volume (when available via per-flow ``demand`` fields) to improve comparison
2396+
across scenarios of different scale. It preserves existing outputs and overlay
2397+
behavior for compatibility.
23942398

23952399
### BACAnalyzer
23962400

@@ -2453,10 +2457,15 @@ convenience to run both.
24532457

24542458
Capacity matrix analysis.
24552459

2456-
Consumes `flow_results` (from MaxFlow step). Builds node→node capacity matrix
2457-
using the *maximum placed value observed* per pair across iterations (i.e., the
2460+
Consumes ``flow_results`` (from MaxFlow step). Builds node→node capacity matrix
2461+
using the maximum placed value observed per pair across iterations (i.e., the
24582462
capacity ceiling under the tested failure set). Provides stats and a heatmap.
24592463

2464+
This enhanced version augments printed statistics (quartiles, density wording)
2465+
and is designed to be extended with distribution plots. To preserve test
2466+
stability and headless environments, histogram/CDF plots are not emitted here;
2467+
they can be added in notebooks explicitly if desired.
2468+
24602469
### CapacityMatrixAnalyzer
24612470

24622471
Analyze max-flow capacities into matrices/statistics/plots.
@@ -2467,6 +2476,47 @@ Analyze max-flow capacities into matrices/statistics/plots.
24672476
- `analyze_and_display(self, results: 'dict[str, Any]', **kwargs) -> 'None'` - Analyze results and render them in notebook format.
24682477
- `analyze_and_display_step(self, results: 'Dict[str, Any]', **kwargs) -> 'None'` - Analyze and render capacity matrix for a single workflow step.
24692478
- `display_analysis(self, analysis: 'Dict[str, Any]', **kwargs) -> 'None'` - Render analysis outputs in notebook format.
2479+
- `get_description(self) -> 'str'` - Return the analyzer description.
2480+
2481+
---
2482+
2483+
## ngraph.workflow.analysis.cost_power_analysis
2484+
2485+
Power/Cost analyzer for CostPower workflow step.
2486+
2487+
Computes absolute and unit-normalised metrics per aggregation level path
2488+
(typically level 2 "sites").
2489+
2490+
Inputs:
2491+
2492+
- CostPower step data under ``steps[step_name]["data"]`` with ``levels`` and
2493+
2494+
``context.aggregation_level``.
2495+
2496+
- Delivered traffic from a ``TrafficMatrixPlacement`` step (auto-detected or
2497+
2498+
provided via ``traffic_step``), using baseline iteration if available.
2499+
2500+
Outputs:
2501+
2502+
- site_metrics: mapping path -> {power_total_watts, capex_total, delivered_gbps}
2503+
- normalized_metrics: mapping path -> {power_per_unit, cost_per_unit}
2504+
2505+
Display renders tables (itables.show) and simple bar charts (seaborn).
2506+
2507+
### CostPowerAnalysis
2508+
2509+
Analyze power and capex per site and normalise by delivered traffic.
2510+
2511+
The analyzer aggregates absolute metrics from the CostPower step and
2512+
attributes delivered traffic to sites based on the baseline iteration of a
2513+
TrafficMatrixPlacement step. Ratios are computed as W/{unit} and $/{unit}.
2514+
2515+
**Methods:**
2516+
2517+
- `analyze(self, results: 'Dict[str, Any]', **kwargs: 'Any') -> 'Dict[str, Any]'` - Compute absolute and normalised metrics per site.
2518+
- `analyze_and_display(self, results: 'dict[str, Any]', **kwargs) -> 'None'` - Analyze results and render them in notebook format.
2519+
- `display_analysis(self, analysis: 'Dict[str, Any]', **kwargs: 'Any') -> 'None'` - Render absolute and normalised metrics tables and bar charts.
24702520
- `get_description(self) -> 'str'` - Return a concise description of the analyzer purpose.
24712521

24722522
---
@@ -2495,8 +2545,12 @@ Latency (distance) and stretch from ``cost_distribution``.
24952545
For each iteration, compute:
24962546
• mean distance per delivered Gbps (km/Gbps) aggregated across flows
24972547
• stretch = (mean distance) / (pair-wise lower-bound distance)
2498-
Lower bound is approximated as the minimum observed path cost per (src,dst) in the
2499-
**baseline** iteration(s) of the same step (or, if absent, across all iterations).
2548+
Lower bound is approximated as the minimum observed path cost per (src, dst) in
2549+
the "baseline" iteration(s) of the same step (or, if absent, across all
2550+
iterations).
2551+
2552+
This enhanced version augments the display with a CDF of stretch values to show
2553+
the distribution across iterations, complementing the scatter plot view.
25002554

25012555
### LatencyAnalyzer
25022556

@@ -2560,12 +2614,17 @@ styling defaults for plots and data tables.
25602614

25612615
## ngraph.workflow.analysis.placement_matrix
25622616

2563-
Placement analysis utilities for flow_results (unified design).
2617+
Placement analysis utilities for ``flow_results`` (unified design).
25642618

25652619
Consumes results produced by ``TrafficMatrixPlacementAnalysis`` with the new
2566-
schema under step["data"]["flow_results"]. Builds matrices of mean placed
2620+
schema under ``step["data"]["flow_results"]``. Builds matrices of mean placed
25672621
volume by pair (overall and per priority), with basic statistics.
25682622

2623+
This enhanced version also computes delivery fraction statistics (placed/
2624+
demand) per flow instance to quantify drops and renders simple distributions
2625+
(histogram and CDF) when demand is present, while preserving existing outputs
2626+
so tests remain stable.
2627+
25692628
### PlacementMatrixAnalyzer
25702629

25712630
Analyze placed Gbps envelopes and display matrices/statistics.
@@ -2740,90 +2799,79 @@ suitable for analysis algorithms. No additional parameters are required.
27402799

27412800
---
27422801

2743-
## ngraph.workflow.cost_power_efficiency
2802+
## ngraph.workflow.cost_power
27442803

2745-
Workflow step to compute cost/power efficiency metrics and optional HW inventory.
2804+
CostPower workflow step: collect capex and power by hierarchy level.
27462805

2747-
Computes total capex and power for the selected network inventory (all or only
2748-
active), and normalizes by a provided delivered-bandwidth figure (e.g., BAC at
2749-
availability target).
2806+
This step aggregates capex and power from the network hardware inventory without
2807+
performing any normalization or reporting. It separates contributions into two
2808+
categories:
27502809

2751-
Optionally collects node and/or link hardware entries to provide an inventory
2752-
view of hardware usage. Each entry includes hardware capacity, allocated
2753-
capacity, typical and maximum power, and a normalized hardware mapping.
2810+
- platform_*: node hardware (e.g., chassis, linecards) resolved from node attrs
2811+
- optics_*: per-end link hardware (e.g., optics) resolved from link attrs
27542812

2755-
This step does not compute BAC itself; it expects callers to pass the delivered
2756-
bandwidth value explicitly or to point to a prior step result.
2813+
Aggregation is computed at hierarchy levels 0..N where level 0 is the global
2814+
root (path ""), and higher levels correspond to prefixes of node names split by
2815+
"/". For example, for node "dc1/plane1/leaf/leaf-1":
27572816

2758-
YAML Configuration Example:
2759-
```yaml
2760-
workflow:
2761-
- step_type: CostPowerEfficiency
2762-
2763-
name: "cost_power_efficiency" # Optional custom name
2764-
delivered_bandwidth_gbps: 10000 # Optional explicit denominator (float)
2765-
delivered_bandwidth_key: "delivered_bandwidth_gbps" # Lookup key in results
2766-
include_disabled: true # Whether to include disabled nodes/links
2767-
collect_node_hw_entries: true # Optional: collect per-node HW entries
2768-
collect_link_hw_entries: false # Optional: collect per-link HW entries
2769-
```
2817+
- level 1 path is "dc1"
2818+
- level 2 path is "dc1/plane1"
2819+
- etc.
27702820

2771-
Results stored in `scenario.results`:
2821+
Disabled handling:
27722822

2773-
- total_capex: Sum of component capex (float)
2774-
- total_power_watts: Sum of component power (float)
2775-
- delivered_bandwidth_gbps: Denominator used for normalization (float)
2776-
- dollars_per_gbit: Normalized capex (float, inf if denominator <= 0)
2777-
- watts_per_gbit: Normalized power (float, inf if denominator <= 0)
2778-
- node_hw_entries: Optional list of node-level hardware dicts with keys:
2823+
- When include_disabled is False, only enabled nodes and links are considered.
2824+
- Optics are counted only when the endpoint node has platform hardware.
27792825

2780-
node, hardware {component, count}, hw_capacity, allocated_capacity,
2781-
power_watts, power_watts_max
2826+
YAML Configuration Example:
2827+
```yaml
2828+
workflow:
2829+
- step_type: CostPower
27822830

2783-
- link_hw_entries: Optional list of link-level hardware dicts with keys:
2831+
name: "cost_power" # Optional custom name
2832+
include_disabled: false # Default: only enabled nodes/links
2833+
aggregation_level: 2 # Produce levels: 0, 1, 2
2834+
```
27842835

2785-
link_id, source, target, capacity,
2786-
hardware {source {component, count, exclusive}, target {component, count, exclusive}},
2787-
hw_capacity, power_watts, power_watts_max
2836+
Results stored in `scenario.results` under this step namespace:
2837+
data:
2838+
context:
2839+
include_disabled: bool
2840+
aggregation_level: int
2841+
levels:
2842+
"0":
27882843

2789-
- hardware_bom_total: Aggregated hardware BOM for the whole network (Dict[str, float])
2790-
- hardware_bom_by_path: Mapping of hierarchy path -> BOM dict for each subtree
2844+
- path: ""
27912845

2792-
(root is stored under the empty string key "")
2846+
platform_capex: float
2847+
platform_power_watts: float
2848+
optics_capex: float
2849+
optics_power_watts: float
2850+
capex_total: float
2851+
power_total_watts: float
2852+
"1": [ ... ]
2853+
"2": [ ... ]
27932854

2794-
### CostPowerEfficiency
2855+
### CostPower
27952856

2796-
Compute $/Gbit and W/Gbit given delivered bandwidth.
2857+
Collect platform and optics capex/power by aggregation level.
27972858

27982859
Attributes:
2799-
delivered_bandwidth_gbps: Delivered bandwidth in Gbit/s used as denominator.
2800-
If not provided, the step will attempt to read a value from
2801-
``scenario.results`` using ``delivered_bandwidth_key``.
2802-
delivered_bandwidth_key: Results key to read if ``delivered_bandwidth_gbps``
2803-
is None. The key is looked up under this step's own namespace first; if
2804-
not present, the key is treated as a global results key.
2805-
include_disabled: If False, only enabled nodes/links are counted for totals.
2806-
Default ``True`` aggregates regardless of disabled flags.
2807-
collect_node_hw_entries: If True, store per-node hardware entries with
2808-
hardware mapping, capacity, allocated capacity, and power metrics.
2809-
collect_link_hw_entries: If True, store per-link hardware entries with
2810-
per-end hardware mapping, capacity, and power metrics.
2860+
include_disabled: If True, include disabled nodes and links.
2861+
aggregation_level: Inclusive depth for aggregation. 0=root only.
28112862

28122863
**Attributes:**
28132864

28142865
- `name` (str)
28152866
- `seed` (Optional[int])
28162867
- `_seed_source` (str)
2817-
- `delivered_bandwidth_gbps` (Optional[float])
2818-
- `delivered_bandwidth_key` (str) = delivered_bandwidth_gbps
2819-
- `include_disabled` (bool) = True
2820-
- `collect_node_hw_entries` (bool) = False
2821-
- `collect_link_hw_entries` (bool) = False
2868+
- `include_disabled` (bool) = False
2869+
- `aggregation_level` (int) = 2
28222870

28232871
**Methods:**
28242872

28252873
- `execute(self, scenario: "'Scenario'") -> 'None'` - Execute the workflow step with logging and metadata storage.
2826-
- `run(self, scenario: 'Any') -> 'None'` - Compute totals and normalized efficiency metrics.
2874+
- `run(self, scenario: 'Any') -> 'None'` - Aggregate capex and power by hierarchy levels 0..N.
28272875

28282876
---
28292877

ngraph/report.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def _create_setup_cell(self) -> nbformat.NotebookNode:
148148
from ngraph.workflow.analysis import (
149149
PackageManager, DataLoader, get_default_registry,
150150
SummaryAnalyzer, CapacityMatrixAnalyzer, PlacementMatrixAnalyzer,
151-
BACAnalyzer, LatencyAnalyzer, MSDAnalyzer
151+
BACAnalyzer, LatencyAnalyzer, MSDAnalyzer, CostPowerAnalysis
152152
)
153153
154154
# Prefer high-resolution inline images in executed notebooks (HTML export)
@@ -208,8 +208,17 @@ def _create_css_cell(self) -> nbformat.NotebookNode:
208208

209209
def _create_data_loading_cell(self) -> nbformat.NotebookNode:
210210
code = f"""# Load analysis results
211+
from pathlib import Path
211212
loader = DataLoader()
212-
load = loader.load_results('{self.results_path.name}')
213+
results_name = '{self.results_path.name}'
214+
candidate = Path(results_name)
215+
if not candidate.exists():
216+
# Fallback: search for the results file under current working directory
217+
try:
218+
candidate = next(Path.cwd().rglob(results_name))
219+
except StopIteration:
220+
pass
221+
load = loader.load_results(str(candidate))
213222
if load['success']:
214223
results = load['results']
215224
workflow_metadata = results.get('workflow', {{}})

ngraph/workflow/analysis/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .bac import BACAnalyzer
1717
from .base import AnalysisContext, NotebookAnalyzer
1818
from .capacity_matrix import CapacityMatrixAnalyzer
19+
from .cost_power_analysis import CostPowerAnalysis
1920
from .data_loader import DataLoader
2021
from .latency import LatencyAnalyzer
2122
from .msd import MSDAnalyzer
@@ -34,6 +35,7 @@
3435
"AnalysisRegistry",
3536
"get_default_registry",
3637
"CapacityMatrixAnalyzer",
38+
"CostPowerAnalysis",
3739
"PlacementMatrixAnalyzer",
3840
"BACAnalyzer",
3941
"LatencyAnalyzer",

0 commit comments

Comments
 (0)