{"record":{"id":"7d764c60fccd49ac","repo":"tracel-ai/burn","slug":"device-gradient-checkpointing-requires-autodiff","errorCode":null,"errorMessage":"Device::gradient_checkpointing requires autodiff; call Device::autodiff first","messagePattern":"Device::gradient_checkpointing requires autodiff; call Device::autodiff first","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-tensor/src/device.rs","lineNumber":606,"sourceCode":"    ///\n    /// ```rust,ignore\n    /// let device = Device::default().autodiff().gradient_checkpointing();\n    /// ```\n    ///\n    /// # Panics\n    ///\n    /// Panics if autodiff is not enabled on this device.\n    #[cfg(feature = \"autodiff\")]\n    #[must_use]\n    pub fn gradient_checkpointing(self) -> Self {\n        match self.into_dispatch() {\n            DispatchDevice::Autodiff(device) => {\n                Self::new(DispatchDevice::autodiff_with_gradient_checkpointing(\n                    device.inner(),\n                    GradientCheckpointingStrategy::Balanced,\n                ))\n            }\n            _ => panic!(\n                \"Device::gradient_checkpointing requires autodiff; call Device::autodiff first\"\n            ),\n        }\n    }\n\n    /// Returns this device without its autodiff association.\n    ///\n    /// If autodiff is not enabled, the device is returned unchanged. This operation is idempotent.\n    ///\n    /// # Example\n    ///\n    /// ```rust,ignore\n    /// let device = Device::default().autodiff();\n    /// let inference_device = device.without_autodiff();\n    ///\n    /// assert!(!inference_device.is_autodiff());\n    /// ```\n    #[must_use]","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-tensor/src/device.rs#L588-L624","documentation":"Burn's Device wrapper can enable gradient checkpointing only on an autodiff device (DispatchDevice::Autodiff). Calling Device::gradient_checkpointing on a plain backend device panics with this message, because checkpointing is a training-time autodiff feature with no meaning without a backward pass. The intended workflow is device.autodiff() first, then gradient_checkpointing().","triggerScenarios":"Calling gradient_checkpointing() directly on a device created from a non-autodiff backend (e.g. Wgpu/Cpu without Autodiff wrapper); calling it before Device::autodiff in the setup code; wrapping order mistakes where the autodiff layer was applied to a different device instance than the one checkpointing is requested on.","commonSituations":"Enabling gradient checkpointing to fit a large model in memory during training but forgetting the .autodiff() wrapper; copying training setup code between a script that used Autodiff<Backend> and one that uses a plain backend; refactors that moved autodiff wrapping into a config so the runtime device is no longer an autodiff variant.","solutions":["Wrap the backend in autodiff first: let dev = device.autodiff(); then call dev.gradient_checkpointing()","Verify the device you call gradient_checkpointing on is the Autodiff-wrapped instance, not the raw backend device","If you only need inference, remove the gradient_checkpointing call entirely — it is meaningless without backward","Check config/flags that select the backend; training runs should build the device as Autodiff<YourBackend>"],"exampleFix":"// before\nlet device = CpuDevice::default();\ndevice.gradient_checkpointing(); // panics: not an autodiff device\n// after\nlet device = CpuDevice::default().autodiff();\ndevice.gradient_checkpointing(); // ok: DispatchDevice::Autodiff","handlingStrategy":"type-guard","validationCode":"// Ensure the device is autodiff-wrapped before enabling checkpointing\nfn autodiff_first<B: AutodiffBackend>(device: &B::Device) { /* gradient_checkpointing is only valid on Autodiff devices */ }","typeGuard":"// match on the internal DispatchDevice kind before calling\nfn is_autodiff_device(dev: &burn_tensor::Device) -> bool {\n    matches!(dev, _ /* DispatchDevice::Autodiff(_) variant, per burn version */)\n}","tryCatchPattern":"// Panic API; structure the code so checkpointing is only requested on autodiff devices:\nlet device = backend_device.autodiff();\ndevice.gradient_checkpointing();","preventionTips":["Always create training devices as Autodiff<Backend> (device.autodiff()) before any training-specific configuration","Keep device construction in one factory function so autodiff wrapping can't be skipped","Only call gradient_checkpointing in training code paths gated on AutodiffBackend","Skip checkpointing entirely for inference runs"],"tags":["autodiff","device","gradient-checkpointing","panic","burn"],"backgroundTag":"autodiff-device-required","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}