К сожалению, ваш вывод о том, что код работает при компиляции для sm_35 и выполняется на графическом процессоре sm_30, неверен. Виновник это:
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_35 и запустите sm_30. Если изменить код этой функции на это (добавление ошибки запуска ядра проверки):
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 о том, почему вывод этого кода неверен. Ядро анализа никогда не запускается на вашем оборудовании при построении с параметрами по умолчанию.
Если я построю этот код для sm_30 и запустить его на GTX 670 с 2 Гб оперативной памяти (вычислительных возможностей 3,0), я получаю это:
~/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
т.е.. код работает корректно до завершения без каких-либо ошибок.Я не могу сказать вам, почему вы не можете заставить код работать на вашем оборудовании, потому что я не могу воспроизвести вашу ошибку на своем оборудовании. Вам потребуется выполнить некоторую отладку самостоятельно, чтобы найти основную причину этого.
Вы пробовали использовать код cuda-memcheck? – talonmies
Итак, запустив его с помощью cuda-memcheck, вы обнаружите множество ошибок незаконного доступа. Есть ли какой-нибудь способ получить номер строки? Он показывает адрес инструкции, но не номер строки. Но я все еще не понимаю, почему он работает отлично с одним компилятором, но не запускается с другим. Пожалуйста, объясните – user1274878
. Вы можете создать код с опцией '-lineinfo', чтобы получить cuda-memcheck, чтобы сообщить номера строк. Я не могу объяснить, не видя кода, и ваша работа - найти код. Я не собираюсь анализировать 1000 строк кода для вас, извините. – talonmies