1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct EnvVarDoc {
27 pub name: &'static str,
29 pub group: &'static str,
31 pub summary: &'static str,
33}
34
35pub const CATALOG: &[EnvVarDoc] = &[
37 EnvVarDoc {
39 name: "RLX_DEVICE",
40 group: "device",
41 summary: "Default device hint for resolved runs (cpu, metal, mlx, cuda, gpu, …)",
42 },
43 EnvVarDoc {
44 name: "RLX_DEVICE_CHAIN",
45 group: "device",
46 summary: "Fallback order when a preferred device fails (e.g. cuda,gpu,cpu)",
47 },
48 EnvVarDoc {
49 name: "RLX_DEVICES",
50 group: "device",
51 summary: "Allow-list of devices for DevicePolicy::from_env",
52 },
53 EnvVarDoc {
54 name: "RLX_BENCHMARK_PICK",
55 group: "device",
56 summary: "Micro-benchmark N runs to pick the fastest device (needs inputs)",
57 },
58 EnvVarDoc {
60 name: "RLX_DISPATCH_REPORT",
61 group: "debug",
62 summary: "Print legalize/dispatch report during compile (1 = on)",
63 },
64 EnvVarDoc {
65 name: "RLX_DBG_CUSTOM",
66 group: "debug",
67 summary: "Log host custom-op staging (onnx.* dtype bridge) on GPU backends",
68 },
69 EnvVarDoc {
70 name: "RLX_VERBOSE",
71 group: "debug",
72 summary: "Extra runtime logging",
73 },
74 EnvVarDoc {
75 name: "RLX_ALLOW_THROTTLE",
76 group: "debug",
77 summary: "Skip thermal gate for one-off benches (prefer `just throttle`)",
78 },
79 EnvVarDoc {
81 name: "RLX_DISABLE_MPSGRAPH",
82 group: "metal",
83 summary: "Force Metal thunk path instead of MPSGraph regions",
84 },
85 EnvVarDoc {
86 name: "RLX_METAL_DEQUANT_GPU_DISABLE",
87 group: "metal",
88 summary: "Disable Metal GPU GGUF dequant (host / legacy path)",
89 },
90 EnvVarDoc {
91 name: "RLX_METAL_DEQUANT_MATMUL_LEGACY",
92 group: "metal",
93 summary: "Use pre-fused dequant+matmul path (materializes weights)",
94 },
95 EnvVarDoc {
97 name: "RLX_MLX_MODE",
98 group: "mlx",
99 summary: "eager | lazy | compiled execution mode",
100 },
101 EnvVarDoc {
102 name: "RLX_MLX_GGUF_HOST_FALLBACK",
103 group: "mlx",
104 summary: "Force host GGUF dequant on MLX",
105 },
106 EnvVarDoc {
107 name: "RLX_MLX_SDPA_REFERENCE",
108 group: "mlx",
109 summary: "Use reference SDPA composition for bisects",
110 },
111 EnvVarDoc {
113 name: "RLX_DISABLE_METAL_DEQUANT_GPU",
114 group: "gguf",
115 summary: "Alias family: opt out of Metal on-device GGUF dequant",
116 },
117 EnvVarDoc {
119 name: "RLX_WGPU_GDN_HOST",
120 group: "wgpu",
121 summary: "Force GatedDeltaNet host fallback on wgpu (skip WGSL)",
122 },
123 EnvVarDoc {
124 name: "RLX_ROCM_PINNED_IO",
125 group: "rocm",
126 summary: "Use pinned host I/O for ROCm graph exec (default on in graph mode)",
127 },
128 EnvVarDoc {
129 name: "RLX_INDEXING_FULL_ARENA",
130 group: "gpu",
131 summary: "Force full-arena mirror for indexing host-fallback (bisect; slow on discrete GPUs)",
132 },
133 EnvVarDoc {
134 name: "RLX_FFT_FAST",
135 group: "gpu",
136 summary: "Enable native on-chip GPU FFT when compiled (0 disables)",
137 },
138 EnvVarDoc {
139 name: "RLX_CUDA_CONV_FWD_HOST",
140 group: "cuda",
141 summary: "Force CUDA Conv2d forward through CPU host-fallback (bisect)",
142 },
143 EnvVarDoc {
144 name: "RLX_CUDA_CONV_BWD_CUDNN",
145 group: "cuda",
146 summary: "Allow cuDNN for grouped/degenerate Conv2d backward shapes",
147 },
148 EnvVarDoc {
149 name: "RLX_FAST_CONV",
150 group: "cpu",
151 summary: "CPU Conv2d im2col+BLAS path (default on; set 0 for scalar nested loops)",
152 },
153 EnvVarDoc {
154 name: "RLX_NO_IO_PEAKS_OUTPUT",
155 group: "compile",
156 summary: "Disable compile-time IO-gated peaks-only fusion",
157 },
158 EnvVarDoc {
160 name: "RLX_COREML_HOST_DEQUANT",
161 group: "coreml",
162 summary: "Force CoreML hybrid host dequant segments",
163 },
164];
165
166pub fn catalog_for_group(group: &str) -> Vec<&'static EnvVarDoc> {
168 if group.is_empty() {
169 return CATALOG.iter().collect();
170 }
171 CATALOG.iter().filter(|e| e.group == group).collect()
172}
173
174pub fn format_catalog(group: Option<&str>) -> String {
176 let entries = catalog_for_group(group.unwrap_or(""));
177 let mut out = String::from("# RLX environment catalog (curated)\n\n");
178 let mut cur = "";
179 for e in entries {
180 if e.group != cur {
181 cur = e.group;
182 out.push_str(&format!("## {cur}\n\n"));
183 }
184 out.push_str(&format!("- `{}` — {}\n", e.name, e.summary));
185 }
186 out.push_str(
187 "\nNot exhaustive — escape-hatch flags live in backend sources. \
188 Prefer CompileOptions when a setting changes compile semantics.\n",
189 );
190 out
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196
197 #[test]
198 fn catalog_nonempty_and_prefixed() {
199 assert!(!CATALOG.is_empty());
200 for e in CATALOG {
201 assert!(e.name.starts_with("RLX_"), "{}", e.name);
202 assert!(!e.group.is_empty());
203 assert!(!e.summary.is_empty());
204 }
205 }
206
207 #[test]
208 fn format_includes_device_group() {
209 let s = format_catalog(Some("device"));
210 assert!(s.contains("RLX_DEVICE"));
211 assert!(!s.contains("RLX_DISABLE_MPSGRAPH"));
212 }
213}