Skip to main content

qualia_core_db/q42/
execution_profile.rs

1//! P64 / Q42 **execution profile** — attested how to run a **native package at excellence**.
2//!
3//! QualiaDB is a human-centric multi-capability system. Inference packages are one toolchain
4//! lane. The profile exists so autonomous campaigns optimise **speed and sense** (and later
5//! grounding/rights), not so agents ship half-working “skeleton” products.
6//!
7//! ## On disk
8//! Sibling of a winner `.p64`: `{stem}.execution-profile.json`
9
10use serde::{Deserialize, Serialize};
11use std::path::{Path, PathBuf};
12
13/// Schema version for campaign tooling (bump when fields change meaning).
14pub const EXECUTION_PROFILE_VERSION: u32 = 1;
15
16/// File suffix: `model.f16.p64` → `model.f16.execution-profile.json` (stem-preserving).
17pub const EXECUTION_PROFILE_SUFFIX: &str = "execution-profile.json";
18
19/// Attested run recipe for a converted native weight package.
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
21pub struct ExecutionProfile {
22    pub version: u32,
23    /// ISO-ish stamp (unix ms) when this profile was written.
24    pub written_unix_ms: u64,
25    /// Source import path if known (GGUF/Safetensors); empty if measured from P64 only.
26    pub source_import: String,
27    /// Absolute or operator-local path to the winning `.p64`.
28    pub p64_path: String,
29    /// Optional `.q42` model-helper path.
30    #[serde(default)]
31    pub q42_helper_path: String,
32    /// Convert layout: `verbatim` | `f16` | `soa` | …
33    pub layout: String,
34    /// `portable` | `cuda` | `quant-graph` | `fast-verify`
35    pub inference_mode: String,
36    /// wgpu backend hint (`auto` | `vulkan` | `dx12` | …).
37    pub backend: String,
38    /// Runtime toggles applied or recommended for this package.
39    pub toggles: ExecutionToggles,
40    /// Measured evidence (honest; may be partial).
41    pub metrics: ExecutionMetrics,
42    /// Representation levers available or used (not all active at once).
43    pub representation: RepresentationNotes,
44    /// Human/agent notes — failures, next steps, human decisions needed.
45    #[serde(default)]
46    pub notes: Vec<String>,
47    /// Multi-objective scores (optional; fill as gates land).
48    #[serde(default)]
49    pub objectives: ObjectiveScores,
50}
51
52/// Runtime knobs that compose with InferenceMode (env-applied at load).
53#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
54pub struct ExecutionToggles {
55    /// W5a int8 KV cache (native; ~3.8× less KV BW when on).
56    pub kv_int8: bool,
57    /// Resident mega-pass decode when available.
58    pub resident_decode: bool,
59    /// Cooperative GEMV.
60    pub coop_gemv: bool,
61    /// FFN fusion in resident path.
62    pub ffn_fusion: bool,
63    /// Promote FFN weights to f16 in VRAM when measuring.
64    pub ffn_f16: bool,
65    /// Ternary (BitNet-class ~1.58b / ≈1.6 bit/weight) FFN path when container has it.
66    pub ternary_ffn: bool,
67}
68
69/// Measured numbers — never invent.
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
71pub struct ExecutionMetrics {
72    /// Decode-proxy tokens/s when measured.
73    pub decode_proxy_tok_s: Option<f64>,
74    /// Token budget used for that measurement.
75    pub decode_proxy_tokens: u32,
76    /// Package size on disk (bytes).
77    pub p64_bytes: u64,
78    /// Optional coherence flag from a later gate (null until implemented).
79    pub coherence_ok: Option<bool>,
80    /// Optional ΔPPL vs reference (null until calibrated).
81    pub delta_ppl: Option<f64>,
82}
83
84/// Documents which representation levers exist in the ecosystem (matrix, not a single format).
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
86pub struct RepresentationNotes {
87    /// Weight quant / layout family used for this package.
88    pub weight_path: String,
89    /// KV cache class recommended: `int8` | `f32` | `dict`.
90    pub kv_class: String,
91    /// BitNet ternary ~1.58b (code type 1158); FFN-only when present.
92    pub ternary_158_available: bool,
93    /// f16 expand layout was candidate or winner.
94    pub f16_layout: bool,
95    /// Q4_K SoA layout was candidate or winner.
96    pub soa_layout: bool,
97}
98
99/// Multi-objective matrix (incremental fill). Missing = not yet measured.
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
101pub struct ObjectiveScores {
102    /// A — throughput (tok/s class).
103    pub throughput: Option<f64>,
104    /// B — format/layout fitness (operator 0..1 or free note in metrics).
105    pub format_fitness: Option<f64>,
106    /// C — text/coherence / ΔPPL gate.
107    pub correctness: Option<f64>,
108    /// D — grounding / tools / graph (later).
109    pub grounding: Option<f64>,
110    /// E — rights / governance path exercised.
111    pub governance: Option<f64>,
112    /// F — resource (inverse memory pressure; later).
113    pub resource: Option<f64>,
114}
115
116impl ExecutionProfile {
117    pub fn path_for_p64(p64_path: &Path) -> PathBuf {
118        let parent = p64_path.parent().unwrap_or_else(|| Path::new("."));
119        let stem = p64_path
120            .file_stem()
121            .and_then(|s| s.to_str())
122            .unwrap_or("model");
123        parent.join(format!("{stem}.{EXECUTION_PROFILE_SUFFIX}"))
124    }
125
126    pub fn now_ms() -> u64 {
127        std::time::SystemTime::now()
128            .duration_since(std::time::UNIX_EPOCH)
129            .map(|d| d.as_millis() as u64)
130            .unwrap_or(0)
131    }
132
133    /// Write JSON beside the P64 (atomic-ish: write temp then rename when possible).
134    pub fn write_beside_p64(&self, p64_path: &Path) -> Result<PathBuf, String> {
135        let path = Self::path_for_p64(p64_path);
136        let json = serde_json::to_string_pretty(self).map_err(|e| format!("serialize: {e}"))?;
137        let tmp = path.with_extension("json.tmp");
138        std::fs::write(&tmp, json.as_bytes())
139            .map_err(|e| format!("write {}: {e}", tmp.display()))?;
140        std::fs::rename(&tmp, &path).or_else(|_| {
141            std::fs::write(&path, json.as_bytes())
142                .map_err(|e| format!("write {}: {e}", path.display()))
143        })?;
144        Ok(path)
145    }
146
147    pub fn load_beside_p64(p64_path: &Path) -> Result<Option<Self>, String> {
148        let path = Self::path_for_p64(p64_path);
149        if !path.is_file() {
150            return Ok(None);
151        }
152        let bytes = std::fs::read(&path).map_err(|e| format!("read {}: {e}", path.display()))?;
153        let p: Self =
154            serde_json::from_slice(&bytes).map_err(|e| format!("parse {}: {e}", path.display()))?;
155        Ok(Some(p))
156    }
157
158    /// Build a profile from an explore winner (minimal attested fields).
159    pub fn from_explore_winner(
160        source_import: &str,
161        p64_path: &Path,
162        layout: &str,
163        inference_mode: &str,
164        backend: &str,
165        tok_s: f64,
166        tokens: u32,
167        toggle_label: &str,
168    ) -> Self {
169        let p64_bytes = std::fs::metadata(p64_path).map(|m| m.len()).unwrap_or(0);
170        let ffn_f16 = toggle_label.contains("ffn_f16=on");
171        let layout_l = layout.to_ascii_lowercase();
172        let helper = crate::q42::model_helper::helper_path_for_p64(p64_path);
173        let q42_helper_path = if helper.is_file() {
174            helper.display().to_string()
175        } else {
176            String::new()
177        };
178
179        // Snapshot ambient toggles (best-effort; campaign may pin env). `llm_bench` only exists
180        // natively or under `wasm-llm`; the slim wasm profiles record the toggles as OFF.
181        #[cfg(any(not(target_arch = "wasm32"), feature = "wasm-llm"))]
182        let (kv_int8, resident_decode, coop_gemv, ffn_fusion, ternary_ffn) = (
183            crate::llm_bench::kv_int8_enabled(),
184            crate::llm_bench::resident_decode_enabled(),
185            crate::llm_bench::coop_gemv_enabled(),
186            crate::llm_bench::ffn_fusion_in_resident(),
187            crate::llm_bench::ternary_ffn_enabled(),
188        );
189        #[cfg(all(target_arch = "wasm32", not(feature = "wasm-llm")))]
190        let (kv_int8, resident_decode, coop_gemv, ffn_fusion, ternary_ffn) =
191            (false, false, false, false, false);
192
193        Self {
194            version: EXECUTION_PROFILE_VERSION,
195            written_unix_ms: Self::now_ms(),
196            source_import: source_import.to_string(),
197            p64_path: p64_path.display().to_string(),
198            q42_helper_path,
199            layout: layout.to_string(),
200            inference_mode: inference_mode.to_string(),
201            backend: backend.to_string(),
202            toggles: ExecutionToggles {
203                kv_int8,
204                resident_decode,
205                coop_gemv,
206                ffn_fusion,
207                ffn_f16,
208                ternary_ffn,
209            },
210            metrics: ExecutionMetrics {
211                decode_proxy_tok_s: Some(tok_s),
212                decode_proxy_tokens: tokens,
213                p64_bytes,
214                coherence_ok: None,
215                delta_ppl: None,
216            },
217            representation: RepresentationNotes {
218                weight_path: layout.to_string(),
219                kv_class: if kv_int8 { "int8".into() } else { "f32".into() },
220                ternary_158_available: false, // filled true when convert emits ternary FFN
221                f16_layout: layout_l.contains("f16"),
222                soa_layout: layout_l.contains("soa"),
223            },
224            notes: vec![
225                "Target: competitive native package (layout×mode×toggles) with coherent decode."
226                    .into(),
227                "BitNet ternary ~1.58b (≈1.6 bits/weight, type 1158) is an FFN compression lever when present."
228                    .into(),
229                format!("explore toggle label: {toggle_label}"),
230            ],
231            objectives: ObjectiveScores {
232                throughput: Some(tok_s),
233                format_fitness: None,
234                correctness: None,
235                grounding: None,
236                governance: None,
237                resource: None,
238            },
239        }
240    }
241
242    /// Env lines a campaign / operator can apply before load (PowerShell-friendly comments separate).
243    pub fn apply_env_script_ps1(&self) -> String {
244        let mut s = String::new();
245        s.push_str("# Qualia execution profile — apply before llm load / decode-proxy\n");
246        s.push_str(&format!(
247            "$env:QUALIA_INFERENCE_MODE='{}'\n",
248            self.inference_mode
249        ));
250        if self.backend != "auto" && !self.backend.is_empty() {
251            s.push_str(&format!("$env:QUALIA_WGPU_BACKEND='{}'\n", self.backend));
252        }
253        s.push_str(&format!(
254            "$env:QUALIA_LLM_KV_INT8='{}'\n",
255            if self.toggles.kv_int8 { "1" } else { "0" }
256        ));
257        s.push_str(&format!(
258            "$env:QUALIA_LLM_FFN_F16='{}'\n",
259            if self.toggles.ffn_f16 { "1" } else { "0" }
260        ));
261        s.push_str(&format!(
262            "$env:QUALIA_LLM_FFN_FUSION='{}'\n",
263            if self.toggles.ffn_fusion { "1" } else { "0" }
264        ));
265        s
266    }
267}
268
269#[cfg(test)]
270mod tests {
271    use super::*;
272    use std::io::Write;
273
274    #[test]
275    fn round_trip_beside_p64() {
276        let dir = std::env::temp_dir().join(format!("qualia-exec-profile-{}", std::process::id()));
277        let _ = std::fs::create_dir_all(&dir);
278        let p64 = dir.join("toy.p64");
279        {
280            let mut f = std::fs::File::create(&p64).unwrap();
281            f.write_all(b"p64\0toy").unwrap();
282        }
283        let mut prof = ExecutionProfile::from_explore_winner(
284            "toy.gguf", &p64, "f16", "portable", "auto", 12.5, 16, "baseline",
285        );
286        prof.representation.ternary_158_available = true;
287        let written = prof.write_beside_p64(&p64).expect("write");
288        assert!(written.is_file());
289        let loaded = ExecutionProfile::load_beside_p64(&p64)
290            .expect("load")
291            .expect("some");
292        assert_eq!(loaded.layout, "f16");
293        assert_eq!(loaded.metrics.decode_proxy_tok_s, Some(12.5));
294        assert!(loaded.representation.ternary_158_available);
295        let _ = std::fs::remove_dir_all(&dir);
296    }
297}