使用 sm_35 编译时 CUDA 代码运行,但使用 sm_30 时失败

CUDA code runs when compiled with sm_35, but fails with sm_30

我的GPU设备是GeForce GT 750M,我发现它的计算能力是3.0。我下载了在这里找到的 CUDA 代码:(https://github.com/fengChenHPC/word2vec_cbow。它的 makefile 有标志 -arch=sm_35。

由于我的设备是计算能力 3.0,我将标志更改为 -arch=sm_30。它编译得很好,但是当我 运行 代码时,我得到以下错误:

word2vec.cu 449 : unspecified launch failure

word2vec.cu 449 : unspecified launch failure

它显示了多次,因为有多个 CPU 线程启动 CUDA 内核。请注意,线程不会使用不同的流来启动内核,因此内核启动都是按顺序进行的。

现在,当我设置标志时,即 -arch=sm_35,那么代码 运行 没问题。有人可以解释为什么当我设置标志以匹配我的设备时代码不会 运行 吗?

如此 LINK 显示没有 GeForce GTX 750M。

你的是:

GeForce GTX 750 Ti

GeForce GTX 750

GeForce GT 750M

如果您的是前两个之一,那么您的 GPU 是基于 Maxwell 的并且计算能力 = 5.0。

否则,您的 GPU 是基于 Kepler 的并且计算能力 = 3.0。

如果您不确定您的 GPU 是什么,请先通过 NVIDIA SAMPLE 中的 运行 deviceQuery 找出它。

不幸的是,您得出的结论是代码在 sm_30 GPU 上为 sm_35 和 运行 编译时有效是不正确的。罪魁祸首是:

void cbow_cuda(long window, long negative, float alpha, long sentence_length, 
               int *sen, long layer1_size, float *syn0, long hs, float *syn1, 
               float *expTable, int *vocab_codelen, char *vocab_code,
               int *vocab_point, int *table, long table_size, 
               long vocab_size, float *syn1neg){
    int blockSize = 256;
    int gridSize = (sentence_length)/(blockSize/32);
    size_t smsize = (blockSize/32)*(2*layer1_size+3)*sizeof(float);
//printf("sm size is %d\n", smsize);
//fflush(stdout);
    cbow_kernel<1><<<gridSize, blockSize, smsize>>>
                   (window, negative, alpha, sentence_length, sen,
                    layer1_size, syn0, syn1, expTable, vocab_codelen,
                    vocab_code, vocab_point, table, table_size,
                    vocab_size, syn1neg);
}

如果内核启动因 API 错误检查不完整而失败,此代码将自动失败。如果您在 sm_30 上构建 sm_35 和 运行,内核启动确实会失败。如果将该函数的代码更改为此(添加内核启动错误检查):

void cbow_cuda(long window, long negative, float alpha, long sentence_length, 
               int *sen, long layer1_size, float *syn0, long hs, float *syn1, 
               float *expTable, int *vocab_codelen, char *vocab_code,
               int *vocab_point, int *table, long table_size, 
               long vocab_size, float *syn1neg){
    int blockSize = 256;
    int gridSize = (sentence_length)/(blockSize/32);
    size_t smsize = (blockSize/32)*(2*layer1_size+3)*sizeof(float);
//printf("sm size is %d\n", smsize);
//fflush(stdout);
    cbow_kernel<1><<<gridSize, blockSize, smsize>>>
                   (window, negative, alpha, sentence_length, sen,
                    layer1_size, syn0, syn1, expTable, vocab_codelen,
                    vocab_code, vocab_point, table, table_size,
                    vocab_size, syn1neg);
    checkCUDAError( cudaPeekAtLastError() );
}

并为 sm_35 编译和 运行 它,你应该在 sm_30 设备上得到它:

~/cbow/word2vec_cbow$ make
nvcc word2vec.cu -o word2vec -O3 -Xcompiler -march=native -w  -Xptxas="-v" -arch=sm_35 -lineinfo
ptxas info    : 0 bytes gmem
ptxas info    : Compiling entry function '_Z11cbow_kernelILx1EEvllflPKilPVfS3_PKfS1_PKcS1_S1_llS3_' for 'sm_35'
ptxas info    : Function properties for _Z11cbow_kernelILx1EEvllflPKilPVfS3_PKfS1_PKcS1_S1_llS3_
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 34 registers, 448 bytes cmem[0], 8 bytes cmem[2]

~/cbow/word2vec_cbow$ ./word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 7 -negative 1 -hs 1 -sample 1e-3 -threads 1 -binary 1 -save-vocab voc #> out 2>&1
Starting training using file text8
Vocab size: 71290
Words in train file: 16718843
vocab size = 71290
cbow.cu 114 : invalid device function

即。内核启动失败,因为在您的应用程序的 CUDA cubin 有效负载中找不到合适的设备代码。这也回答了您 earlier question 为什么此代码的输出不正确。使用默认选项构建时,分析内核根本不会 运行 在您的硬件上。

如果我在具有 2gb 内存(计算能力 3.0)的 GTX 670 上为 sm_30 和 运行 构建此代码,我得到:

~/cbow/word2vec_cbow$ make
nvcc word2vec.cu -o word2vec -O3 -Xcompiler -march=native -w  -Xptxas="-v" -arch=sm_30 -lineinfo
ptxas info    : 0 bytes gmem
ptxas info    : Compiling entry function '_Z11cbow_kernelILx1EEvllflPKilPVfS3_PKfS1_PKcS1_S1_llS3_' for 'sm_30'
ptxas info    : Function properties for _Z11cbow_kernelILx1EEvllflPKilPVfS3_PKfS1_PKcS1_S1_llS3_
    0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads
ptxas info    : Used 34 registers, 448 bytes cmem[0], 12 bytes cmem[2]

~/cbow/word2vec_cbow$ ./word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 7 -negative 1 -hs 1 -sample 1e-3 -threads 1 -binary 1 -save-vocab voc #> out 2>&1
Starting training using file text8
Vocab size: 71290
Words in train file: 16718843
vocab size = 71290
Alpha: 0.000009  Progress: 100.00%  Words/thread/sec: 1217.45k

即。代码 运行 正确完成,没有任何错误。我无法告诉您为什么您无法在您的硬件上获取 运行 的代码,因为我无法在我的硬件上重现您的错误。您将需要自己进行一些调试才能找到根本原因。