use crate::{error::Result, kernels::macros::ops};
use core::ffi::c_void;
ops!(concat, split);
macro_rules! declare_and_dispatch_concat {
($($op:ident),* $(,)?) => {
paste::paste! {
extern "C" {
$(
fn [<$op _bool>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f8e4m3>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f8e5m2>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _bf16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i8>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u8>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
)*
}
unsafe fn dispatch_concat(
name: &str,
input: *const c_void,
output: *mut c_void,
metadata: *const usize,
) {
match name {
$(
concat!(stringify!($op), "_bool") => [<$op _bool>](input, output, metadata),
concat!(stringify!($op), "_f8e4m3") => [<$op _f8e4m3>](input, output, metadata),
concat!(stringify!($op), "_f8e5m2") => [<$op _f8e5m2>](input, output, metadata),
concat!(stringify!($op), "_bf16") => [<$op _bf16>](input, output, metadata),
concat!(stringify!($op), "_f16") => [<$op _f16>](input, output, metadata),
concat!(stringify!($op), "_f32") => [<$op _f32>](input, output, metadata),
concat!(stringify!($op), "_f64") => [<$op _f64>](input, output, metadata),
concat!(stringify!($op), "_i8") => [<$op _i8>](input, output, metadata),
concat!(stringify!($op), "_i16") => [<$op _i16>](input, output, metadata),
concat!(stringify!($op), "_i32") => [<$op _i32>](input, output, metadata),
concat!(stringify!($op), "_i64") => [<$op _i64>](input, output, metadata),
concat!(stringify!($op), "_u8") => [<$op _u8>](input, output, metadata),
concat!(stringify!($op), "_u16") => [<$op _u16>](input, output, metadata),
concat!(stringify!($op), "_u32") => [<$op _u32>](input, output, metadata),
concat!(stringify!($op), "_u64") => [<$op _u64>](input, output, metadata),
)*
_ => panic!("Unknown concat operation: {}", name),
}
}
}
};
}
macro_rules! declare_and_dispatch_split {
($($op:ident),* $(,)?) => {
paste::paste! {
extern "C" {
$(
fn [<$op _bool>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f8e4m3>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f8e5m2>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _bf16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _f64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i8>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _i64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u8>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u16>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u32>](input: *const c_void, output: *mut c_void, metadata: *const usize);
fn [<$op _u64>](input: *const c_void, output: *mut c_void, metadata: *const usize);
)*
}
unsafe fn dispatch_split(
name: &str,
input: *const c_void,
output: *mut c_void,
metadata: *const usize,
) {
match name {
$(
concat!(stringify!($op), "_bool") => [<$op _bool>](input, output, metadata),
concat!(stringify!($op), "_f8e4m3") => [<$op _f8e4m3>](input, output, metadata),
concat!(stringify!($op), "_f8e5m2") => [<$op _f8e5m2>](input, output, metadata),
concat!(stringify!($op), "_bf16") => [<$op _bf16>](input, output, metadata),
concat!(stringify!($op), "_f16") => [<$op _f16>](input, output, metadata),
concat!(stringify!($op), "_f32") => [<$op _f32>](input, output, metadata),
concat!(stringify!($op), "_f64") => [<$op _f64>](input, output, metadata),
concat!(stringify!($op), "_i8") => [<$op _i8>](input, output, metadata),
concat!(stringify!($op), "_i16") => [<$op _i16>](input, output, metadata),
concat!(stringify!($op), "_i32") => [<$op _i32>](input, output, metadata),
concat!(stringify!($op), "_i64") => [<$op _i64>](input, output, metadata),
concat!(stringify!($op), "_u8") => [<$op _u8>](input, output, metadata),
concat!(stringify!($op), "_u16") => [<$op _u16>](input, output, metadata),
concat!(stringify!($op), "_u32") => [<$op _u32>](input, output, metadata),
concat!(stringify!($op), "_u64") => [<$op _u64>](input, output, metadata),
)*
_ => panic!("Unknown split operation: {}", name),
}
}
}
};
}
declare_and_dispatch_concat!(concat);
declare_and_dispatch_split!(split);
pub fn call_ops_concat(
kernel_name: crate::kernels::macros::Kernel,
input: *const c_void,
output: *mut c_void,
metadata: &[usize],
) -> Result<()> {
unsafe {
dispatch_concat(kernel_name.0, input, output, metadata.as_ptr());
}
Ok(())
}
pub fn call_ops_split(
kernel_name: crate::kernels::macros::Kernel,
input: *const c_void,
output: *mut c_void,
metadata: &[usize],
) -> Result<()> {
unsafe {
dispatch_split(kernel_name.0, input, output, metadata.as_ptr());
}
Ok(())
}