qualia_core_db/inference/
inference_modes.rs1use std::sync::atomic::{AtomicU8, Ordering};
18
19#[repr(u8)]
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22pub enum InferenceMode {
23 Portable = 0,
25 CudaTc = 1,
27 QuantGraph = 2,
29 FastVerify = 3,
31}
32
33impl InferenceMode {
34 pub const ALL: [InferenceMode; 4] = [
35 InferenceMode::Portable,
36 InferenceMode::CudaTc,
37 InferenceMode::QuantGraph,
38 InferenceMode::FastVerify,
39 ];
40
41 pub fn as_str(self) -> &'static str {
42 match self {
43 InferenceMode::Portable => "portable",
44 InferenceMode::CudaTc => "cuda",
45 InferenceMode::QuantGraph => "quant-graph",
46 InferenceMode::FastVerify => "fast-verify",
47 }
48 }
49
50 pub fn parse(s: &str) -> Option<Self> {
51 match s.trim().to_ascii_lowercase().as_str() {
52 "portable" | "wgpu" | "default" | "0" => Some(Self::Portable),
53 "cuda" | "cuda-tc" | "cudatc" | "tc" | "1" => Some(Self::CudaTc),
54 "quant-graph" | "quant_graph" | "graph" | "hybrid" | "neuro-symbolic" | "2" => {
55 Some(Self::QuantGraph)
56 }
57 "fast-verify" | "fast_verify" | "fastverify" | "ollama-like" | "post-verify"
58 | "verify" | "3" => Some(Self::FastVerify),
59 _ => None,
60 }
61 }
62
63 pub fn description(self) -> &'static str {
64 match self {
65 InferenceMode::Portable => {
66 "wgpu resident decode/prefill (DX12/Vulkan/Metal); Q4_K SoA INT4 coop GEMV; INT8 KV default; no second DirectML device unless QUALIA_DIRECTML=1"
67 }
68 InferenceMode::CudaTc => {
69 "CUDA-capable lane: resident wgpu decode by default (coherent); Q4_K SoA device GEMV when applicable; dense densify+TC decode GEMV is opt-in QUALIA_LLM_CUDA_TC_DECODE=1 (lab — was incoherent when default-on)"
70 }
71 InferenceMode::QuantGraph => {
72 "INT4 (Q4_K SoA) front-end — A2000 bandwidth sweet spot — + graph/Webizen verify to recover quality; INT2 experimental with graph net"
73 }
74 InferenceMode::FastVerify => {
75 "Ollama-like full-speed decode (no mid-token Sentinel) → post-turn quant-graph + CML/HTML self-heal before turn finalises"
76 }
77 }
78 }
79}
80
81static MODE: AtomicU8 = AtomicU8::new(InferenceMode::Portable as u8);
82
83#[inline]
84fn atomic_inference_mode() -> InferenceMode {
85 match MODE.load(Ordering::Relaxed) {
86 1 => InferenceMode::CudaTc,
87 2 => InferenceMode::QuantGraph,
88 3 => InferenceMode::FastVerify,
89 _ => InferenceMode::Portable,
90 }
91}
92
93pub fn active_inference_mode() -> InferenceMode {
98 if let Ok(s) = std::env::var("QUALIA_INFERENCE_MODE") {
100 if let Some(m) = InferenceMode::parse(&s) {
101 MODE.store(m as u8, Ordering::Relaxed);
102 return m;
103 }
104 }
105 atomic_inference_mode()
106}
107
108pub fn set_inference_mode(mode: InferenceMode) {
110 MODE.store(mode as u8, Ordering::Relaxed);
111 apply_mode_toggles(mode);
112 log::info!("LLM_MODE|active|{}|{}", mode.as_str(), mode.description());
113}
114
115pub fn apply_mode_toggles(mode: InferenceMode) {
117 #[cfg(not(target_arch = "wasm32"))]
118 {
119 use crate::llm_bench::{
120 set_coop_gemv, set_resident_decode, set_resident_prefill, set_resident_weights,
121 };
122 set_resident_decode(true);
124 set_resident_prefill(true);
125 set_resident_weights(true);
126 set_coop_gemv(true);
127 match mode {
128 InferenceMode::Portable => {
129 }
131 InferenceMode::CudaTc => {
132 crate::wgsl_forge::dispatch::ensure_cuda_runtime_path();
133 match std::env::var("QUALIA_LLM_CUDA_DECODE").ok().as_deref() {
138 Some("1") | Some("true") => {
139 crate::llm_bench::set_kv_int8(false);
145 std::env::set_var("QUALIA_LLM_KV_INT8", "0");
147 log::info!(
148 "LLM_MODE|cuda|resident_decode=on|cuda_mega_pass_fallback|f32_kv|device_sdpa|lab_path"
149 );
150 }
151 _ => {
152 log::info!(
156 "LLM_MODE|cuda|resident_decode=on|dense_tc_decode=off|use_q4k_soa_device_when_present"
157 );
158 }
159 }
160 }
161 InferenceMode::QuantGraph => {
162 let n = crate::quant_graph_grounding::seed_facts_from_bundled();
166 log::info!("LLM_MODE|quant-graph|facts_seeded|{n}");
167 }
168 InferenceMode::FastVerify => {
169 let n = crate::quant_graph_grounding::seed_facts_from_bundled();
171 log::info!("LLM_MODE|fast-verify|post_turn_only|facts_seeded|{n}");
172 }
173 }
174 }
175 let _ = mode;
176}
177
178#[inline]
180pub fn prefer_tensor_core_gemm() -> bool {
181 matches!(atomic_inference_mode(), InferenceMode::CudaTc)
182}
183
184#[inline]
187pub fn quant_graph_grounding_enabled() -> bool {
188 matches!(
189 active_inference_mode(),
190 InferenceMode::QuantGraph | InferenceMode::FastVerify
191 )
192}
193
194#[inline]
197pub fn sentinel_mid_decode_enabled() -> bool {
198 match std::env::var("QUALIA_SENTINEL_MID").ok().as_deref() {
200 Some("1") | Some("true") | Some("on") => return true,
201 Some("0") | Some("false") | Some("off") => return false,
202 _ => {}
203 }
204 !matches!(active_inference_mode(), InferenceMode::FastVerify)
205}
206
207#[inline]
209pub fn post_turn_verify_enabled() -> bool {
210 matches!(
211 active_inference_mode(),
212 InferenceMode::FastVerify | InferenceMode::QuantGraph
213 ) || matches!(
214 std::env::var("QUALIA_POST_VERIFY").ok().as_deref(),
215 Some("1") | Some("true") | Some("on")
216 )
217}
218
219#[inline]
221pub fn fast_verify_html_default() -> bool {
222 matches!(
223 std::env::var("QUALIA_RETURN_VERIFY_HTML").ok().as_deref(),
224 Some("1") | Some("true") | Some("on")
225 )
226}
227
228pub fn bootstrap_inference_mode() -> InferenceMode {
235 #[cfg(not(target_arch = "wasm32"))]
236 {
237 let _plan = crate::inference_path_selector::bootstrap_optimal_inference_path();
238 let _app = crate::application_profile::bootstrap_application_profile();
240 }
241 if matches!(
243 std::env::var("QUALIA_RIGHTS_MODE").ok().as_deref(),
244 Some("1") | Some("true") | Some("on")
245 ) {
246 if std::env::var("QUALIA_INFERENCE_MODE").is_err()
247 && std::env::var("QUALIA_APP_PROFILE").is_err()
248 {
249 set_inference_mode(InferenceMode::FastVerify);
250 }
251 log::info!("LLM_MODE|rights|fast-verify|post_turn_heal");
252 }
253 if std::env::var("QUALIA_INFERENCE_MODE").is_err()
256 && std::env::var("QUALIA_APP_PROFILE").is_err()
257 && std::env::var("QUALIA_RIGHTS_MODE").is_err()
258 {
259 set_inference_mode(InferenceMode::FastVerify);
260 log::info!("LLM_MODE|default|fast-verify|consumer_speed");
261 }
262 let m = active_inference_mode();
263 apply_mode_toggles(m);
264 m
265}
266
267#[inline]
269pub fn rights_mode_enabled() -> bool {
270 matches!(
271 std::env::var("QUALIA_RIGHTS_MODE").ok().as_deref(),
272 Some("1") | Some("true") | Some("on")
273 )
274}
275
276#[cfg(test)]
277mod tests {
278 use super::*;
279
280 #[test]
281 fn parse_mode_names() {
282 assert_eq!(
283 InferenceMode::parse("portable"),
284 Some(InferenceMode::Portable)
285 );
286 assert_eq!(InferenceMode::parse("CUDA"), Some(InferenceMode::CudaTc));
287 assert_eq!(
288 InferenceMode::parse("quant-graph"),
289 Some(InferenceMode::QuantGraph)
290 );
291 assert_eq!(
292 InferenceMode::parse("hybrid"),
293 Some(InferenceMode::QuantGraph)
294 );
295 assert_eq!(
296 InferenceMode::parse("fast-verify"),
297 Some(InferenceMode::FastVerify)
298 );
299 assert_eq!(
300 InferenceMode::parse("ollama-like"),
301 Some(InferenceMode::FastVerify)
302 );
303 assert!(InferenceMode::parse("nope").is_none());
304 }
305
306 #[test]
307 fn fast_verify_disables_mid_sentinel() {
308 if std::env::var("QUALIA_INFERENCE_MODE").is_ok()
309 || std::env::var("QUALIA_SENTINEL_MID").is_ok()
310 {
311 return;
312 }
313 set_inference_mode(InferenceMode::FastVerify);
314 assert!(!sentinel_mid_decode_enabled());
315 assert!(post_turn_verify_enabled());
316 set_inference_mode(InferenceMode::Portable);
317 assert!(sentinel_mid_decode_enabled());
318 }
319
320 #[test]
321 fn set_and_read_without_env() {
322 if std::env::var("QUALIA_INFERENCE_MODE").is_ok() {
324 return;
325 }
326 set_inference_mode(InferenceMode::CudaTc);
327 assert_eq!(active_inference_mode(), InferenceMode::CudaTc);
328 set_inference_mode(InferenceMode::Portable);
329 assert_eq!(active_inference_mode(), InferenceMode::Portable);
330 }
331
332 #[test]
333 #[serial_test::serial]
334 fn cold_env_publish_makes_hot_cuda_guard_zero_allocation() {
335 let previous = std::env::var("QUALIA_INFERENCE_MODE").ok();
336 std::env::set_var("QUALIA_INFERENCE_MODE", "cuda");
337 set_inference_mode(InferenceMode::Portable);
338 assert_eq!(active_inference_mode(), InferenceMode::CudaTc);
339 crate::specialized_libs::computational_geometry::allocation_counter::assert_zero_alloc(
340 "atomic_cuda_mode_guard",
341 || assert!(prefer_tensor_core_gemm()),
342 );
343 match previous {
344 Some(value) => {
345 std::env::set_var("QUALIA_INFERENCE_MODE", value);
346 let _ = active_inference_mode();
347 }
348 None => {
349 std::env::remove_var("QUALIA_INFERENCE_MODE");
350 set_inference_mode(InferenceMode::Portable);
351 }
352 }
353 }
354}