pytorch/tools
Richard Barnes ad188a227e Introduce CUDA Device Assertions Infrastructure (#84609)
Summary:
This diff introduces a set of changes that makes it possible for the host to get assertions from CUDA devices. This includes the introduction of

**`CUDA_KERNEL_ASSERT2`**

A preprocessor macro to be used within a CUDA kernel that, upon an assertion failure, writes the assertion message, file, line number, and possibly other information to UVM (Managed memory). Once this is done, the original assertion is triggered, which places the GPU in a Bad State requiring recovery. In my tests, data written to UVM appears there before the GPU reaches the Bad State and is still accessible from the host after the GPU is in this state.

Messages are written to a multi-message buffer which can, in theory, hold many assertion failures. I've done this as a precaution in case there are several, but I don't actually know whether that is possible and a simpler design which holds only a single message may well be all that is necessary.

**`TORCH_DSA_KERNEL_ARGS`**

This preprocess macro is added as an _argument_ to a kernel function's signature. It expands to supply the standardized names of all the arguments needed by `C10_CUDA_COMMUNICATING_KERNEL_ASSERTION` to handle device-side assertions. This includes, eg, the name of the pointer to the UVM memory the assertion would be written to. This macro abstracts the arguments so there is a single point of change if the system needs to be modified.

**`c10::cuda::get_global_cuda_kernel_launch_registry()`**

This host-side function returns a singleton object that manages the host's part of the device-side assertions. Upon allocation, the singleton allocates sufficient UVM (Managed) memory to hold information about several device-side assertion failures. The singleton also provides methods for getting the current traceback (used to identify when a kernel was launched). To avoid consuming all the host's memory the singleton stores launches in a circular buffer; a unique "generation number" is used to ensure that kernel launch failures map to their actual launch points (in the case that the circular buffer wraps before the failure is detected).

**`TORCH_DSA_KERNEL_LAUNCH`**

This host-side preprocessor macro replaces the standard
```
kernel_name<<<blocks, threads, shmem, stream>>>(args)
```
invocation with
```
TORCH_DSA_KERNEL_LAUNCH(blocks, threads, shmem, stream, args);
```
Internally, it fetches the UVM (Managed) pointer and generation number from the singleton and append these to the standard argument list. It also checks to ensure the kernel launches correctly. This abstraction on kernel launches can be modified to provide additional safety/logging.

**`c10::cuda::c10_retrieve_device_side_assertion_info`**
This host-side function checks, when called, that no kernel assertions have occurred. If one has. It then raises an exception with:
1. Information (file, line number) of what kernel was launched.
2. Information (file, line number, message) about the device-side assertion
3. Information (file, line number) about where the failure was detected.

**Checking for device-side assertions**

Device-side assertions are most likely to be noticed by the host when a CUDA API call such as `cudaDeviceSynchronize` is made and fails with a `cudaError_t` indicating
> CUDA error: device-side assert triggered CUDA kernel errors

Therefore, we rewrite `C10_CUDA_CHECK()` to include a call to `c10_retrieve_device_side_assertion_info()`. To make the code cleaner, most of the logic of `C10_CUDA_CHECK()` is now contained within a new function `c10_cuda_check_implementation()` to which `C10_CUDA_CHECK` passes the preprocessor information about filenames, function names, and line numbers. (In C++20 we can use `std::source_location` to eliminate macros entirely!)

# Notes on special cases

* Multiple assertions from the same block are recorded
* Multiple assertions from different blocks are recorded
* Launching kernels from many threads on many streams seems to be handled correctly
* If two process are using the same GPU and one of the processes fails with a device-side assertion the other process continues without issue
* X Multiple assertions from separate kernels on different streams seem to be recorded, but we can't reproduce the test condition
* X Multiple assertions from separate devices should be all be shown upon exit, but we've been unable to generate a test that produces this condition

Differential Revision: D37621532

Pull Request resolved: https://github.com/pytorch/pytorch/pull/84609
Approved by: https://github.com/ezyang, https://github.com/malfet
2022-12-08 01:26:07 +00:00
..
amd_build
autograd Give std/var correction overloads proper defaults (#56398) 2022-12-07 15:15:00 +00:00
bazel_tools
build_defs
code_analyzer [tools] expose selective build library (#89351) 2022-11-21 21:08:13 +00:00
code_coverage Fix typos under benchmarks, test, and tools directories (#87975) 2022-10-29 01:26:17 +00:00
config
coverage_plugins_package
dynamo Add dynamo smoke tests to CI (#89302) 2022-11-30 21:24:45 +00:00
fast_nvcc
gdb
iwyu
jit Reland 2 Many symintifications (#87604) (#87980) 2022-10-28 13:40:11 +00:00
linter Add missing mypy-nofollow.ini (#90179) 2022-12-08 01:05:12 +00:00
lite_interpreter
lldb
onnx [ONNX] Improve diagnostic message formatting (#87830) 2022-11-10 21:42:17 +00:00
pyi Add crossref debug mode for functionalization, catches stride errors (#89498) 2022-11-23 04:18:25 +00:00
rules
setup_helpers
shared
stats Skip upload test stats for test reports from rerun disabled tests workflow (#89548) 2022-11-23 22:39:39 +00:00
test [Pytorch][Vulkan] shader codegen use ordered dictionary (#89951) 2022-12-06 00:49:35 +00:00
testing Disable mem leak check (#88373) 2022-11-04 20:47:42 +00:00
__init__.py
bazel.bzl Introduce CUDA Device Assertions Infrastructure (#84609) 2022-12-08 01:26:07 +00:00
BUCK.bzl [tools] expose selective build library (#89351) 2022-11-21 21:08:13 +00:00
BUCK.oss
build_libtorch.py
build_pytorch_libs.py
download_mnist.py
extract_scripts.py
gen_flatbuffers.sh
gen_vulkan_glsl.py Fix exception causes all over the codebase (#90271) 2022-12-07 04:29:00 +00:00
gen_vulkan_spv.py [vulkan] Add option for buffer representations in vTensor (#87622) 2022-11-09 17:59:49 +00:00
generate_torch_version.py Don't print fatal:... in generate_torch_version.py (#88335) 2022-11-04 20:34:23 +00:00
generated_dirs.txt
git_add_generated_dirs.sh
git_reset_generated_dirs.sh
nightly.py
nvcc_fix_deps.py
pytorch.version
README.md
render_junit.py Fix exception causes all over the codebase (#90271) 2022-12-07 04:29:00 +00:00
substitute.py
update_masked_docs.py
vscode_settings.py

This folder contains a number of scripts which are used as part of the PyTorch build process. This directory also doubles as a Python module hierarchy (thus the __init__.py).

Overview

Modern infrastructure:

  • autograd - Code generation for autograd. This includes definitions of all our derivatives.
  • jit - Code generation for JIT
  • shared - Generic infrastructure that scripts in tools may find useful.
    • module_loader.py - Makes it easier to import arbitrary Python files in a script, without having to add them to the PYTHONPATH first.

Build system pieces:

  • setup_helpers - Helper code for searching for third-party dependencies on the user system.
  • build_pytorch_libs.py - cross-platform script that builds all of the constituent libraries of PyTorch, but not the PyTorch Python extension itself.
  • build_libtorch.py - Script for building libtorch, a standalone C++ library without Python support. This build script is tested in CI.
  • fast_nvcc - Mostly-transparent wrapper over nvcc that parallelizes compilation when used to build CUDA files for multiple architectures at once.
    • fast_nvcc.py - Python script, entrypoint to the fast nvcc wrapper.

Developer tools which you might find useful:

Important if you want to run on AMD GPU:

  • amd_build - HIPify scripts, for transpiling CUDA into AMD HIP. Right now, PyTorch and Caffe2 share logic for how to do this transpilation, but have separate entry-points for transpiling either PyTorch or Caffe2 code.
    • build_amd.py - Top-level entry point for HIPifying our codebase.

Tools which are only situationally useful: