1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum Stage {
5 Welcome,
6 HardwareDetect,
7 Preflight,
8 ComponentDetect,
9 ComponentSelect,
10 Configuration,
11 Confirm,
12 Installing,
13 Complete,
14 Benchmarks,
15 Recovery,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum RunMode {
23 Install,
24 Benchmark,
25 Verify,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum Category {
30 Foundation,
31 Core,
32 UiUx,
33 Extension,
34 Environment,
35 Maintenance,
36 Performance,
37}
38
39#[derive(Debug, Clone)]
40pub struct Component {
41 pub id: String,
42 pub name: String,
43 pub description: String,
44 pub script: String,
56 pub category: Category,
57 pub required: bool,
58 pub selected: bool,
59 pub installed: bool,
60 pub progress: f32,
61 pub estimate: String,
62 pub needs_sudo: bool,
64 pub experimental: bool,
68 pub note: Option<String>,
71}
72
73impl Component {
74 pub fn is_native(&self) -> bool {
81 crate::installers::components::is_native_component(&self.id)
82 }
83}
84
85#[derive(Debug, Clone, Default, Serialize, Deserialize)]
86pub struct GPUInfo {
87 pub model: String,
88 pub driver: String,
89 pub architecture: String,
90 pub rocm_version: String,
91 pub gpu_count: usize,
92 pub memory_gb: f32,
93 pub temperature_c: Option<f32>,
94 pub power_watts: Option<f32>,
95}
96
97#[derive(Debug, Clone, Default, Serialize, Deserialize)]
98pub struct SystemInfo {
99 pub os: String,
100 pub distribution: String,
101 pub kernel: String,
102 pub cpu_model: String,
103 pub memory_gb: f32,
104 pub storage_gb: f32,
105 pub storage_available_gb: f32,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum PreflightStatus {
110 Passed,
111 Warning,
112 Failed,
113}
114
115impl PreflightStatus {
116 pub fn label(self) -> &'static str {
117 match self {
118 PreflightStatus::Passed => "passed",
119 PreflightStatus::Warning => "warning",
120 PreflightStatus::Failed => "failed",
121 }
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub enum PreflightType {
127 Critical,
128 Warning,
129 Info,
130}
131
132#[derive(Debug, Clone)]
133pub struct PreflightCheck {
134 pub name: String,
135 pub status: PreflightStatus,
136 pub check_type: PreflightType,
137 pub message: String,
138 pub details: String,
139 pub score: i32,
140}
141
142#[derive(Debug, Clone, Default)]
143pub struct PreflightResult {
144 pub passed: bool,
145 pub summary: String,
146 pub checks: Vec<PreflightCheck>,
147 pub passed_count: usize,
148 pub failed_count: usize,
149 pub warning_count: usize,
150 pub total_score: i32,
151 pub can_continue: bool,
152}
153
154#[derive(Debug, Clone, Default)]
155pub struct HardwareState {
156 pub gpu: GPUInfo,
157 pub system: SystemInfo,
158 pub status: String,
159 pub progress: f32,
160}
161
162#[derive(Debug, Clone, Default)]
163pub struct InstallStatus {
164 pub progress: f32,
165 pub message: String,
166 pub completed: bool,
167}
168
169pub fn default_components() -> Vec<Component> {
170 use Category::*;
171
172 vec![
173 Component {
175 id: "permanent-env".into(),
176 name: "Permanent ROCm Env".into(),
177 description: "Unified permanent ROCm environment (Python 3.12, \
178 device-filtered — iGPUs excluded)"
179 .into(),
180 script: String::new(), category: Environment,
182 required: false,
183 selected: true,
184 installed: false,
185 progress: 0.0,
186 estimate: "1-2 min".into(),
187 needs_sudo: true,
188 experimental: false,
189 note: Some(
190 "Auto-sourced into bash/zsh/fish on every shell launch when \
191 installed via the Global option (iGPU filtered, ROCm env always \
192 active). Isolated/named envs are written but NOT auto-sourced \
193 into the global shell — source them manually for that env."
194 .into(),
195 ),
196 },
197 Component {
199 id: "rocm".into(),
200 name: "ROCm Platform".into(),
201 description: "AMD ROCm GPU computing platform".into(),
202 script: String::new(), category: Foundation,
204 required: true,
205 selected: true,
206 installed: false,
207 progress: 0.0,
208 estimate: "30-45 min".into(),
209 needs_sudo: true,
210 experimental: false,
211 note: None,
212 },
213 Component {
214 id: "pytorch".into(),
215 name: "PyTorch with ROCm".into(),
216 description: "PyTorch optimized for AMD GPUs".into(),
217 script: String::new(), category: Foundation,
219 required: true,
220 selected: true,
221 installed: false,
222 progress: 0.0,
223 estimate: "10-15 min".into(),
224 needs_sudo: false,
229 experimental: false,
230 note: None,
231 },
232 Component {
233 id: "triton".into(),
234 name: "Triton".into(),
235 description: "Compiler for parallel programming".into(),
236 script: String::new(), category: Foundation,
238 required: true,
239 selected: true,
240 installed: false,
241 progress: 0.0,
242 estimate: "5-10 min".into(),
243 needs_sudo: false,
245 experimental: false,
246 note: None,
247 },
248 Component {
249 id: "mpi4py".into(),
250 name: "MPI4Py".into(),
251 description: "MPI bindings for Python".into(),
252 script: String::new(), category: Foundation,
254 required: true,
255 selected: true,
256 installed: false,
257 progress: 0.0,
258 estimate: "3-5 min".into(),
259 needs_sudo: false,
262 experimental: false,
263 note: None,
264 },
265 Component {
266 id: "deepspeed".into(),
267 name: "DeepSpeed".into(),
268 description: "Deep learning optimization library".into(),
269 script: String::new(), category: Foundation,
271 required: true,
272 selected: true,
273 installed: false,
274 progress: 0.0,
275 estimate: "8-12 min".into(),
276 needs_sudo: false,
278 experimental: false,
279 note: None,
280 },
281 Component {
282 id: "rocm-smi".into(),
283 name: "ROCm SMI".into(),
284 description: "System monitoring for AMD GPUs".into(),
285 script: String::new(), category: Foundation,
287 required: false,
288 selected: true,
289 installed: false,
290 progress: 0.0,
291 estimate: "2-3 min".into(),
292 needs_sudo: true,
293 experimental: false,
294 note: None,
295 },
296 Component {
297 id: "pytorch-profiler".into(),
298 name: "PyTorch Profiler".into(),
299 description: "Performance analysis for PyTorch".into(),
300 script: String::new(), category: Foundation,
302 required: false,
303 selected: false,
304 installed: false,
305 progress: 0.0,
306 estimate: "3-5 min".into(),
307 needs_sudo: false,
309 experimental: false,
310 note: None,
311 },
312 Component {
317 id: "flash-attn-triton".into(),
318 name: "Flash Attention (Triton)".into(),
319 description: "Flash Attention 2 via the ROCm Triton backend".into(),
320 script: String::new(), category: Core,
322 required: false,
323 selected: false,
324 installed: false,
325 progress: 0.0,
326 estimate: "20-30 min".into(),
327 needs_sudo: false,
329 experimental: false,
330 note: Some(
331 "Full forward + backward pass — the only Flash Attention backend \
332 with a backward pass on RDNA3, so it is the choice for \
333 training/backprop (CDNA + RDNA, fp16/bf16/fp32; causal, MQA/GQA, \
334 rotary, ALiBi, paged, FP8). Mutually exclusive with Flash Attention \
335 (CK): both install the identical flash_attn package, so installing \
336 this replaces CK (the active backend is tracked by the \
337 ~/.mlstack/flash-attention/.backend marker). Source: ROCm/flash-attention \
338 Triton backend."
339 .to_string(),
340 ),
341 },
342 Component {
343 id: "flash-attn-ck".into(),
344 name: "Flash Attention (CK)".into(),
345 description: "Flash Attention 2 via the ROCm composable-kernel backend".into(),
346 script: String::new(), category: Core,
348 required: false,
349 selected: false,
350 installed: false,
351 progress: 0.0,
352 estimate: "20-30 min".into(),
353 needs_sudo: false,
355 experimental: true,
356 note: Some(
357 "EXPERIMENTAL — RDNA3 forward-pass only. The composable-kernel \
358 backward pass is not implemented on RDNA3 \
359 (ROCm/composable_kernel#1434). Inference, generation, and forward \
360 attention are accelerated; training/backprop through this backend \
361 falls back to unfused PyTorch SDPA (higher VRAM, slower). RDNA4 \
362 gains backward with deterministic=False. Mutually exclusive with \
363 the Triton backend — installing this replaces it. \
364 Source: ROCm/flash-attention CK backend."
365 .to_string(),
366 ),
367 },
368 Component {
369 id: "migraphx".into(),
370 name: "MIGraphX".into(),
371 description: "AMD graph inference engine".into(),
372 script: String::new(), category: Core,
374 required: false,
375 selected: false,
376 installed: false,
377 progress: 0.0,
378 estimate: "10-15 min".into(),
379 needs_sudo: false,
381 experimental: false,
382 note: None,
383 },
384 Component {
385 id: "migraphx-python".into(),
394 name: "MIGraphX Python".into(),
395 description: "AMDMIGraphX Python bindings (source build)".into(),
396 script: String::new(), category: Core,
398 required: false,
399 selected: false,
400 installed: false,
401 progress: 0.0,
402 estimate: "15-25 min".into(),
403 needs_sudo: false,
405 experimental: true,
406 note: Some(
407 "Standalone AMDMIGraphX Python bindings built from source \
408 (MLSTACK_MIGRAPHX_BUILD_PYTHON=1). The C++ core + onnxruntime \
409 MIGraphX EP already cover ONNX inference, so these bindings are \
410 only needed for direct Python migraphx API access. Source: \
411 ROCm/AMDMIGraphX."
412 .to_string(),
413 ),
414 },
415 Component {
416 id: "llama-cpp".into(),
417 name: "Rusty Llama (llama.cpp)".into(),
418 description: "Rusty Llama — llama.cpp fork with HIP/ROCm GPU acceleration".into(),
419 script: String::new(), category: Core,
421 required: false,
422 selected: false,
423 installed: false,
424 progress: 0.0,
425 estimate: "10-15 min".into(),
426 needs_sudo: false,
428 experimental: false,
429 note: None,
430 },
431 Component {
432 id: "megatron".into(),
433 name: "Megatron-LM".into(),
434 description: "Large-scale training framework".into(),
435 script: String::new(), category: Core,
437 required: false,
438 selected: false,
439 installed: false,
440 progress: 0.0,
441 estimate: "25-40 min".into(),
442 needs_sudo: false,
445 experimental: false,
446 note: None,
447 },
448 Component {
449 id: "aiter".into(),
450 name: "AITER".into(),
451 description: "AMD AITER optimization tooling".into(),
452 script: String::new(), category: Core,
454 required: false,
455 selected: false,
456 installed: false,
457 progress: 0.0,
458 estimate: "10-20 min".into(),
459 needs_sudo: false,
461 experimental: false,
462 note: None,
463 },
464 Component {
466 id: "vllm".into(),
467 name: "vLLM".into(),
468 description: "High-throughput inference engine".into(),
469 script: String::new(), category: Extension,
471 required: false,
472 selected: false,
473 installed: false,
474 progress: 0.0,
475 estimate: "15-25 min".into(),
476 needs_sudo: false,
478 experimental: false,
479 note: None,
480 },
481 Component {
482 id: "onnx".into(),
483 name: "ONNX Runtime".into(),
484 description: "Cross-platform inference accelerator".into(),
485 script: String::new(), category: Extension,
487 required: false,
488 selected: false,
489 installed: false,
490 progress: 0.0,
491 estimate: "2-5 min".into(),
492 needs_sudo: false,
493 experimental: false,
494 note: None,
495 },
496 Component {
497 id: "bitsandbytes".into(),
498 name: "BITSANDBYTES".into(),
499 description: "Efficient quantization for deep learning".into(),
500 script: String::new(), category: Extension,
502 required: false,
503 selected: false,
504 installed: false,
505 progress: 0.0,
506 estimate: "3-5 min".into(),
507 needs_sudo: false,
509 experimental: false,
510 note: None,
511 },
512 Component {
513 id: "wandb".into(),
514 name: "Weights & Biases".into(),
515 description: "Experiment tracking and visualization".into(),
516 script: String::new(), category: Extension,
518 required: false,
519 selected: false,
520 installed: false,
521 progress: 0.0,
522 estimate: "5-8 min".into(),
523 needs_sudo: false,
525 experimental: false,
526 note: None,
527 },
528 Component {
529 id: "fastvideo".into(),
530 name: "FastVideo".into(),
531 description: "Video generation framework with ROCm gfx11 optimizations".into(),
532 script: String::new(), category: Extension,
534 required: false,
535 selected: false,
536 installed: false,
537 progress: 0.0,
538 estimate: "10-20 min".into(),
539 needs_sudo: false,
540 experimental: false,
541 note: None,
542 },
543 Component {
545 id: "vllm-studio".into(),
546 name: "vLLM Studio".into(),
547 description: "Model lifecycle manager for vLLM/SGLang".into(),
548 script: String::new(), category: UiUx,
550 required: false,
551 selected: false,
552 installed: false,
553 progress: 0.0,
554 estimate: "10-20 min".into(),
555 needs_sudo: false,
556 experimental: false,
557 note: None,
558 },
559 Component {
560 id: "comfyui".into(),
561 name: "ComfyUI".into(),
562 description: "Node-based AI image generation UI with ROCm support".into(),
563 script: String::new(), category: UiUx,
565 required: false,
566 selected: false,
567 installed: false,
568 progress: 0.0,
569 estimate: "5-10 min".into(),
570 needs_sudo: false,
571 experimental: false,
572 note: None,
573 },
574 Component {
575 id: "textgen".into(),
576 name: "text-generation-webui".into(),
577 description: "LLM chat/inference web UI with ROCm support (oobabooga)".into(),
578 script: String::new(), category: UiUx,
580 required: false,
581 selected: false,
582 installed: false,
583 progress: 0.0,
584 estimate: "10-20 min".into(),
585 needs_sudo: false,
586 experimental: false,
587 note: None,
588 },
589 Component {
591 id: "verify-basic".into(),
592 name: "Verify Installation".into(),
593 description: "Basic verification".into(),
594 script: String::new(), category: Maintenance,
596 required: false,
597 selected: false,
598 installed: false,
599 progress: 0.0,
600 estimate: "2-5 min".into(),
601 needs_sudo: true,
602 experimental: false,
603 note: None,
604 },
605 Component {
606 id: "verify-enhanced".into(),
607 name: "Enhanced Verify Installation".into(),
608 description: "Advanced verification".into(),
609 script: String::new(), category: Maintenance,
611 required: false,
612 selected: false,
613 installed: false,
614 progress: 0.0,
615 estimate: "5-10 min".into(),
616 needs_sudo: true,
617 experimental: false,
618 note: None,
619 },
620 Component {
621 id: "verify-build".into(),
622 name: "Verify and Build".into(),
623 description: "Verify + build components".into(),
624 script: String::new(), category: Maintenance,
626 required: false,
627 selected: false,
628 installed: false,
629 progress: 0.0,
630 estimate: "10-15 min".into(),
631 needs_sudo: true,
632 experimental: false,
633 note: None,
634 },
635 Component {
636 id: "repair-stack".into(),
637 name: "Repair ML Stack".into(),
638 description: "Repair ML Stack installation".into(),
639 script: String::new(), category: Maintenance,
641 required: false,
642 selected: false,
643 installed: false,
644 progress: 0.0,
645 estimate: "5-10 min".into(),
646 needs_sudo: true,
647 experimental: false,
648 note: None,
649 },
650 Component {
651 id: "rccl-repair".into(),
652 name: "Repair RCCL Multi-GPU".into(),
653 description: "Probe and repair ROCm RCCL multi-GPU collectives".into(),
654 script: String::new(), category: Maintenance,
656 required: false,
657 selected: false,
658 installed: false,
659 progress: 0.0,
660 estimate: "30-90 min".into(),
661 needs_sudo: false,
662 experimental: false,
663 note: None,
664 },
665 Component {
667 id: "mlperf-inference".into(),
668 name: "MLPerf Inference".into(),
669 description: "MLPerf benchmark suite for inference performance".into(),
670 script: String::new(), category: Performance,
672 required: false,
673 selected: false,
674 installed: false,
675 progress: 0.0,
676 estimate: "30-60 min".into(),
677 needs_sudo: false,
678 experimental: false,
679 note: None,
680 },
681 Component {
682 id: "rocm-benchmarks".into(),
683 name: "ROCm Benchmarks".into(),
684 description: "ROCm-specific performance benchmarks".into(),
685 script: String::new(), category: Performance,
687 required: false,
688 selected: false,
689 installed: false,
690 progress: 0.0,
691 estimate: "20-40 min".into(),
692 needs_sudo: false,
693 experimental: false,
694 note: None,
695 },
696 Component {
697 id: "gpu-memory-bandwidth".into(),
698 name: "GPU Memory Bandwidth".into(),
699 description: "Memory bandwidth performance testing".into(),
700 script: String::new(), category: Performance,
702 required: false,
703 selected: false,
704 installed: false,
705 progress: 0.0,
706 estimate: "10-15 min".into(),
707 needs_sudo: false,
708 experimental: false,
709 note: None,
710 },
711 Component {
712 id: "rocm-smi-bench".into(),
713 name: "ROCm SMI Benchmarks".into(),
714 description: "ROCm SMI performance monitoring".into(),
715 script: String::new(), category: Performance,
717 required: false,
718 selected: false,
719 installed: false,
720 progress: 0.0,
721 estimate: "15-25 min".into(),
722 needs_sudo: false,
723 experimental: false,
724 note: None,
725 },
726 Component {
727 id: "vllm-performance".into(),
728 name: "vLLM Performance".into(),
729 description: "High-throughput vLLM inference benchmark".into(),
730 script: String::new(), category: Performance,
732 required: false,
733 selected: false,
734 installed: false,
735 progress: 0.0,
736 estimate: "15-25 min".into(),
737 needs_sudo: false,
738 experimental: false,
739 note: None,
740 },
741 Component {
742 id: "deepspeed-performance".into(),
743 name: "DeepSpeed Performance".into(),
744 description: "DeepSpeed ZeRO optimization throughput benchmark".into(),
745 script: String::new(), category: Performance,
747 required: false,
748 selected: false,
749 installed: false,
750 progress: 0.0,
751 estimate: "10-20 min".into(),
752 needs_sudo: false,
753 experimental: false,
754 note: None,
755 },
756 Component {
757 id: "megatron-performance".into(),
758 name: "Megatron-LM Performance".into(),
759 description: "Megatron-LM import and throughput benchmark".into(),
760 script: String::new(), category: Performance,
762 required: false,
763 selected: false,
764 installed: false,
765 progress: 0.0,
766 estimate: "10-20 min".into(),
767 needs_sudo: false,
768 experimental: false,
769 note: None,
770 },
771 Component {
772 id: "onnx-performance".into(),
773 name: "ONNX Runtime Performance".into(),
774 description: "ONNX Runtime inference benchmark".into(),
775 script: String::new(), category: Performance,
777 required: false,
778 selected: false,
779 installed: false,
780 progress: 0.0,
781 estimate: "1-2 min".into(),
782 needs_sudo: false,
783 experimental: false,
784 note: None,
785 },
786 Component {
787 id: "flash-attention-ck-performance".into(),
788 name: "Flash Attention (CK) Performance".into(),
789 description: "Genuine-model forward throughput via the CK backend".into(),
790 script: String::new(), category: Performance,
792 required: false,
793 selected: false,
794 installed: false,
795 progress: 0.0,
796 estimate: "1-2 min".into(),
797 needs_sudo: false,
798 experimental: true,
799 note: Some(
800 "RDNA3 forward-only: measures inference throughput of a genuine \
801 Llama-style decoder through the composable-kernel flash_attn_func."
802 .into(),
803 ),
804 },
805 Component {
806 id: "rusty-llama-performance".into(),
807 name: "Rusty Llama Performance".into(),
808 description: "Rusty Llama (llama.cpp) inference benchmark".into(),
809 script: String::new(), category: Performance,
811 required: false,
812 selected: false,
813 installed: false,
814 progress: 0.0,
815 estimate: "1-2 min".into(),
816 needs_sudo: false,
817 experimental: false,
818 note: Some(
819 "Runs llama-bench against the installed Rusty Llama binary — \
820 downloads a small verification model if needed, runs NO installs."
821 .into(),
822 ),
823 },
824 Component {
825 id: "all-benchmarks".into(),
826 name: "Full Suite Benchmark".into(),
827 description: "Run all post-installation performance tests".into(),
828 script: String::new(), category: Performance,
830 required: false,
831 selected: false,
832 installed: false,
833 progress: 0.0,
834 estimate: "45-90 min".into(),
835 needs_sudo: false,
836 experimental: false,
837 note: None,
838 },
839 ]
840}
841
842#[cfg(test)]
843mod tests {
844 use super::*;
845
846 #[test]
847 fn onnx_performance_is_exposed_as_frontend_benchmark_option() {
848 let component = default_components()
849 .into_iter()
850 .find(|component| component.id == "onnx-performance")
851 .expect("ONNX benchmark should be exposed in component list");
852 assert_eq!(component.category, Category::Performance);
853 assert_eq!(component.name, "ONNX Runtime Performance");
854 }
855}