Skip to content

Commit 0f86ec5

Browse files
committed
finalizing release
1 parent 212c8fe commit 0f86ec5

6 files changed

Lines changed: 193 additions & 40 deletions

File tree

README.md

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,42 @@ Professional GPU monitoring and stress testing tool with real-time visualization
55
## Features
66

77
- **Real-time Monitoring**: GPU utilization, memory, temperature, power, and system metrics
8-
- **Web Dashboard**: Interactive charts with live updates and historical data
8+
- **Web Dashboard**: Interactive charts with live updates and historical data (optional)
99
- **GPU Stress Testing**: Particle simulation with auto-scaling backend load
1010
- **Performance Baselines**: Track and compare GPU performance over time
11-
- **Visualization**: Real-time particle physics simulation with interactive controls
11+
- **Visualization**: Real-time particle physics simulation with interactive controls (optional)
1212
- **Multiple Test Modes**: Quick, Standard, Extended, Stress Test, and Custom configurations
13+
- **Modular Installation**: Install only what you need (CLI-only, with Web UI, or Full)
1314

1415
## Requirements
1516

1617
- Python 3.8+
17-
- NVIDIA GPU with drivers
18-
- CUDA Toolkit 12.0+ (for GPU benchmarking)
18+
- NVIDIA GPU with drivers (optional - for GPU benchmarking)
19+
- CUDA Toolkit 12.0+ (optional - for GPU acceleration)
1920
- Windows 10/11 or Linux
2021

22+
## Installation Options
23+
24+
The tool supports three installation types:
25+
26+
### 1. MINIMAL (CLI only)
27+
- Command-line interface with rich output
28+
- Basic monitoring (click, rich, psutil)
29+
- Smallest installation (~10 MB)
30+
- **Use case**: Headless servers, minimal footprint
31+
32+
### 2. STANDARD (CLI + Web UI)
33+
- Everything in Minimal
34+
- Web dashboard with real-time charts
35+
- REST API endpoints
36+
- **Use case**: Remote monitoring, multiple users
37+
38+
### 3. FULL (Standard + Visualization + GPU)
39+
- Everything in Standard
40+
- Particle simulation visualization
41+
- GPU benchmarking support
42+
- **Use case**: Full-featured installation, development
43+
2144
## Quick Start
2245

2346
### Installation
@@ -32,28 +55,34 @@ Professional GPU monitoring and stress testing tool with real-time visualization
3255
.\setup.ps1
3356
```
3457

35-
3. **Launch** web dashboard:
58+
3. **Select** installation type (1=Minimal, 2=Standard, 3=Full)
59+
60+
4. **Launch**:
3661

3762
```powershell
63+
# For MINIMAL or STANDARD:
64+
python health_monitor.py cli
65+
66+
# For STANDARD or FULL:
3867
python health_monitor.py web
39-
```text
40-
Access at: http://localhost:8090
68+
```
4169

4270
### Usage
4371

44-
**Web Dashboard (Recommended)**
72+
**Web Dashboard** (Standard/Full installations)
4573

4674
```powershell
4775
python health_monitor.py web
4876
```
77+
Access at: http://localhost:8090
4978

50-
**Terminal Interface**
79+
**Terminal Interface** (All installations)
5180

5281
```powershell
5382
python health_monitor.py cli
5483
```
5584

56-
**Command-Line Benchmark**
85+
**Command-Line Benchmark** (Full installation with GPU libraries)
5786

5887
```powershell
5988
# Quick 15s test
@@ -136,10 +165,16 @@ REST API endpoints (web mode):
136165
- Download CUDA Toolkit: <https://developer.nvidia.com/cuda-downloads>
137166
- Re-run `setup.ps1` after installation
138167

139-
**Benchmark disabled**
168+
**Benchmark disabled / Simulation button grayed out**
169+
170+
- GPU compute libraries not installed or not detected
171+
- Solution 1: Run `python health_monitor.py refresh` to update detection cache
172+
- Solution 2: Re-run `setup.ps1` and install CuPy or PyTorch
173+
174+
**CuPy installation fails on CUDA 13.0**
140175

141-
- GPU compute libraries not installed
142-
- Run `setup.ps1` and install CuPy or PyTorch when prompted
176+
- Use: `pip install "cupy-cuda12x>=13.0.0"`
177+
- CuPy 13.x supports CUDA 12.x and 13.0
143178

144179
**Port already in use**
145180

health_monitor.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,69 @@ def term(ctx):
343343
"""Launch the interactive terminal dashboard."""
344344
_run_app(ctx.obj['config_path'], port=None, nodes=None, once=False, cli_mode=True)
345345

346+
@cli.command()
347+
def refresh():
348+
"""Refresh feature detection cache (run after installing GPU libraries)."""
349+
from monitor.utils import detect_features
350+
import os
351+
from pathlib import Path
352+
353+
cache_file = Path('.features_cache')
354+
if cache_file.exists():
355+
os.remove(cache_file)
356+
console.print("[yellow]Removed old cache[/yellow]")
357+
358+
# Run diagnostics first
359+
console.print("\n[cyan]Running diagnostics...[/cyan]")
360+
361+
# Test CuPy
362+
try:
363+
import cupy as cp
364+
cp.cuda.Device(0).compute_capability
365+
console.print(" CuPy: [green]OK[/green]")
366+
except ImportError:
367+
console.print(" CuPy: [yellow]Not installed[/yellow]")
368+
except Exception as e:
369+
console.print(f" CuPy: [red]Error - {str(e)}[/red]")
370+
371+
# Test PyTorch
372+
try:
373+
import torch
374+
if torch.cuda.is_available():
375+
console.print(f" PyTorch: [green]OK (CUDA {torch.version.cuda})[/green]")
376+
else:
377+
console.print(f" PyTorch: [red]Installed but CUDA not available[/red]")
378+
console.print(f" [dim]PyTorch version: {torch.__version__}[/dim]")
379+
except ImportError:
380+
console.print(" PyTorch: [yellow]Not installed[/yellow]")
381+
except Exception as e:
382+
console.print(f" PyTorch: [red]Error - {str(e)}[/red]")
383+
384+
console.print("\n[cyan]Detecting features...[/cyan]")
385+
features = detect_features(force=True)
386+
387+
console.print("\n[green]Feature Detection Results:[/green]")
388+
console.print(f" NVIDIA GPU: {'[green]Available[/green]' if features.get('nvidia_smi') else '[red]Not found[/red]'}")
389+
console.print(f" CuPy: {'[green]Available[/green]' if features.get('cupy') else '[yellow]Not installed[/yellow]'}")
390+
console.print(f" PyTorch: {'[green]Available[/green]' if features.get('torch') else '[yellow]Not installed[/yellow]'}")
391+
console.print(f" GPU Benchmark: {'[green]Enabled[/green]' if features.get('gpu_benchmark') else '[red]Disabled[/red]'}")
392+
393+
if not features.get('gpu_benchmark'):
394+
console.print("\n[yellow]GPU Benchmark is DISABLED because:[/yellow]")
395+
if not features.get('cupy') and not features.get('torch'):
396+
console.print(" [red]Neither CuPy nor PyTorch with CUDA is available[/red]")
397+
console.print("\n[cyan]To fix:[/cyan]")
398+
console.print(" 1. Install a GPU library:")
399+
console.print(" pip install \"cupy-cuda12x>=13.0.0\"")
400+
console.print(" OR")
401+
console.print(" pip install torch --index-url https://download.pytorch.org/whl/cu121")
402+
console.print(" 2. Run 'python health_monitor.py refresh' again")
403+
else:
404+
console.print("\n[green]All GPU features enabled![/green]")
405+
406+
console.print("\n[cyan]Cache updated successfully![/cyan]\n")
407+
408+
346409

347410
if __name__ == '__main__':
348411
cli.add_command(benchmark_cli)

monitor/api/static/benchmark.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,21 @@ function selectMode(mode) {
3030
document.getElementById('custom-controls').style.display = mode === 'custom' ? 'block' : 'none';
3131

3232
// Disable Start Simulation button for stress-test and custom modes
33+
// (or if GPU features not available - checked by loadFeatures)
3334
const simBtn = document.getElementById('start-sim-btn');
3435
if (simBtn) {
3536
if (mode === 'stress-test' || mode === 'custom') {
3637
simBtn.disabled = true;
3738
simBtn.style.opacity = '0.5';
3839
simBtn.style.cursor = 'not-allowed';
3940
} else {
40-
simBtn.disabled = false;
41-
simBtn.style.opacity = '1';
42-
simBtn.style.cursor = 'pointer';
41+
// Only enable if not already disabled by loadFeatures
42+
// Check if it's disabled due to missing GPU libraries
43+
if (simBtn.title !== 'Install CuPy or PyTorch for simulation') {
44+
simBtn.disabled = false;
45+
simBtn.style.opacity = '1';
46+
simBtn.style.cursor = 'pointer';
47+
}
4348
}
4449
}
4550

@@ -182,7 +187,7 @@ async function pollBenchmarkStatus() {
182187

183188
function displayBenchmarkResults(results) {
184189
const resultsDiv = document.getElementById('benchmark-results');
185-
resultsDiv.innerHTML = '<h3>📊 Benchmark Results</h3>';
190+
resultsDiv.innerHTML = '<h3>Benchmark Results</h3>';
186191

187192
// Build results HTML based on benchmark type
188193
let html = '<div class="results-grid">';

monitor/api/static/main.js

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -770,23 +770,23 @@ async function checkForUpdates() {
770770
const result = await install.json();
771771

772772
if (result.status === 'success') {
773-
btn.textContent = 'Restart App';
773+
btn.textContent = 'Restart App';
774774
btn.classList.add('success');
775775
btn.setAttribute('data-tooltip', 'Update installed - restart application');
776776
} else {
777-
btn.textContent = 'Update Failed';
777+
btn.textContent = 'Update Failed';
778778
btn.classList.add('error');
779779
btn.setAttribute('data-tooltip', result.message);
780780
btn.disabled = false;
781781
}
782782
};
783783
} else if (data.error) {
784-
btn.textContent = 'Check Failed';
784+
btn.textContent = 'Check Failed';
785785
btn.classList.add('error');
786786
btn.setAttribute('data-tooltip', data.error);
787787
btn.disabled = false;
788788
} else {
789-
btn.textContent = 'Latest Version';
789+
btn.textContent = 'Latest Version';
790790
btn.classList.add('success');
791791
btn.setAttribute('data-tooltip', `Version ${data.current}`);
792792
setTimeout(() => {
@@ -797,7 +797,7 @@ async function checkForUpdates() {
797797
}, 3000);
798798
}
799799
} catch (error) {
800-
btn.textContent = 'Network Error';
800+
btn.textContent = 'Network Error';
801801
btn.classList.add('error');
802802
btn.setAttribute('data-tooltip', 'Could not connect to update server');
803803
btn.disabled = false;
@@ -832,13 +832,14 @@ async function loadFeatures() {
832832
const response = await fetch('/api/features');
833833
const features = await response.json();
834834

835+
const benchTab = document.querySelector('[data-tab="benchmark"]');
836+
const startBtn = document.getElementById('start-bench-btn');
837+
const startSimBtn = document.getElementById('start-sim-btn');
838+
const typeButtons = document.querySelectorAll('.type-btn');
839+
const modeButtons = document.querySelectorAll('.mode-btn');
840+
835841
// Disable benchmark controls if GPU benchmark not available
836842
if (!features.gpu_benchmark) {
837-
const benchTab = document.querySelector('[data-tab="benchmark"]');
838-
const startBtn = document.getElementById('start-bench-btn');
839-
const typeButtons = document.querySelectorAll('.type-btn');
840-
const modeButtons = document.querySelectorAll('.mode-btn');
841-
842843
if (benchTab) {
843844
benchTab.classList.add('disabled');
844845
benchTab.setAttribute('data-tooltip', 'Install CuPy or PyTorch for GPU benchmarking');
@@ -852,6 +853,13 @@ async function loadFeatures() {
852853
startBtn.title = 'GPU benchmark libraries not installed';
853854
}
854855

856+
if (startSimBtn) {
857+
startSimBtn.disabled = true;
858+
startSimBtn.style.opacity = '0.5';
859+
startSimBtn.style.cursor = 'not-allowed';
860+
startSimBtn.title = 'Install CuPy or PyTorch for simulation';
861+
}
862+
855863
typeButtons.forEach(btn => {
856864
btn.disabled = true;
857865
btn.style.opacity = '0.5';
@@ -863,6 +871,39 @@ async function loadFeatures() {
863871
btn.style.opacity = '0.5';
864872
btn.style.cursor = 'not-allowed';
865873
});
874+
} else {
875+
// ENABLE controls when GPU benchmark IS available
876+
if (benchTab) {
877+
benchTab.classList.remove('disabled');
878+
benchTab.removeAttribute('data-tooltip');
879+
benchTab.style.pointerEvents = '';
880+
}
881+
882+
if (startBtn) {
883+
startBtn.disabled = false;
884+
startBtn.style.opacity = '1';
885+
startBtn.style.cursor = 'pointer';
886+
startBtn.title = 'Start GPU benchmark';
887+
}
888+
889+
if (startSimBtn) {
890+
startSimBtn.disabled = false;
891+
startSimBtn.style.opacity = '1';
892+
startSimBtn.style.cursor = 'pointer';
893+
startSimBtn.title = 'Start particle simulation with visualization';
894+
}
895+
896+
typeButtons.forEach(btn => {
897+
btn.disabled = false;
898+
btn.style.opacity = '1';
899+
btn.style.cursor = 'pointer';
900+
});
901+
902+
modeButtons.forEach(btn => {
903+
btn.disabled = false;
904+
btn.style.opacity = '1';
905+
btn.style.cursor = 'pointer';
906+
});
866907
}
867908
} catch (error) {
868909
console.error('Error loading features:', error);

monitor/api/templates/simulation.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,20 @@ <h1>🎱 3D Ball Physics Simulation</h1>
255255
<div id="controls">
256256
<!-- Baseline Information -->
257257
<div class="control-group" id="sim-baseline-info" style="display: none;">
258-
<h3>📊 Baseline (Simulation Mode)</h3>
258+
<h3>Baseline (Simulation Mode)</h3>
259259
<div id="sim-baseline-details" style="font-size: 0.9em; line-height: 1.6;">
260260
<!-- Baseline content loaded via JavaScript -->
261261
</div>
262262
</div>
263263

264264
<div class="control-group">
265-
<h3>Simulation Control</h3>
265+
<h3>Simulation Control</h3>
266266
<button id="startBtn" class="button">Start Simulation</button>
267267
<button id="stopBtn" class="button stop" style="display: none;">Stop Simulation</button>
268268
</div>
269269

270270
<div class="control-group">
271-
<h3>🎮 Physics Parameters</h3>
271+
<h3>Physics Parameters</h3>
272272

273273
<div class="slider-control">
274274
<label>Gravity: <span class="slider-value" id="gravityValue">500</span></label>

requirements.txt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
1-
# Core dependencies
2-
fastapi>=0.104.0
3-
uvicorn[standard]>=0.24.0
4-
websockets>=12.0
5-
psutil>=5.9.0
6-
pyyaml>=6.0
1+
# MINIMAL CORE - CLI only (no web UI)
72
click>=8.1.0
83
rich>=13.0.0
9-
numpy>=1.24.0
4+
psutil>=5.9.0
5+
pyyaml>=6.0
106
requests>=2.31.0
11-
pygame>=2.5.0
127

13-
# GPU libraries (optional - choose one based on CUDA version)
8+
# WEB UI (optional - for web dashboard)
9+
# Uncomment these lines to enable web interface:
10+
# fastapi>=0.104.0
11+
# uvicorn[standard]>=0.24.0
12+
# websockets>=12.0
13+
14+
# VISUALIZATION (optional - for particle simulation)
15+
# Uncomment these lines to enable visualization:
16+
# pygame>=2.5.0
17+
# numpy>=1.24.0
18+
19+
# GPU ACCELERATION (optional - for benchmarking)
20+
# Choose one based on your CUDA version:
21+
#
1422
# CuPy for CUDA 12.x (recommended):
15-
# pip install cupy-cuda12x>=12.0.0
23+
# pip install cupy-cuda12x>=13.0.0
1624
#
1725
# PyTorch with CUDA 12.1:
1826
# pip install torch --index-url https://download.pytorch.org/whl/cu121
1927

28+

0 commit comments

Comments
 (0)