Thrust::sort 使无效参数崩溃

Posted

技术标签:

【中文标题】Thrust::sort 使无效参数崩溃【英文标题】:Thrust::sort crashes invalid argument 【发布时间】:2016-01-18 04:04:05 【问题描述】:

我正在尝试在设备内存上使用推力::排序。但它在运行时崩溃。 我还尝试禁用调试信息生成。

这是一个最小的例子:

cudaSetDevice(0);
int u[10];
int* v;
cudaMalloc(&v, 10 * sizeof(int));
for (int i = 0; i < 10 ; i++)
    u[i] = 10-i;
cudaMemcpy(u, v, 10 * sizeof(int), cudaMemcpyHostToDevice);
try
    thrust::sort(thrust::device_ptr<int>(v), thrust::device_ptr<int>(v+10));

catch (thrust::system_error &e)
    printf("Error: %s \n",e.what());
cudaMemcpy(v, u, 10 * sizeof(int), cudaMemcpyDeviceToHost);
for (int i = 0; i < 10; i++)
    printf("%d\n", u[i]);

e.what() 给出以下消息:

CUDA 错误 11 [c:\program files\nvidia gpu 计算工具包\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp atch/device_radix_sort_dispatch.cuh,687]:无效参数 CUDA错误11 [c:\program files\nvidia gpu计算工具包\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp atch/device_radix_sort_dispatch.cuh,875]:无效参数 错误:在 cub_::DeviceRadixSort::SortKeys(1) 之后:参数无效

我正在使用带有 Cuda 助手的 GeForce 940M 和 VS13 来生成项目。 nvcc Build-line 是:

"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\bin\nvcc.exe" -gencode=arch=compute_20,code=\"sm_20,compute_20\" --use-local-env --cl-version 2013 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include" - I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include" --keep-dir Debug -maxrregcount=0 --machine 32 --compile -cudart static -g -DWIN32 -D_DEBUG -D_CONSOLE - D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd " -o Debug\kernel.cu.obj "C:\Users\ndrei\Documents\Visual Studio\2013\Projects\Thrust_Test\Thrust_Test\kernel .cu”

请帮帮我!

【问题讨论】:

【参考方案1】:

首先,您的示例不完整。切断头文件等有什么好处?这不会让其他试图帮助你的人更容易。我认为这甚至不是您实际运行的代码的摘录,因为您的 try/catch 格式不正确(编译错误)。

以后请提供正确的MCVE。它应该是一个完整代码,有人可以复制、粘贴、编译和运行,而无需添加任何内容或更改任何内容。

关于推力误差:

    cudaMemcpy 不是推力的一部分。它是 cuda 运行时 API 的一部分,建议您在使用 cuda 运行时 API 的代码遇到问题时使用proper cuda error checking。如果你这样做了,而不是不知道错误在哪里,你的注意力会立即减少到一行代码。

    这是错误的:

    cudaMemcpy(u, v, 10 * sizeof(int), cudaMemcpyHostToDevice);
    

    cudaMemcpymemcpy 一样,将指向复制操作的目标 的指针作为其第一个参数,然后是指向复制操作的 的指针。复制操作。

    由于u是主机指针,v是设备指针,这与您的意图(以及复制操作的指定方向,即cudaMemcpyHostToDevice)不一致。

    您在随后的cudaMemcpy 操作中也犯了类似的错误。

以下是MCVE 的更好示例。这是您显示的代码的修改版本,已修复错误:

#include <stdio.h>
#include <thrust/sort.h>
#include <thrust/device_ptr.h>
#include <thrust/system_error.h>


#define cudaCheckErrors(msg) \
    do  \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess)  \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
         \
     while (0)

int main()

  cudaSetDevice(0);
  int u[10];
  int* v;
  cudaMalloc(&v, 10 * sizeof(int));
  cudaCheckErrors("cudaMalloc fail");
  for (int i = 0; i < 10 ; i++)
    u[i] = 10-i;
  cudaMemcpy(v, u, 10 * sizeof(int), cudaMemcpyHostToDevice);
  cudaCheckErrors("cudaMemcpy 1 fail");
  try
    thrust::sort(thrust::device_ptr<int>(v), thrust::device_ptr<int>(v+10));
    
  catch (thrust::system_error &e)
    printf("Error: %s \n",e.what());
  cudaMemcpy(u, v, 10 * sizeof(int), cudaMemcpyDeviceToHost);
  cudaCheckErrors("cudaMemcpy 2 fail");
  for (int i = 0; i < 10; i++)
    printf("%d\n", u[i]);

注意事项:

    Thrust 系统错误机制会捕获预先存在的 CUDA 错误,并抛出这些错误,以及可能与您的实际推力代码相关的任何错误。因此,建议对 CUDA 代码进行 CUDA 错误检查,并对推力代码进行推力错误检查,以减少调试过程的混乱。

    作为一个不相关的建议:您的项目设置为:

    cc2.0 设备。 32 位应用程序

    这些都不是推荐的设置。我建议修改您的项目以构建 Release, x64 应用程序,并且我建议从 cc2.0 修改您的构建目标以匹配您的 GPU 的计算能力。在您的项目设置中,这可能意味着将 CUDA 设备下的 Visual Studio 项目设置从 compute_20,sm_20 更改为 compute_50,sm_50 以匹配您的 GeForce 940M GPU。

【讨论】:

嗨罗伯特。谢谢您的回答。但是排序仍然抛出异常。收到此消息:> 错误:参数无效致命错误:cudaMemcpy 2 失败(C:/Users/ndrei/Documents/Visual Studio/2013/Projects/Thrust_Test/Thr ust_Test/kernel.cu:37 处的参数无效)*** FAILED - 中止 你在运行我提供的代码吗?似乎不是因为我提供的代码中的cudaCheckErrors 行号是 36,而您的错误发生在第 37 行。我已经编译并运行了我指定的代码,它似乎工作正常。 是的,我运行了这段代码。但是由于复制粘贴过程,我不得不重新排列一些行。我发现,如果我使用 x64 作为目标机器,它就可以工作。

以上是关于Thrust::sort 使无效参数崩溃的主要内容,如果未能解决你的问题,请参考以下文章

崩溃使 NSPersistentStoreCoordinator 的 url 无效

使画布视图无效时单击按钮后应用程序崩溃(Android Studio,Java)

UICollectionViewDiffableDataSource 崩溃:无效参数不满足:itemCount

使用无效参数调用“setRegion”时,iOS 6 Map 崩溃

pageViewController setViewControllers 因“无效参数不满足:[views count] == 3”而崩溃

当无效字符串作为参数传递时,如何确保 posix_time_zone 构造函数不会崩溃