cubecl_core/codegen/
dump.rs1use cubecl_runtime::config::{CubeClRuntimeConfig, RuntimeConfig};
2use pliron::pass::PMConfig;
3
4#[derive(Clone, Debug, Default)]
9pub struct KernelDump {
10 #[cfg(feature = "std")]
11 dir: Option<std::path::PathBuf>,
12}
13
14impl KernelDump {
15 #[must_use]
17 #[cfg_attr(not(feature = "std"), allow(unused_variables))]
18 pub fn new(kernel_name: &str) -> Self {
19 Self {
20 #[cfg(feature = "std")]
21 dir: kernel_dir(kernel_name),
22 }
23 }
24
25 #[must_use]
27 pub fn is_enabled(&self) -> bool {
28 #[cfg(feature = "std")]
29 return self.dir.is_some();
30 #[cfg(not(feature = "std"))]
31 false
32 }
33
34 #[cfg_attr(not(feature = "std"), allow(unused_variables))]
36 pub fn write<C: AsRef<[u8]>>(&self, file_name: &str, contents: impl FnOnce() -> C) {
37 #[cfg(feature = "std")]
38 if let Some(dir) = &self.dir {
39 let path = dir.join(file_name);
40 if let Err(err) = std::fs::write(&path, contents()) {
41 log::warn!("Can't write the dump file {}: {err}", path.display());
42 }
43 }
44 }
45
46 #[must_use]
49 pub fn pass_config(&self) -> PMConfig {
50 PMConfig {
51 print_after_all: self.is_enabled(),
52 #[cfg(feature = "std")]
53 ir_printing_dir: self.dir.clone(),
54 time_all_passes: CubeClRuntimeConfig::get().compilation.time_passes,
55 ..Default::default()
56 }
57 }
58}
59
60#[cfg(feature = "std")]
62fn kernel_dir(kernel_name: &str) -> Option<std::path::PathBuf> {
63 let root = CubeClRuntimeConfig::get().compilation.dump_dir.clone()?;
64 create_kernel_dir(&root, kernel_name)
65}
66
67#[cfg(feature = "std")]
68fn create_kernel_dir(root: &std::path::Path, kernel_name: &str) -> Option<std::path::PathBuf> {
69 let options = sanitize_filename::Options {
70 replacement: "_",
71 ..Default::default()
72 };
73 let dir = root.join(sanitize_filename::sanitize_with_options(
74 kernel_name,
75 options,
76 ));
77 match std::fs::create_dir_all(&dir) {
78 Ok(()) => Some(dir),
79 Err(err) => {
80 log::warn!("Can't create the dump directory {}: {err}", dir.display());
81 None
82 }
83 }
84}
85
86#[cfg(all(test, feature = "std"))]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn disabled_dump_builds_no_contents() {
92 KernelDump::default().write("never.txt", || -> &[u8] {
93 panic!("contents must not be built")
94 });
95 }
96
97 #[test]
98 fn enabled_dump_writes_to_a_sanitized_kernel_dir() {
99 let root = std::env::temp_dir().join(alloc::format!("cubecl-dump-{}", std::process::id()));
100 let dump = KernelDump {
101 dir: create_kernel_dir(&root, "matmul<f32>/tile"),
102 };
103 dump.write("module.cpp", || "kernel");
104
105 let dir = root.join("matmul_f32__tile");
106 assert_eq!(
107 std::fs::read_to_string(dir.join("module.cpp")).unwrap(),
108 "kernel"
109 );
110 let config = dump.pass_config();
111 assert!(config.print_after_all);
112 assert_eq!(config.ir_printing_dir, Some(dir));
113 std::fs::remove_dir_all(root).unwrap();
114 }
115}