1use super::*;
6use crate::container_10d::crc32c::crc32c;
7use crate::gguf_sharder::{GgufTensorIndex, GgufTensorInfo};
8
9fn p64_tensor_name(role: u16, layer: u16, source_name_hash: u64) -> String {
10 if layer == P64_LAYER_GLOBAL {
11 return match role {
12 P64_ROLE_TOKEN_EMBD => "token_embd.weight".to_string(),
13 P64_ROLE_OUTPUT => "output.weight".to_string(),
14 P64_ROLE_OUTPUT_NORM => "output_norm.weight".to_string(),
15 _ => format!("tensor.{source_name_hash:016x}"),
16 };
17 }
18 match p64_role_suffix(role) {
19 Some(suffix) => format!("blk.{layer}.{}", String::from_utf8_lossy(suffix)),
20 None => format!("tensor.{source_name_hash:016x}"),
21 }
22}
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
33pub enum P64ConvertLayout {
34 #[default]
36 Verbatim,
37 F16Expand,
40 Q4kSoa,
43}
44
45pub fn compile_gguf_to_p64(input: &[u8], page_log2: u16) -> Result<Vec<u8>, String> {
53 compile_gguf_to_p64_with_layout(input, page_log2, P64ConvertLayout::Verbatim)
54}
55
56pub fn compile_gguf_to_p64_with_layout(
58 input: &[u8],
59 page_log2: u16,
60 layout: P64ConvertLayout,
61) -> Result<Vec<u8>, String> {
62 let index = GgufTensorIndex::from_gguf(input);
63 if index.tensor_data_start == 0 || index.entries.is_empty() {
64 return Err("p64: GGUF parse yielded no tensors".to_string());
65 }
66 let page_log2 = if page_log2 == 0 {
67 P64_DEFAULT_PAGE_LOG2
68 } else {
69 page_log2
70 };
71 if !(8..=30).contains(&page_log2) {
72 return Err(format!("p64: page_log2 {page_log2} out of range"));
73 }
74 let page = 1usize << page_log2;
75 let tensor_data_start = index.tensor_data_start as usize;
76
77 let mut planned: Vec<(u16, u16, u64, GgufTensorInfo)> = Vec::with_capacity(index.entries.len());
79 let mut push_known = |role: u16, layer: u16, candidate: Option<GgufTensorInfo>| {
80 if let Some(info) = candidate {
81 if planned
82 .iter()
83 .any(|(_, _, _, existing)| existing.byte_offset == info.byte_offset)
84 {
85 return;
86 }
87 let name_hash = index
88 .entries
89 .iter()
90 .find(|(_, source)| source.byte_offset == info.byte_offset)
91 .map(|(hash, _)| *hash)
92 .unwrap_or(0);
93 planned.push((role, layer, name_hash, info));
94 }
95 };
96 for layer in 0..index.hyperparams.n_layer {
97 let tensors = index.get_layer_tensors(layer);
98 let layer = u16::try_from(layer).map_err(|_| "p64: layer index exceeds u16")?;
99 push_known(P64_ROLE_ATTN_NORM, layer, tensors.attn_norm);
100 push_known(P64_ROLE_ATTN_Q, layer, tensors.attn_q);
101 push_known(P64_ROLE_ATTN_K, layer, tensors.attn_k);
102 push_known(P64_ROLE_ATTN_V, layer, tensors.attn_v);
103 push_known(P64_ROLE_ATTN_OUTPUT, layer, tensors.attn_output);
104 push_known(P64_ROLE_FFN_NORM, layer, tensors.ffn_norm);
105 push_known(P64_ROLE_FFN_GATE, layer, tensors.ffn_gate);
106 push_known(P64_ROLE_FFN_UP, layer, tensors.ffn_up);
107 push_known(P64_ROLE_FFN_DOWN, layer, tensors.ffn_down);
108 }
109 push_known(
110 P64_ROLE_TOKEN_EMBD,
111 P64_LAYER_GLOBAL,
112 index.token_embd_info().copied(),
113 );
114 push_known(
115 P64_ROLE_OUTPUT,
116 P64_LAYER_GLOBAL,
117 index.output_weight_info().copied(),
118 );
119 push_known(
120 P64_ROLE_OUTPUT_NORM,
121 P64_LAYER_GLOBAL,
122 index.output_norm_info().copied(),
123 );
124 for (name_hash, info) in &index.entries {
125 if !planned
126 .iter()
127 .any(|(_, _, _, existing)| existing.byte_offset == info.byte_offset)
128 {
129 planned.push((P64_ROLE_UNKNOWN, P64_LAYER_GLOBAL, *name_hash, *info));
130 }
131 }
132 let mut unknowns: Vec<_> = planned
136 .iter()
137 .copied()
138 .filter(|(role, _, _, _)| *role == P64_ROLE_UNKNOWN)
139 .collect();
140 unknowns.sort_by_key(|(_, _, _, info)| info.byte_offset);
141 planned.retain(|(role, _, _, _)| *role != P64_ROLE_UNKNOWN);
142 planned.extend(unknowns);
143
144 let mut string_table = vec![0u8];
145 let mut name_offsets = Vec::with_capacity(planned.len());
146 for (role, layer, name_hash, _) in &planned {
147 let name_offset =
148 u32::try_from(string_table.len()).map_err(|_| "p64: string table exceeds 4 GiB")?;
149 name_offsets.push(name_offset);
150 let name = p64_tensor_name(*role, *layer, *name_hash);
151 string_table.extend_from_slice(name.as_bytes());
152 string_table.push(0);
153 }
154 let tokenizer = crate::gguf_sharder::GgufTokenizer::from_gguf(input).to_p64_section();
155 let manifold_count = index
156 .hyperparams
157 .n_layer
158 .checked_add(1)
159 .ok_or("p64: manifold count overflow")? as usize;
160
161 let hparams_offset = P64_WEIGHT_HEADER_BYTES;
162 let n_layer_u = index.hyperparams.n_layer as usize;
163 let schedule_offset = align_up(hparams_offset + 64, 64);
165 let schedule_bytes = n_layer_u
166 .checked_mul(core::mem::size_of::<P64LayerScheduleEntry>())
167 .ok_or("p64: schedule overflow")?;
168 let tensor_table_offset = align_up(schedule_offset + schedule_bytes, 64);
169 let tensor_table_bytes = planned
170 .len()
171 .checked_mul(P64_TENSOR_ENTRY_BYTES)
172 .ok_or("p64: tensor table overflow")?;
173 let string_table_offset = tensor_table_offset + tensor_table_bytes;
174 let manifold_table_offset = align_up(string_table_offset + string_table.len(), 64);
175 let manifold_bytes = manifold_count
176 .checked_mul(P64_MANIFOLD_ENTRY_BYTES)
177 .ok_or("p64: manifold table overflow")?;
178 let tokenizer_offset = align_up(manifold_table_offset + manifold_bytes, 64);
179 let checksum_offset = align_up(tokenizer_offset + tokenizer.len(), 64);
180 let checksum_bytes = planned
181 .len()
182 .checked_add(1)
183 .and_then(|count| count.checked_mul(4))
184 .ok_or("p64: checksum table overflow")?;
185 let blob_region_offset = align_up(checksum_offset + checksum_bytes, page);
186
187 let mut entries = Vec::with_capacity(planned.len());
188 #[derive(Clone, Copy)]
190 enum BlobKind {
191 Copy,
192 F16Expand,
193 Q4kSoa,
194 Q4kSoaRequant,
195 }
196 let mut blob_kind: Vec<BlobKind> = Vec::with_capacity(planned.len());
197 let mut cursor = blob_region_offset;
198 for (position, (role, layer, name_hash, info)) in planned.iter().enumerate() {
199 let source_blob_size = crate::ggml_quants::tensor_byte_len(info)
200 .ok_or_else(|| format!("p64: unsupported GGML type {}", info.ggml_type))?;
201 let source_start = tensor_data_start
202 .checked_add(info.byte_offset as usize)
203 .ok_or("p64: source tensor offset overflow")?;
204 let source_end = source_start
205 .checked_add(source_blob_size)
206 .ok_or("p64: source tensor length overflow")?;
207 if source_end > input.len() {
208 return Err(format!("p64: source tensor {position} is out of bounds"));
209 }
210
211 let do_f16 = matches!(layout, P64ConvertLayout::F16Expand)
212 && p64_role_is_weight_matrix(*role)
213 && info.n_dims >= 2
214 && info.ggml_type != crate::ggml_quants::GGML_TYPE_F16
215 && info.ggml_type != crate::ggml_quants::GGML_TYPE_F32;
216 let do_soa = matches!(layout, P64ConvertLayout::Q4kSoa)
217 && p64_role_is_weight_matrix(*role)
218 && info.n_dims >= 2;
219 let do_soa_requant = do_soa && info.ggml_type != crate::ggml_quants::GGML_TYPE_Q4_K;
222 let do_soa = do_soa && !do_soa_requant;
223 let (out_dtype, blob_size, kind) = if do_f16 {
224 let n0 = info.dims[0] as usize;
225 let n1 = info.dims[1] as usize;
226 let elems = n0
227 .checked_mul(n1)
228 .ok_or("p64: f16 expand element count overflow")?;
229 let bytes = elems
230 .checked_mul(2)
231 .ok_or("p64: f16 expand byte count overflow")?;
232 (
233 crate::ggml_quants::GGML_TYPE_F16 as u16,
234 bytes,
235 BlobKind::F16Expand,
236 )
237 } else if do_soa || do_soa_requant {
238 let n0 = info.dims[0] as usize;
239 let n1 = info.dims[1].max(1) as usize;
240 let bytes =
241 crate::ggml_quants::ggml_row_bytes(crate::ggml_quants::GGML_TYPE_Q4_K_SOA, n0)
242 .and_then(|r| r.checked_mul(n1))
243 .ok_or("p64: Q4_K SoA size overflow")?;
244 let kind = if do_soa_requant {
245 BlobKind::Q4kSoaRequant
246 } else {
247 BlobKind::Q4kSoa
248 };
249 (crate::ggml_quants::GGML_TYPE_Q4_K_SOA as u16, bytes, kind)
250 } else {
251 (
252 u16::try_from(info.ggml_type).map_err(|_| "p64: GGML type exceeds u16")?,
253 source_blob_size,
254 BlobKind::Copy,
255 )
256 };
257
258 let pack_align = if position == 0 {
262 page
263 } else {
264 let prev_layer = planned[position - 1].1;
265 if *layer != prev_layer {
266 page
267 } else {
268 256
269 }
270 };
271 cursor = align_up(cursor, pack_align);
272 let mut dimensions = [0u32; 4];
273 for (target, source) in dimensions.iter_mut().zip(info.dims) {
274 *target = u32::try_from(source).map_err(|_| "p64: tensor dimension exceeds u32")?;
275 }
276 let manifold_idx = if *layer == P64_LAYER_GLOBAL {
277 index.hyperparams.n_layer
278 } else {
279 *layer as u32
280 };
281 entries.push(P64TensorEntry {
282 name_offset: name_offsets[position],
283 role_id: *role,
284 dtype: out_dtype,
285 manifold_idx,
286 rank: info.n_dims,
287 dimensions,
288 blob_offset: u32::try_from(cursor).map_err(|_| "p64: container exceeds 4 GiB")?,
289 blob_size: u32::try_from(blob_size).map_err(|_| "p64: tensor exceeds 4 GiB")?,
290 source_offset: info.byte_offset,
291 source_name_hash: *name_hash,
292 alt_dtype: 0,
293 precision_views_mask: 0,
294 alt_blob_offset: 0,
295 });
296 blob_kind.push(kind);
297 cursor = cursor
298 .checked_add(blob_size)
299 .ok_or("p64: container size overflow")?;
300 }
301 let total_size = align_up(cursor, 64);
302 if total_size > u32::MAX as usize {
303 return Err("p64: 32-bit relative-offset container exceeds 4 GiB".to_string());
304 }
305
306 let mut flags = P64_FLAG_LITTLE_ENDIAN
307 | P64_FLAG_LAYER_MAJOR
308 | P64_FLAG_LAYER_PACK
309 | P64_FLAG_LAYER_SCHEDULE;
310 if matches!(layout, P64ConvertLayout::Q4kSoa)
311 && blob_kind
312 .iter()
313 .any(|k| matches!(k, BlobKind::Q4kSoa | BlobKind::Q4kSoaRequant))
314 {
315 flags |= P64_FLAG_Q4K_SOA;
316 }
317 let mut schedule = vec![P64LayerScheduleEntry::default(); n_layer_u];
319 for (i, s) in schedule.iter_mut().enumerate() {
320 s.layer = i as u32;
321 s.blob_begin = u32::MAX;
322 s.blob_end = 0;
323 }
324 for e in &entries {
325 let li = e.manifold_idx as usize;
326 if li >= n_layer_u {
327 continue; }
329 let s = &mut schedule[li];
330 s.blob_begin = s.blob_begin.min(e.blob_offset);
331 s.blob_end = s.blob_end.max(e.blob_offset.saturating_add(e.blob_size));
332 s.tensor_count = s.tensor_count.saturating_add(1);
333 if e.role_id < 16 {
334 s.roles_mask |= 1u16 << e.role_id;
335 }
336 }
337 for s in &mut schedule {
338 if s.blob_begin == u32::MAX {
339 s.blob_begin = 0;
340 s.blob_end = 0;
341 }
342 }
343 let header = P64WeightHeader {
344 magic: P64_MAGIC,
345 version: P64_VERSION,
346 flags,
347 role_table_offset: schedule_offset as u32, tensor_table_offset: tensor_table_offset as u32,
349 tokenizer_offset: tokenizer_offset as u32,
350 hparams_offset: hparams_offset as u32,
351 string_table_offset: string_table_offset as u32,
352 checksum_offset: checksum_offset as u32,
353 manifold_table_offset: manifold_table_offset as u32,
354 tensor_count: entries.len() as u32,
355 page_size: page as u32,
356 reserved: [0; 20],
357 };
358 let hp = P64HParams {
359 n_layer: index.hyperparams.n_layer,
360 n_embd: index.hyperparams.n_embd,
361 n_head: index.hyperparams.n_head,
362 n_kv_head: index.hyperparams.effective_n_kv_head(),
363 vocab_size: index.vocab_dim() as u32,
364 rope_freq_base: index.hyperparams.effective_rope_freq_base(),
365 rope_scale: index.hyperparams.effective_rope_scale(),
366 head_dim: index.hyperparams.head_dim,
367 head_dim_swa: index.hyperparams.head_dim_swa,
368 sliding_window: index.hyperparams.sliding_window,
369 shared_kv_layers: index.hyperparams.shared_kv_layers,
370 logit_softcap: index.hyperparams.logit_softcap,
371 architecture: index.hyperparams.architecture,
372 arch_flags: index.hyperparams.arch_flags,
373 reserved: [0; 8],
374 };
375
376 let mut output = vec![0u8; total_size];
377 header.write_le(&mut output[..P64_WEIGHT_HEADER_BYTES]);
378 hp.write_le(&mut output[hparams_offset..hparams_offset + 64]);
379 for (i, s) in schedule.iter().enumerate() {
380 let start = schedule_offset + i * core::mem::size_of::<P64LayerScheduleEntry>();
381 let dest = &mut output[start..start + 64];
382 dest.fill(0);
383 dest[0..4].copy_from_slice(&s.layer.to_le_bytes());
384 dest[4..8].copy_from_slice(&s.blob_begin.to_le_bytes());
385 dest[8..12].copy_from_slice(&s.blob_end.to_le_bytes());
386 dest[12..14].copy_from_slice(&s.tensor_count.to_le_bytes());
387 dest[14..16].copy_from_slice(&s.roles_mask.to_le_bytes());
388 }
389 for (position, entry) in entries.iter().enumerate() {
390 let start = tensor_table_offset + position * P64_TENSOR_ENTRY_BYTES;
391 write_tensor_entry(entry, &mut output[start..start + P64_TENSOR_ENTRY_BYTES]);
392 }
393 output[string_table_offset..string_table_offset + string_table.len()]
394 .copy_from_slice(&string_table);
395 for layer in 0..manifold_count {
396 let coordinate = crate::modalities::manifold::ManifoldCoordinate10D::from_sequential_layer(
397 layer.min(index.hyperparams.n_layer as usize) as u32,
398 index.hyperparams.n_layer.max(1),
399 );
400 let start = manifold_table_offset + layer * P64_MANIFOLD_ENTRY_BYTES;
401 write_manifold_coordinate(
402 &coordinate,
403 &mut output[start..start + P64_MANIFOLD_ENTRY_BYTES],
404 );
405 }
406 output[tokenizer_offset..tokenizer_offset + tokenizer.len()].copy_from_slice(&tokenizer);
407
408 for (position, entry) in entries.iter().enumerate() {
409 let target_start = entry.blob_offset as usize;
410 let target_end = target_start + entry.blob_size as usize;
411 match blob_kind[position] {
412 BlobKind::F16Expand => {
413 let info = &planned[position].3;
414 let source_blob_size = crate::ggml_quants::tensor_byte_len(info)
415 .ok_or("p64: f16 expand missing source size")?;
416 let source_start = tensor_data_start + entry.source_offset as usize;
417 let source_end = source_start + source_blob_size;
418 let raw = &input[source_start..source_end];
419 expand_tensor_to_f16_blob(raw, info, &mut output[target_start..target_end])?;
420 }
421 BlobKind::Q4kSoa => {
422 let info = &planned[position].3;
423 let source_blob_size = crate::ggml_quants::tensor_byte_len(info)
424 .ok_or("p64: Q4_K SoA missing source size")?;
425 let source_start = tensor_data_start + entry.source_offset as usize;
426 let source_end = source_start + source_blob_size;
427 let raw = &input[source_start..source_end];
428 let n0 = info.dims[0] as usize;
429 let n1 = info.dims[1].max(1) as usize;
430 crate::ggml_quants::expand_q4k_tensor_to_soa(
431 raw,
432 n0,
433 n1,
434 &mut output[target_start..target_end],
435 )
436 .map_err(|e| format!("p64: Q4_K SoA expand: {e:?}"))?;
437 }
438 BlobKind::Q4kSoaRequant => {
439 let info = &planned[position].3;
440 let source_blob_size = crate::ggml_quants::tensor_byte_len(info)
441 .ok_or("p64: Q4_K SoA requant missing source size")?;
442 let source_start = tensor_data_start + entry.source_offset as usize;
443 let source_end = source_start + source_blob_size;
444 let raw = &input[source_start..source_end];
445 let n0 = info.dims[0] as usize;
446 let n1 = info.dims[1].max(1) as usize;
447 let total_elems = n0
448 .checked_mul(n1)
449 .ok_or("p64: Q4_K SoA requant element count overflow")?;
450 let mut f32_buf: Vec<f32> = vec![0.0f32; total_elems];
452 crate::ggml_quants::dequantize_row_into(
453 raw,
454 info.ggml_type,
455 total_elems,
456 &mut f32_buf,
457 )
458 .map_err(|e| format!("p64: Q4_K SoA requant dequant: {e:?}"))?;
459 crate::ggml_quants::quantize_f32_to_q4_k_soa_tensor(
460 &f32_buf,
461 n0,
462 n1,
463 &mut output[target_start..target_end],
464 )
465 .map_err(|e| format!("p64: Q4_K SoA requant: {e:?}"))?;
466 }
467 BlobKind::Copy => {
468 let source_start = tensor_data_start + entry.source_offset as usize;
469 let source_end = source_start + entry.blob_size as usize;
470 output[target_start..target_end].copy_from_slice(&input[source_start..source_end]);
471 }
472 }
473 let crc = crc32c(&output[target_start..target_end]);
474 let crc_start = checksum_offset + 4 + position * 4;
475 output[crc_start..crc_start + 4].copy_from_slice(&crc.to_le_bytes());
476 }
477 let metadata_crc = crc32c(&output[..checksum_offset]);
478 output[checksum_offset..checksum_offset + 4].copy_from_slice(&metadata_crc.to_le_bytes());
479 Ok(output)
480}
481
482#[inline]
484fn p64_role_is_weight_matrix(role: u16) -> bool {
485 matches!(
486 role,
487 P64_ROLE_ATTN_K
488 | P64_ROLE_ATTN_V
489 | P64_ROLE_ATTN_Q
490 | P64_ROLE_ATTN_OUTPUT
491 | P64_ROLE_FFN_GATE
492 | P64_ROLE_FFN_UP
493 | P64_ROLE_FFN_DOWN
494 | P64_ROLE_TOKEN_EMBD
495 | P64_ROLE_OUTPUT
496 )
497}
498
499fn expand_tensor_to_f16_blob(
501 raw: &[u8],
502 info: &GgufTensorInfo,
503 out: &mut [u8],
504) -> Result<(), String> {
505 let n0 = info.dims[0] as usize; let n1 = info.dims[1] as usize; let need = n0
508 .checked_mul(n1)
509 .and_then(|e| e.checked_mul(2))
510 .ok_or("p64: f16 expand size overflow")?;
511 if out.len() < need {
512 return Err("p64: f16 expand output buffer too small".into());
513 }
514 let mut row_f32 = vec![0f32; n0];
515 for r in 0..n1 {
516 crate::ggml_quants::dequant_matrix_row_into(raw, info, r, &mut row_f32)
517 .map_err(|e| format!("p64: f16 expand dequant row {r}: {e:?}"))?;
518 let row_off = r * n0 * 2;
519 for (c, &v) in row_f32.iter().enumerate() {
520 let bits = half::f16::from_f32(v).to_le_bytes();
521 let o = row_off + c * 2;
522 out[o] = bits[0];
523 out[o + 1] = bits[1];
524 }
525 }
526 Ok(())
527}
528
529#[allow(dead_code)]
532fn compile_gguf_to_p64_legacy(input: &[u8], page_log2: u16) -> Result<Vec<u8>, String> {
533 let idx = crate::gguf_sharder::GgufTensorIndex::from_gguf(input);
534 if idx.tensor_data_start == 0 && idx.hyperparams.n_layer == 0 {
535 return Err("GGUF parse failed or yielded no tensor metadata".to_string());
536 }
537 let page_log2 = if page_log2 == 0 {
538 12 } else {
540 page_log2
541 };
542 if page_log2 < 8 || page_log2 > 30 {
543 return Err(format!("page_log2 {page_log2} out of range"));
544 }
545 let page = 1usize << page_log2;
546 let n_layer = idx.hyperparams.n_layer;
547 let tds = idx.tensor_data_start as usize;
548
549 let mut planned: Vec<(u16, u16, crate::gguf_sharder::GgufTensorInfo)> = Vec::new();
550 let mut push = |role_id: u16, layer: u16, t: Option<crate::gguf_sharder::GgufTensorInfo>| {
551 if let Some(info) = t {
552 planned.push((role_id, layer, info));
553 }
554 };
555 for layer in 0..n_layer {
556 let t = idx.get_layer_tensors(layer);
557 let l = layer as u16;
558 push(P64_ROLE_ATTN_NORM, l, t.attn_norm);
559 push(P64_ROLE_ATTN_Q, l, t.attn_q);
560 push(P64_ROLE_ATTN_K, l, t.attn_k);
561 push(P64_ROLE_ATTN_V, l, t.attn_v);
562 push(P64_ROLE_ATTN_OUTPUT, l, t.attn_output);
563 push(P64_ROLE_FFN_NORM, l, t.ffn_norm);
564 push(P64_ROLE_FFN_GATE, l, t.ffn_gate);
565 push(P64_ROLE_FFN_UP, l, t.ffn_up);
566 push(P64_ROLE_FFN_DOWN, l, t.ffn_down);
567 }
568 push(
569 P64_ROLE_TOKEN_EMBD,
570 P64_LAYER_GLOBAL,
571 idx.token_embd_info().copied(),
572 );
573 push(
574 P64_ROLE_OUTPUT_NORM,
575 P64_LAYER_GLOBAL,
576 idx.output_norm_info().copied(),
577 );
578 push(
579 P64_ROLE_OUTPUT,
580 P64_LAYER_GLOBAL,
581 idx.output_weight_info().copied(),
582 );
583
584 planned.retain(|(_, _, info)| info.dims[0] > 0);
586
587 let mut string_table: Vec<u8> = Vec::new();
589 let mut name_offsets = std::collections::HashMap::new();
590
591 string_table.push(0u8);
593
594 for (role, layer, info) in &planned {
595 let name = if let Some(suffix) = p64_role_suffix(*role) {
596 if *layer == P64_LAYER_GLOBAL {
597 String::from_utf8_lossy(suffix).to_string()
598 } else {
599 format!("blk.{}.{}", layer, String::from_utf8_lossy(suffix))
600 }
601 } else {
602 format!("tensor_{}", info.byte_offset)
603 };
604
605 if !name_offsets.contains_key(&name) {
606 let offset = string_table.len() as u32;
607 name_offsets.insert(name.clone(), offset);
608 string_table.extend_from_slice(name.as_bytes());
609 string_table.push(0u8);
610 }
611 }
612
613 let tokenizer_offset = string_table.len() as u32;
615 let tok = crate::gguf_sharder::GgufTokenizer::from_gguf(input);
616
617 let mut tok_bytes: Vec<u8> = Vec::new();
618 tok_bytes.extend_from_slice(&(tok.vocab.len() as u32).to_le_bytes());
620 for v in &tok.vocab {
621 let v_bytes = v.as_bytes();
622 tok_bytes.extend_from_slice(&(v_bytes.len() as u32).to_le_bytes());
623 tok_bytes.extend_from_slice(v_bytes);
624 }
625 let tokenizer_size = tok_bytes.len() as u32;
626
627 string_table.extend_from_slice(&tok_bytes);
628
629 while string_table.len() % 64 != 0 {
631 string_table.push(0u8);
632 }
633
634 let string_table_size = string_table.len() as u32;
635 let tensor_count = planned.len() as u32;
636
637 let mut manifold_table: Vec<u8> = Vec::new();
639 let total_layers = idx.hyperparams.n_layer;
640 for l in 0..total_layers {
641 let coord = crate::modalities::manifold::ManifoldCoordinate10D::from_sequential_layer(
642 l,
643 total_layers,
644 );
645 manifold_table.extend_from_slice(&coord.scale.to_le_bytes());
647 manifold_table.extend_from_slice(&coord.attention_depth.to_le_bytes());
648 manifold_table.extend_from_slice(&coord.epistemic_weight.to_le_bytes());
649 manifold_table.extend_from_slice(&coord.topological_spin.to_le_bytes());
650 manifold_table.extend_from_slice(&coord.temporal_decay.to_le_bytes());
651 manifold_table.extend_from_slice(&coord.entropy_bias.to_le_bytes());
652 manifold_table.extend_from_slice(&coord.spatial_phase.to_le_bytes());
653 manifold_table.extend_from_slice(&coord.recurrence_frequency.to_le_bytes());
654 manifold_table.extend_from_slice(&coord.density_threshold.to_le_bytes());
655 manifold_table.extend_from_slice(&coord.manifold_curvature.to_le_bytes());
656 }
657 let global_coord =
659 crate::modalities::manifold::ManifoldCoordinate10D::from_sequential_layer(0, 1);
660 manifold_table.extend_from_slice(&global_coord.scale.to_le_bytes());
661 manifold_table.extend_from_slice(&global_coord.attention_depth.to_le_bytes());
662 manifold_table.extend_from_slice(&global_coord.epistemic_weight.to_le_bytes());
663 manifold_table.extend_from_slice(&global_coord.topological_spin.to_le_bytes());
664 manifold_table.extend_from_slice(&global_coord.temporal_decay.to_le_bytes());
665 manifold_table.extend_from_slice(&global_coord.entropy_bias.to_le_bytes());
666 manifold_table.extend_from_slice(&global_coord.spatial_phase.to_le_bytes());
667 manifold_table.extend_from_slice(&global_coord.recurrence_frequency.to_le_bytes());
668 manifold_table.extend_from_slice(&global_coord.density_threshold.to_le_bytes());
669 manifold_table.extend_from_slice(&global_coord.manifold_curvature.to_le_bytes());
670 let manifold_table_size = manifold_table.len() as u32;
671
672 let hparams_offset = 64;
674 let entries_offset = 128;
675 let string_table_offset = entries_offset + (tensor_count * 64) as u32;
676 let manifold_table_offset = string_table_offset + string_table_size;
677 let end_of_manifold_table = manifold_table_offset + manifold_table_size;
678 let page_aligned_tensor_start =
679 (end_of_manifold_table + (page as u32) - 1) & !((page as u32) - 1);
680
681 let mut out = vec![0u8; page_aligned_tensor_start as usize];
682
683 out[0..4].copy_from_slice(&P64_MAGIC);
685 out[4..6].copy_from_slice(&P64_VERSION.to_le_bytes());
686 out[6..8].copy_from_slice(&0u16.to_le_bytes()); out[8..12].copy_from_slice(&0u32.to_le_bytes()); out[12..16].copy_from_slice(&(entries_offset as u32).to_le_bytes()); out[16..20].copy_from_slice(&(tokenizer_offset as u32).to_le_bytes()); out[20..24].copy_from_slice(&(hparams_offset as u32).to_le_bytes()); out[24..28].copy_from_slice(&string_table_offset.to_le_bytes()); out[28..32].copy_from_slice(&0u32.to_le_bytes()); out[32..36].copy_from_slice(&manifold_table_offset.to_le_bytes()); out[36..40].copy_from_slice(&tensor_count.to_le_bytes());
697 out[40..44].copy_from_slice(&(page as u32).to_le_bytes());
698 out[44..48].copy_from_slice(&tokenizer_size.to_le_bytes());
700
701 let hparams = &idx.hyperparams;
705 let h_off = hparams_offset as usize;
706 out[h_off..h_off + 4].copy_from_slice(&hparams.n_layer.to_le_bytes());
707 out[h_off + 4..h_off + 8].copy_from_slice(&hparams.n_embd.to_le_bytes());
708 out[h_off + 8..h_off + 12].copy_from_slice(&hparams.n_head.to_le_bytes());
709 out[h_off + 12..h_off + 16].copy_from_slice(&hparams.n_kv_head.to_le_bytes());
710 out[h_off + 16..h_off + 20].copy_from_slice(&0u32.to_le_bytes()); out[h_off + 20..h_off + 24].copy_from_slice(&hparams.rope_freq_base.to_le_bytes());
712 out[h_off + 24..h_off + 28].copy_from_slice(&hparams.rope_scale.to_le_bytes());
713 out[h_off + 28..h_off + 32].copy_from_slice(&hparams.head_dim.to_le_bytes());
714 out[h_off + 32..h_off + 36].copy_from_slice(&hparams.head_dim_swa.to_le_bytes());
715 out[h_off + 36..h_off + 40].copy_from_slice(&hparams.sliding_window.to_le_bytes());
716 out[h_off + 40..h_off + 44].copy_from_slice(&hparams.shared_kv_layers.to_le_bytes());
717 out[h_off + 44..h_off + 48].copy_from_slice(&hparams.logit_softcap.to_le_bytes());
718 out[h_off + 48..h_off + 52].copy_from_slice(&hparams.architecture.to_le_bytes());
719 out[h_off + 52..h_off + 56].copy_from_slice(&hparams.arch_flags.to_le_bytes());
720
721 let mt_off = manifold_table_offset as usize;
723 out[mt_off..mt_off + manifold_table.len()].copy_from_slice(&manifold_table);
724
725 let mut cursor_blob = page_aligned_tensor_start as usize;
727 for (i, (role, layer, info)) in planned.iter().enumerate() {
728 let e_off = entries_offset as usize + i * 64;
729
730 let name = if let Some(suffix) = p64_role_suffix(*role) {
731 if *layer == P64_LAYER_GLOBAL {
732 String::from_utf8_lossy(suffix).to_string()
733 } else {
734 format!("blk.{}.{}", layer, String::from_utf8_lossy(suffix))
735 }
736 } else {
737 format!("tensor_{}", info.byte_offset)
738 };
739 let n_offset = *name_offsets.get(&name).unwrap();
740
741 cursor_blob = (cursor_blob + 31) & !31;
745
746 let n_elements =
747 info.dims[0] * info.dims[1].max(1) * info.dims[2].max(1) * info.dims[3].max(1);
748 let byte_len = crate::ggml_quants::tensor_byte_len(info).unwrap_or(0);
749
750 out.resize(cursor_blob + byte_len, 0);
752 let src_start = tds + info.byte_offset as usize;
753 if src_start + byte_len <= input.len() {
754 out[cursor_blob..cursor_blob + byte_len]
755 .copy_from_slice(&input[src_start..src_start + byte_len]);
756 }
757
758 out[e_off..e_off + 4].copy_from_slice(&n_offset.to_le_bytes());
760 out[e_off + 4..e_off + 6].copy_from_slice(&role.to_le_bytes());
761 out[e_off + 6..e_off + 8].copy_from_slice(&(info.ggml_type as u16).to_le_bytes());
762
763 let m_idx = if *layer == P64_LAYER_GLOBAL {
764 total_layers
765 } else {
766 *layer as u32
767 };
768 out[e_off + 8..e_off + 12].copy_from_slice(&m_idx.to_le_bytes()); out[e_off + 12..e_off + 16].copy_from_slice(&info.n_dims.to_le_bytes());
771 out[e_off + 16..e_off + 20].copy_from_slice(&(info.dims[0] as u32).to_le_bytes());
772 out[e_off + 20..e_off + 24].copy_from_slice(&(info.dims[1] as u32).to_le_bytes());
773 out[e_off + 24..e_off + 28].copy_from_slice(&(info.dims[2] as u32).to_le_bytes());
774 out[e_off + 28..e_off + 32].copy_from_slice(&(info.dims[3] as u32).to_le_bytes());
775 out[e_off + 32..e_off + 36].copy_from_slice(&(cursor_blob as u32).to_le_bytes());
776 out[e_off + 36..e_off + 40].copy_from_slice(&(byte_len as u32).to_le_bytes());
777 out[e_off + 40..e_off + 44].copy_from_slice(&(n_elements as u32).to_le_bytes());
778
779 cursor_blob += byte_len;
780 }
781
782 out[string_table_offset as usize..string_table_offset as usize + string_table.len()]
784 .copy_from_slice(&string_table);
785
786 Ok(out)
787}
788
789pub fn compile_gguf_to_q42(input: &[u8], page_log2: u16) -> Result<Vec<u8>, String> {
791 compile_gguf_to_p64(input, page_log2)
792}
793
794pub fn compile_gguf_to_p64_ternary_ffn(input: &[u8], page_log2: u16) -> Result<Vec<u8>, String> {
801 compile_gguf_to_p64_ffn_quant_awq(input, page_log2, None, 0.0, FfnQuant::Ternary)
802}
803
804pub fn compile_gguf_to_q42_ternary_ffn(input: &[u8], page_log2: u16) -> Result<Vec<u8>, String> {
806 compile_gguf_to_p64_ternary_ffn(input, page_log2)
807}
808
809#[derive(Clone, Copy, PartialEq, Eq, Debug)]
811pub enum FfnQuant {
812 Ternary,
814 Q4_0,
816}
817
818pub fn compile_gguf_to_p64_ternary_ffn_awq(
820 input: &[u8],
821 page_log2: u16,
822 awq_scales: Option<&[Vec<f32>]>,
823 alpha: f32,
824) -> Result<Vec<u8>, String> {
825 compile_gguf_to_p64_ffn_quant_awq(input, page_log2, awq_scales, alpha, FfnQuant::Ternary)
826}
827
828pub fn compile_gguf_to_q42_ternary_ffn_awq(
830 input: &[u8],
831 page_log2: u16,
832 awq_scales: Option<&[Vec<f32>]>,
833 alpha: f32,
834) -> Result<Vec<u8>, String> {
835 compile_gguf_to_p64_ternary_ffn_awq(input, page_log2, awq_scales, alpha)
836}
837
838pub fn compile_gguf_to_p64_q4_ffn_awq(
841 input: &[u8],
842 page_log2: u16,
843 awq_scales: Option<&[Vec<f32>]>,
844 alpha: f32,
845) -> Result<Vec<u8>, String> {
846 compile_gguf_to_p64_ffn_quant_awq(input, page_log2, awq_scales, alpha, FfnQuant::Q4_0)
847}
848
849pub fn compile_gguf_to_q42_q4_ffn_awq(
851 input: &[u8],
852 page_log2: u16,
853 awq_scales: Option<&[Vec<f32>]>,
854 alpha: f32,
855) -> Result<Vec<u8>, String> {
856 compile_gguf_to_p64_q4_ffn_awq(input, page_log2, awq_scales, alpha)
857}
858
859pub fn compile_gguf_to_p64_ffn_quant_awq(
867 input: &[u8],
868 page_log2: u16,
869 awq_scales: Option<&[Vec<f32>]>,
870 alpha: f32,
871 quant: FfnQuant,
872) -> Result<Vec<u8>, String> {
873 use crate::ggml_quants::GGML_TYPE_Q4_0;
874 use crate::llm_kernel_parity::{q4_0_bytes, quantize_q4_0_from_f32};
875 use crate::ternary::{ternary_blob, ternary_blob_len, GGML_TYPE_TERNARY_158};
876
877 let base = compile_gguf_to_p64(input, page_log2)?;
878 let base_index = P64TensorIndex::from_p64(&base)?;
879 let mut header = base_index.header;
880 let hparams = base_index.hparams;
881 let mut entries = base_index.entries;
882 let string_region =
883 base[header.string_table_offset as usize..header.manifold_table_offset as usize].to_vec();
884 let manifold_region =
885 base[header.manifold_table_offset as usize..header.tokenizer_offset as usize].to_vec();
886 let tokenizer_region =
887 base[header.tokenizer_offset as usize..header.checksum_offset as usize].to_vec();
888 drop(base);
889
890 let page = header.page_size as usize;
891 let checksum_start = header.checksum_offset as usize;
892 let checksum_bytes = (entries.len() + 1)
893 .checked_mul(4)
894 .ok_or("p64: checksum table overflow")?;
895 let mut cursor = align_up(checksum_start + checksum_bytes, page);
896 let is_ffn = |role: u16| {
897 matches!(
898 role,
899 P64_ROLE_FFN_GATE | P64_ROLE_FFN_UP | P64_ROLE_FFN_DOWN
900 )
901 };
902 let element_count = |entry: &P64TensorEntry| -> Result<usize, String> {
903 entry.dimensions[..entry.rank as usize]
904 .iter()
905 .try_fold(1usize, |count, dimension| {
906 count.checked_mul((*dimension).max(1) as usize)
907 })
908 .ok_or_else(|| "p64: tensor element count overflow".to_string())
909 };
910
911 for entry in &mut entries {
912 let output_size = if is_ffn(entry.role_id) {
913 let count = element_count(entry)?;
914 match quant {
915 FfnQuant::Ternary => {
916 entry.dtype = u16::try_from(GGML_TYPE_TERNARY_158)
917 .map_err(|_| "p64: ternary type exceeds u16")?;
918 ternary_blob_len(count)
919 }
920 FfnQuant::Q4_0 => {
921 entry.dtype =
922 u16::try_from(GGML_TYPE_Q4_0).map_err(|_| "p64: Q4_0 type exceeds u16")?;
923 q4_0_bytes(count)
924 }
925 }
926 } else {
927 entry.blob_size as usize
928 };
929 cursor = align_up(cursor, page);
930 entry.blob_offset = u32::try_from(cursor).map_err(|_| "p64: container exceeds 4 GiB")?;
931 entry.blob_size = u32::try_from(output_size).map_err(|_| "p64: tensor exceeds 4 GiB")?;
932 cursor = cursor
933 .checked_add(output_size)
934 .ok_or("p64: output size overflow")?;
935 }
936 let total_size = align_up(cursor, 64);
937 if total_size > u32::MAX as usize {
938 return Err("p64: 32-bit relative-offset container exceeds 4 GiB".to_string());
939 }
940 if matches!(quant, FfnQuant::Ternary) {
941 header.flags |= FORMAT_FLAG_TERNARY;
942 } else {
943 header.flags &= !FORMAT_FLAG_TERNARY;
944 }
945
946 let mut output = vec![0u8; total_size];
947 header.write_le(&mut output[..P64_WEIGHT_HEADER_BYTES]);
948 let hparams_start = header.hparams_offset as usize;
949 hparams.write_le(&mut output[hparams_start..hparams_start + 64]);
950 let tensor_table_start = header.tensor_table_offset as usize;
951 for (position, entry) in entries.iter().enumerate() {
952 let start = tensor_table_start + position * P64_TENSOR_ENTRY_BYTES;
953 write_tensor_entry(entry, &mut output[start..start + P64_TENSOR_ENTRY_BYTES]);
954 }
955 let string_start = header.string_table_offset as usize;
956 output[string_start..string_start + string_region.len()].copy_from_slice(&string_region);
957 let manifold_start = header.manifold_table_offset as usize;
958 output[manifold_start..manifold_start + manifold_region.len()]
959 .copy_from_slice(&manifold_region);
960 let tokenizer_start = header.tokenizer_offset as usize;
961 output[tokenizer_start..tokenizer_start + tokenizer_region.len()]
962 .copy_from_slice(&tokenizer_region);
963
964 let source_index = GgufTensorIndex::from_gguf(input);
965 let source_data_start = source_index.tensor_data_start as usize;
966 let awq_enabled = awq_scales.is_some() && alpha != 0.0;
967 let awq_scale = |layer: u32, channel: usize| -> f32 {
968 awq_scales
969 .and_then(|layers| layers.get(layer as usize))
970 .and_then(|channels| channels.get(channel))
971 .copied()
972 .unwrap_or(1.0)
973 .max(1e-6)
974 .powf(alpha)
975 };
976 let mut scratch = Vec::<f32>::new();
977 for (position, entry) in entries.iter().enumerate() {
978 let source_entry = source_index
979 .entries
980 .iter()
981 .find(|(_, info)| info.byte_offset == entry.source_offset)
982 .map(|(_, info)| *info)
983 .ok_or_else(|| format!("p64: source tensor {position} disappeared"))?;
984 let source_size = crate::ggml_quants::tensor_byte_len(&source_entry)
985 .ok_or_else(|| format!("p64: source tensor {position} type is unsupported"))?;
986 let source_start = source_data_start + source_entry.byte_offset as usize;
987 let source_end = source_start + source_size;
988 if source_end > input.len() {
989 return Err(format!("p64: source tensor {position} is out of bounds"));
990 }
991 let target_start = entry.blob_offset as usize;
992 let target_end = target_start + entry.blob_size as usize;
993
994 if is_ffn(entry.role_id) {
995 let count = element_count(entry)?;
996 scratch.resize(count, 0.0);
997 crate::ggml_quants::dequantize_row_into(
998 &input[source_start..source_end],
999 source_entry.ggml_type,
1000 count,
1001 &mut scratch,
1002 )
1003 .map_err(|error| format!("p64: FFN dequantization failed: {error:?}"))?;
1004 if awq_enabled && matches!(entry.role_id, P64_ROLE_FFN_GATE | P64_ROLE_FFN_UP) {
1005 let n_in = entry.dimensions[0] as usize;
1006 let n_out = entry.dimensions[1] as usize;
1007 if n_in > 0 && n_in.saturating_mul(n_out) == count {
1008 for output_channel in 0..n_out {
1009 let row = output_channel * n_in;
1010 for input_channel in 0..n_in {
1011 scratch[row + input_channel] *=
1012 awq_scale(entry.manifold_idx, input_channel);
1013 }
1014 }
1015 }
1016 }
1017 match quant {
1018 FfnQuant::Ternary => {
1019 let blob = ternary_blob(&scratch);
1020 if blob.len() != entry.blob_size as usize {
1021 return Err("p64: ternary output length mismatch".to_string());
1022 }
1023 output[target_start..target_end].copy_from_slice(&blob);
1024 }
1025 FfnQuant::Q4_0 => {
1026 if !quantize_q4_0_from_f32(&scratch, &mut output[target_start..target_end]) {
1027 return Err(format!(
1028 "p64: Q4_0 quantization failed for tensor {position}"
1029 ));
1030 }
1031 }
1032 }
1033 } else if awq_enabled && entry.role_id == P64_ROLE_FFN_NORM {
1034 let count = element_count(entry)?;
1035 match source_entry.ggml_type {
1036 crate::ggml_quants::GGML_TYPE_F32 if source_size >= count * 4 => {
1037 for channel in 0..count {
1038 let source = source_start + channel * 4;
1039 let value =
1040 f32::from_le_bytes(input[source..source + 4].try_into().unwrap())
1041 / awq_scale(entry.manifold_idx, channel);
1042 let target = target_start + channel * 4;
1043 output[target..target + 4].copy_from_slice(&value.to_le_bytes());
1044 }
1045 }
1046 crate::ggml_quants::GGML_TYPE_F16 if source_size >= count * 2 => {
1047 for channel in 0..count {
1048 let source = source_start + channel * 2;
1049 let value =
1050 half::f16::from_le_bytes(input[source..source + 2].try_into().unwrap())
1051 .to_f32()
1052 / awq_scale(entry.manifold_idx, channel);
1053 let target = target_start + channel * 2;
1054 output[target..target + 2]
1055 .copy_from_slice(&half::f16::from_f32(value).to_le_bytes());
1056 }
1057 }
1058 _ => {
1059 return Err(format!(
1060 "p64: AWQ cannot fold FFN norm type {} at manifold {}",
1061 source_entry.ggml_type, entry.manifold_idx
1062 ));
1063 }
1064 }
1065 } else {
1066 if source_size != entry.blob_size as usize {
1067 return Err(format!(
1068 "p64: verbatim tensor {position} changed byte length"
1069 ));
1070 }
1071 output[target_start..target_end].copy_from_slice(&input[source_start..source_end]);
1072 }
1073 let crc = crc32c(&output[target_start..target_end]);
1074 let crc_start = checksum_start + 4 + position * 4;
1075 output[crc_start..crc_start + 4].copy_from_slice(&crc.to_le_bytes());
1076 }
1077 let metadata_crc = crc32c(&output[..checksum_start]);
1078 output[checksum_start..checksum_start + 4].copy_from_slice(&metadata_crc.to_le_bytes());
1079 P64TensorIndex::from_p64(&output)?;
1080 Ok(output)
1081}
1082
1083pub fn compile_gguf_to_q42_ffn_quant_awq(
1085 input: &[u8],
1086 page_log2: u16,
1087 awq_scales: Option<&[Vec<f32>]>,
1088 alpha: f32,
1089 quant: FfnQuant,
1090) -> Result<Vec<u8>, String> {
1091 compile_gguf_to_p64_ffn_quant_awq(input, page_log2, awq_scales, alpha, quant)
1092}