From 580970808ed601e5be7598e23f81a04c0480427c Mon Sep 17 00:00:00 2001 From: Shane Manaton Date: Fri, 17 Jul 2026 18:51:37 +0100 Subject: [PATCH 1/3] Fix --json inspect: serialize tensor map as a sequence serde_json cannot serialize maps with tuple keys, so every --json inspect run failed with "key must be a string" after a full model load. Emit the tensor list instead; each TensorInfo already carries layer and projection. Co-Authored-By: Claude Fable 5 --- src/architecture.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/architecture.rs b/src/architecture.rs index d9e0e02..c2cfb1b 100644 --- a/src/architecture.rs +++ b/src/architecture.rs @@ -96,11 +96,24 @@ impl TensorInfo { #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ArchitectureMap { + // Tuple keys cannot be JSON map keys ("key must be a string"); emit the + // tensor list instead — each TensorInfo already carries layer+projection. + #[serde(serialize_with = "serialize_tensor_map")] tensors: BTreeMap<(usize, Projection), TensorInfo>, layer_count: usize, signature: String, } +fn serialize_tensor_map( + tensors: &BTreeMap<(usize, Projection), TensorInfo>, + serializer: S, +) -> std::result::Result +where + S: serde::Serializer, +{ + serializer.collect_seq(tensors.values()) +} + impl ArchitectureMap { pub fn discover(descriptors: &[TensorDescriptor]) -> Result { let mut tensors = BTreeMap::new(); From 3b9a14c34215cda54762eb098a947903481b7587 Mon Sep 17 00:00:00 2001 From: Shane Manaton Date: Fri, 17 Jul 2026 18:51:37 +0100 Subject: [PATCH 2/3] Document Windows (MSVC) build requirements CMake >= 4.3 for the Visual Studio 18 generator, and Ninja + vcvars64 for CUDA builds when VS is newer than the CUDA toolkit's VS integration. Co-Authored-By: Claude Fable 5 --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 22110b0..3ca685e 100644 --- a/README.md +++ b/README.md @@ -379,6 +379,25 @@ MIYAGI_TEST_GPU_LAYERS=0 \ cargo test --no-default-features --test model_backend ``` +### Building on Windows (MSVC) + +Miyagi builds and runs on Windows (validated on Windows 11, Rust +`x86_64-pc-windows-msvc`, against mainline llama.cpp b10054 with an RTX 4090). +Notes: + +- With Visual Studio 18 installed, the `cmake` crate requests the + "Visual Studio 18 2026" generator, which needs CMake ≥ 4.3 on `PATH` + (VS's bundled CMake works). +- For `--features cuda` with a VS version newer than your CUDA toolkit's VS + integration, use the Ninja generator inside a `vcvars64` environment of a VS + version the toolkit supports, e.g.: + + ```bat + call "...\BuildTools\VC\Auxiliary\Build\vcvars64.bat" + set CMAKE_GENERATOR=Ninja + cargo build --release --features cuda + ``` + ## Compatibility and Boundaries - Miyagi supports descriptor-driven Qwen/Bonsai MLP mapping for two-dimensional From c35e4c906620920dd4437169ac4bfb236172d364 Mon Sep 17 00:00:00 2001 From: Shane Manaton Date: Sun, 19 Jul 2026 19:03:34 +0100 Subject: [PATCH 3/3] test: assert ArchitectureMap JSON emits tensors as an array Guards the serde_json tuple-key fix for --json inspect. --- src/architecture.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/architecture.rs b/src/architecture.rs index c2cfb1b..f36a86d 100644 --- a/src/architecture.rs +++ b/src/architecture.rs @@ -308,4 +308,34 @@ mod tests { "\"down_proj\"" ); } + + #[test] + fn architecture_map_json_serializes_tensors_as_array() { + let mut descriptors = Vec::new(); + for layer in 0..2 { + descriptors.push(descriptor( + &format!("blk.{layer}.ffn_gate.weight"), + 4096, + 12288, + )); + descriptors.push(descriptor( + &format!("blk.{layer}.ffn_up.weight"), + 4096, + 12288, + )); + descriptors.push(descriptor( + &format!("blk.{layer}.ffn_down.weight"), + 12288, + 4096, + )); + } + let map = ArchitectureMap::discover(&descriptors).unwrap(); + let value = serde_json::to_value(&map).expect("JSON serialize must not fail on tuple keys"); + let tensors = value + .get("tensors") + .and_then(|t| t.as_array()) + .expect("tensors must serialize as a JSON array"); + assert_eq!(tensors.len(), 6); + assert!(tensors.iter().all(|t| t.get("layer").is_some() && t.get("projection").is_some())); + } }