Обработка памяти cuda в классе приводит к повреждению адресов памяти - PullRequest
2 голосов
/ 19 января 2012

Для удобства работы с памятью на хосте и устройстве я создал следующий класс. Теоретически он должен управлять копированием с хоста на устройство и наоборот.

struct CudaArray
{

int* memoryHost;
int* memoryDevice;

int size;

CudaArray(int datasize) // creates array on host and allocates memory on device with cudaMalloc
{
    size = datasize;
    memoryHost = new int[size];

    for (int i = 0; i < size; i++)
    {
        memoryHost[i] = 0;
    }

    cudaMalloc((void**)&memoryDevice, sizeof(int) * size);
}

~CudaArray() // frees memory on device and host
{
    delete[] memoryHost;
    cudaFree(memoryDevice);
}

void Upload() // upload data from host to device
{
    cudaMemcpy(memoryDevice, memoryHost, sizeof(int) * size, cudaMemcpyHostToDevice);
}
void Download() // download data from device to host
{
    cudaMemcpy(memoryHost, memoryDevice, sizeof(int) * size, cudaMemcpyDeviceToHost);
}

void Insert(int* src); // copy from src to memoryHost
void Retrieve(int* dest); // copy from memoryHost to dest
};

Внутренне все в порядке. Но когда я использую объект моего CudaArray, возникают проблемы с указателями:

CudaArray cuda_ar(1000);
kernel <<<blocks, threads_per_block>>> (cuda_ar.memoryDevice, cuda_ar.size);

С помощью отладчика мне удалось прочитать указатель memoryDevice. Внутри структуры (например, при переходе через Upload ()) это 0x01000000. Но в том месте, где выполняется ядро, memoryDevice указывает на 0x00000400 (числа являются примерами).

Я знаю, что memoryDevice - это указатель, указывающий на память на устройстве. Есть ли способ объяснить это поведение и дать решение моей проблемы?

1 Ответ

1 голос
/ 20 января 2012

Когда я запускаю следующую программу

#include <cstdio>
struct CudaArray
{

  int* memoryHost;
  int* memoryDevice;

  int size;

  CudaArray(int datasize) // creates array on host and allocates memory on device with cudaMalloc
  {
    size = datasize;
    memoryHost = new int[size];

    for (int i = 0; i < size; i++)
    {
      memoryHost[i] = 0;
    }

    cudaMalloc((void**)&memoryDevice, sizeof(int) * size);
}

~CudaArray() // frees memory on device and host
{
  delete[] memoryHost;
  cudaFree(memoryDevice);
}

void Upload() // upload data from host to device
{
  cudaMemcpy(memoryDevice, memoryHost, sizeof(int) * size, cudaMemcpyHostToDevice);
}
void Download() // download data from device to host
{
  cudaMemcpy(memoryHost, memoryDevice, sizeof(int) * size, cudaMemcpyDeviceToHost);
}

};

__global__ void kernel(int *ptr, int n)
{
  printf("On Device : %p %d\n", ptr, n);
}

int main(void)
{
  CudaArray cuda_ar(1000);
  printf("On Host   : %p %d\n", cuda_ar.memoryDevice, cuda_ar.size);
  kernel<<<1, 1>>>(cuda_ar.memoryDevice, cuda_ar.size);
  return 0;
}

Я получаю

On Host   : 0x200400000 1000
On Device : 0x200400000 1000

Вы должны убедиться, что все вызовы времени выполнения CUDA, такие как cudaMalloc, cudaMemcpy и запуска ядра, возвращаются успешно.Вы можете попробовать этот код после всех вызовов CUDA во время выполнения, чтобы убедиться, что:

if (cudaSuccess != cudaGetLastError())
  printf( "Error!\n" );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...