extern crate self as svod_model;
use svod_macros::jit_wrapper;
use svod_tensor::{PrepareConfig, Tensor};
use crate::jit::InputSpec;
struct AddModel;
impl AddModel {
fn forward(&self, x: &Tensor, y: &Tensor) -> crate::jit::Result<Tensor> {
x.try_add(y).map_err(|e| crate::jit::JitError::Tensor { source: Box::new(e) })
}
}
jit_wrapper! {
AddJit(AddModel) {
x: Tensor,
y: Tensor,
build(x, y) {
model.forward(x, y)
}
}
}
#[test]
fn test_jit_single_input_prepare_and_execute() {
let mut jit = AddJit::new(AddModel);
let cfg = PrepareConfig::default();
jit.prepare_with_config(InputSpec::f32(&[3]), InputSpec::f32(&[3]), &cfg).unwrap();
copy_tensor_to_buffer(&Tensor::from_slice([1.0f32, 2.0, 3.0]), jit.x_mut().unwrap());
copy_tensor_to_buffer(&Tensor::from_slice([10.0f32, 20.0, 30.0]), jit.y_mut().unwrap());
jit.execute().unwrap();
let output = jit.output().unwrap();
let mut result = vec![0.0f32; 3];
output.copyout(unsafe { std::slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, 12) }).unwrap();
assert_eq!(result, vec![11.0, 22.0, 33.0]);
}
#[test]
fn test_jit_replay() {
let mut jit = AddJit::new(AddModel);
jit.prepare(InputSpec::f32(&[3]), InputSpec::f32(&[3])).unwrap();
copy_tensor_to_buffer(&Tensor::from_slice([1.0f32, 2.0, 3.0]), jit.x_mut().unwrap());
copy_tensor_to_buffer(&Tensor::from_slice([10.0f32, 20.0, 30.0]), jit.y_mut().unwrap());
jit.execute().unwrap();
copy_tensor_to_buffer(&Tensor::from_slice([100.0f32, 200.0, 300.0]), jit.x_mut().unwrap());
copy_tensor_to_buffer(&Tensor::from_slice([1.0f32, 2.0, 3.0]), jit.y_mut().unwrap());
jit.execute().unwrap();
let output = jit.output().unwrap();
let mut result = vec![0.0f32; 3];
output.copyout(unsafe { std::slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, 12) }).unwrap();
assert_eq!(result, vec![101.0, 202.0, 303.0]);
}
#[test]
fn test_jit_multiple_replays() {
let mut jit = AddJit::new(AddModel);
jit.prepare(InputSpec::f32(&[3]), InputSpec::f32(&[3])).unwrap();
for i in 0..5 {
copy_tensor_to_buffer(&Tensor::from_slice([i as f32; 3]), jit.x_mut().unwrap());
copy_tensor_to_buffer(&Tensor::from_slice([(i + 1) as f32; 3]), jit.y_mut().unwrap());
jit.execute().unwrap();
let output = jit.output().unwrap();
let mut result = vec![0.0f32; 3];
output.copyout(unsafe { std::slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, 12) }).unwrap();
assert_eq!(result, vec![(i + i + 1) as f32; 3]);
}
}
#[test]
fn test_jit_profiled_execution_apis() {
let mut jit = AddJit::new(AddModel);
jit.prepare(InputSpec::f32(&[3]), InputSpec::f32(&[3])).unwrap();
copy_tensor_to_buffer(&Tensor::from_slice([1.0f32, 2.0, 3.0]), jit.x_mut().unwrap());
copy_tensor_to_buffer(&Tensor::from_slice([10.0f32, 20.0, 30.0]), jit.y_mut().unwrap());
let profiles = jit.execute_profiled().unwrap();
assert!(!profiles.is_empty(), "expected at least one kernel profile");
let profiles_with_vars = jit.execute_with_vars_profiled(&[]).unwrap();
assert!(!profiles_with_vars.is_empty(), "expected at least one kernel profile with vars");
let output = jit.output().unwrap();
let mut result = vec![0.0f32; 3];
output.copyout(unsafe { std::slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, 12) }).unwrap();
assert_eq!(result, vec![11.0, 22.0, 33.0]);
}
fn copy_tensor_to_buffer(tensor: &Tensor, dst: &mut svod_device::Buffer) {
let src_buf = tensor.buffer().unwrap();
let mut data = vec![0u8; src_buf.size()];
src_buf.copyout(&mut data).unwrap();
dst.copyin(&data).unwrap();
}