(
&self,
device: &candle_core::MetalDevice,
kernel_name: &'static str,
)
| 60 | } |
| 61 | |
| 62 | fn get_or_create( |
| 63 | &self, |
| 64 | device: &candle_core::MetalDevice, |
| 65 | kernel_name: &'static str, |
| 66 | ) -> Result<candle_metal_kernels::metal::ComputePipeline> { |
| 67 | if let Ok(cache) = self.pipelines.read() { |
| 68 | if let Some(pipeline) = cache.get(kernel_name) { |
| 69 | return Ok(pipeline.clone()); |
| 70 | } |
| 71 | } |
| 72 | let _guard = self.compile_lock.lock().map_err(|e| candle_core::Error::Msg(format!("compile lock: {e}")))?; |
| 73 | if let Ok(cache) = self.pipelines.read() { |
| 74 | if let Some(pipeline) = cache.get(kernel_name) { |
| 75 | return Ok(pipeline.clone()); |
| 76 | } |
| 77 | } |
| 78 | let lib = device.new_library_with_source(FUSED_OPS_MSL, None) |
| 79 | .map_err(|e| candle_core::Error::Msg(format!("metal shader compile: {e}")))?; |
| 80 | let mut cache = self.pipelines.write().map_err(|e| candle_core::Error::Msg(format!("pipeline write lock: {e}")))?; |
| 81 | for &name in ALL_KERNELS { |
| 82 | if cache.contains_key(name) { continue; } |
| 83 | if let Ok(func) = lib.get_function(name, None) { |
| 84 | if let Ok(pipeline) = device.new_compute_pipeline_state_with_function(&func) { |
| 85 | cache.insert(name, pipeline); |
| 86 | } |
| 87 | } |
| 88 | } |
| 89 | cache.get(kernel_name).cloned().ok_or_else(|| { |
| 90 | candle_core::Error::Msg(format!("metal kernel not found: {kernel_name}")) |
| 91 | }) |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | static PIPELINE_CACHE: std::sync::LazyLock<PipelineCache> = std::sync::LazyLock::new(PipelineCache::new); |
no test coverage detected