2015-10-19 71 views
0

我試圖在設備內存上使用推力::排序。但它在運行時崩潰。 我也嘗試禁用調試信息生成。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

我使用的GeForce 940M和VS13在CUDA助理項目生成。 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"

請幫幫我!

回答

2

首先,您的示例不完整。它切斷頭文件等有什麼好處?這並不能讓那些試圖幫助你的人更容易。我認爲這甚至不是你正在運行的代碼的摘錄,因爲你的try/catch形成不正確(編譯錯誤)。

未來,請提供適當的MCVE。它應該是一個完整的代碼,有人可以複製,粘貼,編譯和運行,而無需添加任何內容或更改任何內容。

關於推力誤差:

  1. cudaMemcpy不是推力的一部分。它是cuda運行時API的一部分,如果您在使用cuda運行時API的代碼時遇到問題,建議您使用proper cuda error checking。如果你這樣做了,而不是不知道錯誤發生在哪裏,那麼你的注意力已經被立即縮減爲一行代碼。

  2. 這是錯誤的:

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

    cudaMemcpy,像memcpy,作爲其第一個參數的指針複製操作的目的地,隨後的指針拷貝的操作。

    由於u是主機指針,並且v是設備指針,這與您的意圖(以及複製操作的陳述方向,即cudaMemcpyHostToDevice)不一致。

  3. 您在後續的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]); 
} 

注:

  1. 推力系統錯誤機制捕獲預先存在的CUDA錯誤,並拋出這些以及可能與您的實際推力代碼相關的任何內容。因此,建議對CUDA代碼進行CUDA錯誤檢查,並對推力代碼進行推力錯誤檢查,以使調試過程更加容易混淆。

  2. 到無關的建議:你的項目設置爲構建:

    • 一個CC2.0設備。
    • 32位應用

    的這些都不是推薦的設置。我會建議修改您的項目以構建版本,x64應用程序,並且我會建議從cc2.0修改您的構建目標以匹配GPU的計算能力。在您的項目設置中,這可能意味着將CUDA設備下的Visual Studio項目設置從compute_20,sm_20更改爲compute_50,sm_50以匹配您的GeForce 940M GPU

+0

嗨羅伯特。謝謝您的回答。但排序仍然拋出一個異常。獲取此消息: >錯誤:無效參數 致命錯誤:cudaMemcpy 2失敗(C:/ Users/ndrei/Documents/Visual Studio/2013/Projects/Thrust_Test/Thr ust_Test/kernel.cu:37上的無效參數) *** FAILED - ABORTING –

+1

您是否正在運行我準備提供的代碼?看起來沒有,因爲我提供的代碼中的'cudaCheckErrors'行號是36,而你的錯誤發生在行37上。我編譯並運行了我指出的代碼,它似乎工作正常。 –

+1

這段代碼對我來說也沒有錯誤 – talonmies