44 < meta charset ="UTF-8 ">
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
66 < title > GPU Hot - Interactive Demo</ title >
7-
8- <!-- Google Analytics -->
9- < script async src ="https://www.googletagmanager.com/gtag/js?id=G-RPQC788155 "> </ script >
10- < script >
11- window . dataLayer = window . dataLayer || [ ] ;
12- function gtag ( ) { dataLayer . push ( arguments ) ; }
13- gtag ( 'js' , new Date ( ) ) ;
14- gtag ( 'config' , 'G-RPQC788155' ) ;
15- </ script >
16-
7+
178 <!-- External Libraries -->
189 < script src ="https://cdn.jsdelivr.net/npm/chart.js "> </ script >
1910 < link href ="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap " rel ="stylesheet ">
20-
11+
2112 <!-- Embed the exact CSS from the real application via CDN -->
2213 < link rel ="stylesheet " href ="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/css/styles.css ">
23-
14+
2415 < style >
2516 /* Demo-specific notice banner */
2617 .demo-notice {
@@ -104,32 +95,32 @@ <h1>🔥 GPU Hot</h1>
10495 < script src ="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/charts.js "> </ script >
10596 < script src ="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/gpu-cards.js "> </ script >
10697 < script src ="https://cdn.jsdelivr.net/gh/psalias2006/gpu-hot@main/static/js/ui.js "> </ script >
107-
98+
10899 <!-- Demo Data Generator (replaces socket-handlers.js) -->
109100 < script >
110101 // ============================================================================
111102 // DEMO DATA GENERATOR - Simulates realistic GPU data
112103 // ============================================================================
113-
104+
114105 const GPU_NAMES = [
115106 'NVIDIA GeForce RTX 4060 Ti' ,
116107 'NVIDIA GeForce RTX 4080' ,
117108 ] ;
118-
109+
119110 const PROCESS_NAMES = [
120111 'python3' ,
121112 'pytorch_train.py' ,
122113 'tensorflow' ,
123114 'chrome' ,
124115 'code' ,
125116 ] ;
126-
117+
127118 class DemoDataGenerator {
128119 constructor ( numGPUs = 1 ) {
129120 this . numGPUs = numGPUs ;
130121 this . gpuStates = [ ] ;
131122 this . time = 0 ;
132-
123+
133124 // Initialize GPU states - realistic idle behavior
134125 for ( let i = 0 ; i < numGPUs ; i ++ ) {
135126 this . gpuStates . push ( {
@@ -142,63 +133,63 @@ <h1>🔥 GPU Hot</h1>
142133 } ) ;
143134 }
144135 }
145-
136+
146137 generateGPUData ( ) {
147138 this . time += 1 ;
148139 const gpus = { } ;
149-
140+
150141 for ( let i = 0 ; i < this . numGPUs ; i ++ ) {
151142 const state = this . gpuStates [ i ] ;
152-
143+
153144 // Simulate realistic idle with occasional small spikes
154145 const noise = ( ) => ( Math . random ( ) - 0.5 ) * 3 ;
155146 const wave = Math . sin ( this . time * 0.03 + i ) * 8 ;
156-
147+
157148 const utilization = Math . max ( 0 , Math . min ( 100 , state . baseUtil + wave + noise ( ) ) ) ;
158149 const temperature = Math . max ( 25 , Math . min ( 85 , 31 + utilization * 0.2 + noise ( ) * 0.3 ) ) ;
159-
150+
160151 // Power scales with utilization
161152 const idlePower = 11.5 ;
162- const powerDraw = utilization > 3 ?
153+ const powerDraw = utilization > 3 ?
163154 Math . max ( idlePower , Math . min ( 165 , idlePower + ( utilization / 100 ) * 150 + wave + noise ( ) * 2 ) ) :
164155 idlePower ;
165-
156+
166157 const memoryUsed = Math . max ( 512 , Math . min ( state . memTotal , state . baseMemUsed + wave * 20 + noise ( ) * 50 ) ) ;
167-
158+
168159 // Clock speeds - idle clocks when idle
169160 const idleGraphicsClock = 210 ;
170161 const maxGraphicsClock = 2610 ;
171162 const idleMemoryClock = 405 ;
172163 const maxMemoryClock = 10501 ;
173-
164+
174165 const clockGraphics = utilization > 3 ?
175166 Math . round ( idleGraphicsClock + ( utilization / 100 ) * ( maxGraphicsClock - idleGraphicsClock ) ) :
176167 idleGraphicsClock ;
177-
168+
178169 const clockMemory = utilization > 3 ?
179170 Math . round ( idleMemoryClock + ( utilization / 100 ) * ( maxMemoryClock - idleMemoryClock ) ) :
180171 idleMemoryClock ;
181-
172+
182173 const clockSm = Math . round ( clockGraphics * 1.0 ) ;
183174 const clockSmMax = 3105 ;
184175 const clockVideo = Math . round ( clockGraphics * 0.95 ) ;
185-
176+
186177 // PCIe link adjusts with utilization
187178 const pcieGen = utilization > 10 ? 4 : utilization > 5 ? 2 : 1 ;
188179 const pcieWidth = utilization > 10 ? 16 : 8 ;
189-
180+
190181 // Energy accumulation (Wh)
191182 if ( ! state . totalEnergy ) state . totalEnergy = 0 ;
192183 state . totalEnergy += ( powerDraw * ( 0.5 / 3600 ) ) ; // 500ms interval, in Wh
193-
184+
194185 // BAR1 memory (small portion of total)
195186 const bar1Used = Math . round ( memoryUsed * 0.0004 ) ;
196187 const bar1Total = Math . round ( state . memTotal * 0.016 ) ;
197-
188+
198189 // Process counts
199190 const computeProcesses = utilization > 20 ? Math . floor ( utilization / 30 ) : 0 ;
200191 const graphicsProcesses = utilization > 10 ? Math . floor ( Math . random ( ) * 2 ) : utilization > 5 ? 2 : 0 ;
201-
192+
202193 gpus [ i ] = {
203194 name : GPU_NAMES [ i % GPU_NAMES . length ] ,
204195 utilization : Math . round ( utilization ) ,
@@ -236,36 +227,36 @@ <h1>🔥 GPU Hot</h1>
236227 _fallback_mode : false
237228 } ;
238229 }
239-
230+
240231 return gpus ;
241232 }
242-
233+
243234 generateProcesses ( ) {
244235 const numProcesses = Math . floor ( Math . random ( ) * 3 ) ;
245236 const processes = [ ] ;
246-
237+
247238 for ( let i = 0 ; i < numProcesses ; i ++ ) {
248239 processes . push ( {
249240 pid : 1000 + Math . floor ( Math . random ( ) * 30000 ) ,
250241 name : PROCESS_NAMES [ Math . floor ( Math . random ( ) * PROCESS_NAMES . length ) ] ,
251242 memory : Math . round ( 500 + Math . random ( ) * 3000 )
252243 } ) ;
253244 }
254-
245+
255246 return processes ;
256247 }
257-
248+
258249 generateSystemInfo ( ) {
259250 const cpuBase = 10 + Math . random ( ) * 20 ;
260251 const cpuNoise = ( Math . random ( ) - 0.5 ) * 10 ;
261252 const memBase = 30 + Math . random ( ) * 20 ;
262-
253+
263254 return {
264255 cpu_percent : Math . max ( 5 , Math . min ( 95 , cpuBase + cpuNoise ) ) ,
265256 memory_percent : Math . max ( 20 , Math . min ( 85 , memBase + ( Math . random ( ) - 0.5 ) * 5 ) )
266257 } ;
267258 }
268-
259+
269260 generateFullData ( ) {
270261 return {
271262 gpus : this . generateGPUData ( ) ,
@@ -274,38 +265,38 @@ <h1>🔥 GPU Hot</h1>
274265 } ;
275266 }
276267 }
277-
268+
278269 // ============================================================================
279270 // DEMO APPLICATION - Uses the same update functions as the real app
280271 // ============================================================================
281-
272+
282273 const dataGenerator = new DemoDataGenerator ( 1 ) ; // 1 GPU for demo
283-
274+
284275 function updateDemo ( ) {
285276 const data = dataGenerator . generateFullData ( ) ;
286-
277+
287278 // Use the EXACT same update functions from the real application
288279 handleGPUDataUpdate ( data ) ;
289280 }
290-
281+
291282 // This function mimics what socket-handlers.js does
292283 function handleGPUDataUpdate ( data ) {
293284 const overviewContainer = document . getElementById ( 'overview-container' ) ;
294-
285+
295286 if ( ! data . gpus || Object . keys ( data . gpus ) . length === 0 ) {
296287 overviewContainer . innerHTML = '<div class="loading">No GPU data available</div>' ;
297288 return ;
298289 }
299-
290+
300291 // Update each GPU
301292 Object . keys ( data . gpus ) . forEach ( gpuId => {
302293 const gpuInfo = data . gpus [ gpuId ] ;
303-
294+
304295 // Initialize chart data if needed
305296 if ( ! chartData [ gpuId ] ) {
306297 initGPUData ( gpuId ) ;
307298 }
308-
299+
309300 // Create or update overview card
310301 const existingOverview = overviewContainer . querySelector ( `[data-gpu-id="${ gpuId } "]` ) ;
311302 if ( ! existingOverview ) {
@@ -314,37 +305,37 @@ <h1>🔥 GPU Hot</h1>
314305 } else {
315306 updateOverviewCard ( gpuId , gpuInfo , true ) ;
316307 }
317-
308+
318309 // Create or update detailed GPU tab
319310 ensureGPUTab ( gpuId , gpuInfo , true ) ;
320311 } ) ;
321-
312+
322313 // Update processes
323314 if ( data . processes ) {
324315 updateProcesses ( data . processes ) ;
325316 }
326-
317+
327318 // Update system info
328319 if ( data . system ) {
329320 updateSystemInfo ( data . system ) ;
330321 }
331-
322+
332323 // Auto-switch to single GPU view on first load
333324 const gpuCount = Object . keys ( data . gpus ) . length ;
334325 const gpuIds = Object . keys ( data . gpus ) ;
335326 autoSwitchSingleGPU ( gpuCount , gpuIds ) ;
336327 }
337-
328+
338329 // Initialize and start demo
339330 document . addEventListener ( 'DOMContentLoaded' , function ( ) {
340331 console . log ( 'GPU Hot Demo initialized' ) ;
341-
332+
342333 // Initial update
343334 updateDemo ( ) ;
344-
335+
345336 // Update every 500ms (same as real app)
346337 setInterval ( updateDemo , 500 ) ;
347-
338+
348339 // Initialize system charts
349340 initSystemCharts ( ) ;
350341 } ) ;
0 commit comments