// @generated by smolvm-cuda-codegen — do not edit. lib='cudnn' id=2
pub struct GenLib { _lib: Library,
    f_cudnnCreate: unsafe extern "C" fn(*mut *mut c_void) -> c_int,
    f_cudnnDestroy: unsafe extern "C" fn(*mut c_void) -> c_int,
    f_cudnnSetStream: unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_int,
    f_cudnnCreateTensorDescriptor: unsafe extern "C" fn(*mut *mut c_void) -> c_int,
    f_cudnnSetTensor4dDescriptor: unsafe extern "C" fn(*mut c_void, c_int, c_int, c_int, c_int, c_int, c_int) -> c_int,
    f_cudnnDestroyTensorDescriptor: unsafe extern "C" fn(*mut c_void) -> c_int,
    f_cudnnCreateFilterDescriptor: unsafe extern "C" fn(*mut *mut c_void) -> c_int,
    f_cudnnSetFilter4dDescriptor: unsafe extern "C" fn(*mut c_void, c_int, c_int, c_int, c_int, c_int, c_int) -> c_int,
    f_cudnnDestroyFilterDescriptor: unsafe extern "C" fn(*mut c_void) -> c_int,
    f_cudnnCreateConvolutionDescriptor: unsafe extern "C" fn(*mut *mut c_void) -> c_int,
    f_cudnnSetConvolution2dDescriptor: unsafe extern "C" fn(*mut c_void, c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_int) -> c_int,
    f_cudnnDestroyConvolutionDescriptor: unsafe extern "C" fn(*mut c_void) -> c_int,
    f_cudnnGetConvolutionForwardWorkspaceSize: unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void, *mut c_void, *mut c_void, c_int, *mut usize) -> c_int,
    f_cudnnConvolutionForward: unsafe extern "C" fn(*mut c_void, *const f32, *mut c_void, *mut c_void, *mut c_void, *mut c_void, *mut c_void, c_int, *mut c_void, usize, *const f32, *mut c_void, *mut c_void) -> c_int,
}
impl GenLib {
    pub fn load() -> Result<GenLib, String> {
        unsafe {
            let lib = super::open_host_lib("SMOLVM_CUDNN_LIB", &["libcudnn.so", "libcudnn.so.9", "libcudnn.so.8"])?;
            Ok(GenLib {
                f_cudnnCreate: sym(&lib, b"cudnnCreate\0")?,
                f_cudnnDestroy: sym(&lib, b"cudnnDestroy\0")?,
                f_cudnnSetStream: sym(&lib, b"cudnnSetStream\0")?,
                f_cudnnCreateTensorDescriptor: sym(&lib, b"cudnnCreateTensorDescriptor\0")?,
                f_cudnnSetTensor4dDescriptor: sym(&lib, b"cudnnSetTensor4dDescriptor\0")?,
                f_cudnnDestroyTensorDescriptor: sym(&lib, b"cudnnDestroyTensorDescriptor\0")?,
                f_cudnnCreateFilterDescriptor: sym(&lib, b"cudnnCreateFilterDescriptor\0")?,
                f_cudnnSetFilter4dDescriptor: sym(&lib, b"cudnnSetFilter4dDescriptor\0")?,
                f_cudnnDestroyFilterDescriptor: sym(&lib, b"cudnnDestroyFilterDescriptor\0")?,
                f_cudnnCreateConvolutionDescriptor: sym(&lib, b"cudnnCreateConvolutionDescriptor\0")?,
                f_cudnnSetConvolution2dDescriptor: sym(&lib, b"cudnnSetConvolution2dDescriptor\0")?,
                f_cudnnDestroyConvolutionDescriptor: sym(&lib, b"cudnnDestroyConvolutionDescriptor\0")?,
                f_cudnnGetConvolutionForwardWorkspaceSize: sym(&lib, b"cudnnGetConvolutionForwardWorkspaceSize\0")?,
                f_cudnnConvolutionForward: sym(&lib, b"cudnnConvolutionForward\0")?,
                _lib: lib,
            })
        }
    }
    pub fn dispatch(&self, func: u16, args: &[u8], __vh: &mut std::collections::HashMap<u64, u64>, __streams: &std::collections::HashMap<u64, u64>) -> (i32, Vec<u8>) {
        let mut __c = GenCur { b: args, p: 0 };
        let _ = __streams;
        match func {
            0 => { let mut h: *mut c_void = std::ptr::null_mut(); let st = unsafe { (self.f_cudnnCreate)(&mut h) }; if st == 0 && args.len() >= 8 { let id = u64::from_le_bytes(args[..8].try_into().unwrap()); if id & super::VHANDLE_TAG != 0 { __vh.insert(id, h as u64); if std::env::var_os("SMOLVM_CUDA_HOST_OPLOG").is_some() { eprintln!("[vh-insert] pid={} id={id:#x}", std::process::id()); } } } (st, (h as u64).to_le_bytes().to_vec()) }
            1 => {
                let __raw = __c.u64();
                let handle = super::vh_resolve(__vh, __raw) as *mut c_void;
                if __raw & super::VHANDLE_TAG != 0 { __vh.remove(&__raw); }
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnDestroy)(handle) };
                (st, out)
            }
            2 => {
                let handle = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let stream = super::stream_resolve(__streams, __c.u64()) as *mut c_void;
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnSetStream)(handle, stream) };
                (st, out)
            }
            3 => { let mut h: *mut c_void = std::ptr::null_mut(); let st = unsafe { (self.f_cudnnCreateTensorDescriptor)(&mut h) }; if st == 0 && args.len() >= 8 { let id = u64::from_le_bytes(args[..8].try_into().unwrap()); if id & super::VHANDLE_TAG != 0 { __vh.insert(id, h as u64); if std::env::var_os("SMOLVM_CUDA_HOST_OPLOG").is_some() { eprintln!("[vh-insert] pid={} id={id:#x}", std::process::id()); } } } (st, (h as u64).to_le_bytes().to_vec()) }
            4 => {
                let t = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let fmt = __c.i32();
                let dtype = __c.i32();
                let n = __c.i32();
                let c = __c.i32();
                let h = __c.i32();
                let w = __c.i32();
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnSetTensor4dDescriptor)(t, fmt as c_int, dtype as c_int, n as c_int, c as c_int, h as c_int, w as c_int) };
                (st, out)
            }
            5 => {
                let __raw = __c.u64();
                let t = super::vh_resolve(__vh, __raw) as *mut c_void;
                if __raw & super::VHANDLE_TAG != 0 { __vh.remove(&__raw); }
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnDestroyTensorDescriptor)(t) };
                (st, out)
            }
            6 => { let mut h: *mut c_void = std::ptr::null_mut(); let st = unsafe { (self.f_cudnnCreateFilterDescriptor)(&mut h) }; if st == 0 && args.len() >= 8 { let id = u64::from_le_bytes(args[..8].try_into().unwrap()); if id & super::VHANDLE_TAG != 0 { __vh.insert(id, h as u64); if std::env::var_os("SMOLVM_CUDA_HOST_OPLOG").is_some() { eprintln!("[vh-insert] pid={} id={id:#x}", std::process::id()); } } } (st, (h as u64).to_le_bytes().to_vec()) }
            7 => {
                let f = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let dtype = __c.i32();
                let fmt = __c.i32();
                let k = __c.i32();
                let c = __c.i32();
                let h = __c.i32();
                let w = __c.i32();
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnSetFilter4dDescriptor)(f, dtype as c_int, fmt as c_int, k as c_int, c as c_int, h as c_int, w as c_int) };
                (st, out)
            }
            8 => {
                let __raw = __c.u64();
                let f = super::vh_resolve(__vh, __raw) as *mut c_void;
                if __raw & super::VHANDLE_TAG != 0 { __vh.remove(&__raw); }
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnDestroyFilterDescriptor)(f) };
                (st, out)
            }
            9 => { let mut h: *mut c_void = std::ptr::null_mut(); let st = unsafe { (self.f_cudnnCreateConvolutionDescriptor)(&mut h) }; if st == 0 && args.len() >= 8 { let id = u64::from_le_bytes(args[..8].try_into().unwrap()); if id & super::VHANDLE_TAG != 0 { __vh.insert(id, h as u64); if std::env::var_os("SMOLVM_CUDA_HOST_OPLOG").is_some() { eprintln!("[vh-insert] pid={} id={id:#x}", std::process::id()); } } } (st, (h as u64).to_le_bytes().to_vec()) }
            10 => {
                let cv = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let pad_h = __c.i32();
                let pad_w = __c.i32();
                let u = __c.i32();
                let v = __c.i32();
                let dil_h = __c.i32();
                let dil_w = __c.i32();
                let mode = __c.i32();
                let ctype = __c.i32();
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnSetConvolution2dDescriptor)(cv, pad_h as c_int, pad_w as c_int, u as c_int, v as c_int, dil_h as c_int, dil_w as c_int, mode as c_int, ctype as c_int) };
                (st, out)
            }
            11 => {
                let __raw = __c.u64();
                let cv = super::vh_resolve(__vh, __raw) as *mut c_void;
                if __raw & super::VHANDLE_TAG != 0 { __vh.remove(&__raw); }
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnDestroyConvolutionDescriptor)(cv) };
                (st, out)
            }
            12 => {
                let handle = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let x = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let w = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let cv = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let y = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let algo = __c.i32();
                let mut size_v: usize = 0 as usize;
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnGetConvolutionForwardWorkspaceSize)(handle, x, w, cv, y, algo as c_int, &mut size_v) };
                out.extend_from_slice(&(size_v as u64).to_le_bytes());
                (st, out)
            }
            13 => {
                let handle = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let alpha_v = __c.f32();
                let xDesc = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let x = super::dptr_resolve(__c.u64()) as *mut c_void;
                let wDesc = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let w = super::dptr_resolve(__c.u64()) as *mut c_void;
                let convDesc = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let algo = __c.i32();
                let workspace = super::dptr_resolve(__c.u64()) as *mut c_void;
                let wsSize = __c.u64();
                let beta_v = __c.f32();
                let yDesc = super::vh_resolve(__vh, __c.u64()) as *mut c_void;
                let y = super::dptr_resolve(__c.u64()) as *mut c_void;
                let mut out = Vec::new();
                let st = unsafe { (self.f_cudnnConvolutionForward)(handle, &alpha_v, xDesc, x, wDesc, w, convDesc, algo as c_int, workspace, wsSize as usize, &beta_v, yDesc, y) };
                (st, out)
            }
            _ => (super::super::CUDA_ERROR_NOT_FOUND, Vec::new()),
        }
    }
}
struct GenCur<'a> { b: &'a [u8], p: usize }
impl GenCur<'_> {
    fn take(&mut self, n: usize) -> [u8; 8] { let mut o = [0u8; 8]; let end = (self.p + n).min(self.b.len()); o[..end - self.p].copy_from_slice(&self.b[self.p..end]); self.p = end; o }
    fn u16(&mut self) -> u16 { u16::from_le_bytes(self.take(2)[..2].try_into().unwrap()) }
    fn i32(&mut self) -> i32 { i32::from_le_bytes(self.take(4)[..4].try_into().unwrap()) }
    fn i64(&mut self) -> i64 { i64::from_le_bytes(self.take(8)) }
    fn u64(&mut self) -> u64 { u64::from_le_bytes(self.take(8)) }
    fn f32(&mut self) -> f32 { f32::from_le_bytes(self.take(4)[..4].try_into().unwrap()) }
    fn f64(&mut self) -> f64 { f64::from_le_bytes(self.take(8)) }
}
