Skip to content

Adding Evaluation suite to test hardware and Network#3135

Open
rushabhdhoke wants to merge 14 commits into
dimensionalOS:mainfrom
rushabhdhoke:main
Open

Adding Evaluation suite to test hardware and Network#3135
rushabhdhoke wants to merge 14 commits into
dimensionalOS:mainfrom
rushabhdhoke:main

Conversation

@rushabhdhoke

Copy link
Copy Markdown

Contribution path

  • Created a folder "eval" inside the "dimos" folder
  • root/dimos/eval/

Problem

Requirement of an FDE-facing eval utility for Jetson, Nvidia, AGX systems. Added Network eval for simulating network stability for real world deployments.

Solution

Introduced "dimos/eval` with two standalone tools that reusing existing DimOS infrastructure.

  1. Resource eval - uses the StatsMonitor (used by dtop) to an in-memory logger to calculate startup cost. Measures CPU, PSS Memory, GPU utilization and startup times for Jetson and Nividia hardware. Outputs a JSON file with a hardware profile.
  2. Network eval - Uses the same measure_throughput function as the existing benchmark then runs the 'tc netem'. It evaluates the transport, profilepair and calculates % loss and latency.

How to Test

Resource eval — list available blueprints

python -m dimos.eval --list

Network eval (smoke test)

python -m dimos.eval.network --baseline-only

Full netem sweep (Linux + root )

sudo -E python -m dimos.eval.network --iface lo

AI assistance

Gemini 3.5 Flash & Claude Sonnet 4.6

Checklist

  • I have read and approved the CLA.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds hardware and network evaluation tools for DimOS. The main changes are:

  • Hardware detection and resource sampling for blueprint runs.
  • JSON and terminal reports for CPU, memory, GPU, and startup metrics.
  • Shared pubsub throughput measurement under network impairment profiles.
  • Command-line entry points for resource and network evaluations.

Confidence Score: 5/5

The latest changes look safe to merge.

  • The interval checks prevent non-positive values from starting tight sampler loops.
  • Monitor cleanup now runs when evaluation fails after startup.
  • No additional blocking issue met the requirements for this follow-up review.

Important Files Changed

Filename Overview
dimos/eval/network.py Adds transport selection, network impairment profiles, result grading, reporting, and CLI handling.
dimos/eval/runner.py Adds blueprint execution, resource monitoring, result aggregation, interval validation, and cleanup.
dimos/eval/measure.py Adds the shared pubsub throughput measurement used by network evaluations.
dimos/eval/sampler.py Adds in-memory process sampling, GPU polling, and resource aggregation.
dimos/eval/hardware.py Adds host, Jetson, CUDA, and GPU hardware detection.
dimos/eval/metrics.py Adds evaluation result models, JSON serialization, and terminal reports.
dimos/eval/main.py Adds the command-line interface for blueprint resource evaluation.

Reviews (4): Last reviewed commit: "Merge branch 'main' into main" | Re-trigger Greptile

Comment thread dimos/eval/network.py Outdated

def _display_name(case: Any) -> str:
"""Pretty transport label, shared with the benchmark's pubsub_id."""
from dimos.protocol.pubsub.benchmark.measure import transport_name

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.

P0 Missing Benchmark Module

Both _display_name() and run_network_eval() import helpers from dimos.protocol.pubsub.benchmark.measure, but that module is absent from the repository. The documented network run fails with ModuleNotFoundError before measuring a transport, and --list fails when it calls _display_name().

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

module.py was existing in previous dimos versions, current version doesn't have that file, so this was failing. Added the file in my folder and referenced it.

Comment thread dimos/eval/network.py Outdated

def networked_cases() -> list[Any]:
"""The subset of the benchmark's testcases that actually cross a link."""
from dimos.protocol.pubsub.benchmark.testdata import testcases

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.

P1 Runtime Path Requires Pytest

networked_cases() imports the benchmark's test-data module, which imports pytest even though it is only a test dependency. A normal installation without development dependencies therefore fails when a network run or --list reaches this line.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Wrapped the from testdata import testcases in a try/except ImportError that gives a clear error message telling the user to install dev dependencies.

Comment thread dimos/eval/runner.py
worker_source = cast("WorkerManagerPython", coordinator._managers["python"])
monitor = StatsMonitor(worker_source, resource_logger=resource_logger, interval=interval)

monitor.start()

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.

P1 Failed Runs Leak Monitor Thread

After this monitor starts, an exception during GPU startup, warmup, sampling, or aggregation skips monitor.stop(). The finally block stops the GPU and coordinator but leaves this daemon monitor running, so repeated failed API calls accumulate sampling threads.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added monitor.stop() to the finally block. The monitor variable is now tracked in the outer scope (initialized to None) so finally can always reach it, even if the exception happens after monitor.start().

Comment thread dimos/eval/runner.py Outdated
build_start = time.monotonic()
from dimos.core.coordination.module_coordinator import ModuleCoordinator

coordinator = ModuleCoordinator.build(bp)

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.

P1 Partial Build Loses Cleanup Handle

ModuleCoordinator.build() starts managers before completing deployment. If a later build step raises, this assignment never stores the coordinator, so the finally block sees None and cannot stop the workers already started by the failed build.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Changed the build to built = ModuleCoordinator.build(bp) then coordinator = built on the next line. If build() raises partway through, coordinator stays None so finally won't try to call .stop() on a half-built object. The actual teardown of any partially-started managers is ModuleCoordinator's responsibility.

Comment thread dimos/eval/__main__.py
Comment on lines +60 to +61
help="Steady-state sampling window in seconds (default: 15).")
parser.add_argument("--warmup", type=float, default=3.0,

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.

P1 Zero Interval Corrupts Measurements

The CLI accepts --interval 0, which makes both sampler threads repeatedly call Event.wait(0) in a tight loop. Their CPU usage then becomes part of the benchmark, producing inflated CPU results while consuming a core.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in runner.py + main.py, run_eval() now raises ValueError if interval <= 0
The CLI in main.py validates --interval > 0 before calling run_eval()

Comment thread dimos/eval/network.py
Comment on lines +67 to +72
from dimos.protocol.pubsub.benchmark.testdata import testcases
except ImportError as exc:
raise ImportError(
"The transport benchmark test-data module requires pytest and its "
"dependencies to be installed. Install with: uv sync --all-extras"
) from exc

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.

P1 Runtime dependency remains unresolved

Importing benchmark.testdata still executes its unconditional import pytest. A normal installation without test dependencies therefore cannot run --list or any network evaluation. This handler only replaces the original exception, and its suggested uv sync --all-extras command does not install the test group containing pytest. Move the reusable cases out of the pytest module or declare the required runtime dependency.

Comment thread dimos/eval/runner.py
Comment on lines +99 to +100
built = ModuleCoordinator.build(bp)
coordinator = built

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.

P1 Partial builds still leak

ModuleCoordinator.build() starts worker processes before connecting streams and references or starting modules. If one of those later steps raises, build() never returns, so coordinator remains None. The finally block then skips coordinator.stop(), leaving workers or partially started modules running. Cleanup must happen inside ModuleCoordinator.build() for every exception after startup, or the coordinator must be available before those fallible steps run.

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