cudaMalloc 或 cudaMemcpy 上的分段错误

Segmentation fault on cudaMalloc or cudaMemcpy

本文关键字:分段 错误 cudaMemcpy cudaMalloc      更新时间:2023-10-16

CUDA 编程新手,对为什么我在以下代码中出现段错误感到非常困惑:

  #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 passwordn");
          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)

编辑:在我处理了 int memcpy 和 malloc 之后,错误仍然发生,显然我不必分配或 cpy 它。可能只是把它过去了。所以,错误是由于以下几行造成的,我不确定是哪一行或为什么?

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);

编辑2:我清理了所有内容,但仍然无法弄清楚。通过在下一行CUDA_SAFE_CALL( cudaMalloc((void**) &d_pwds, pwds_size)); CUDA_SAFE_CALL即使所有其他内存分配命令都被注释掉,我也会出现分段错误。

对于想知道出了什么问题的人,我能够修复它。我不确定到底出了什么问题,但我在某些地方的内存分配不当,在其他情况下,我什至不需要使用 cudaMalloccudaMemcpy .另外,使用 CUDA 运行时 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 %dn", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

我仍然不完全理解 CUDA(设备和主机分配)中的内存管理,但我的代码现在可以工作了!谢谢大家。