快捷方式

CUDA Stream Sanitizer

注意

这是一个原型特性,这意味着它处于早期阶段,用于收集反馈和测试,其组件可能会发生变化。

概述

此模块介绍了 CUDA Sanitizer,一个用于检测在不同流上运行的内核之间同步错误的工具。

它存储对张量的访问信息,以确定它们是否已同步。当在 python 程序中启用并在检测到可能的数据竞争时,将打印详细的警告,程序将退出。

可以通过导入此模块并调用 enable_cuda_sanitizer() 或导出 TORCH_CUDA_SANITIZER 环境变量来启用它。

用法

这是一个 PyTorch 中简单同步错误的示例

import torch

a = torch.rand(4, 2, device="cuda")

with torch.cuda.stream(torch.cuda.Stream()):
    torch.mul(a, 5, out=a)

a 张量在默认流上初始化,并且在没有任何同步方法的情况下,在新流上被修改。这两个内核将在同一个张量上并发运行,这可能会导致第二个内核在第一个内核能够写入数据之前读取未初始化的数据,或者第一个内核可能会覆盖第二个内核的部分结果。当此脚本在命令行中使用以下命令运行时

TORCH_CUDA_SANITIZER=1 python example_error.py

CSAN 打印以下输出

============================
CSAN detected a possible data race on tensor with data pointer 139719969079296
Access by stream 94646435460352 during kernel:
aten::mul.out(Tensor self, Tensor other, *, Tensor(a!) out) -> Tensor(a!)
writing to argument(s) self, out, and to the output
With stack trace:
  File "example_error.py", line 6, in <module>
    torch.mul(a, 5, out=a)
  ...
  File "pytorch/torch/cuda/_sanitizer.py", line 364, in _handle_kernel_launch
    stack_trace = traceback.StackSummary.extract(

Previous access by stream 0 during kernel:
aten::rand(int[] size, *, int? dtype=None, Device? device=None) -> Tensor
writing to the output
With stack trace:
  File "example_error.py", line 3, in <module>
    a = torch.rand(10000, device="cuda")
  ...
  File "pytorch/torch/cuda/_sanitizer.py", line 364, in _handle_kernel_launch
    stack_trace = traceback.StackSummary.extract(

Tensor was allocated with stack trace:
  File "example_error.py", line 3, in <module>
    a = torch.rand(10000, device="cuda")
  ...
  File "pytorch/torch/cuda/_sanitizer.py", line 420, in _handle_memory_allocation
    traceback.StackSummary.extract(

这提供了对错误来源的广泛深入了解

  • 张量从流中被错误地访问,流 ID 为:0 (默认流) 和 94646435460352 (新流)

  • 该张量是通过调用 a = torch.rand(10000, device="cuda") 分配的

  • 错误访问是由算子引起的
    • a = torch.rand(10000, device="cuda") 在流 0 上

    • torch.mul(a, 5, out=a) 在流 94646435460352 上

  • 错误消息还显示了调用的算子的模式,以及一个注释,显示了算子的哪些参数对应于受影响的张量。

    • 在示例中,可以看到张量 a 对应于调用的算子 torch.mul 的参数 selfoutoutput 值。

另请参阅

支持的 torch 算子及其模式的列表可以在 此处 查看。

可以通过强制新流等待默认流来修复此错误

with torch.cuda.stream(torch.cuda.Stream()):
    torch.cuda.current_stream().wait_stream(torch.cuda.default_stream())
    torch.mul(a, 5, out=a)

当再次运行脚本时,没有报告任何错误。

API 参考

torch.cuda._sanitizer.enable_cuda_sanitizer()[source][source]

启用 CUDA Sanitizer。

Sanitizer 将开始分析 torch 函数调用的底层 CUDA 调用,以查找同步错误。所有找到的数据竞争都将打印到标准错误输出,并附带可疑原因的堆栈跟踪。为了获得最佳结果,应在程序的最开始启用 sanitizer。

文档

访问 PyTorch 的全面开发者文档

查看文档

教程

获取面向初学者和高级开发者的深入教程

查看教程

资源

查找开发资源并获得您的问题解答

查看资源