Thrust::sort 使无效参数崩溃
Thrust::sort crashes invalid argument
我正尝试在设备内存上使用 thrust::sort。但它在运行时崩溃。
我也试过禁用调试信息生成。
这是一个最小的例子:
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 error 11 [c:\program files\nvidia gpu computing toolkit\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp
atch/device_radix_sort_dispatch.cuh, 687]: invalid argument
CUDA error 11 [c:\program files\nvidia gpu computing toolkit\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp
atch/device_radix_sort_dispatch.cuh, 875]: invalid argument
Error: after cub_::DeviceRadixSort::SortKeys(1): invalid argument
我正在使用带有 Cuda 助手的 GeForce 940M 和 VS13 来生成项目。
nvcc 构建行是:
"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 Studio13\Projects\Thrust_Test\Thrust_Test\kernel.cu"
请帮帮我!
首先,您的示例不完整。把头文件等砍掉有什么好处呢?这不会让其他试图帮助您的人变得更容易。我认为这甚至不是您实际上 运行ning 的代码的摘录,因为您的 try/catch 格式不正确(编译错误)。
以后请提供合适的MCVE。它应该是一个 完整的 代码,有人可以复制、粘贴、编译和 运行,而无需添加或更改任何内容。
关于推力误差:
cudaMemcpy
不是推力的一部分。它是 cuda 运行time API 的一部分,建议您在使用 cuda 运行time [=] 的代码遇到问题时使用 proper cuda error checking 84=]。如果你这样做了,而不是不知道错误在哪里,你的注意力会立即减少到一行代码。
这是错误的:
cudaMemcpy(u, v, 10 * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy
和 memcpy
一样,将指向复制操作的 目标 的指针作为其第一个参数,然后是指向 复制操作的来源。
由于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.
我正尝试在设备内存上使用 thrust::sort。但它在运行时崩溃。 我也试过禁用调试信息生成。
这是一个最小的例子:
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 error 11 [c:\program files\nvidia gpu computing toolkit\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp atch/device_radix_sort_dispatch.cuh, 687]: invalid argument CUDA error 11 [c:\program files\nvidia gpu computing toolkit\cuda\v7.5\include\thrust\system\cuda\detail\cub\device\disp atch/device_radix_sort_dispatch.cuh, 875]: invalid argument Error: after cub_::DeviceRadixSort::SortKeys(1): invalid argument
我正在使用带有 Cuda 助手的 GeForce 940M 和 VS13 来生成项目。 nvcc 构建行是:
"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 Studio13\Projects\Thrust_Test\Thrust_Test\kernel.cu"
请帮帮我!
首先,您的示例不完整。把头文件等砍掉有什么好处呢?这不会让其他试图帮助您的人变得更容易。我认为这甚至不是您实际上 运行ning 的代码的摘录,因为您的 try/catch 格式不正确(编译错误)。
以后请提供合适的MCVE。它应该是一个 完整的 代码,有人可以复制、粘贴、编译和 运行,而无需添加或更改任何内容。
关于推力误差:
cudaMemcpy
不是推力的一部分。它是 cuda 运行time API 的一部分,建议您在使用 cuda 运行time [=] 的代码遇到问题时使用 proper cuda error checking 84=]。如果你这样做了,而不是不知道错误在哪里,你的注意力会立即减少到一行代码。这是错误的:
cudaMemcpy(u, v, 10 * sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy
和memcpy
一样,将指向复制操作的 目标 的指针作为其第一个参数,然后是指向 复制操作的来源。由于
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.