| 277 | |
| 278 | @staticmethod |
| 279 | def backward(ctx, *args): |
| 280 | if not torch.autograd._is_checkpoint_valid(): |
| 281 | raise RuntimeError("Checkpointing is not compatible with .grad(), " |
| 282 | "please use .backward() if possible") |
| 283 | inputs = ctx.saved_tensors |
| 284 | if _CHECKPOINTED_ACTIVATIONS_MEMORY_BUFFER is not None: |
| 285 | inputs[0].data = gather_split_1d_tensor(inputs[0].data) |
| 286 | inputs[0].data = inputs[0].data.view(ctx.input_0_shape) |
| 287 | |
| 288 | # Store the current states. |
| 289 | bwd_cpu_rng_state = torch.get_rng_state() |
| 290 | bwd_cuda_rng_state = torch.cuda.get_rng_state() |
| 291 | bwd_cuda_rng_state_tracker = get_cuda_rng_tracker().get_states() |
| 292 | |
| 293 | # Set the states to what it used to be before the forward pass. |
| 294 | torch.set_rng_state(ctx.fwd_cpu_rng_state) |
| 295 | _set_cuda_rng_state(ctx.fwd_cuda_rng_state) |
| 296 | get_cuda_rng_tracker().set_states(ctx.fwd_cuda_rng_state_tracker) |
| 297 | |
| 298 | # Compute the forward pass. |
| 299 | detached_inputs = detach_variable(inputs) |
| 300 | with torch.enable_grad(): |
| 301 | outputs = ctx.run_function(*detached_inputs) |
| 302 | |
| 303 | # Set the states back to what it was at the start of this function. |
| 304 | torch.set_rng_state(bwd_cpu_rng_state) |
| 305 | _set_cuda_rng_state(bwd_cuda_rng_state) |
| 306 | get_cuda_rng_tracker().set_states(bwd_cuda_rng_state_tracker) |
| 307 | |
| 308 | if isinstance(outputs, torch.Tensor): |
| 309 | outputs = (outputs,) |
| 310 | torch.autograd.backward(outputs, args) |
| 311 | grads = tuple(inp.grad if isinstance(inp, torch.Tensor) else inp |
| 312 | for inp in detached_inputs) |
| 313 | return (None,) + grads |
| 314 | |
| 315 | |
| 316 | def checkpoint(function, *args): |