Понимание CUDA's cudaGetSymbolAddress - PullRequest
0 голосов
/ 19 марта 2020

Я новичок в CUDA, теперь я пытаюсь понять, как работает cudaGetSymbolAddress. Я получаю неожиданную ошибку сегментации в действительно простом коде. Я делаю следующее:

  1. Я объявляю глобальную переменную устройства (device_int)
  2. В main () я проверяю правильность определения, устанавливая его значение в Ядро
  3. Я создаю указатель (host_pointer_to_device_int) в памяти хоста и указываю на device_int через cudaGetSymbolAddress
  4. Я создаю еще один указатель (host_pointer_to_host_int) и пытаюсь cudaMemcpy значение от host_pointer_to_device_int до host_pointer_to_host_int

Все эти операции заканчиваются sh без ошибок, но я получаю Ошибка сегментации при попытке вывести значение host_pointer_to_host_int. Вот код:

#include <iostream>
#include <cassert>
using namespace std;


__device__ int device_int;


__global__ void kernel()
{
    device_int = 1000;
}


int main()
{
    kernel<<<1, 1>>>();
    assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully

    int *host_pointer_to_device_int;
    cudaGetSymbolAddress((void **)&host_pointer_to_device_int, device_int);
    assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully

    int *host_pointer_to_host_int;
    // Copy the device_int's value
    cudaMemcpy((void **)&host_pointer_to_host_int, host_pointer_to_device_int,
            sizeof(int), cudaMemcpyDeviceToHost);
    assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully

    cout << *host_pointer_to_host_int << endl; // Segmentation fault
}

1 Ответ

1 голос
/ 19 марта 2020

(отредактировано)

Благодаря @ talonmies

Моя ошибка была не в неправильном понимании того, как работает cudaGetSymbolAddress, а в использовании cudaMemcpy с неверными типами параметров: я ожидал, что cudaMemcpy будет выделите память для меня, поэтому я привел мои переменные к неправильным типам.

Исправленный код:

#include <iostream>
#include <cassert>
using namespace std;


__device__ int device_int;


__global__ void kernel()
{
    device_int = 1000;
}

int main()
{
    kernel<<<1, 1>>>();
    assert(cudaGetLastError() == cudaSuccess);

    int *host_pointer_to_device_int;
    /* Get a pointer to device_int. After this, I won't be able to access it,
     * but I'm going to copy its value with cudaMemcpy */
    cudaGetSymbolAddress((void **)&host_pointer_to_device_int, device_int);
    assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully

    int host_int;
    // Copy the device_int's value
    cudaMemcpy(&host_int, host_pointer_to_device_int,
            sizeof(int), cudaMemcpyDeviceToHost);
    assert(cudaGetLastError() == cudaSuccess); // The above operation executed successfully

    cout << host_int << endl; // Everything's fine!
}
...