2016-01-20 2 views
0

Новое в CUDA программирование и крайне запутанным, почему я получаю Segfault в следующем коде:Сегментация на cudaMalloc или cudaMemcpy

#include <cuda.h> 
    #include <stdio.h> 
    #include <stdint.h> 
    #include <fstream> 
    #include <iostream> 
    #include <sstream> 
    #include <string> 

    using namespace std; 

    typedef struct password_t{ 
     char word[56]; 
     size_t length; 
    } password; 

    typedef struct libEntry_t{ 
     uint8_t digest[16]; 
     password pwd; 
    } libEntry; 

    // Generates a library of passwords and their corresponding MD5 hashes 
    // 
    // Params: 
    // numPwds - the number of passwords for which to generate hashes 
    // pwds - the list of passwords to hash 
    // library - the array in which to store the unhashed/hashed password library 
    __global__ void generateLibraryKernel(int numPwds, password* pwds, libEntry* library) 
    { 
     // __device__ void cuda_md5(const password *pwd, uint8_t *digest) { 
     int index = (blockIdx.x * blockDim.x) + threadIdx.x; 
     uint8_t hashed[16]; 

     if (index < numPwds) { 
     cuda_md5(&pwds[index], hashed); 
     for (int j = 0; j < 16; j++) { 
      library[index].digest[j] = hashed[j]; 
     } 
     library[index].pwd = pwds[index]; 
     } 
    } 

    int crack_password (uint8_t* classified) 
    { 
     int count = 10; 
     unsigned int mem_size = sizeof(password) * count; 
     password *h_pwds = (password*) malloc(mem_size); 

     ifstream inFile("passwords.txt"); 
     if (!inFile) { 
     cerr << "File passwords.txt not found." << endl; 
     return -1; 
     } 

     string line; 
     int i; 
     while (getline(inFile, line)) { 
     if (line.empty()) continue; 
     memcpy(h_pwds[i].word,line.c_str(),line.size()); 
     h_pwds[i].length = line.size(); 
     cout << "Password: " << h_pwds[i].word << "\n"; 
     cout << "Length: " << h_pwds[i].length << "\n"; 
     i++; 
     } 

     inFile.close(); 

     /***** KERNEL CONFIGURATION & MEMORY MANAGEMENT ******/ 
     password* d_pwds; 
     cudaMalloc((void**) &d_pwds, mem_size); 
     cudaMemcpy(d_pwds, h_pwds, mem_size, cudaMemcpyHostToDevice); 

     libEntry *h_library = (libEntry*) malloc(sizeof(libEntry) * count); 

     libEntry* d_library; 
     cudaMalloc((void**) &d_library, sizeof(libEntry) * count); 

     int h_numPwds = i; 
     cout << "INT NUMPWDS: " << h_numPwds << "\n"; 

     int* d_numPwds; 
     cudaMalloc((void**) &d_numPwds, sizeof(int)); 
     cudaMemcpy(d_numPwds, &h_numPwds, sizeof(int), cudaMemcpyHostToDevice); 

     /*unsigned int threads_per_block = 1024; 
     dim3 grid(1024, 1, 1); 
     dim3 threads(threads_per_block, 1, 1); 

     // generateLibraryKernel(int numPwds, password* pwds, libEntry* library) 
     generateLibraryKernel<<<grid, threads>>>(d_numPwds[0], d_pwds, d_library); 

     cudaMemcpy(h_library, d_library, mem_size, cudaMemcpyDeviceToHost);*/ 

     return 0; 
    } 

    int main(int argc, char *argv[]) 
    { 
     if (argc != 2) { 
      fprintf(stderr, "usage: ./prog password\n"); 
      return 1; 
     } 

     crack_password((uint8_t*) argv[1]); 
     cout << "Hack Password: " << argv[1] << "\n"; 
     return 0; 
    } 

Я прошел через это построчно, и я считаю, что это происходит на следующие строки:

 int* d_numPwds; 
     cudaMalloc((void**) &d_numPwds, sizeof(int)); 
     cudaMemcpy(d_numPwds, &h_numPwds, sizeof(int), cudaMemcpyHostToDevice); 

Когда я комментирую cudaMemcpy выше, я по крайней мере получить cout выход на моем терминале. Обратите внимание, что я еще не добрался до части выполнения ядра, я просто сосредоточен на распределении памяти, прежде чем я смогу выполнить и отладить ядро. Любая помощь будет оценена!

Как я проверял для возвращения статуса:

#define CUDA_SAFE_CALL(call) do {          \ 
    CUDA_SAFE_CALL_NO_SYNC(call);           \ 
    cudaError err = cudaThreadSynchronize();        \ 
    if(cudaSuccess != err) {            \ 
    fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",  \ 
       __FILE__, __LINE__, cudaGetErrorString(err));  \ 
    exit(EXIT_FAILURE);            \ 
    } } while (0) 

EDIT: ошибка возникает после того, как я позаботилась о Int тетсра и таНоса, видимо, я не должна Alloc или КОМ его. Мог бы просто передать это. Итак, ошибка вызвана следующими строками, и я не уверен, какой из них или почему?

password* d_pwds; 
cudaMalloc((void**) &d_pwds, mem_size); 
cudaMemcpy(d_pwds, h_pwds, mem_size, cudaMemcpyHostToDevice); 

libEntry *h_library = (libEntry*) malloc(sizeof(libEntry) * count); 

libEntry* d_library; 
cudaMalloc((void**) &d_library, sizeof(libEntry) * count); 

EDIT2: Я очистил все и до сих пор не могу понять. Имея CUDA_SAFE_CALL на следующей строке CUDA_SAFE_CALL(cudaMalloc((void**) &d_pwds, pwds_size));, я получаю ошибку сегментации, даже если каждая другая команда выделения памяти закомментирована.

+0

Попробуйте проверить статус возврата вызовов CUDA http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime -api –

+0

@terence hill Я на самом деле делаю это, но вместо этого я получаю результат вместо segfault. Я добавил выше кода, который я использовал для проверки состояния. – Blizzard

+0

Это почти наверняка будет, потому что у вас есть буфер, переполняющий код, который загружается из файла в память. Вы не прилагаете никаких усилий, чтобы убедиться, что из файла читаются не более строк 'count'. Я не думаю, что это имеет какое-то отношение к CUDA. – talonmies

ответ

1

Для кого-то интересно, что пошло не так, я смог это исправить. Я не совсем уверен, что именно не так, но в некоторых местах у меня были неправильные выделения памяти, а в других случаях мне даже не нужно было использовать cudaMalloc или cudaMemcpy. Кроме того, с использованием What is the canonical way to check for errors using the CUDA runtime API? для проверки ошибок вместо моей собственной работы. То, что я есть сейчас:

/***** KERNEL CONFIGURATION & MEMORY MANAGEMENT ******/ 
/***** GENERATE HASHED PASSWORD LIBRARY FOR COMPARE **/ 
unsigned int threads_per_block = 1024; 
dim3 grid(1024, 1, 1); 
dim3 threads(threads_per_block, 1, 1); 

password* d_pwds; 
ERROR_CHECK(cudaMalloc((void**) &d_pwds, pwds_size)); 
ERROR_CHECK(cudaMemcpy(d_pwds, h_pwds, pwds_size, cudaMemcpyHostToDevice)); 

libEntry* d_library; 
ERROR_CHECK(cudaMalloc((void**) &d_library, sizeof(libEntry) * count)); 

// generateLibraryKernel(int numPwds, password* pwds, libEntry* library) 
generateLibraryKernel<<<grid, threads>>>(i, d_pwds, d_library); 
ERROR_CHECK(cudaPeekAtLastError()); 
ERROR_CHECK(cudaDeviceSynchronize()); 

Где ERROR_CHECK определяется из приведенной выше ссылке.

#define ERROR_CHECK(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

Я все еще не полностью понимаю управление памятью в CUDA (распределение устройств и хостов), но мой код работает прямо сейчас! Спасибо вам всем.

Смежные вопросы