Skip to main content

ferrum_testkit/op_diff/
activation_bridge.rs

1//! `activation_bridge` op-diff harness — see `crate::op_diff`.
2//!
3//! Exercises the buffer-plumbing path each backend uses to move activations
4//! host<->device: `from_slice` upload, `copy_slice` device-to-device, and
5//! `to_vec` readback. Compared at the fp16-storage tolerance since Metal/CUDA
6//! store activations as f16.
7
8use super::{random_vec, OpUnderTest, Output};
9
10pub struct ActivationBridgeOp {
11    pub len: usize,
12}
13
14macro_rules! run_backend {
15    ($B:ty, $self:expr, $seed:expr) => {{
16        use ferrum_kernels::backend::Backend;
17        let data = random_vec($self.len, -2.0, 2.0, $seed);
18        let mut ctx = <$B>::new_context();
19        let src = <$B>::from_slice(&data);
20        let mut dst = <$B>::alloc($self.len);
21        <$B>::copy_slice(&mut ctx, &src, 0, &mut dst, 0, $self.len);
22        <$B>::sync(&mut ctx);
23        <$B>::to_vec(&dst, $self.len)
24    }};
25}
26
27impl OpUnderTest for ActivationBridgeOp {
28    fn name(&self) -> &str {
29        "activation_bridge"
30    }
31
32    fn run_cpu(&self, seed: u64) -> Output {
33        run_backend!(ferrum_kernels::backend::cpu::CpuBackend, self, seed)
34    }
35
36    #[cfg(all(target_os = "macos", feature = "metal"))]
37    fn run_metal(&self, seed: u64) -> Output {
38        run_backend!(ferrum_kernels::backend::metal::MetalBackend, self, seed)
39    }
40
41    #[cfg(feature = "cuda")]
42    fn run_cuda(&self, seed: u64) -> Output {
43        run_backend!(ferrum_kernels::backend::cuda::CudaBackend, self, seed)
44    }
45}