use super::abi::*;
use super::sidecar::*;
use core::mem::size_of;
const HEADER: &str = include_str!("../../include/fuel_dlpack_ext.h");
fn rust_size_of(name: &str) -> Option<usize> {
Some(match name {
"DLDevice" => size_of::<DLDevice>(),
"DLDataType" => size_of::<DLDataType>(),
"DLTensor" => size_of::<DLTensor>(),
"DLPackVersion" => size_of::<DLPackVersion>(),
"DLManagedTensorVersioned" => size_of::<DLManagedTensorVersioned>(),
"FDXDTypeExt" => size_of::<FDXDTypeExt>(),
"FDXQuant" => size_of::<FDXQuant>(),
"FDXAffineTerm" => size_of::<FDXAffineTerm>(),
"FDXAffine" => size_of::<FDXAffine>(),
"FDXExtent" => size_of::<FDXExtent>(),
"FDXTiling" => size_of::<FDXTiling>(),
"FDXResidency" => size_of::<FDXResidency>(),
"FDXStorage" => size_of::<FDXStorage>(),
"FDXOutputView" => size_of::<FDXOutputView>(),
"FDXBlockTable" => size_of::<FDXBlockTable>(),
"FDXIndexedResidency" => size_of::<FDXIndexedResidency>(),
"FDXBufferRef" => size_of::<FDXBufferRef>(),
"FDXSymBinding" => size_of::<FDXSymBinding>(),
"FDXSymEnv" => size_of::<FDXSymEnv>(),
"FDXSidecar" => size_of::<FDXSidecar>(),
_ => return None,
})
}
fn parse_sizeof_asserts(text: &str) -> Vec<(String, usize)> {
let mut out = Vec::new();
for line in text.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("_Static_assert(") else {
continue;
};
let Some(rest) = rest.trim_start().strip_prefix("sizeof(") else {
continue;
};
let Some((name, after)) = rest.split_once(')') else {
continue;
};
let name = name.trim();
let after = after.trim_start();
let Some(after) = after.strip_prefix("==") else {
continue;
};
let Some((num, _)) = after.split_once(',') else {
continue;
};
let num = num.trim();
let Ok(n) = num.parse::<usize>() else {
continue; };
out.push((name.to_string(), n));
}
out
}
#[cfg(target_pointer_width = "64")]
#[test]
fn header_struct_sizes_match_rust() {
let asserts = parse_sizeof_asserts(HEADER);
assert!(
!asserts.is_empty(),
"no `_Static_assert(sizeof(...) == N` lines parsed from the header — \
the include path or parser is broken"
);
let known = [
"DLDevice",
"DLDataType",
"DLTensor",
"DLPackVersion",
"DLManagedTensorVersioned",
"FDXDTypeExt",
"FDXQuant",
"FDXAffineTerm",
"FDXAffine",
"FDXExtent",
"FDXTiling",
"FDXResidency",
"FDXStorage",
"FDXOutputView",
"FDXBlockTable",
"FDXIndexedResidency",
"FDXBufferRef",
"FDXSymBinding",
"FDXSymEnv",
"FDXSidecar",
];
let mut seen = std::collections::BTreeSet::new();
for (name, header_n) in &asserts {
let rust_n = rust_size_of(name).unwrap_or_else(|| {
panic!(
"header pins sizeof({name}) == {header_n} but the cross-check \
test has no Rust size_of mapping for `{name}` — add it to \
`rust_size_of`"
)
});
assert_eq!(
*header_n, rust_n,
"header↔Rust size DRIFT: header says sizeof({name}) == {header_n}, \
Rust size_of::<{name}>() == {rust_n}"
);
seen.insert(name.as_str());
}
for k in known {
assert!(
seen.contains(k),
"struct `{k}` is no longer size-pinned by a \
`_Static_assert(sizeof({k}) == N` line in the header — restore it"
);
}
}
fn parse_offsetof_asserts(text: &str) -> Vec<(String, String, usize)> {
let mut out = Vec::new();
for line in text.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("_Static_assert(") else {
continue;
};
let Some(rest) = rest.trim_start().strip_prefix("offsetof(") else {
continue;
};
let Some((args, after)) = rest.split_once(')') else {
continue;
};
let Some((sname, fname)) = args.split_once(',') else {
continue;
};
let after = after.trim_start();
let Some(after) = after.strip_prefix("==") else {
continue;
};
let Some((num, _)) = after.split_once(',') else {
continue;
};
let Ok(n) = num.trim().parse::<usize>() else {
continue; };
out.push((sname.trim().to_string(), fname.trim().to_string(), n));
}
out
}
#[cfg(target_pointer_width = "64")]
#[test]
fn header_field_offsets_match_rust() {
use core::mem::offset_of;
let asserts = parse_offsetof_asserts(HEADER);
assert!(
!asserts.is_empty(),
"no `_Static_assert(offsetof(...) == N` lines parsed from the header"
);
let rust_off = |s: &str, f: &str| -> Option<usize> {
Some(match (s, f) {
("FDXExtent", "kind") => offset_of!(FDXExtent, kind),
("FDXExtent", "_pad") => offset_of!(FDXExtent, _pad),
("FDXExtent", "min") => offset_of!(FDXExtent, min),
("FDXExtent", "capacity") => offset_of!(FDXExtent, capacity),
("FDXExtent", "sym_id") => offset_of!(FDXExtent, sym_id),
("FDXExtent", "sym_scope") => offset_of!(FDXExtent, sym_scope),
("FDXExtent", "_pad2") => offset_of!(FDXExtent, _pad2),
("FDXExtent", "cap_kind") => offset_of!(FDXExtent, cap_kind),
("FDXExtent", "_pad3") => offset_of!(FDXExtent, _pad3),
("FDXExtent", "_pad4") => offset_of!(FDXExtent, _pad4),
("FDXExtent", "affine") => offset_of!(FDXExtent, affine),
("FDXExtent", "reserved") => offset_of!(FDXExtent, reserved),
("FDXIndexedResidency", "logical_extents") => {
offset_of!(FDXIndexedResidency, logical_extents)
}
("FDXIndexedResidency", "context_lens_buffer") => {
offset_of!(FDXIndexedResidency, context_lens_buffer)
}
("FDXIndexedResidency", "context_len_sym") => {
offset_of!(FDXIndexedResidency, context_len_sym)
}
("FDXIndexedResidency", "context_len_scope") => {
offset_of!(FDXIndexedResidency, context_len_scope)
}
("FDXIndexedResidency", "reserved") => {
offset_of!(FDXIndexedResidency, reserved)
}
("FDXSidecar", "gather") => offset_of!(FDXSidecar, gather),
("FDXSidecar", "reserved") => offset_of!(FDXSidecar, reserved),
_ => return None,
})
};
for (s, f, header_n) in &asserts {
let rust_n = rust_off(s, f).unwrap_or_else(|| {
panic!(
"header pins offsetof({s}, {f}) == {header_n} but the \
cross-check has no Rust offset_of! for `{s}.{f}`"
)
});
assert_eq!(
*header_n, rust_n,
"header↔Rust offset DRIFT: header says offsetof({s}, {f}) == \
{header_n}, Rust offset_of!({s}, {f}) == {rust_n}"
);
}
}
fn parse_define_ints(text: &str) -> std::collections::BTreeMap<String, u64> {
let mut out = std::collections::BTreeMap::new();
for line in text.lines() {
let line = line.trim();
let Some(rest) = line.strip_prefix("#define ") else {
continue;
};
let mut it = rest.split_whitespace();
let Some(name) = it.next() else { continue };
let Some(val) = it.next() else { continue };
let val_trim = val.trim_end_matches(['u', 'U', 'l', 'L']);
let parsed = if let Some(hex) = val_trim
.strip_prefix("0x")
.or_else(|| val_trim.strip_prefix("0X"))
{
u64::from_str_radix(hex, 16).ok()
} else {
val_trim.parse::<u64>().ok()
};
if let Some(v) = parsed {
out.insert(name.to_string(), v);
}
}
out
}
#[test]
fn header_define_constants_match_codes() {
use super::codes::*;
let defines = parse_define_ints(HEADER);
macro_rules! check {
($name:literal, $rust:expr) => {{
let got = *defines
.get($name)
.unwrap_or_else(|| panic!("header is missing a parseable `#define {} N`", $name));
assert_eq!(
got, $rust as u64,
"header `#define {}` == {}, codes.rs == {}",
$name, got, $rust as u64
);
}};
}
check!("FDX_MAGIC", FDX_MAGIC);
check!("FDX_VERSION_1", FDX_VERSION_1);
check!("FDX_VERSION_MAX", FDX_VERSION_MAX);
check!("FDX_SYM_NONE", FDX_SYM_NONE);
check!("FDX_DTYPE_NONE", FDX_DTYPE_NONE);
check!("FDX_BUFFER_INLINE", FDX_BUFFER_INLINE);
check!("FDX_BUFFER_NONE", FDX_BUFFER_NONE);
check!("FDX_AFFINE_MAX_TERMS", FDX_AFFINE_MAX_TERMS);
check!("FDX_QUANT_NONE", FDX_QUANT_NONE);
check!("FDX_QUANT_AFFINE_BLOCK", FDX_QUANT_AFFINE_BLOCK);
check!("FDX_DTYPE_F8E8M0", FDX_DTYPE_F8E8M0);
check!("FDX_GGML_BF16", FDX_GGML_BF16);
check!("FDX_BACKEND_METAL", FDX_BACKEND_METAL);
}