{"record":{"id":"0583b4423b3144ea","repo":"huggingface/candle","slug":"not-implemented-yet-self-device-device","errorCode":null,"errorMessage":"not implemented yet, self.device: {:?}, device: {:?}","messagePattern":"not implemented yet, self\\.device: (.+?), device: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/tensor.rs","lineNumber":2416,"sourceCode":"            Ok(self.clone())\n        } else {\n            let storage = match (&*self.storage(), device) {\n                (Storage::Cpu(storage), Device::Cuda(cuda)) => {\n                    Storage::Cuda(cuda.storage_from_cpu_storage(storage)?)\n                }\n                (Storage::Cpu(storage), Device::Metal(metal)) => {\n                    Storage::Metal(metal.storage_from_cpu_storage(storage)?)\n                }\n                (Storage::Cuda(storage), Device::Cpu) => Storage::Cpu(storage.to_cpu_storage()?),\n                (Storage::Metal(storage), Device::Cpu) => Storage::Cpu(storage.to_cpu_storage()?),\n                (Storage::Cuda(storage), Device::Cuda(cuda)) => {\n                    // can't clone storage if it's the same device because of the underlying device ptr\n                    let dst_storage = storage.transfer_to_device(cuda)?;\n                    Storage::Cuda(dst_storage)\n                }\n                (Storage::Cpu(storage), Device::Cpu) => Storage::Cpu(storage.clone()),\n                _ => {\n                    bail!(\n                        \"not implemented yet, self.device: {:?}, device: {:?}\",\n                        self.device(),\n                        device\n                    )\n                }\n            };\n            let op = BackpropOp::new1(self, Op::ToDevice);\n            let tensor_ = Tensor_ {\n                id: TensorId::new(),\n                storage: Arc::new(RwLock::new(storage)),\n                layout: self.layout.clone(),\n                op,\n                is_variable: false,\n                dtype: self.dtype,\n                device: device.clone(),\n            };\n            Ok(Tensor(Arc::new(tensor_)))\n        }","sourceCodeStart":2398,"sourceCodeEnd":2434,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/tensor.rs#L2398-L2434","documentation":"Tensor::to_device (and related device-transfer paths) only implements transfers for known storage/device combinations: Cpu->Cuda, Cuda->Cpu, Cpu->Cpu, and Cuda->Cuda. Any other combination, such as transfers involving Metal storage or an unexpected Storage variant, hits the catch-all arm and bails with this message, reporting the tensor's current device and the requested target device.","triggerScenarios":"Calling tensor.to_device(Device::Cpu) on a Metal-backed tensor, or to_device between devices where the (Storage, Device) pattern match falls into the `_` arm (e.g. Storage::Cuda with Device::Metal, or a device variant lacking a transfer implementation).","commonSituations":"Running models on Metal or other backends and then calling .to_device() assuming CPU/GPU transfer support exists; mixing backends after loading a model saved from a different device setup; code written for CUDA builds being reused on Metal builds.","solutions":["Check which device pair is unsupported and upgrade candle to a version that implements transfer_to_device for that backend","Transfer via an intermediate device explicitly (e.g. Metal -> Cpu -> Cuda) only if both individual paths are implemented","Avoid the unsupported transfer: keep the tensor on its original device and pass the target device at model load/creation time","Use backend-appropriate APIs (e.g. Metal tensor methods) instead of generic to_device"],"exampleFix":"// before\nlet t = t.to_device(&Device::Cpu)?; // Metal tensor: bails 'not implemented yet'\n// after\n// compile with the cuda feature or verify self.device() supports the transfer first\nlet t = if t.device().is_cuda() || t.device().is_cpu() { t.to_device(&Device::Cpu)? } else { t };","handlingStrategy":"validation","validationCode":"fn can_transfer(dev: &candle_core::Device, target: &candle_core::Device) -> bool {\n    use candle_core::Device::*;\n    matches!((dev, target), (Cpu, Cpu) | (Cpu, Cuda(_)) | (Cuda(_), Cpu) | (Cuda(_), Cuda(_)))\n}\n// call: assert!(can_transfer(&t.device(), &target_device));","typeGuard":null,"tryCatchPattern":"match t.to_device(&target) {\n    Ok(v) => v,\n    Err(e) if e.to_string().contains(\"not implemented yet\") => fallback_cpu_path(),\n    Err(e) => return Err(e),\n}","preventionTips":["Only call to_device on Cpu/Cuda pairs unless you've confirmed backend support","Feature-gate device transfer code by the backend you compiled with","Keep tensors on one device for a model's lifetime; transfer only at load/IO boundaries"],"tags":["rust","candle","device-transfer","unimplemented"],"backgroundTag":"device-transfer-not-implemented","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}