2014-03-24 35 views
1

我寫了下面的CUDA內核,我試圖將其加載到一個模塊:CUDA調試無效的內核映像錯誤

nvcc -ptx -arch=sm_20 vadd.cu 

#include <stdio.h> 

extern "C" // ensure function name to be exactly "vadd" 
{ 
    __global__ void vadd(const float *a, const float *b, float *c) 
    { 
     int i = threadIdx.x + blockIdx.x * blockDim.x; 
     printf("Thread id %d\n", i); 
     c[i] = a[i] + b[i]; 
    } 
} 

我使用下面的命令把它編譯成PTX代碼當試圖使用cuModuleLoad將此文件加載到模塊中時,我得到一個CUDA 200錯誤(無效的內核映像)。我怎樣才能找出內核映像有什麼問題?我試過ptxas,但據此,生成的ptx代碼很好。

編輯:這是我使用的加載模塊的代碼:

#include "cuda.h" 
#include <cassert> 
#include <dlfcn.h> 
#include <stdio.h> 

void check(CUresult err) { 
    if (err != CUDA_SUCCESS) { 
    printf("Error %i\n", err); 
    } 
    assert(err == CUDA_SUCCESS); 
} 

int main(int argc, char **argv) { 
    void *cuda = dlopen("libcuda.so", RTLD_NOW | RTLD_DEEPBIND | RTLD_GLOBAL); 
    assert(cuda != NULL); 

    printf("cuInit\n"); 
    CUresult (*Init)() = (CUresult (*)()) dlsym(cuda, "cuInit"); 
    check(Init()); 

    printf("cuDeviceGet\n"); 
    CUresult (*DeviceGet)(CUdevice *, int) = (CUresult (*)(CUdevice *, int)) dlsym(cuda, "cuDeviceGet"); 
    CUdevice device; 
    check(DeviceGet(&device, 0)); 

    printf("cuCtxCreate\n"); 
    CUresult (*CtxCreate)(CUcontext * , unsigned int, CUdevice) = (CUresult (*)(CUcontext * , unsigned int, CUdevice)) dlsym(cuda, "cuCtxCreate"); 
    CUcontext context; 
    check(CtxCreate(&context, 0, device)); 

    printf("cuModuleLoad\n"); 
    CUresult (*ModuleLoad)(CUmodule *, const char*) = (CUresult (*)(CUmodule *, const char*)) dlsym(cuda, "cuModuleLoad"); 
    CUmodule mod; 
    check(ModuleLoad(&mod, "vadd.ptx")); 

    return 0; 
} 
+0

撇開:根據文檔,'cuModuleLoad'永遠不應該導致'CUDA_ERROR_INVALID_IMAGE'。你有沒有其他的情況下,一般的調用工作(例如一個空的內核,沒有printf語句,編譯對照sm_10左右)? – Marco13

+0

@ Marco13您確定:[cuModuleLoad期間的CUDA_ERROR_INVALID_IMAGE](http://stackoverflow.com/questions/18844976/cuda-error-invalid-image-during-cumoduleload)? – JackOLantern

+0

對不起,我只是提到它沒有在文檔中提到過(http://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__MODULE.html#group__CUDA__MODULE),但也可能在實踐中出現 – Marco13

回答

2

這與Why cuCtxCreate creates old context?:您正在使用cuCtxCreate直接,它給你一箇舊的API上下文(V3.1 )與您使用printf不符。您可以使用​​檢查API版本。如果您切換到cuCtxCreate_v2,這通常通過cuda.h中的某些#define使用,您將獲得更新的API上下文。

爲了發現這種差異,我用LD_DEBUG=symbols運行了您的示例,並將其與使用CUDA API直接進行比較(因爲它正確運行您的示例PTX)。比較符號的分辨率,最大的區別是調用cuCtxCreate

cuCtxCreate(...) 
    symbol=cuCtxCreate_v2; lookup in file=./test [0] 
    symbol=cuCtxCreate_v2; lookup in file=/usr/lib/x86_64-linux-gnu/libcuda.so.1 [0] 

...這在你的原代碼,使用dlsym(..., "cuCtxCreate")直接映射到cuCtxCreate

+0

優秀的答案! – talonmies