当前位置:   article > 正文

【已解决】RuntimeError: CUDA error: device-side assert triggeredCUDA kernel errors might be asynchronous

runtimeerror: cuda error: device-side assert triggered cuda kernel errors mi

问题描述

Traceback (most recent call last):
  File "/home/sysu/qfy/project/GCL/GCL/Main.py", line 281, in <module>
    main(args)
  File "/home/sysu/qfy/project/GCL/GCL/Main.py", line 200, in main
    loss, Matrix = train(encoder_model, args, data, optimizer, epoch)
  File "/home/sysu/qfy/project/GCL/GCL/Main.py", line 146, in train
    Matrix = get_sampleMatrix(z0, args, args.max_iter)
  File "/home/sysu/qfy/project/GCL/GCL/Main.py", line 45, in get_sampleMatrix
    Z, S = idr(
  File "/home/sysu/qfy/project/GCL/GCL/SubspaceClustering_.py", line 162, in idr
    Z = torch.linalg.solve(A, B)
RuntimeError: CUDA error: device-side assert triggered
CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.

解决过程

        先上一下搜索结果:

这个错误表明在调用 torch.linalg.solve 函数时触发了 CUDA 错误,可能是因为设备端断言失败。这可能是由于多种原因引起的,包括输入数据的问题、CUDA 版本不匹配、显存问题等。

以下是一些建议来解决这个问题:

  1. 启用 CUDA 追踪: 通过设置环境变量 CUDA_LAUNCH_BLOCKING=1 启用 CUDA 追踪,以便更容易追踪到问题所在。在代码运行之前,你可以使用以下命令设置这个环境变量:

    bash

    export CUDA_LAUNCH_BLOCKING=1

    或者在代码中设置:

    python

    import os os.environ['CUDA_LAUNCH_BLOCKING'] = '1'

  2. 检查输入数据: 确保传递给 torch.linalg.solve 函数的输入数据是正确的,包括矩阵 A 和 B 的形状和数据类型。也要确保矩阵 A 是可逆的。

  3. CUDA 版本和驱动问题: 确保你的 CUDA 版本与 PyTorch 版本兼容,并且你的 GPU 驱动程序是最新的。不匹配的版本可能导致不稳定性和错误。

  4. 显存问题: 检查 GPU 的显存,确保有足够的空间执行操作。有时,内存不足可能导致 CUDA 函数失败。可以尝试减小批量大小或使用更小的模型,以确保不会超出 GPU 内存限制。

  5. 使用 PyTorch 内置调试工具: 使用 torch.autograd.detect_anomaly() 来捕捉异常的计算图操作。这有助于定位导致问题的操作。

  6. 考虑编译选项: 如错误信息中所述,可以考虑在编译时启用 TORCH_USE_CUDA_DSA,以便启用设备端断言。

    TORCH_CUDA_ARCH_LIST="3.5;5.0+PTX" TORCH_NVCC_FLAGS="-Xfatbin -compress-all" TORCH_USE_CUDA_DSA=1 python setup.py install

请根据具体的代码和上下文尝试这些建议,找到导致问题的确切原因。

        我看到这段话的感觉

        不知道大佬怎么看这个问题,但是对我来说就像天书一样,唯有2可能对我有点用,因为他提示了我取判断A是否可逆,关于是否可逆也挺好判断,但是从程序的角度来说,这边不算是问题,因为基本上输入的矩阵总是有逆的。

        进一步分析:逐步debug

        按这个向下的箭头就可以了,这边的调试是这样的: 暂停和继续箭头用于多步循环的调试(但如果手动控制则会出现中断正在进行的运算的问题,进而报错),向下箭头用于逐步调试,让我们知道程序的运行是怎么来回横跳的,进而把握整个程序运行过程。停止和重新运行就不再赘述了,其他俩箭头我暂时没有用到。

        先确定报错位置

        在第一次报错是在这个位置

        报错内容如下,首先是原因所在

../aten/src/ATen/native/cuda/IndexKernel.cu:92: operator(): block: [111,0,0], thread: [71,0,0] Assertion `index >= -sizes[i] && index < sizes[i] && "index out of bounds"` failed.

         其次是报错内容如下

  • Traceback (most recent call last):
    File "/media/visionx/monica/project/GCL/GCL/Main.py", line 282, in <module>
    main(args)
    File "/media/visionx/monica/project/GCL/GCL/Main.py", line 202, in main
    loss, Matrix = train(encoder_model, args, data, optimizer, epoch)
    File "/media/visionx/monica/project/GCL/GCL/Main.py", line 149, in train
    Matrix = get_sampleMatrix(z0, args, args.max_iter)
    File "/media/visionx/monica/project/GCL/GCL/Main.py", line 45, in get_sampleMatrix
    Z, S = idr(
    File "/media/visionx/monica/project/GCL/GCL/SubspaceClustering_.py", line 166, in idr
    Z = torch.linalg.solve(A, B)torch._C._LinAlgError: cusolver error: CUSOLVER_STATUS_EXECUTION_FAILED, when calling `cusolverDnSgetrf( handle, m, n, dA, ldda, static_cast<float*>(dataPtr.get()), ipiv, info)`. This error may appear if the input matrix contains NaN.

       索引越界导致了这个错误,逐步debug找报错节点

        这个时候问题就清晰了,就是索引越界,但是是哪里越界了却不清楚,继续dubug

        这是在while循环进行14次,没有报错,继续debug,因为点击了暂停按钮,所以运算过程中有中间结果的副本或者交叉操作占用了额外的内存,所以会报错outofmemory,不用在意,改小一点就可以了,因为这并不是问题的关键

        意外的额外的bug 

         改小batchsize后,继续按照上述操作,会发现循环76次依然没有问题

        那就继续debug,但是这个时候问题出现了,当大于100,也就是满足循环跳出条件,进行下一次循环的时候报了错 

        是在不同GPU的问题吗? 

        一开始以为是device的问题,因为报错内容包括“asynchronously”,我以为和之前的错误一样,数据在不同位置,但很明显,我天真了,打印出来之后是 “cuda:0”,也就是说和我们预设的是一样的,但是为什么会报这个错呢?如果是数据在不同的位置应该报这个错:RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cuda:1!那是怎么回事呢?

        在调试控制台输入A.size()和B.size(),这个时候的结果都是[4930, 4930] ,也就是满足运行预设的条件,那为什么会出错呢?也就是这里运算是不会出错的,那问题就出在输入矩阵了,输入矩阵的选择我们再看一眼,这个时候我们发现,我们如果这样操作的话,第二个循环进行采样的时候z1已经变了,也就是我们不再是在原来的z1和z2(z, z1, z2 = encoder_model(data.x, edge_index, edge_weight))上进行取值了,所以会出问题那就改一下

        问题原来在这

        把上述代码改为如下 

         这里需要注意的是,后面引用到变量的位置也要进行修改。

        这个时候再进行操作,就没有问题了

总结

        这篇较为详细的记叙了关于一个bug但又不是很麻烦的bug的解决过程,有部分过程没有记录下来,因为感觉对整个理解过程有影响,所以就挑了主要的过程进行记录。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/89153
推荐阅读
相关标签
  

闽ICP备14008679号