#![cfg(feature = "serialize")]
use crate::hir::HirModule;
use crate::lir::LirModule;
pub fn hir_to_json(hir: &HirModule) -> Result<String, serde_json::Error> {
serde_json::to_string(hir)
}
pub fn hir_from_json(s: &str) -> Result<HirModule, serde_json::Error> {
serde_json::from_str(s)
}
pub fn lir_to_json(lir: &LirModule) -> Result<String, serde_json::Error> {
serde_json::to_string(lir)
}
pub fn lir_from_json(s: &str) -> Result<LirModule, serde_json::Error> {
serde_json::from_str(s)
}
const LIR_BIN_MAGIC: &[u8; 8] = b"RLXLIR01";
pub const LIR_BIN_VERSION: u32 = 2;
pub fn lir_to_bytes(lir: &LirModule) -> Result<Vec<u8>, bincode::Error> {
let body = bincode::serialize(lir)?;
let mut out = Vec::with_capacity(12 + body.len());
out.extend_from_slice(LIR_BIN_MAGIC);
out.extend_from_slice(&LIR_BIN_VERSION.to_le_bytes());
out.extend_from_slice(&body);
Ok(out)
}
pub fn lir_from_bytes(b: &[u8]) -> Result<LirModule, bincode::Error> {
if b.len() >= 12 && &b[..8] == LIR_BIN_MAGIC {
let ver = u32::from_le_bytes(b[8..12].try_into().unwrap());
if ver != LIR_BIN_VERSION {
return Err(Box::new(bincode::ErrorKind::Custom(format!(
"LIR binary schema version {ver} != current {LIR_BIN_VERSION} (stale AOT cache)"
))));
}
return bincode::deserialize(&b[12..]);
}
bincode::deserialize(b)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::DType;
use crate::Shape;
use crate::hir::HirModule;
#[test]
fn hir_module_json_roundtrip() {
let mut hir = HirModule::new("serde_test");
let x = hir.input("x", Shape::new(&[2, 4], DType::F32));
let w = hir.param("w", Shape::new(&[4, 3], DType::F32));
let y = hir.linear(x, w, None, None, Shape::new(&[2, 3], DType::F32));
hir.set_outputs(vec![y]);
let json = hir_to_json(&hir).expect("serialize HIR");
let back = hir_from_json(&json).expect("deserialize HIR");
assert_eq!(back.name, hir.name);
assert_eq!(back.len(), hir.len());
assert_eq!(back.outputs, hir.outputs);
}
}