pxl_rust/kernel/module.rs
1//! Represents a compiled device kernel.
2//!
3//! A `Module` contains one or more device-side functions, and is typically loaded from a file containing compiled code (e.g., `.mubin` format).//!
4//! This module provides a Rust abstraction around the C++ `pxl::Module` class.
5
6use crate::Function;
7use crate::ffi;
8use std::ffi::CString;
9use std::pin::Pin;
10
11/// Represents a compiled device kernel.
12///
13/// This struct wraps a FFI pointer to the C++ `pxl::Module` class.
14/// It provides methods for creating functions.
15pub struct Module {
16 /// Pointer to the underlying FFI `Module` object.
17 inner: *mut ffi::Module,
18}
19
20/// Implementation of the `Module` struct.
21impl Module {
22 /// Creates a new `Module` wrapper from a raw FFI pointer.
23 /// This is called in runtime wrapper APIs requiring an actual `Module` object.
24 /// # Arguments
25 /// * `ptr` - A raw pointer to the underlying FFI `Module` object.
26 /// # Safety
27 /// Caller must ensure that `ptr` is valid and remains valid for the lifetime of `Module`.
28 pub(crate) fn new(filename: &str) -> Self {
29 let filename_cstr = CString::new(filename).expect("Failed to create CString");
30 Module {
31 inner: unsafe { ffi::createModule(filename_cstr.as_ptr() as *const i8) },
32 }
33 }
34
35 /// Destroys the `Module` object.
36 /// # Safety
37 /// Caller must ensure that `module` is valid.
38 /// # Example
39 /// ```
40 /// module.destroy();
41 /// ```
42 pub(crate) fn destroy(&mut self) {
43 if !self.inner.is_null() {
44 unsafe { ffi::destroyModule(self.inner) };
45 self.inner = std::ptr::null_mut();
46 }
47 }
48
49 /// Returns a raw pointer to the underlying FFI `Module` object.
50 /// This is called in runtime wrapper APIs requiring a raw pointer.
51 /// # Safety
52 /// Caller must ensure that `module` is valid.
53 /// # Example
54 /// ```
55 /// let module_ptr = module.get();
56 /// ```
57 pub fn get(&self) -> *mut ffi::Module {
58 self.inner
59 }
60
61 /// Creates a new `Function` object.
62 /// # Arguments
63 /// * `name` - Name of the `Function` to be created.
64 /// # Returns
65 /// A new `Function` object.
66 /// # Safety
67 /// Caller must ensure that `name` is valid and corresponds to an actual function in the module.
68 /// # Example
69 /// ```ignore
70 /// let module = pxl::create_module("tests/mu_kernel.mubin");
71 /// let function = module.create_function("sort_with_ptr");
72 /// ```
73 pub fn create_function(&mut self, name: &str) -> Function {
74 let name_cstr: CString = CString::new(name).expect("Failed to create CString");
75 let function_ptr = unsafe {
76 Pin::new_unchecked(&mut *self.inner).createFunction(name_cstr.as_ptr() as *const i8)
77 };
78 Function::new(function_ptr)
79 }
80
81 /// Destroys the `Function` object.
82 /// # Safety
83 /// Caller must ensure that `function` is valid.
84 /// # Example
85 /// ```
86 /// module.destroy_function(function);
87 /// ```
88 pub fn destroy_function(&self, function: Function) {
89 unsafe { Pin::new_unchecked(&mut *self.inner).destroyFunction(function.get()) };
90 }
91}