1use memra_gguf::config::JsonObj;
51use std::collections::BTreeMap;
52
53pub const EP_MAP_ENV: &str = "MEMRA_EP_MAP";
56pub const EP_MAP_ENV_GLM5: &str = "MEMRA_GLM5_EP_MAP";
59
60pub fn resolve_ep_map_env(
68 general: Option<String>,
69 glm5_alias: Option<String>,
70) -> Result<Option<(&'static str, String)>, String> {
71 match (general, glm5_alias) {
72 (Some(g), Some(a)) if g != a => Err(format!(
73 "{EP_MAP_ENV}={g:?} and {EP_MAP_ENV_GLM5}={a:?} disagree — the alias and the \
74 general flag must name the SAME map (unset one; refused rather than \
75 silently picking a precedence winner)"
76 )),
77 (Some(g), _) => Ok(Some((EP_MAP_ENV, g))),
78 (None, Some(a)) => Ok(Some((EP_MAP_ENV_GLM5, a))),
79 (None, None) => Ok(None),
80 }
81}
82
83pub fn ep_map_env() -> Result<Option<(&'static str, String)>, String> {
85 resolve_ep_map_env(
86 std::env::var(EP_MAP_ENV).ok(),
87 std::env::var(EP_MAP_ENV_GLM5).ok(),
88 )
89}
90
91#[derive(Clone, Debug, PartialEq, Eq)]
93pub struct EpMap {
94 pub n_experts: usize,
95 pub ranks: usize,
96 pub entry_rank: usize,
99 pub layers: BTreeMap<usize, Vec<u8>>,
101}
102
103fn raw_usize(obj: &JsonObj, key: &str) -> Result<usize, String> {
104 let v = obj
105 .raw(key)
106 .ok_or(format!("ep-map: missing required field {key:?}"))?
107 .trim();
108 v.parse::<usize>()
109 .map_err(|_| format!("ep-map: field {key:?} = {v:?} is not an unsigned integer"))
110}
111
112fn split_objects(raw: &str) -> Result<Vec<&str>, String> {
116 let b = raw.as_bytes();
117 let mut out = Vec::new();
118 let mut depth = 0usize;
119 let mut start = None;
120 let mut in_str = false;
121 let mut escaped = false;
122 for (i, &c) in b.iter().enumerate() {
123 if in_str {
124 if escaped {
125 escaped = false;
126 } else if c == b'\\' {
127 escaped = true;
128 } else if c == b'"' {
129 in_str = false;
130 }
131 continue;
132 }
133 match c {
134 b'"' => in_str = true,
135 b'{' => {
136 if depth == 0 {
137 start = Some(i);
138 }
139 depth += 1;
140 }
141 b'}' => {
142 depth = depth
143 .checked_sub(1)
144 .ok_or("ep-map: unbalanced braces in layers array")?;
145 if depth == 0 {
146 let s = start.take().ok_or("ep-map: object end without start")?;
147 out.push(&raw[s..=i]);
148 }
149 }
150 _ => {}
151 }
152 }
153 if depth != 0 || in_str {
154 return Err("ep-map: layers array ends inside an object or string".into());
155 }
156 Ok(out)
157}
158
159impl EpMap {
160 pub fn even_owners(n_experts: usize, ranks: usize) -> Vec<u8> {
164 let per = n_experts / ranks;
165 (0..n_experts).map(|ex| (ex / per) as u8).collect()
166 }
167
168 pub fn parse(text: &str) -> Result<EpMap, String> {
171 let obj = JsonObj::parse(text);
172 match obj.string("format") {
173 Some(f) if f == "memra-ep-map-v1" => {}
174 Some(f) => {
175 return Err(format!(
176 "ep-map: format {f:?} is not \"memra-ep-map-v1\" (fail-closed: one \
177 frozen format, no silent best-effort read)"
178 ));
179 }
180 None => {
181 return Err("ep-map: missing \"format\" field (not a memra-ep-map-v1 \
182 document)"
183 .into());
184 }
185 }
186 let ranks = raw_usize(&obj, "ranks")?;
187 let n_experts = raw_usize(&obj, "expert_count")?;
188 let entry_rank = raw_usize(&obj, "entry_rank")?;
189 if n_experts == 0 || ranks < 2 {
190 return Err(format!(
191 "ep-map: expert_count={n_experts} ranks={ranks} is not a partitionable \
192 geometry"
193 ));
194 }
195 if entry_rank >= ranks {
196 return Err(format!(
197 "ep-map: entry_rank {entry_rank} outside the {ranks}-rank map"
198 ));
199 }
200 let layers_raw = obj
201 .raw("layers")
202 .ok_or("ep-map: missing \"layers\" array")?;
203 let mut layers: BTreeMap<usize, Vec<u8>> = BTreeMap::new();
204 for layer_obj in split_objects(layers_raw)? {
205 let lo = JsonObj::parse(layer_obj);
206 let layer = raw_usize(&lo, "layer")?;
207 let assignment = lo
208 .u32_array("assignment")
209 .ok_or(format!("ep-map: layer {layer} is missing \"assignment\""))?;
210 if assignment.len() != n_experts {
211 return Err(format!(
212 "ep-map: layer {layer} assignment carries {} entries, the map \
213 declares expert_count={n_experts}",
214 assignment.len()
215 ));
216 }
217 if let Some(bad) = assignment.iter().find(|&&r| (r as usize) >= ranks) {
218 return Err(format!(
219 "ep-map: layer {layer} assigns rank {bad} >= ranks {ranks}"
220 ));
221 }
222 for r in 0..ranks {
223 if !assignment.iter().any(|&a| a as usize == r) {
224 return Err(format!(
225 "ep-map: layer {layer} leaves rank {r} with ZERO experts \
226 (refused: an empty rank slab is an unmeasured degenerate arm)"
227 ));
228 }
229 }
230 let owners: Vec<u8> = assignment.iter().map(|&r| r as u8).collect();
231 if layers.insert(layer, owners).is_some() {
232 return Err(format!("ep-map: duplicate row for layer {layer}"));
233 }
234 }
235 if layers.is_empty() {
236 return Err("ep-map: empty \"layers\" array (fail-closed: an empty map \
237 places nothing)"
238 .into());
239 }
240 Ok(EpMap {
241 n_experts,
242 ranks,
243 entry_rank,
244 layers,
245 })
246 }
247
248 pub fn render(&self) -> String {
253 let mut out = String::from("{\n");
254 out.push_str(&format!(" \"entry_rank\": {},\n", self.entry_rank));
255 out.push_str(&format!(" \"expert_count\": {},\n", self.n_experts));
256 out.push_str(" \"format\": \"memra-ep-map-v1\",\n");
257 out.push_str(" \"layers\": [\n");
258 let rows: Vec<String> = self
259 .layers
260 .iter()
261 .map(|(layer, owners)| {
262 let a: Vec<String> = owners.iter().map(|r| r.to_string()).collect();
263 format!(
264 " {{\"assignment\": [{}], \"layer\": {layer}}}",
265 a.join(", ")
266 )
267 })
268 .collect();
269 out.push_str(&rows.join(",\n"));
270 out.push_str("\n ],\n");
271 out.push_str(&format!(" \"ranks\": {}\n", self.ranks));
272 out.push_str("}\n");
273 out
274 }
275
276 pub fn validate_layer_cover(&self, ep_layers: &[usize]) -> Result<(), String> {
281 for il in ep_layers {
282 if !self.layers.contains_key(il) {
283 return Err(format!(
284 "ep-map: EP-armed MoE layer {il} has no map row (fail-closed: a missing \
285 row must never silently fall back to the even split)"
286 ));
287 }
288 }
289 for il in self.layers.keys() {
290 if !ep_layers.contains(il) {
291 return Err(format!(
292 "ep-map: map row for layer {il} does not match any EP-armed MoE layer of \
293 this load (a map minted for a different arrangement is refused by name)"
294 ));
295 }
296 }
297 Ok(())
298 }
299}
300
301#[cfg(test)]
302mod tests {
303 use super::*;
304
305 fn doc(body: &str) -> String {
306 format!(
307 "{{\"format\": \"memra-ep-map-v1\", \"ranks\": 2, \"entry_rank\": 0, \
308 \"expert_count\": 4, {body}}}"
309 )
310 }
311
312 #[test]
313 fn parse_render_roundtrip_and_even_split() {
314 assert_eq!(EpMap::even_owners(4, 2), vec![0, 0, 1, 1]);
315 let m = EpMap {
316 n_experts: 4,
317 ranks: 2,
318 entry_rank: 0,
319 layers: [(1usize, EpMap::even_owners(4, 2)), (2, vec![0, 1, 1, 0])]
320 .into_iter()
321 .collect(),
322 };
323 let text = m.render();
324 let back = EpMap::parse(&text).unwrap();
325 assert_eq!(back, m);
326 assert_eq!(text, back.render());
328 }
329
330 #[test]
331 fn parses_the_shared_tools_emission_shape() {
332 let text = r#"{
336 "entry_rank": 0,
337 "expert_count": 4,
338 "format": "memra-ep-map-v1",
339 "layers": [
340 {
341 "assignment": [0, 1, 1, 0],
342 "layer": 3,
343 "stats": {
344 "even_baseline_expected_max_rank_touch": 2.75,
345 "expected_max_rank_touch": 2.0,
346 "intra_rank_coactivation_fraction": 0.58,
347 "peer_touch_fraction": 0.625
348 }
349 }
350 ],
351 "params": {"balance_tolerance": 0.05, "decode_only": true, "hotness_signal": "pick-count"},
352 "ranks": 2,
353 "strategy": "coactivation",
354 "traces": [{"lines": 59, "path": "odd{path}.txt", "sha256": "ab12"}]
355}
356"#;
357 let m = EpMap::parse(text).unwrap();
358 assert_eq!(m.n_experts, 4);
359 assert_eq!(m.ranks, 2);
360 assert_eq!(m.entry_rank, 0);
361 assert_eq!(m.layers[&3], vec![0, 1, 1, 0]);
362 }
363
364 #[test]
365 fn parse_refusals_name_the_law() {
366 let e = EpMap::parse("{\"format\": \"other-v9\"}").unwrap_err();
368 assert!(e.contains("memra-ep-map-v1"), "{e}");
369 assert!(EpMap::parse("{}").unwrap_err().contains("format"));
370 let e =
372 EpMap::parse(&doc("\"layers\": [{\"layer\": 1, \"assignment\": [0, 1]}]")).unwrap_err();
373 assert!(
374 e.contains("2 entries") && e.contains("expert_count=4"),
375 "{e}"
376 );
377 let e = EpMap::parse(&doc(
379 "\"layers\": [{\"layer\": 1, \"assignment\": [0, 1, 2, 1]}]",
380 ))
381 .unwrap_err();
382 assert!(e.contains(">= ranks"), "{e}");
383 let e = EpMap::parse(&doc(
385 "\"layers\": [{\"layer\": 1, \"assignment\": [0, 0, 0, 0]}]",
386 ))
387 .unwrap_err();
388 assert!(e.contains("ZERO experts"), "{e}");
389 let e = EpMap::parse(&doc(
391 "\"layers\": [{\"layer\": 1, \"assignment\": [0, 0, 1, 1]}, \
392 {\"layer\": 1, \"assignment\": [0, 0, 1, 1]}]",
393 ))
394 .unwrap_err();
395 assert!(e.contains("duplicate"), "{e}");
396 let e = EpMap::parse(&doc("\"layers\": []")).unwrap_err();
398 assert!(e.contains("empty"), "{e}");
399 let e = EpMap::parse(
401 "{\"format\": \"memra-ep-map-v1\", \"ranks\": 2, \"entry_rank\": 2, \
402 \"expert_count\": 4, \"layers\": [{\"layer\": 1, \"assignment\": [0, 0, 1, 1]}]}",
403 )
404 .unwrap_err();
405 assert!(e.contains("entry_rank"), "{e}");
406 }
407
408 #[test]
409 fn parses_the_committed_example_map_bytes() {
410 let text = include_str!(
414 "../../../research/ep-placement-map-20260831/example-map-coactivation.json"
415 );
416 let m = EpMap::parse(text).unwrap();
417 assert_eq!(m.n_experts, 16);
418 assert_eq!(m.ranks, 2);
419 assert_eq!(m.entry_rank, 0);
420 assert_eq!(m.layers.len(), 2);
421 for owners in m.layers.values() {
422 assert_eq!(owners.len(), 16);
423 assert_eq!(owners.iter().filter(|&&r| r == 0).count(), 8);
424 }
425 }
426
427 #[test]
428 fn env_resolution_names_the_armed_flag_and_refuses_disagreement() {
429 assert_eq!(resolve_ep_map_env(None, None).unwrap(), None);
431 assert_eq!(
433 resolve_ep_map_env(Some("m.json".into()), None).unwrap(),
434 Some((EP_MAP_ENV, "m.json".to_string()))
435 );
436 assert_eq!(
437 resolve_ep_map_env(None, Some("m.json".into())).unwrap(),
438 Some((EP_MAP_ENV_GLM5, "m.json".to_string()))
439 );
440 assert_eq!(
441 resolve_ep_map_env(Some("m.json".into()), Some("m.json".into())).unwrap(),
442 Some((EP_MAP_ENV, "m.json".to_string()))
443 );
444 let e = resolve_ep_map_env(Some("a.json".into()), Some("b.json".into())).unwrap_err();
446 assert!(e.contains(EP_MAP_ENV) && e.contains(EP_MAP_ENV_GLM5), "{e}");
447 assert_eq!(
449 resolve_ep_map_env(Some(String::new()), None).unwrap(),
450 Some((EP_MAP_ENV, String::new()))
451 );
452 }
453
454 #[test]
455 fn layer_cover_is_exact_both_ways() {
456 let m = EpMap::parse(&doc(
457 "\"layers\": [{\"layer\": 1, \"assignment\": [0, 0, 1, 1]}]",
458 ))
459 .unwrap();
460 assert!(m.validate_layer_cover(&[1]).is_ok());
461 assert!(
462 m.validate_layer_cover(&[1, 2])
463 .unwrap_err()
464 .contains("layer 2")
465 );
466 assert!(
467 m.validate_layer_cover(&[2])
468 .unwrap_err()
469 .contains("layer 2")
470 );
471 }
472}