2014-01-28 91 views
2

我想用cudaMemcpy3D使用CUDA 5.5做一個簡單的測試。我搜索了四周,發現了不同的例子,並閱讀了適當的Runtime API文檔,但無法弄清楚我做錯了什麼。下面的代碼編譯得很好,但是當我嘗試運行它時,我在cudaMemcpy3D調用中遇到了分段錯誤。我試着用cuda-gdb來運行這個,但是不能從它得到任何有用的信息來告訴我什麼是錯的(也許是因爲我不熟悉gdb/cuda-gdb的用法)。任何幫助確定我的錯誤是什麼將不勝感激。cudaMemcpy3D在CUDA 5.5中的設置問題

#include <cstdio> 
#include <cuda_runtime.h> 

int main() { 
    static const size_t NX = 60; 
    static const size_t NY = 60; 
    static const size_t NZ = 60; 

    float* h_data = new float[NX * NY * NZ]; 
    for(unsigned int i = 0; i < NX * NY * NZ; ++i) { 
    h_data[i] = static_cast<float>(i); 
    } 

    float* d_data = 0; 

    cudaPitchedPtr dstPtr = make_cudaPitchedPtr((void**)&d_data, NX * sizeof(float), NX, NY); 
    printf("cudaPitchedPtr: %s\n", cudaGetErrorString(cudaGetLastError())); 

    cudaExtent extent = make_cudaExtent(NX * sizeof(float), NY, NZ);; 

    cudaMalloc3D(&dstPtr, extent); 
    printf("cudaMalloc3D: %s\n", cudaGetErrorString(cudaGetLastError())); 

    cudaMemset3D(dstPtr, 0, extent); 
    printf("cudaMemset3D: %s\n", cudaGetErrorString(cudaGetLastError())); 

    cudaPitchedPtr srcPtr = make_cudaPitchedPtr((void**)&h_data, NX * sizeof(float), NX, NY); 
    printf("cudaPitchedPtr: %s\n", cudaGetErrorString(cudaGetLastError())); 

    cudaMemcpy3DParms params = {0}; 
    params.srcPtr = srcPtr; 
    params.dstPtr = dstPtr; 
    params.extent = extent; 
    params.kind = cudaMemcpyHostToDevice; 

    cudaMemcpy3D(&params); 
    printf("cudaMemcpy3D: %s\n", cudaGetErrorString(cudaGetLastError())); 

    delete[] h_data; 
    return 0; 
} 

回答

2

這裏有幾個問題。沒有特定的順序:

  1. 通過 通過參考值通作源存儲器主機指針,而不是cudaMakePitchedPtr。這可能是此代碼中的主要問題
  2. 調用目標設備指針的cudaMakePitchedPtr是多餘的。 cudaMalloc3d調用將根據您提供的範圍以及驅動程序和設備對分配所施加的任何要求進行調整指針
  3. 您的錯誤檢查不正確。不要將cudaGetLastError用於可能產生錯誤的API調用。他們直接返回錯誤代碼。改爲使用該狀態(請參閱here,以瞭解使用運行時API檢查錯誤的有用方法)。請注意,像make_cudaExtentmake_cudaPitchedPtr這樣的幫助程序例程不會修改cudaGetLastError()使用的運行時API狀態,因此這些錯誤檢查調用也是多餘的。

在修復那些東西,你可能有代碼看起來像這樣:

#include <cstdio> 
#include <cuda_runtime.h> 

int main() { 
    static const size_t NX = 60; 
    static const size_t NY = 60; 
    static const size_t NZ = 60; 

    float* h_data = new float[NX * NY * NZ]; 
    for(unsigned int i = 0; i < NX * NY * NZ; ++i) { 
    h_data[i] = static_cast<float>(i); 
    } 

    cudaPitchedPtr srcPtr = make_cudaPitchedPtr(h_data, NX * sizeof(float), NX, NY); 

    cudaPitchedPtr dstPtr; 
    cudaExtent extent = make_cudaExtent(NX * sizeof(float), NY, NZ);; 
    cudaMalloc3D(&dstPtr, extent); 
    cudaMemset3D(dstPtr, 0, extent); 

    cudaMemcpy3DParms params = {0}; 
    params.srcPtr = srcPtr; 
    params.dstPtr = dstPtr; 
    params.extent = extent; 
    params.kind = cudaMemcpyHostToDevice; 

    cudaMemcpy3D(&params); 
    printf("cudaMemcpy3D: %s\n", cudaGetErrorString(cudaGetLastError())); 

    delete[] h_data; 
    return 0; 
} 

,你可能會發現,它按預期工作。

+0

謝謝。那就是訣竅。我希望文檔更清晰。在錯誤檢查中,我通常使用您鏈接的內容,但只是爲此示例進行了快速打印。不過,有關哪些調用實際返回代碼的信息很有用。 – joelmeans