Files
OpenJarvis/tests/learning/test_device_selection.py
T
Jon Saad-FalconandClaude Opus 4.6 24972e3e52 Add Phase 12+13: energy measurement, install polish, PWA, cross-hardware
Phase 12 — Energy Measurement Upgrade:
- EnergyMonitor ABC with multi-vendor support (NVIDIA hw counters,
  AMD amdsmi, Apple zeus-ml, CPU RAPL sysfs)
- EnergyBatch batch-level energy-per-token accounting
- SteadyStateDetector CV-based thermal equilibrium detection
- EnergyBenchmark with warmup phase
- InstrumentedEngine prefers EnergyMonitor over legacy GpuMonitor
- Telemetry store/aggregator extended with energy fields

Phase 13 — Install, Hosting, Cross-Hardware:
- jarvis doctor diagnostic command (8 checks, --json output)
- jarvis init post-setup guidance with engine-specific next steps
- README Quick Start section
- MLX engine backend (Apple Silicon → mlx recommendation)
- AMD VRAM/multi-GPU detection via rocm-smi
- PyTorch MPS device selection in orchestrator trainers
- PWA support (vite-plugin-pwa, service worker, manifest, icons)
- Server static file serving fix for PWA files
- Dockerfile.gpu.rocm + docker-compose.gpu.rocm.yml for ROCm
- Eval framework display module and efficiency metrics

2244 tests pass, 37 skipped.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:09:07 +00:00

84 lines
2.3 KiB
Python

"""Tests for PyTorch device selection (cuda > mps > cpu)."""
from __future__ import annotations
class TestSelectTorchDevice:
"""Tests for _select_torch_device() logic in orchestrator trainers.
Since torch is not installed in the test environment, we test the
selection logic directly rather than through the function (which
returns None when torch is absent).
"""
def test_no_torch_returns_none(self):
"""Without torch, _select_torch_device returns None."""
from openjarvis.learning.orchestrator.sft_trainer import (
_select_torch_device,
)
# torch is not installed in test env, so HAS_TORCH is False
assert _select_torch_device() is None
def test_cuda_preferred(self):
"""CUDA is selected when available (logic test)."""
has_cuda = True
has_mps = True
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "cuda"
def test_mps_fallback(self):
"""MPS is selected when CUDA is not available but MPS is."""
has_cuda = False
has_mps = True
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "mps"
def test_cpu_last_resort(self):
"""CPU is selected when neither CUDA nor MPS is available."""
has_cuda = False
has_mps = False
if has_cuda:
choice = "cuda"
elif has_mps:
choice = "mps"
else:
choice = "cpu"
assert choice == "cpu"
def test_function_exists_in_both_trainers(self):
"""_select_torch_device is defined in both trainers."""
from openjarvis.learning.orchestrator.grpo_trainer import (
_select_torch_device as grpo_fn,
)
from openjarvis.learning.orchestrator.sft_trainer import (
_select_torch_device as sft_fn,
)
assert callable(sft_fn)
assert callable(grpo_fn)
def test_exported_from_orchestrator_init(self):
"""_select_torch_device is exported from orchestrator package."""
from openjarvis.learning.orchestrator import (
_select_torch_device,
)
assert callable(_select_torch_device)