Skip to main content

cubecl_runtime/config/
cache.rs

1/// Cache location options.
2#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
3pub enum CacheConfig {
4    /// Stores cache in the current working directory.
5    #[serde(rename = "local")]
6    Local,
7
8    /// Stores cache in the project's `target` directory (default).
9    #[default]
10    #[serde(rename = "target")]
11    Target,
12
13    /// Stores cache in the system's local configuration directory.
14    #[serde(rename = "global")]
15    Global,
16
17    /// Stores cache in a user-specified file path.
18    #[serde(rename = "file")]
19    File(std::path::PathBuf),
20}
21
22impl CacheConfig {
23    /// Returns the root directory for the cache.
24    pub fn root(&self) -> std::path::PathBuf {
25        match self {
26            Self::Local => std::env::current_dir().unwrap(),
27            Self::Target => {
28                let dir_original =
29                    std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("/"));
30                let mut dir = dir_original.clone();
31
32                // Search for Cargo.toml in parent directories to locate project root.
33                loop {
34                    if let Ok(true) = std::fs::exists(dir.join("Cargo.toml")) {
35                        return dir.join("target");
36                    }
37
38                    if !dir.pop() {
39                        break;
40                    }
41                }
42
43                // No Cargo.toml anywhere above cwd — this is a bundled or
44                // installed application (Tauri, GUI app, CLI installed via
45                // cargo install, etc.) running outside a workspace. The
46                // previous fallback of `dir_original.join("target")` became
47                // `/target` when cwd was `/`, which fails on most platforms
48                // with EROFS (read-only system volume on macOS, root-owned
49                // on Linux) and cascaded a `CacheFile::new` directory
50                // failure into the whole autotune pipeline. Use the
51                // platform-appropriate user cache directory instead.
52                if let Some(cache) = dirs::cache_dir() {
53                    return cache.join("cubecl");
54                }
55                dir_original.join("target")
56            }
57            Self::Global => dirs::config_local_dir().unwrap(),
58            Self::File(path_buf) => path_buf.clone(),
59        }
60    }
61}