Spaces:
Running
Running
| /* βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| Mock SSE Service β Replay engine for demo mode | |
| Replays mock_analysis.json events with realistic timing | |
| βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| const SPEED_MULTIPLIER = 1; // Set < 1 to speed up, > 1 to slow down | |
| export class MockSSEService { | |
| constructor() { | |
| this.timeouts = []; | |
| this.isRunning = false; | |
| this.eventHandlers = {}; | |
| } | |
| on(eventType, handler) { | |
| if (!this.eventHandlers[eventType]) { | |
| this.eventHandlers[eventType] = []; | |
| } | |
| this.eventHandlers[eventType].push(handler); | |
| return this; | |
| } | |
| emit(eventType, data) { | |
| const handlers = this.eventHandlers[eventType] || []; | |
| handlers.forEach(handler => handler(data)); | |
| } | |
| async startScan(payload) { | |
| this.isRunning = true; | |
| this.timeouts = []; | |
| try { | |
| const response = await fetch('/mock_analysis.json'); | |
| const mockData = await response.json(); | |
| // Emit scan started | |
| this.emit('scan_started', { | |
| scanId: mockData.meta.scanId, | |
| filesAnalyzed: mockData.meta.filesAnalyzed, | |
| linesScanned: mockData.meta.linesScanned, | |
| }); | |
| // ββ Simulated AMD metrics (every 2 seconds) ββ | |
| const metricsInterval = setInterval(() => { | |
| if (!this.isRunning) { clearInterval(metricsInterval); return; } | |
| this.emit('amd_metrics', { | |
| gpu_utilization_percent: Math.floor(78 + Math.random() * 16), | |
| vram_used_gb: +(44 + Math.random() * 8).toFixed(1), | |
| vram_total_gb: 192.0, | |
| temperature_c: Math.floor(58 + Math.random() * 9), | |
| power_draw_w: Math.floor(580 + Math.random() * 70), | |
| memory_bandwidth_tbs: +(4.2 + Math.random() * 0.9).toFixed(1), | |
| tokens_per_sec: Math.floor(1100 + Math.random() * 300), | |
| timestamp: new Date().toISOString(), | |
| }); | |
| }, 2000); | |
| this.timeouts.push(metricsInterval); | |
| // Schedule each event with its delay | |
| mockData.events.forEach((event) => { | |
| const delay = event.delay * SPEED_MULTIPLIER; | |
| const timeout = setTimeout(() => { | |
| if (!this.isRunning) return; | |
| this.emit(event.type, { | |
| agent: event.agent, | |
| ...event.data, | |
| }); | |
| // Also emit a generic 'event' for logging | |
| this.emit('event', { | |
| type: event.type, | |
| agent: event.agent, | |
| ...event.data, | |
| }); | |
| }, delay); | |
| this.timeouts.push(timeout); | |
| }); | |
| // ββ Simulated AMD migration findings (after perf agent) ββ | |
| const migrationDelay = (mockData.events.length > 0 | |
| ? Math.max(...mockData.events.map(e => e.delay)) - 3000 | |
| : 8000) * SPEED_MULTIPLIER; | |
| const migTimeout = setTimeout(() => { | |
| if (!this.isRunning) return; | |
| const mockMigrationFindings = [ | |
| { id: 'AMD_M02', title: 'NVIDIA-Specific CLI Tool', description: 'nvidia-smi is NVIDIA-only and will fail on AMD hardware.', rocm_fix: "Replace nvidia-smi with rocm-smi. Example: subprocess.run(['rocm-smi', '--showmeminfo', 'vram'])", severity: 'critical', file: 'monitor.py', line: 42, code_snippet: '>>> 42 | subprocess.run(["nvidia-smi"])' }, | |
| { id: 'AMD_M03', title: 'CUDA Device Selection Environment Variable', description: 'CUDA_VISIBLE_DEVICES is ignored on AMD/ROCm hardware.', rocm_fix: 'Replace with HIP_VISIBLE_DEVICES=0 for AMD GPU selection.', severity: 'high', file: 'config.py', line: 15, code_snippet: '>>> 15 | os.environ["CUDA_VISIBLE_DEVICES"] = "0"' }, | |
| { id: 'AMD_M05', title: 'FP16 Precision (Suboptimal on MI300X)', description: 'FP16 works on AMD but bfloat16 is natively supported on MI300X.', rocm_fix: 'Replace .half() with .bfloat16() and torch.float16 with torch.bfloat16.', severity: 'medium', file: 'model.py', line: 28, code_snippet: '>>> 28 | model = model.half()' }, | |
| ]; | |
| mockMigrationFindings.forEach((f, i) => { | |
| setTimeout(() => { | |
| if (!this.isRunning) return; | |
| this.emit('amd_migration_finding', f); | |
| }, i * 300); | |
| }); | |
| setTimeout(() => { | |
| if (!this.isRunning) return; | |
| this.emit('amd_migration_summary', { | |
| compatibility_score: 57, | |
| compatibility_label: 'Needs Migration Work', | |
| total_cuda_patterns_found: 3, | |
| summary: 'Found 3 CUDA-specific patterns. After applying fixes, this codebase will be fully optimized for AMD MI300X.', | |
| }); | |
| }, mockMigrationFindings.length * 300 + 200); | |
| }, Math.max(migrationDelay, 5000)); | |
| this.timeouts.push(migTimeout); | |
| } catch (error) { | |
| console.error('Mock SSE: Failed to load mock data', error); | |
| this.emit('error', { message: 'Failed to load mock analysis data' }); | |
| } | |
| } | |
| stop() { | |
| this.isRunning = false; | |
| this.timeouts.forEach(t => clearTimeout(t)); | |
| this.timeouts = []; | |
| } | |
| destroy() { | |
| this.stop(); | |
| this.eventHandlers = {}; | |
| } | |
| } | |
| export function createMockService() { | |
| return new MockSSEService(); | |
| } | |