use std::sync::{Arc, RwLock};
use fuel_graph::{Graph, NodeId};
use fuel_ir::Result;
use crate::Device;
pub struct Planner;
impl Planner {
pub fn warm(_graph: &Arc<RwLock<Graph>>, _targets: &[NodeId], _device: &Device) -> Result<()> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use fuel_dispatch::pipelined::StorageCache;
use fuel_graph::{Node, Op};
use fuel_ir::{DType, Shape};
use fuel_memory::{BackendStorage, Storage};
fn push_node(g: &mut Graph, op: Op, inputs: Vec<NodeId>) -> NodeId {
g.push(Node {
op,
inputs,
shape: Shape::from_dims(&[4]),
dtype: DType::F32,
})
}
fn cpu_storage_f32(vals: &[f32]) -> Arc<RwLock<Storage>> {
let bytes: &[u8] = bytemuck::cast_slice(vals);
Arc::new(RwLock::new(Storage::new(
BackendStorage::Cpu(fuel_cpu_backend::byte_storage::CpuStorageBytes::from_bytes(
bytes,
)),
DType::F32,
)))
}
#[test]
fn warm_is_noop_and_realize_still_correct() {
let device = crate::Device::cpu();
let graph = Arc::new(RwLock::new(Graph::new()));
let (c1, c2, add) = {
let mut g = graph.write().unwrap();
let c1 = push_node(&mut g, Op::Const, vec![]);
let c2 = push_node(&mut g, Op::Const, vec![]);
let add = push_node(&mut g, Op::Add, vec![c1, c2]);
(c1, c2, add)
};
Planner::warm(&graph, &[add], &device).expect("warm is a no-op Ok");
let mut initial = StorageCache::new();
initial.insert(c1, cpu_storage_f32(&[1.0, 2.0, 3.0, 4.0]));
initial.insert(c2, cpu_storage_f32(&[10.0, 20.0, 30.0, 40.0]));
let out = crate::pipelined_bridge::realize_one_as_with_initial::<f32>(
&graph, add, &device, initial,
)
.expect("realize after warm");
assert_eq!(out, vec![11.0, 22.0, 33.0, 44.0]);
}
#[test]
fn warm_empty_targets_is_noop() {
let graph = Arc::new(RwLock::new(Graph::new()));
Planner::warm(&graph, &[], &crate::Device::cpu()).expect("no-op");
}
}