tazwarrrr commited on
Commit
1985a9f
·
verified ·
1 Parent(s): 98360c5

initial update

Browse files
Files changed (1) hide show
  1. index.html +1724 -19
index.html CHANGED
@@ -1,19 +1,1724 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>ROCmPort AI</title>
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link
10
+ href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@500;600;700&display=swap"
11
+ rel="stylesheet">
12
+ <style>
13
+ :root {
14
+ --bg: #030303;
15
+ --s1: #0a0a0b;
16
+ --s2: #121214;
17
+ --s3: #1a1a1e;
18
+ --b1: rgba(255, 255, 255, 0.08);
19
+ --b2: rgba(255, 255, 255, 0.15);
20
+ --red: #ff3344;
21
+ --red-glow: rgba(255, 51, 68, 0.4);
22
+ --green: #00ff88;
23
+ --green-glow: rgba(0, 255, 136, 0.4);
24
+ --yellow: #ffcc00;
25
+ --cyan: #00d9ff;
26
+ --muted: #88888e;
27
+ --t1: #a1a1aa;
28
+ --t2: #d4d4d8;
29
+ --t3: #ffffff;
30
+ --mono: 'JetBrains Mono', monospace;
31
+ --sans: 'Space Grotesk', sans-serif;
32
+ --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
33
+ }
34
+
35
+ * {
36
+ margin: 0;
37
+ padding: 0;
38
+ box-sizing: border-box;
39
+ cursor: none !important;
40
+ }
41
+
42
+ .hide {
43
+ display: none !important;
44
+ }
45
+
46
+ body {
47
+ background: var(--bg);
48
+ color: var(--t1);
49
+ font-family: var(--sans);
50
+ font-size: 14px;
51
+ line-height: 1.6;
52
+ overflow-x: hidden;
53
+ min-height: 100vh;
54
+ }
55
+
56
+ /* Animated Gradient Background */
57
+ body::before {
58
+ content: '';
59
+ position: fixed;
60
+ inset: 0;
61
+ background:
62
+ radial-gradient(circle at 20% 30%, rgba(0, 217, 255, 0.05), transparent 40%),
63
+ radial-gradient(circle at 80% 70%, rgba(255, 51, 68, 0.05), transparent 40%),
64
+ radial-gradient(circle at 50% 50%, rgba(0, 255, 136, 0.03), transparent 60%);
65
+ z-index: -1;
66
+ animation: bgMove 20s ease-in-out infinite alternate;
67
+ }
68
+
69
+ @keyframes bgMove {
70
+ 0% {
71
+ transform: scale(1) translate(0, 0);
72
+ }
73
+
74
+ 50% {
75
+ transform: scale(1.1) translate(20px, -20px);
76
+ }
77
+
78
+ 100% {
79
+ transform: scale(1) translate(-20px, 20px);
80
+ }
81
+ }
82
+
83
+ .w {
84
+ max-width: 1200px;
85
+ margin: 0 auto;
86
+ padding: 32px 24px;
87
+ position: relative;
88
+ }
89
+
90
+ /* Container Glow */
91
+ .w::after {
92
+ content: '';
93
+ position: absolute;
94
+ inset: 0;
95
+ background: radial-gradient(circle at 50% 0%, rgba(255, 51, 68, 0.08), transparent 70%);
96
+ pointer-events: none;
97
+ z-index: -1;
98
+ }
99
+
100
+ header {
101
+ padding-bottom: 24px;
102
+ border-bottom: 1px solid var(--b1);
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: space-between;
106
+ margin-bottom: 24px;
107
+ }
108
+
109
+ .logo {
110
+ font-weight: 700;
111
+ font-size: 18px;
112
+ color: var(--t3);
113
+ letter-spacing: -0.02em;
114
+ }
115
+
116
+ .logo em {
117
+ font-style: normal;
118
+ color: var(--red);
119
+ text-shadow: 0 0 15px var(--red-glow);
120
+ }
121
+
122
+ .hr {
123
+ font-size: 12px;
124
+ color: var(--muted);
125
+ display: flex;
126
+ align-items: center;
127
+ gap: 10px;
128
+ background: var(--s1);
129
+ padding: 6px 12px;
130
+ border-radius: 20px;
131
+ border: 1px solid var(--b1);
132
+ }
133
+
134
+ .hd {
135
+ width: 6px;
136
+ height: 6px;
137
+ border-radius: 50%;
138
+ background: var(--green);
139
+ box-shadow: 0 0 10px var(--green-glow);
140
+ }
141
+
142
+ .hd.on {
143
+ animation: pulse 2s ease-in-out infinite;
144
+ }
145
+
146
+ @keyframes pulse {
147
+
148
+ 0%,
149
+ 100% {
150
+ opacity: 1;
151
+ transform: scale(1);
152
+ }
153
+
154
+ 50% {
155
+ opacity: 0.4;
156
+ transform: scale(0.8);
157
+ }
158
+ }
159
+
160
+ .g {
161
+ display: grid;
162
+ grid-template-columns: 1.2fr 0.8fr;
163
+ gap: 24px;
164
+ padding: 0;
165
+ }
166
+
167
+ .fs {
168
+ grid-column: 1 / -1;
169
+ }
170
+
171
+ @media (max-width: 900px) {
172
+ .g {
173
+ grid-template-columns: 1fr;
174
+ }
175
+ }
176
+
177
+ /* Card Styling */
178
+ .p {
179
+ background: var(--s1);
180
+ border: 1px solid var(--b1);
181
+ border-radius: 12px;
182
+ overflow: hidden;
183
+ display: flex;
184
+ flex-direction: column;
185
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
186
+ backdrop-filter: blur(10px);
187
+ transition: transform 0.3s var(--spring), border-color 0.3s ease;
188
+ }
189
+
190
+ .p:hover {
191
+ border-color: var(--b2);
192
+ }
193
+
194
+ .ph {
195
+ padding: 12px 16px;
196
+ border-bottom: 1px solid var(--b1);
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: space-between;
200
+ font-size: 12px;
201
+ color: var(--muted);
202
+ background: rgba(255, 255, 255, 0.02);
203
+ }
204
+
205
+ .ph b {
206
+ color: var(--red);
207
+ font-weight: 600;
208
+ text-transform: uppercase;
209
+ letter-spacing: 0.05em;
210
+ }
211
+
212
+ textarea.code {
213
+ width: 100%;
214
+ flex: 1;
215
+ min-height: 300px;
216
+ background: var(--bg);
217
+ border: none;
218
+ color: var(--t2);
219
+ font-family: var(--mono);
220
+ font-size: 13px;
221
+ line-height: 1.7;
222
+ padding: 20px;
223
+ resize: vertical;
224
+ outline: none;
225
+ caret-color: var(--red);
226
+ will-change: transform;
227
+ }
228
+
229
+ .db {
230
+ padding: 12px 16px;
231
+ border-top: 1px solid var(--b1);
232
+ display: flex;
233
+ align-items: center;
234
+ gap: 8px;
235
+ background: var(--s1);
236
+ }
237
+
238
+ .db .l {
239
+ font-size: 11px;
240
+ color: var(--muted);
241
+ font-weight: 500;
242
+ }
243
+
244
+ .ch {
245
+ font-family: var(--sans);
246
+ font-size: 11px;
247
+ padding: 4px 12px;
248
+ background: var(--s2);
249
+ border: 1px solid var(--b1);
250
+ border-radius: 6px;
251
+ color: var(--t1);
252
+ cursor: pointer;
253
+ transition: all 0.2s var(--spring);
254
+ }
255
+
256
+ .ch:hover {
257
+ background: var(--s3);
258
+ color: var(--t3);
259
+ transform: translateY(-1px);
260
+ border-color: var(--b2);
261
+ }
262
+
263
+ .ch.on {
264
+ background: var(--red);
265
+ border-color: var(--red);
266
+ color: #fff;
267
+ box-shadow: 0 0 15px var(--red-glow);
268
+ }
269
+
270
+ .bg {
271
+ margin: 16px;
272
+ padding: 14px;
273
+ background: var(--red);
274
+ border: none;
275
+ border-radius: 8px;
276
+ color: #fff;
277
+ font-family: var(--sans);
278
+ font-size: 14px;
279
+ font-weight: 700;
280
+ cursor: pointer;
281
+ transition: all 0.3s var(--spring);
282
+ text-transform: uppercase;
283
+ letter-spacing: 0.05em;
284
+ box-shadow: 0 4px 15px var(--red-glow);
285
+ }
286
+
287
+ .bg:hover {
288
+ background: #ff4d5a;
289
+ transform: translateY(-2px);
290
+ box-shadow: 0 6px 20px var(--red-glow);
291
+ }
292
+
293
+ .bg:active {
294
+ transform: translateY(0);
295
+ }
296
+
297
+ .bg:disabled {
298
+ opacity: 0.4;
299
+ cursor: not-allowed;
300
+ transform: none;
301
+ box-shadow: none;
302
+ }
303
+
304
+ /* Agent log */
305
+ .al {
306
+ padding: 12px;
307
+ display: flex;
308
+ flex-direction: column;
309
+ gap: 8px;
310
+ }
311
+
312
+ .ar {
313
+ padding: 12px 16px;
314
+ border-radius: 8px;
315
+ background: rgba(255, 255, 255, 0.03);
316
+ border: 1px solid transparent;
317
+ transition: all 0.4s var(--spring);
318
+ animation: slideIn 0.5s var(--spring) forwards;
319
+ opacity: 0;
320
+ transform: translateX(20px);
321
+ }
322
+
323
+ @keyframes slideIn {
324
+ to {
325
+ opacity: 1;
326
+ transform: translateX(0);
327
+ }
328
+ }
329
+
330
+ .ar.run {
331
+ border-color: var(--cyan);
332
+ background: rgba(0, 217, 255, 0.05);
333
+ }
334
+
335
+ .ar.done {
336
+ border-color: var(--green);
337
+ background: rgba(0, 255, 136, 0.05);
338
+ }
339
+
340
+ .ar.fail {
341
+ border-color: var(--red);
342
+ background: rgba(255, 51, 68, 0.05);
343
+ }
344
+
345
+ .ar.retry {
346
+ border-color: var(--yellow);
347
+ background: rgba(255, 204, 0, 0.05);
348
+ animation: pulse-border 1.5s ease-in-out infinite;
349
+ }
350
+
351
+ @keyframes pulse-border {
352
+ 50% {
353
+ border-color: rgba(255, 204, 0, 0.2);
354
+ }
355
+ }
356
+
357
+ .at {
358
+ display: flex;
359
+ align-items: center;
360
+ gap: 12px;
361
+ }
362
+
363
+ .an {
364
+ font-size: 10px;
365
+ font-weight: 700;
366
+ color: var(--muted);
367
+ min-width: 90px;
368
+ text-transform: uppercase;
369
+ letter-spacing: 0.1em;
370
+ }
371
+
372
+ .am {
373
+ font-size: 13px;
374
+ color: var(--t2);
375
+ font-weight: 500;
376
+ }
377
+
378
+ .ad {
379
+ font-size: 11px;
380
+ color: var(--muted);
381
+ margin-top: 4px;
382
+ padding-left: 102px;
383
+ white-space: pre-wrap;
384
+ line-height: 1.6;
385
+ max-height: 100px;
386
+ overflow-y: auto;
387
+ }
388
+
389
+ .ad .w {
390
+ color: var(--yellow);
391
+ font-weight: 600;
392
+ }
393
+
394
+ .ad .g {
395
+ color: var(--green);
396
+ font-weight: 600;
397
+ }
398
+
399
+ /* Horizontal Timeline */
400
+ .timeline {
401
+ display: flex;
402
+ justify-content: space-between;
403
+ padding: 16px 20px;
404
+ background: rgba(255, 255, 255, 0.02);
405
+ border-bottom: 1px solid var(--b1);
406
+ margin-bottom: 8px;
407
+ }
408
+
409
+ .node {
410
+ display: flex;
411
+ flex-direction: column;
412
+ align-items: center;
413
+ gap: 6px;
414
+ position: relative;
415
+ flex: 1;
416
+ }
417
+
418
+ .node::after {
419
+ content: '';
420
+ position: absolute;
421
+ top: 12px;
422
+ left: 50%;
423
+ width: 100%;
424
+ height: 2px;
425
+ background: var(--b1);
426
+ z-index: 0;
427
+ }
428
+
429
+ .node:last-child::after {
430
+ display: none;
431
+ }
432
+
433
+ .ni {
434
+ width: 24px;
435
+ height: 24px;
436
+ border-radius: 50%;
437
+ background: var(--s3);
438
+ border: 2px solid var(--b1);
439
+ display: flex;
440
+ align-items: center;
441
+ justify-content: center;
442
+ font-size: 12px;
443
+ z-index: 1;
444
+ transition: all 0.4s var(--spring);
445
+ }
446
+
447
+ .node.on .ni {
448
+ background: var(--cyan);
449
+ border-color: var(--cyan);
450
+ color: #000;
451
+ box-shadow: 0 0 15px var(--cyan);
452
+ }
453
+
454
+ .node.done .ni {
455
+ background: var(--green);
456
+ border-color: var(--green);
457
+ color: #000;
458
+ box-shadow: 0 0 15px var(--green);
459
+ }
460
+
461
+ .node.fail .ni {
462
+ background: var(--red);
463
+ border-color: var(--red);
464
+ color: #fff;
465
+ }
466
+
467
+ .node.retry .ni {
468
+ animation: pulse-node 1s var(--spring) infinite;
469
+ background: var(--yellow);
470
+ border-color: var(--yellow);
471
+ }
472
+
473
+ @keyframes pulse-node {
474
+
475
+ 0%,
476
+ 100% {
477
+ transform: scale(1);
478
+ }
479
+
480
+ 50% {
481
+ transform: scale(1.2);
482
+ }
483
+ }
484
+
485
+ .nl {
486
+ font-size: 9px;
487
+ font-weight: 700;
488
+ color: var(--muted);
489
+ text-transform: uppercase;
490
+ letter-spacing: 0.05em;
491
+ }
492
+
493
+ .node.on .nl,
494
+ .node.done .nl {
495
+ color: var(--t3);
496
+ }
497
+
498
+ /* Tabs */
499
+ .tabs {
500
+ display: flex;
501
+ gap: 8px;
502
+ }
503
+
504
+ .tab {
505
+ background: var(--s2);
506
+ border: 1px solid var(--b1);
507
+ padding: 6px 16px;
508
+ border-radius: 8px;
509
+ font-family: var(--sans);
510
+ font-size: 12px;
511
+ font-weight: 600;
512
+ color: var(--muted);
513
+ cursor: pointer;
514
+ transition: all 0.2s var(--spring);
515
+ }
516
+
517
+ .tab:hover {
518
+ color: var(--t2);
519
+ background: var(--s3);
520
+ }
521
+
522
+ .tab.on {
523
+ color: var(--t3);
524
+ background: var(--red);
525
+ border-color: var(--red);
526
+ box-shadow: 0 0 10px var(--red-glow);
527
+ }
528
+
529
+ .tc {
530
+ display: none;
531
+ padding: 0;
532
+ animation: fadeIn 0.4s ease;
533
+ }
534
+
535
+ .tc.on {
536
+ display: block;
537
+ }
538
+
539
+ @keyframes fadeIn {
540
+ from {
541
+ opacity: 0;
542
+ transform: translateY(10px);
543
+ }
544
+
545
+ to {
546
+ opacity: 1;
547
+ transform: translateY(0);
548
+ }
549
+ }
550
+
551
+ /* Summary row */
552
+ .sum-row {
553
+ padding: 24px;
554
+ display: flex;
555
+ align-items: center;
556
+ gap: 32px;
557
+ flex-wrap: wrap;
558
+ border-bottom: 1px solid var(--b1);
559
+ background: rgba(0, 255, 136, 0.02);
560
+ }
561
+
562
+ .sum-big {
563
+ font-size: 32px;
564
+ font-weight: 800;
565
+ color: var(--green);
566
+ line-height: 1;
567
+ letter-spacing: -0.02em;
568
+ text-shadow: 0 0 20px var(--green-glow);
569
+ }
570
+
571
+ .sum-big .u {
572
+ font-size: 13px;
573
+ font-weight: 500;
574
+ color: var(--muted);
575
+ margin-left: 4px;
576
+ display: block;
577
+ margin-top: 4px;
578
+ letter-spacing: 0;
579
+ }
580
+
581
+ .sum-big .vic {
582
+ font-size: 11px;
583
+ color: var(--cyan);
584
+ font-weight: 600;
585
+ display: block;
586
+ margin-top: 8px;
587
+ text-shadow: none;
588
+ opacity: 0.8;
589
+ }
590
+
591
+ .sum-sep {
592
+ width: 1px;
593
+ height: 40px;
594
+ background: var(--b1);
595
+ }
596
+
597
+ .sum-chk {
598
+ display: flex;
599
+ align-items: center;
600
+ gap: 8px;
601
+ font-size: 12px;
602
+ color: var(--t2);
603
+ font-weight: 500;
604
+ }
605
+
606
+ .sum-dot {
607
+ width: 8px;
608
+ height: 8px;
609
+ border-radius: 50%;
610
+ flex-shrink: 0;
611
+ }
612
+
613
+ .sum-dot.ok {
614
+ background: var(--green);
615
+ box-shadow: 0 0 8px var(--green-glow);
616
+ }
617
+
618
+ .sum-dot.no {
619
+ background: var(--red);
620
+ box-shadow: 0 0 8px var(--red-glow);
621
+ }
622
+
623
+ .sum-dot.na {
624
+ background: var(--muted);
625
+ box-shadow: none;
626
+ }
627
+
628
+ .sum-type {
629
+ font-size: 11px;
630
+ color: var(--cyan);
631
+ text-transform: uppercase;
632
+ letter-spacing: 0.1em;
633
+ font-weight: 700;
634
+ padding: 4px 10px;
635
+ background: rgba(0, 217, 255, 0.1);
636
+ border-radius: 4px;
637
+ }
638
+
639
+ .sum-bar {
640
+ padding: 16px 24px;
641
+ display: flex;
642
+ align-items: center;
643
+ gap: 12px;
644
+ flex-wrap: wrap;
645
+ border-bottom: 1px solid var(--b1);
646
+ }
647
+
648
+ .bs {
649
+ font-family: var(--sans);
650
+ font-size: 11px;
651
+ font-weight: 700;
652
+ padding: 8px 16px;
653
+ border-radius: 8px;
654
+ border: 1px solid var(--b1);
655
+ background: var(--s2);
656
+ color: var(--t2);
657
+ cursor: pointer;
658
+ transition: all 0.2s var(--spring);
659
+ text-transform: uppercase;
660
+ letter-spacing: 0.05em;
661
+ }
662
+
663
+ .bs:hover {
664
+ border-color: var(--b2);
665
+ transform: translateY(-1px);
666
+ background: var(--s3);
667
+ }
668
+
669
+ .bs.r {
670
+ background: var(--bg);
671
+ border-color: var(--red);
672
+ color: var(--red);
673
+ }
674
+
675
+ .bs.r:hover {
676
+ background: var(--red);
677
+ color: #fff;
678
+ box-shadow: 0 4px 15px var(--red-glow);
679
+ }
680
+
681
+ .bs.gr {
682
+ background: var(--green);
683
+ border-color: var(--green);
684
+ color: #000;
685
+ }
686
+
687
+ .bs.gr:hover {
688
+ box-shadow: 0 4px 15px var(--green-glow);
689
+ transform: translateY(-2px);
690
+ }
691
+
692
+ .sp {
693
+ flex: 1;
694
+ }
695
+
696
+ /* Details tab */
697
+ .dm {
698
+ display: grid;
699
+ grid-template-columns: repeat(5, 1fr);
700
+ border-bottom: 1px solid var(--b1);
701
+ }
702
+
703
+ @media (max-width: 800px) {
704
+ .dm {
705
+ grid-template-columns: repeat(2, 1fr);
706
+ }
707
+ }
708
+
709
+ .di {
710
+ padding: 20px;
711
+ border-right: 1px solid var(--b1);
712
+ background: rgba(255, 255, 255, 0.01);
713
+ }
714
+
715
+ .di:last-child {
716
+ border-right: none;
717
+ }
718
+
719
+ .dl {
720
+ font-size: 10px;
721
+ color: var(--muted);
722
+ text-transform: uppercase;
723
+ letter-spacing: 0.1em;
724
+ margin-bottom: 8px;
725
+ font-weight: 700;
726
+ }
727
+
728
+ .dv {
729
+ font-size: 20px;
730
+ font-weight: 800;
731
+ line-height: 1;
732
+ margin-bottom: 4px;
733
+ color: var(--t3);
734
+ }
735
+
736
+ .dv.g {
737
+ color: var(--green);
738
+ }
739
+
740
+ .dv.c {
741
+ color: var(--cyan);
742
+ }
743
+
744
+ .dv.y {
745
+ color: var(--yellow);
746
+ }
747
+
748
+ .dv.t {
749
+ color: var(--t2);
750
+ font-size: 13px;
751
+ }
752
+
753
+ .ds {
754
+ font-size: 10px;
755
+ color: var(--muted);
756
+ line-height: 1.4;
757
+ }
758
+
759
+ /* Benchmark bars */
760
+ .bk {
761
+ padding: 24px;
762
+ border-bottom: 1px solid var(--b1);
763
+ }
764
+
765
+ .bk-t {
766
+ font-size: 11px;
767
+ color: var(--muted);
768
+ text-transform: uppercase;
769
+ letter-spacing: 0.1em;
770
+ margin-bottom: 16px;
771
+ font-weight: 700;
772
+ }
773
+
774
+ .br {
775
+ display: flex;
776
+ align-items: center;
777
+ gap: 16px;
778
+ margin-bottom: 12px;
779
+ }
780
+
781
+ .br:last-child {
782
+ margin-bottom: 0;
783
+ }
784
+
785
+ .bl {
786
+ font-size: 12px;
787
+ color: var(--t2);
788
+ width: 140px;
789
+ flex-shrink: 0;
790
+ font-weight: 500;
791
+ }
792
+
793
+ .bt {
794
+ flex: 1;
795
+ height: 8px;
796
+ background: var(--bg);
797
+ border-radius: 4px;
798
+ overflow: hidden;
799
+ border: 1px solid var(--b1);
800
+ }
801
+
802
+ .bf {
803
+ height: 100%;
804
+ border-radius: 4px;
805
+ transition: width 1s var(--spring);
806
+ width: 0;
807
+ }
808
+
809
+ .bf.bad {
810
+ background: linear-gradient(90deg, #ff334466, #ff3344);
811
+ box-shadow: 0 0 10px rgba(255, 51, 68, 0.3);
812
+ }
813
+
814
+ .bf.good {
815
+ background: linear-gradient(90deg, #00ff8866, #00ff88);
816
+ box-shadow: 0 0 10px rgba(0, 255, 136, 0.3);
817
+ }
818
+
819
+ .bv {
820
+ font-size: 12px;
821
+ font-weight: 700;
822
+ width: 40px;
823
+ text-align: right;
824
+ flex-shrink: 0;
825
+ }
826
+
827
+ .bv.bad {
828
+ color: var(--red);
829
+ }
830
+
831
+ .bv.good {
832
+ color: var(--green);
833
+ }
834
+
835
+ /* Simple mode note */
836
+ .sn {
837
+ padding: 20px;
838
+ border: 1px solid var(--cyan);
839
+ border-radius: 12px;
840
+ background: rgba(0, 217, 255, 0.05);
841
+ margin: 24px;
842
+ font-size: 13px;
843
+ color: var(--t2);
844
+ line-height: 1.6;
845
+ border-left-width: 4px;
846
+ }
847
+
848
+ /* Diff */
849
+ .dg {
850
+ display: grid;
851
+ grid-template-columns: 1fr 1fr;
852
+ background: var(--bg);
853
+ }
854
+
855
+ .dfs {
856
+ min-width: 0;
857
+ }
858
+
859
+ @media (max-width: 780px) {
860
+ .dg {
861
+ grid-template-columns: 1fr;
862
+ }
863
+
864
+ .dfs:first-child {
865
+ border-right: none !important;
866
+ border-bottom: 1px solid var(--b1);
867
+ }
868
+ }
869
+
870
+ .dfs:first-child {
871
+ border-right: 1px solid var(--b1);
872
+ }
873
+
874
+ .dfh {
875
+ padding: 10px 16px;
876
+ border-bottom: 1px solid var(--b1);
877
+ font-size: 11px;
878
+ color: var(--muted);
879
+ display: flex;
880
+ align-items: center;
881
+ gap: 8px;
882
+ font-weight: 600;
883
+ background: var(--s2);
884
+ }
885
+
886
+ .dft {
887
+ font-size: 9px;
888
+ font-weight: 800;
889
+ padding: 2px 6px;
890
+ border-radius: 4px;
891
+ text-transform: uppercase;
892
+ }
893
+
894
+ .dft.cu {
895
+ background: rgba(255, 51, 68, 0.2);
896
+ color: var(--red);
897
+ }
898
+
899
+ .dft.ro {
900
+ background: rgba(0, 255, 136, 0.2);
901
+ color: var(--green);
902
+ }
903
+
904
+ .dfp {
905
+ padding: 20px;
906
+ font-family: var(--mono);
907
+ font-size: 12px;
908
+ line-height: 1.7;
909
+ overflow: auto;
910
+ max-height: min(70vh, 760px);
911
+ white-space: pre-wrap;
912
+ overflow-wrap: anywhere;
913
+ word-break: break-word;
914
+ tab-size: 2;
915
+ color: var(--t2);
916
+ }
917
+
918
+ .dlo {
919
+ background: rgba(255, 51, 68, 0.08);
920
+ color: var(--red);
921
+ display: block;
922
+ border-left: 2px solid rgba(255, 51, 68, 0.45);
923
+ padding-left: 8px;
924
+ }
925
+
926
+ .dln {
927
+ background: rgba(0, 255, 136, 0.08);
928
+ color: var(--green);
929
+ display: block;
930
+ border-left: 2px solid rgba(0, 255, 136, 0.45);
931
+ padding-left: 8px;
932
+ }
933
+
934
+ /* Loading Skeleton */
935
+ .skeleton {
936
+ position: relative;
937
+ overflow: hidden;
938
+ background: var(--s2);
939
+ border-radius: 12px;
940
+ height: 200px;
941
+ margin-top: 24px;
942
+ }
943
+
944
+ .skeleton::after {
945
+ content: '';
946
+ position: absolute;
947
+ inset: 0;
948
+ transform: translateX(-100%);
949
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent);
950
+ animation: shimmer 1.5s infinite;
951
+ }
952
+
953
+ @keyframes shimmer {
954
+ 100% {
955
+ transform: translateX(100%);
956
+ }
957
+ }
958
+
959
+ /* Custom Cursor */
960
+ #cursor {
961
+ position: fixed;
962
+ width: 20px;
963
+ height: 20px;
964
+ background: rgba(255, 255, 255, 0.2);
965
+ border: 1px solid rgba(255, 255, 255, 0.4);
966
+ border-radius: 50%;
967
+ pointer-events: none;
968
+ z-index: 9999;
969
+ transition: transform 0.1s ease, width 0.3s var(--spring), height 0.3s var(--spring), background 0.3s ease;
970
+ mix-blend-mode: difference;
971
+ }
972
+
973
+ #cursor.active {
974
+ transform: scale(3);
975
+ background: rgba(255, 51, 68, 0.3);
976
+ border-color: var(--red);
977
+ }
978
+
979
+ /* Modal */
980
+ .mo {
981
+ display: none;
982
+ position: fixed;
983
+ inset: 0;
984
+ background: rgba(0, 0, 0, 0.85);
985
+ z-index: 1000;
986
+ place-items: center;
987
+ backdrop-filter: blur(8px);
988
+ }
989
+
990
+ .mo.open {
991
+ display: grid;
992
+ }
993
+
994
+ .mb {
995
+ background: var(--s1);
996
+ border: 1px solid var(--b1);
997
+ border-radius: 16px;
998
+ width: 90%;
999
+ max-width: 800px;
1000
+ max-height: 90vh;
1001
+ overflow: hidden;
1002
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
1003
+ }
1004
+
1005
+ .mt {
1006
+ padding: 16px 24px;
1007
+ border-bottom: 1px solid var(--b1);
1008
+ display: flex;
1009
+ justify-content: space-between;
1010
+ align-items: center;
1011
+ background: var(--s2);
1012
+ }
1013
+
1014
+ .mt h3 {
1015
+ font-size: 16px;
1016
+ color: var(--t3);
1017
+ font-weight: 700;
1018
+ }
1019
+
1020
+ .mx {
1021
+ background: none;
1022
+ border: none;
1023
+ color: var(--muted);
1024
+ font-size: 24px;
1025
+ cursor: pointer !important;
1026
+ line-height: 1;
1027
+ transition: color 0.2s;
1028
+ }
1029
+
1030
+ .mx:hover {
1031
+ color: var(--t3);
1032
+ }
1033
+
1034
+ .mc {
1035
+ padding: 24px;
1036
+ }
1037
+
1038
+ .mc textarea {
1039
+ width: 100%;
1040
+ height: 400px;
1041
+ background: var(--bg);
1042
+ border: 1px solid var(--b1);
1043
+ border-radius: 8px;
1044
+ padding: 16px;
1045
+ color: var(--cyan);
1046
+ font-family: var(--mono);
1047
+ font-size: 12px;
1048
+ line-height: 1.6;
1049
+ resize: vertical;
1050
+ outline: none;
1051
+ }
1052
+
1053
+ .mc textarea:focus {
1054
+ border-color: var(--cyan);
1055
+ box-shadow: 0 0 10px rgba(0, 217, 255, 0.2);
1056
+ }
1057
+
1058
+ .mf {
1059
+ padding: 16px 24px;
1060
+ border-top: 1px solid var(--b1);
1061
+ display: flex;
1062
+ justify-content: flex-end;
1063
+ gap: 12px;
1064
+ background: var(--s2);
1065
+ }
1066
+
1067
+ ::-webkit-scrollbar {
1068
+ width: 6px;
1069
+ height: 6px;
1070
+ }
1071
+
1072
+ ::-webkit-scrollbar-track {
1073
+ background: transparent;
1074
+ }
1075
+
1076
+ ::-webkit-scrollbar-thumb {
1077
+ background: var(--b1);
1078
+ border-radius: 10px;
1079
+ }
1080
+
1081
+ ::-webkit-scrollbar-thumb:hover {
1082
+ background: var(--b2);
1083
+ }
1084
+
1085
+ footer {
1086
+ padding: 32px 0;
1087
+ border-top: 1px solid var(--b1);
1088
+ display: flex;
1089
+ justify-content: space-between;
1090
+ font-size: 11px;
1091
+ color: var(--muted);
1092
+ font-weight: 500;
1093
+ }
1094
+
1095
+ footer a {
1096
+ color: var(--muted);
1097
+ text-decoration: none;
1098
+ transition: color 0.2s;
1099
+ border-bottom: 1px solid transparent;
1100
+ }
1101
+
1102
+ footer a:hover {
1103
+ color: var(--t2);
1104
+ border-bottom-color: var(--muted);
1105
+ }
1106
+
1107
+ .idle {
1108
+ flex: 1;
1109
+ display: flex;
1110
+ align-items: center;
1111
+ justify-content: center;
1112
+ color: var(--b2);
1113
+ font-size: 13px;
1114
+ font-weight: 500;
1115
+ min-height: 100px;
1116
+ }
1117
+
1118
+ /* Data source badge */
1119
+ .ds-badge {
1120
+ display: inline-flex;
1121
+ align-items: center;
1122
+ gap: 6px;
1123
+ font-size: 10px;
1124
+ font-weight: 800;
1125
+ letter-spacing: 0.08em;
1126
+ text-transform: uppercase;
1127
+ padding: 4px 10px;
1128
+ border-radius: 4px;
1129
+ margin-left: 12px;
1130
+ vertical-align: middle;
1131
+ }
1132
+ .ds-badge.real {
1133
+ background: rgba(0,255,136,0.15);
1134
+ color: var(--green);
1135
+ border: 1px solid rgba(0,255,136,0.3);
1136
+ }
1137
+ .ds-badge.demo {
1138
+ background: rgba(255,204,0,0.12);
1139
+ color: var(--yellow);
1140
+ border: 1px solid rgba(255,204,0,0.3);
1141
+ }
1142
+ .ds-badge.sim {
1143
+ background: rgba(255,255,255,0.06);
1144
+ color: var(--muted);
1145
+ border: 1px solid var(--b1);
1146
+ }
1147
+
1148
+ /* Risk matrix panel */
1149
+ .risk-panel {
1150
+ margin: 0 24px 24px;
1151
+ border-radius: 10px;
1152
+ overflow: hidden;
1153
+ border: 1px solid var(--b1);
1154
+ }
1155
+ .risk-header {
1156
+ background: rgba(255,255,255,0.03);
1157
+ padding: 10px 16px;
1158
+ font-size: 11px;
1159
+ font-weight: 700;
1160
+ color: var(--muted);
1161
+ text-transform: uppercase;
1162
+ letter-spacing: 0.08em;
1163
+ border-bottom: 1px solid var(--b1);
1164
+ display: flex;
1165
+ align-items: center;
1166
+ gap: 10px;
1167
+ }
1168
+ .risk-badge {
1169
+ font-size: 9px;
1170
+ font-weight: 800;
1171
+ padding: 2px 6px;
1172
+ border-radius: 3px;
1173
+ text-transform: uppercase;
1174
+ letter-spacing: 0.05em;
1175
+ }
1176
+ .risk-badge.crit { background: rgba(255,51,68,0.2); color: var(--red); }
1177
+ .risk-badge.high { background: rgba(255,153,0,0.2); color: #ff9900; }
1178
+ .risk-badge.med { background: rgba(255,204,0,0.2); color: var(--yellow); }
1179
+ .risk-row {
1180
+ padding: 12px 16px;
1181
+ border-bottom: 1px solid rgba(255,255,255,0.04);
1182
+ display: grid;
1183
+ grid-template-columns: 70px 1fr auto;
1184
+ gap: 12px;
1185
+ align-items: start;
1186
+ font-size: 12px;
1187
+ transition: background 0.2s;
1188
+ }
1189
+ .risk-row:last-child { border-bottom: none; }
1190
+ .risk-row:hover { background: rgba(255,255,255,0.02); }
1191
+ .risk-loc {
1192
+ font-family: var(--mono);
1193
+ font-size: 11px;
1194
+ color: var(--muted);
1195
+ padding-top: 1px;
1196
+ }
1197
+ .risk-desc { color: var(--t2); line-height: 1.5; }
1198
+ .risk-hint {
1199
+ font-size: 10px;
1200
+ color: var(--cyan);
1201
+ margin-top: 4px;
1202
+ line-height: 1.4;
1203
+ }
1204
+ </style>
1205
+ </head>
1206
+ <div id="cursor"></div>
1207
+
1208
+ <div class="w">
1209
+ <header>
1210
+ <div class="logo">ROCmPort <em>AI</em></div>
1211
+ <div class="hr">
1212
+ <div class="hd on" id="hdot"></div>
1213
+ <span id="hstat">Ready</span>
1214
+ </div>
1215
+ </header>
1216
+
1217
+ <div class="g">
1218
+ <div class="p">
1219
+ <div class="ph">
1220
+ <div><b>//</b> CUDA source</div>
1221
+ <div id="lc">0 lines</div>
1222
+ </div>
1223
+ <textarea class="code" id="inp" spellcheck="false" placeholder="// Paste CUDA code here
1224
+ // or pick a demo below
1225
+
1226
+ __global__ void kernel(float* A, float* B, int N) {
1227
+ int idx = blockIdx.x * blockDim.x + threadIdx.x;
1228
+ ...
1229
+ }"></textarea>
1230
+ <div class="db">
1231
+ <span class="l">Select a template:</span>
1232
+ <button class="ch" onclick="lk('vector_add', this)">Vector addition</button>
1233
+ <button class="ch" onclick="lk('matrix_multiply', this)">Matrix multiplication</button>
1234
+ <button class="ch" onclick="lk('convolution_2d', this)">2D convolution</button>
1235
+ <button class="ch" onclick="lk('reduction', this)">Parallel reduction</button>
1236
+ </div>
1237
+ <button class="bg" id="go" onclick="go()">Port to ROCm</button>
1238
+ </div>
1239
+
1240
+ <div class="p">
1241
+ <div class="ph">
1242
+ <div><b>//</b> Pipeline</div>
1243
+ <div id="pt">0.0s</div>
1244
+ </div>
1245
+ <div class="timeline" id="tl">
1246
+ <!-- Nodes injected by JS -->
1247
+ </div>
1248
+ <div class="al" id="al">
1249
+ <div class="idle">Paste CUDA code to begin migration</div>
1250
+ </div>
1251
+ </div>
1252
+
1253
+ <div class="p fs hide" id="rp">
1254
+ <div class="ph">
1255
+ <div style="display:flex;align-items:center;gap:12px"><b>//</b> Results</div>
1256
+ <div class="tabs" id="tabs">
1257
+ <button class="tab on" onclick="stab('sum',this)">Summary</button>
1258
+ <button class="tab" onclick="stab('diff',this)">Visual Diff</button>
1259
+ <button class="tab" onclick="stab('det',this)">Performance</button>
1260
+ </div>
1261
+ </div>
1262
+ <div id="t-loader" class="hide">
1263
+ <div class="skeleton"></div>
1264
+ </div>
1265
+ <div id="t-sum" class="tc on"></div>
1266
+ <div id="t-diff" class="tc"></div>
1267
+ <div id="t-det" class="tc">
1268
+ </div>
1269
+ </div>
1270
+ </div>
1271
+
1272
+ <footer>
1273
+ <div>ROCmPort AI</div>
1274
+ <div><a href="https://x.com/TazwarEnan" target="_blank">Tazwar Ahnaf Enan</a> · <a
1275
+ href="https://github.com/tazwaryayyyy" target="_blank">GitHub</a></div>
1276
+ </footer>
1277
+ </div>
1278
+
1279
+ <div class="mo" id="modal">
1280
+ <div class="mb">
1281
+ <div class="mt">
1282
+ <h3>Edit ROCm code</h3><button class="mx" onclick="cm()">&times;</button>
1283
+ </div>
1284
+ <div class="mc"><textarea id="edt"></textarea></div>
1285
+ <div class="mf"><button class="bs" onclick="cm()">Cancel</button><button class="bs r"
1286
+ onclick="rec()">Re-test</button></div>
1287
+ </div>
1288
+ </div>
1289
+ <script>
1290
+ const API = window.location.protocol === 'file:'
1291
+ ? 'http://localhost:8000'
1292
+ : window.location.origin;
1293
+ const S = { code: '', kn: 'custom', run: false, t0: null, iv: null, rep: null, tl: [], kernels: {} };
1294
+ const AG = {
1295
+ analyzer: { n: 'ANALYZER', i: '🔍' },
1296
+ translator: { n: 'TRANSLATOR', i: '🔄' },
1297
+ optimizer: { n: 'OPTIMIZER', i: '⚡' },
1298
+ tester: { n: 'TESTER', i: '🧪' },
1299
+ coordinator: { n: 'COORDINATOR', i: '📋' }
1300
+ };
1301
+
1302
+ // Custom Cursor Logic
1303
+ const cur = document.getElementById('cursor');
1304
+ document.addEventListener('mousemove', (e) => {
1305
+ cur.style.left = e.clientX + 'px';
1306
+ cur.style.top = e.clientY + 'px';
1307
+ const target = e.target;
1308
+ const isClickable = target.onclick ||
1309
+ target.tagName === 'BUTTON' ||
1310
+ target.tagName === 'A' ||
1311
+ target.tagName === 'TEXTAREA' ||
1312
+ target.classList.contains('ch') ||
1313
+ target.classList.contains('tab');
1314
+
1315
+ if (isClickable) {
1316
+ cur.classList.add('active');
1317
+ if (target.id === 'go') cur.style.background = 'rgba(255, 51, 68, 0.5)';
1318
+ else cur.style.background = 'rgba(255, 255, 255, 0.3)';
1319
+ } else {
1320
+ cur.classList.remove('active');
1321
+ cur.style.background = 'rgba(255, 255, 255, 0.2)';
1322
+ }
1323
+ });
1324
+
1325
+ async function init() {
1326
+ const ta = document.getElementById('inp');
1327
+ ta.oninput = () => {
1328
+ document.getElementById('lc').textContent = ta.value.split('\n').length + ' lines';
1329
+ S.code = ta.value;
1330
+ };
1331
+ try {
1332
+ const r = await fetch(API + '/demo-kernels');
1333
+ S.kernels = await r.json();
1334
+ } catch (e) { S.kernels = FB; }
1335
+ }
1336
+
1337
+ function lk(n, btn) {
1338
+ document.querySelectorAll('.ch').forEach(c => c.classList.remove('on'));
1339
+ btn.classList.add('on');
1340
+ const code = S.kernels[n] || FB[n] || '', ta = document.getElementById('inp');
1341
+ ta.value = code; S.code = code; S.kn = n;
1342
+ document.getElementById('lc').textContent = code.split('\n').length + ' lines';
1343
+ }
1344
+
1345
+ function stab(id, btn) {
1346
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('on'));
1347
+ document.querySelectorAll('.tc').forEach(t => t.classList.remove('on'));
1348
+ btn.classList.add('on');
1349
+ document.getElementById('t-' + id).classList.add('on');
1350
+ if (id === 'diff' && S.rep) rDiff(S.code, S.rep.optimized_code);
1351
+ }
1352
+
1353
+ async function go() {
1354
+ if (S.run) return;
1355
+ const code = document.getElementById('inp').value.trim();
1356
+ if (!code) return;
1357
+
1358
+ S.code = code; S.run = true; S.t0 = Date.now(); S.tl = [];
1359
+ const btn = document.getElementById('go');
1360
+ btn.disabled = true;
1361
+ btn.textContent = 'Running pipeline...';
1362
+
1363
+ document.getElementById('hstat').textContent = 'Pipeline running...';
1364
+ document.getElementById('rp').classList.add('hide');
1365
+
1366
+ bLog();
1367
+ sTimer();
1368
+
1369
+ try {
1370
+ const simpleModeCheckbox = document.getElementById('sm');
1371
+ const res = await fetch(API + '/port', {
1372
+ method: 'POST',
1373
+ headers: { 'Content-Type': 'application/json' },
1374
+ body: JSON.stringify({
1375
+ cuda_code: code,
1376
+ kernel_name: S.kn,
1377
+ simple_mode: simpleModeCheckbox ? simpleModeCheckbox.checked : false
1378
+ })
1379
+ });
1380
+
1381
+ // Show results panel with loader immediately
1382
+ document.getElementById('rp').classList.remove('hide');
1383
+ document.getElementById('t-loader').classList.remove('hide');
1384
+ document.getElementById('t-sum').classList.remove('on');
1385
+ document.getElementById('t-diff').classList.remove('on');
1386
+ document.getElementById('t-det').classList.remove('on');
1387
+
1388
+ const rd = res.body.getReader(), dc = new TextDecoder();
1389
+ let buf = '';
1390
+ while (true) {
1391
+ const { done, value } = await rd.read();
1392
+ if (done) break;
1393
+ buf += dc.decode(value, { stream: true });
1394
+ const lines = buf.split('\n');
1395
+ buf = lines.pop();
1396
+ for (const ln of lines) {
1397
+ if (!ln.startsWith('data: ')) continue;
1398
+ const raw = ln.slice(6).trim();
1399
+ if (raw === '[DONE]') { done_(); break; }
1400
+ try { hEvt(JSON.parse(raw)); } catch (e) { console.error('Parse error:', e); }
1401
+ }
1402
+ }
1403
+ } catch (e) {
1404
+ document.getElementById('hstat').textContent = 'Pipeline error';
1405
+ document.getElementById('t-loader').classList.add('hide'); // Hide loader on error
1406
+ console.error(e);
1407
+ } finally {
1408
+ xTimer();
1409
+ S.run = false;
1410
+ btn.disabled = false;
1411
+ btn.textContent = 'Port to ROCm';
1412
+ document.getElementById('t-loader').classList.add('hide');
1413
+ }
1414
+ }
1415
+
1416
+ function hEvt(ev) {
1417
+ uLog(ev.agent, ev.status, ev.message, ev.detail);
1418
+ if (ev.agent === 'tester' && (ev.status === 'done' || ev.status === 'failed')) {
1419
+ const m = ev.message.match(/([\d.]+)x/);
1420
+ if (m) {
1421
+ const sp = parseFloat(m[1]), ok = sp >= 1, im = ev.message.match(/Iteration (\d+)/i);
1422
+ S.tl.push({
1423
+ label: 'Iteration ' + (im ? im[1] : S.tl.length + 1) + (ok ? ' (optimized)' : ' (baseline)'),
1424
+ speedup: sp,
1425
+ good: ok
1426
+ });
1427
+ }
1428
+ }
1429
+ if (ev.agent === 'coordinator' && ev.status === 'done' && ev.detail) {
1430
+ try {
1431
+ const r = JSON.parse(ev.detail);
1432
+ S.rep = r;
1433
+ rRes(r, S.tl);
1434
+ } catch (e) { console.error('Coordinator detail parse error:', e); }
1435
+ }
1436
+ }
1437
+
1438
+ function done_() {
1439
+ document.getElementById('hstat').textContent = 'Pipeline complete';
1440
+ document.getElementById('t-loader').classList.add('hide');
1441
+ if (!S.rep) {
1442
+ document.getElementById('t-sum').innerHTML = '<div class="idle">Migration finished but no report was generated. Check agent logs for details.</div>';
1443
+ document.getElementById('t-sum').classList.add('on');
1444
+ }
1445
+ }
1446
+
1447
+ function bLog() {
1448
+ const el = document.getElementById('al');
1449
+ const tl = document.getElementById('tl');
1450
+ el.innerHTML = '';
1451
+ tl.innerHTML = '';
1452
+
1453
+ let i = 0;
1454
+ for (const [k, obj] of Object.entries(AG)) {
1455
+ // Log row
1456
+ const d = document.createElement('div');
1457
+ d.className = 'ar';
1458
+ d.id = 'ar-' + k;
1459
+ d.style.animationDelay = (i * 0.1) + 's';
1460
+ d.innerHTML = `
1461
+ <div class="at">
1462
+ <span class="an">${obj.n}</span>
1463
+ <span class="am" id="am-${k}">Waiting</span>
1464
+ </div>
1465
+ <div class="ad" id="ad-${k}"></div>`;
1466
+ el.appendChild(d);
1467
+
1468
+ // Timeline node
1469
+ const n = document.createElement('div');
1470
+ n.className = 'node';
1471
+ n.id = 'nd-' + k;
1472
+ n.title = obj.n;
1473
+ n.innerHTML = `<div class="ni">${obj.i}</div><div class="nl">${obj.n.slice(0, 3)}</div>`;
1474
+ tl.appendChild(n);
1475
+ i++;
1476
+ }
1477
+ }
1478
+
1479
+ function uLog(a, s, m, d) {
1480
+ const row = document.getElementById('ar-' + a);
1481
+ const node = document.getElementById('nd-' + a);
1482
+ if (!row || !node) return;
1483
+
1484
+ const statusClass = { running: 'run', done: 'done', failed: 'fail', retrying: 'retry' }[s] || '';
1485
+ row.className = 'ar ' + statusClass;
1486
+ node.className = 'node ' + (s === 'running' ? 'on' : s === 'retrying' ? 'retry' : s === 'done' ? 'done' : s === 'failed' ? 'fail' : '');
1487
+
1488
+ const me = document.getElementById('am-' + a);
1489
+ if (me) me.textContent = m;
1490
+
1491
+ // Node tooltip message update
1492
+ node.title = m;
1493
+
1494
+ const de = document.getElementById('ad-' + a);
1495
+ if (de && d) {
1496
+ de.innerHTML = esc(d)
1497
+ .replace(/\u26a0\ufe0f([^\n]*)/g, '<span class="w">⚠️ $1</span>')
1498
+ .replace(/\u2705([^\n]*)/g, '<span class="g">✅ $1</span>');
1499
+ de.scrollTop = de.scrollHeight;
1500
+ }
1501
+ }
1502
+
1503
+ function rRes(r, tl) {
1504
+ // Hide loader, show summary
1505
+ document.getElementById('t-loader').classList.add('hide');
1506
+ document.getElementById('t-sum').classList.add('on');
1507
+
1508
+ const v = r.verification || {}, bw = r.bandwidth_utilized;
1509
+ const dot = ok => `<div class="sum-dot ${ok === true ? 'ok' : ok === false ? 'no' : 'na'}"></div>`;
1510
+
1511
+ // Data source badge
1512
+ const ds = r.data_source || 'simulated';
1513
+ const dsBadge = ds === 'real_rocm'
1514
+ ? `<span class="ds-badge real">🟢 LIVE MI300X</span>`
1515
+ : ds === 'demo_artifact'
1516
+ ? `<span class="ds-badge demo">🟡 DEMO DATA</span>`
1517
+ : `<span class="ds-badge sim">⚪ SIMULATED</span>`;
1518
+
1519
+ document.getElementById('t-sum').innerHTML = `
1520
+ <div class="sum-row">
1521
+ <div class="sum-big">
1522
+ ${r.speedup}x
1523
+ ${dsBadge}
1524
+ <span class="u">vs baseline hipify</span>
1525
+ <span class="vic">Measured against declared baseline. ${ds === 'demo_artifact' ? 'Representative MI300X values — set ROCM_AVAILABLE=true for real numbers.' : ds === 'real_rocm' ? 'Real rocprof measurement on AMD MI300X.' : 'Set ROCM_AVAILABLE=true on AMD Cloud for real numbers.'}</span>
1526
+ </div>
1527
+ <div class="sum-sep"></div>
1528
+ <div>
1529
+ <div class="sum-chk">${dot(v.compiled_successfully)} Compiled${v.mock_mode ? ' (simulated)' : ''}</div>
1530
+ <div class="sum-chk" style="margin-top:8px">${dot(v.executed_without_error)} Executed without error</div>
1531
+ <div class="sum-chk" style="margin-top:8px">${dot(v.output_matches_expected)} Output matches expected</div>
1532
+ </div>
1533
+ <div class="sum-sep"></div>
1534
+ <div class="sum-type">${(r.bottleneck || 'optimized').toLowerCase()}</div>
1535
+ </div>
1536
+ <div class="sum-bar">
1537
+ <button class="bs r" onclick="om()">Edit code</button>
1538
+ <button class="bs gr" onclick="exM()">Export PR</button>
1539
+ <button class="bs" onclick="dlR()">Download report</button>
1540
+ <div class="sp"></div>
1541
+ </div>
1542
+ <div class="sn" id="sn" style="margin: 24px; border-left-width: 4px;">
1543
+ <div style="font-weight: bold; margin-bottom: 8px; color: var(--cyan);">🧠 Simple explanation</div>
1544
+ ${r.simplified_explanation ? esc(r.simplified_explanation) : '<em>Simplified explanation will appear here</em>'}
1545
+ </div>
1546
+ ${riskMatrix(r.static_risk_report)}`;
1547
+
1548
+ // Details tab
1549
+ let dh = `<div class="dm">
1550
+ <div class="di"><div class="dl">Speedup</div><div class="dv g">${r.speedup}x</div><div class="ds">optimized ROCm vs straight hipify output</div></div>
1551
+ <div class="di"><div class="dl">Bandwidth</div><div class="dv c">${bw != null ? bw.toFixed(1) : '—'}%</div><div class="ds">of MI300X 5.3 TB/s HBM3</div></div>
1552
+ <div class="di"><div class="dl">Changes</div><div class="dv y">${r.total_changes}</div><div class="ds">hipify + LLM + optimizer changes</div></div>
1553
+ <div class="di"><div class="dl">Iterations</div><div class="dv c">${r.iterations || 1}</div><div class="ds">optimizer retry loop count</div></div>
1554
+ <div class="di"><div class="dl">Type</div><div class="dv t">${(r.bottleneck || '—').toUpperCase()}</div><div class="ds">workload classification</div></div>
1555
+ </div>`;
1556
+
1557
+ if (tl.length) {
1558
+ dh += '<div class="bk"><div class="bk-t">Benchmark iterations (optimized vs baseline hipify)</div>';
1559
+ tl.forEach(d => {
1560
+ const pct = Math.min(Math.max((d.speedup / 2) * 100, 3), 95);
1561
+ dh += `<div class="br">
1562
+ <div class="bl">${esc(d.label)}</div>
1563
+ <div class="bt"><div class="bf ${d.good ? 'good' : 'bad'}" style="width: 0" data-w="${pct}%"></div></div>
1564
+ <div class="bv ${d.good ? 'good' : 'bad'}">${d.speedup}x</div>
1565
+ </div>`;
1566
+ });
1567
+ dh += '</div>';
1568
+ }
1569
+
1570
+ document.getElementById('t-det').innerHTML = dh;
1571
+ tsm(); // Ensure simple note visibility matches current toggle state
1572
+
1573
+ // Progress bar animation
1574
+ setTimeout(() => {
1575
+ document.querySelectorAll('.bf[data-w]').forEach(b => {
1576
+ b.style.width = b.dataset.w;
1577
+ });
1578
+ }, 100);
1579
+ }
1580
+
1581
+ function riskMatrix(srr) {
1582
+ if (!srr || !srr.items || srr.items.length === 0) return '';
1583
+
1584
+ const levelClass = { CRITICAL: 'crit', HIGH: 'high', MEDIUM: 'med' };
1585
+ const critical = srr.critical_count || 0;
1586
+ const high = srr.high_count || 0;
1587
+ const medium = srr.medium_count || 0;
1588
+
1589
+ let rows = srr.items.map(item => {
1590
+ const cls = levelClass[item.risk_level] || 'med';
1591
+ const loc = item.line ? `line ${item.line}` : '—';
1592
+ return `<div class="risk-row">
1593
+ <div class="risk-loc">${esc(loc)}</div>
1594
+ <div>
1595
+ <div class="risk-desc">${esc(item.description)}</div>
1596
+ <div class="risk-hint">Fix: ${esc(item.amd_fix_hint)}</div>
1597
+ </div>
1598
+ <div><span class="risk-badge ${cls}">${esc(item.risk_level)}</span></div>
1599
+ </div>`;
1600
+ }).join('');
1601
+
1602
+ const scanMs = srr.scan_duration_ms != null ? `${srr.scan_duration_ms.toFixed(1)}ms` : '';
1603
+
1604
+ return `<div class="risk-panel">
1605
+ <div class="risk-header">
1606
+ ⚠️ Static Risk Scan
1607
+ ${critical > 0 ? `<span class="risk-badge crit">${critical} CRITICAL</span>` : ''}
1608
+ ${high > 0 ? `<span class="risk-badge high">${high} HIGH</span>` : ''}
1609
+ ${medium > 0 ? `<span class="risk-badge med">${medium} MEDIUM</span>` : ''}
1610
+ <span style="margin-left:auto;font-size:9px;opacity:0.5">Pure-Python pre-scan · ${scanMs}</span>
1611
+ </div>
1612
+ ${rows}
1613
+ </div>`;
1614
+ }
1615
+
1616
+ function rDiff(o, n) {
1617
+ if (!o || !n) return;
1618
+ document.getElementById('t-diff').innerHTML = `<div class="dg">
1619
+ <div class="dfs"><div class="dfh"><span class="dft cu">CUDA</span> Original Source</div><pre class="dfp" id="d-o"></pre></div>
1620
+ <div class="dfs"><div class="dfh"><span class="dft ro">ROCm</span> Optimized HIP</div><pre class="dfp" id="d-n"></pre></div>
1621
+ </div>`;
1622
+
1623
+ const oL = o.split('\n'), nL = n.split('\n'), mx = Math.max(oL.length, nL.length);
1624
+ let oH = '', nH = '';
1625
+ for (let i = 0; i < mx; i++) {
1626
+ const a = oL[i] ?? '', b = nL[i] ?? '', c = a !== b;
1627
+ oH += `<span class="${c ? 'dlo' : ''}">${esc(a)}\n</span>`;
1628
+ nH += `<span class="${c ? 'dln' : ''}">${esc(b)}\n</span>`;
1629
+ }
1630
+ const left = document.getElementById('d-o');
1631
+ const right = document.getElementById('d-n');
1632
+ left.innerHTML = oH;
1633
+ right.innerHTML = nH;
1634
+
1635
+ // Keep both panes aligned while scrolling for easier comparison.
1636
+ let syncing = false;
1637
+ left.addEventListener('scroll', () => {
1638
+ if (syncing) return;
1639
+ syncing = true;
1640
+ right.scrollTop = left.scrollTop;
1641
+ syncing = false;
1642
+ }, { passive: true });
1643
+ right.addEventListener('scroll', () => {
1644
+ if (syncing) return;
1645
+ syncing = true;
1646
+ left.scrollTop = right.scrollTop;
1647
+ syncing = false;
1648
+ }, { passive: true });
1649
+ }
1650
+
1651
+ function sTimer() { S.iv = setInterval(() => { document.getElementById('pt').textContent = ((Date.now() - S.t0) / 1000).toFixed(1) + 's' }, 100) }
1652
+ function xTimer() { clearInterval(S.iv) }
1653
+
1654
+ function dlR() {
1655
+ const r = S.rep; if (!r) return;
1656
+ const md = `# ROCmPort AI — Migration Report\n\n## Results\n- **Speedup**: ${r.speedup}x\n- **Bandwidth**: ${r.bandwidth_utilized ? r.bandwidth_utilized.toFixed(1) : '—'}%\n- **Changes**: ${r.total_changes}\n- **Iterations**: ${r.iterations}\n- **Type**: ${r.bottleneck}\n\n${r.amd_advantage_explanation ? '> ' + r.amd_advantage_explanation + '\n\n' : ''}${r.cost_estimate ? '## Cost Impact\n- Manual: ' + r.cost_estimate.manual_porting_weeks + '\n- ROCmPort: ' + r.cost_estimate.rocmport_minutes + '\n- Savings: ' + r.cost_estimate.estimated_savings + '\n\n' : ''}## ROCm/HIP Code\n\`\`\`cpp\n${r.optimized_code || ''}\n\`\`\`\n\n---\n*Generated by ROCmPort AI*\n`;
1657
+ const a = document.createElement('a'); a.href = URL.createObjectURL(new Blob([md], { type: 'text/markdown' })); a.download = 'rocmport-migration-report.md'; a.click();
1658
+ }
1659
+
1660
+ function om() { if (!S.rep) return alert('No results yet!'); document.getElementById('edt').value = S.rep?.optimized_code || ''; document.getElementById('modal').classList.add('open') }
1661
+ function cm() { document.getElementById('modal').classList.remove('open') }
1662
+
1663
+ async function rec() {
1664
+ const code = document.getElementById('edt').value.trim(); if (!code) return;
1665
+ try {
1666
+ const res = await fetch(API + '/recompile', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ edited_code: code, kernel_name: S.kn }) });
1667
+ const r = await res.json();
1668
+ if (r.success) { cm(); if (r.result) rRes(r.result, S.tl); }
1669
+ else alert('Failed: ' + (r.detail || 'Unknown'))
1670
+ } catch (e) { alert('Error: ' + e.message) }
1671
+ }
1672
+
1673
+ async function exM() {
1674
+ if (!S.rep) return;
1675
+ try {
1676
+ const currentInput = document.getElementById('inp')?.value || '';
1677
+ const payload = {
1678
+ original_cuda: S.code || currentInput,
1679
+ final_rocm: S.rep.optimized_code || '',
1680
+ migration_report: S.rep
1681
+ };
1682
+ const res = await fetch(API + '/export', {
1683
+ method: 'POST',
1684
+ headers: { 'Content-Type': 'application/json' },
1685
+ body: JSON.stringify(payload)
1686
+ });
1687
+
1688
+ if (!res.ok) {
1689
+ let msg = `Export failed (${res.status})`;
1690
+ try {
1691
+ const err = await res.json();
1692
+ if (err && err.detail) msg = err.detail;
1693
+ } catch (_) { }
1694
+ throw new Error(msg);
1695
+ }
1696
+
1697
+ const a = document.createElement('a');
1698
+ a.href = URL.createObjectURL(await res.blob());
1699
+ a.download = 'rocmport-migration.zip';
1700
+ a.click();
1701
+ } catch (e) {
1702
+ alert('Export error: ' + (e.message || 'Unknown error'));
1703
+ }
1704
+ }
1705
+
1706
+ function tsm() {
1707
+ const sn = document.getElementById('sn');
1708
+ if (sn) sn.classList.remove('hide');
1709
+ }
1710
+
1711
+ function esc(s) { return String(s ?? '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;') }
1712
+
1713
+ const FB = {
1714
+ vector_add: `#include <cuda_runtime.h>\n\n__global__ void vector_add_kernel(float* A, float* B, float* C, int N) {\n int idx = blockIdx.x * blockDim.x + threadIdx.x;\n if (idx < N) {\n C[idx] = A[idx] + B[idx];\n }\n}\n\nint main() {\n int N = 1 << 24;\n size_t size = N * sizeof(float);\n float *d_A, *d_B, *d_C;\n cudaMalloc(&d_A, size);\n cudaMalloc(&d_B, size);\n cudaMalloc(&d_C, size);\n int threads = 128;\n int blocks = (N + threads - 1) / threads;\n vector_add_kernel<<<blocks, threads>>>(d_A, d_B, d_C, N);\n cudaDeviceSynchronize();\n cudaFree(d_A); cudaFree(d_B); cudaFree(d_C);\n return 0;\n}`,
1715
+ matrix_multiply: `#include <cuda_runtime.h>\n#define WARP_SIZE 32\n\n__global__ void matmul_kernel(float* A, float* B, float* C, int N) {\n int row = blockIdx.y * blockDim.y + threadIdx.y;\n int col = blockIdx.x * blockDim.x + threadIdx.x;\n float sum = 0.0f;\n if (row < N && col < N) {\n for (int k = 0; k < N; k++)\n sum += A[row * N + k] * B[k * N + col];\n C[row * N + col] = sum;\n }\n}\n\n__global__ void warp_reduce(float* data, float* result, int N) {\n int tid = threadIdx.x;\n extern __shared__ float sdata[];\n sdata[tid] = (tid < N) ? data[tid] : 0;\n __syncthreads();\n for (int s = WARP_SIZE/2; s > 0; s >>= 1) {\n if (tid < s) sdata[tid] += sdata[tid + s];\n __syncthreads();\n }\n if (tid == 0) result[blockIdx.x] = sdata[0];\n}\n\nint main() {\n int N = 1024;\n size_t size = N * N * sizeof(float);\n float *d_A, *d_B, *d_C;\n cudaMalloc(&d_A, size);\n cudaMalloc(&d_B, size);\n cudaMalloc(&d_C, size);\n dim3 block(16, 16);\n dim3 grid((N+15)/16, (N+15)/16);\n matmul_kernel<<<grid, block>>>(d_A, d_B, d_C, N);\n cudaDeviceSynchronize();\n cudaFree(d_A); cudaFree(d_B); cudaFree(d_C);\n return 0;\n}`,
1716
+ convolution_2d: `#include <cuda_runtime.h>\n#define BLOCK_SIZE 16\n\n__global__ void conv2d_kernel(\n float* input, float* kernel, float* output,\n int width, int height\n) {\n int x = blockIdx.x * blockDim.x + threadIdx.x;\n int y = blockIdx.y * blockDim.y + threadIdx.y;\n if (x >= width || y >= height) return;\n float sum = 0.0f;\n for (int ky = -1; ky <= 1; ky++) {\n for (int kx = -1; kx <= 1; kx++) {\n int ix = x + kx, iy = y + ky;\n if (ix >= 0 && ix < width && iy >= 0 && iy < height)\n sum += input[iy * width + ix] * kernel[(ky+1)*3 + (kx+1)];\n }\n }\n output[y * width + x] = sum;\n}\n\nint main() {\n int W = 2048, H = 2048;\n float *d_in, *d_ker, *d_out;\n cudaMalloc(&d_in, W*H*sizeof(float));\n cudaMalloc(&d_ker, 9*sizeof(float));\n cudaMalloc(&d_out, W*H*sizeof(float));\n dim3 block(BLOCK_SIZE, BLOCK_SIZE);\n dim3 grid((W+BLOCK_SIZE-1)/BLOCK_SIZE, (H+BLOCK_SIZE-1)/BLOCK_SIZE);\n conv2d_kernel<<<grid, block>>>(d_in, d_ker, d_out, W, H);\n cudaDeviceSynchronize();\n cudaFree(d_in); cudaFree(d_ker); cudaFree(d_out);\n return 0;\n}`,
1717
+ reduction: `#include <cuda_runtime.h>\n#include <stdio.h>\n#include <iostream>\n#include <vector>\n#include <numeric>\n\n// Tree-based reduction kernel\n__global__ void reduction_kernel(float* g_idata, float* g_odata, unsigned int n) {\n extern __shared__ float sdata[];\n unsigned int tid = threadIdx.x;\n unsigned int i = blockIdx.x * (blockDim.x * 2) + threadIdx.x;\n\n float mySum = (i < n) ? g_idata[i] : 0;\n if (i + blockDim.x < n) mySum += g_idata[i + blockDim.x];\n sdata[tid] = mySum;\n __syncthreads();\n\n for (unsigned int s = blockDim.x / 2; s > 32; s >>= 1) {\n if (tid < s) sdata[tid] = mySum = mySum + sdata[tid + s];\n __syncthreads();\n }\n\n // DELIBERATE WARP-SIZE BUG: Unroll to 32 instead of 64\n if (tid < 32) {\n volatile float* vsmem = sdata;\n vsmem[tid] = mySum = mySum + vsmem[tid + 32];\n vsmem[tid] = mySum = mySum + vsmem[tid + 16];\n vsmem[tid] = mySum = mySum + vsmem[tid + 8];\n vsmem[tid] = mySum = mySum + vsmem[tid + 4];\n vsmem[tid] = mySum = mySum + vsmem[tid + 2];\n vsmem[tid] = mySum = mySum + vsmem[tid + 1];\n }\n\n if (tid == 0) g_odata[blockIdx.x] = sdata[0];\n}\n\nint main() {\n const int N = 1048576;\n // ... Host code for Parallel Reduction demo\n printf("Parallel Reduction demo loaded.\\n");\n return 0;\n}`
1718
+ };
1719
+
1720
+ init();
1721
+ </script>
1722
+ </body>
1723
+
1724
+ </html>