| 330 | |
| 331 | @staticmethod |
| 332 | def backward(ctx, *args): |
| 333 | if not torch.autograd._is_checkpoint_valid(): |
| 334 | raise RuntimeError("Checkpointing is not compatible with .grad(), " |
| 335 | "please use .backward() if possible") |
| 336 | |
| 337 | global cuda_device, transport_stream, PARTITION_ACTIVATIONS |
| 338 | |
| 339 | if PARTITION_ACTIVATIONS: |
| 340 | with torch.cuda.stream(transport_stream): |
| 341 | inputs = get_full_inputs(ctx.saved_tensors) |
| 342 | detached_inputs = detach_variable(inputs) |
| 343 | else: |
| 344 | inputs = ctx.saved_tensors |
| 345 | detached_inputs = detach_variable(inputs) |
| 346 | |
| 347 | # Store the current states. |
| 348 | bwd_cpu_rng_state = torch.get_rng_state() |
| 349 | bwd_cuda_rng_state = torch.cuda.get_rng_state() |
| 350 | bwd_cuda_rng_state_tracker = get_cuda_rng_tracker().get_states() |
| 351 | |
| 352 | # Set the states to what it used to be before the forward pass. |
| 353 | torch.set_rng_state(ctx.fwd_cpu_rng_state) |
| 354 | _set_cuda_rng_state(ctx.fwd_cuda_rng_state) |
| 355 | get_cuda_rng_tracker().set_states(ctx.fwd_cuda_rng_state_tracker) |
| 356 | |
| 357 | if PARTITION_ACTIVATIONS: |
| 358 | current_stream=torch.cuda.current_stream() |
| 359 | current_stream.wait_stream(transport_stream) |
| 360 | |
| 361 | with torch.enable_grad(): |
| 362 | outputs = ctx.run_function(*detached_inputs) |
| 363 | |
| 364 | # Set the states back to what it was at the start of this function. |
| 365 | torch.set_rng_state(bwd_cpu_rng_state) |
| 366 | _set_cuda_rng_state(bwd_cuda_rng_state) |
| 367 | get_cuda_rng_tracker().set_states(bwd_cuda_rng_state_tracker) |
| 368 | |
| 369 | if isinstance(outputs, torch.Tensor): |
| 370 | outputs = (outputs,) |
| 371 | torch.autograd.backward(outputs, args) |
| 372 | return (None,) + tuple(inp.grad for inp in detached_inputs) |
| 373 | |
| 374 | |
| 375 | def checkpoint(function, *args): |