zernel_ebpf/consumers/
cuda_trace.rs

1// Copyright (C) 2026 Dyber, Inc. — GPL-2.0
2
3use serde::Serialize;
4
5/// CUDA kernel launch event from BPF uprobe on cuLaunchKernel.
6/// Layout must match struct zernel_cuda_event in common.h.
7#[derive(Debug, Clone, Serialize)]
8#[repr(C)]
9pub struct CudaLaunchEvent {
10    pub pid: u32,
11    _pad: u32,
12    pub kernel_hash: u64,
13    pub launch_ns: u64,
14    pub return_ns: u64,
15    pub latency_ns: u64,
16}
17
18pub struct CudaTraceConsumer;
19
20impl CudaTraceConsumer {
21    pub fn new() -> Self {
22        Self
23    }
24
25    pub fn process_event(&self, raw: &[u8]) -> Option<CudaLaunchEvent> {
26        if raw.len() < std::mem::size_of::<CudaLaunchEvent>() {
27            return None;
28        }
29        let event = unsafe { &*(raw.as_ptr() as *const CudaLaunchEvent) };
30        Some(event.clone())
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn deserialize_cuda_event() {
40        let event = CudaLaunchEvent {
41            pid: 5678,
42            _pad: 0,
43            kernel_hash: 0xDEADBEEF,
44            launch_ns: 1000,
45            return_ns: 1142,
46            latency_ns: 142,
47        };
48
49        let raw = unsafe {
50            std::slice::from_raw_parts(
51                &event as *const CudaLaunchEvent as *const u8,
52                std::mem::size_of::<CudaLaunchEvent>(),
53            )
54        };
55
56        let consumer = CudaTraceConsumer::new();
57        let result = consumer.process_event(raw).unwrap();
58        assert_eq!(result.pid, 5678);
59        assert_eq!(result.latency_ns, 142);
60    }
61}