Почему cudaPointerGetAttributes () возвращает неверный аргумент для указателя хоста? - PullRequest
0 голосов
/ 01 мая 2018

Я хочу написать функцию, которая сообщает мне, является ли указатель указателем на хост или устройство. По сути, это оболочка cudaPointerGetAttributes(), которая возвращает 1 или 0, если указатель предназначен для устройства или нет.

Я не могу понять, почему cudaPointerGetAttributes не проходит проверку ошибок, возвращая неверный аргумент при тестировании указателя хоста. Пример приведен ниже.

#include <stdio.h>
#include <stdlib.h>

#define CUDA_ERROR_CHECK(fun)                                                                   \
do{                                                                                             \
    cudaError_t err = fun;                                                                      \
    if(err != cudaSuccess)                                                                      \
    {                                                                                           \
      fprintf(stderr, "Cuda error %d %s:: %s\n", __LINE__, __func__, cudaGetErrorString(err));  \
      exit(EXIT_FAILURE);                                                                       \
    }                                                                                           \
}while(0);

int is_device_pointer(const void *ptr)
{
  int is_device_ptr = 0;
  cudaPointerAttributes attributes;

  CUDA_ERROR_CHECK(cudaPointerGetAttributes(&attributes, ptr));

  if(attributes.devicePointer != NULL)
  {
    is_device_ptr = 1;
  }

  return is_device_ptr;
}

int main()
{
  int *host_ptr, x = 0;
  int is_dev_ptr;

  host_ptr = &x;

  int *dev_ptr;
  cudaMalloc((void **)&dev_ptr, 16);

  //is_dev_ptr = is_device_pointer((const void *)host_ptr); //Causes invalid argument
  is_dev_ptr = is_device_pointer((const void *)dev_ptr);  //Works

  if(is_dev_ptr == 1)
  {
    fprintf(stdout, "Device pointer\n");
  }
  else
  {
    fprintf(stdout, "Not device Pointer\n");
  }

  CUDA_ERROR_CHECK(cudaFree((void *)dev_ptr));
  CUDA_ERROR_CHECK(cudaDeviceReset());

  return EXIT_SUCCESS;
}

1 Ответ

0 голосов
/ 01 мая 2018

Это ожидаемое поведение. cudaPointerGetAttributes может только анализировать указатели, которые были каким-то образом записаны с помощью API среды выполнения CUDA. См. документацию :

Если указатель не был размещен, отображен или зарегистрирован с контекстом, поддерживающим унифицированную адресацию, возвращается cudaErrorInvalidValue.

Это говорит о том, что указатель должен быть возвращен или передан через API, такой как cudaMalloc, cudaMallocManaged, cudaHostRegister и т. Д., Чтобы он был "распознан" cudaPointerGetAttributes. Вы должны быть в режиме UVA , и вы должны получить указатель, используя соответствующий метод.

В вашем случае, передача пустого указателя хоста таким способом не соответствует требованиям, изложенным в документации, поэтому ожидается возврат ошибки.

Этот конкретный код возврата ошибки является «нелипкой» ошибкой CUDA, то есть ее можно удалить с помощью cudaGetLastError(). На мой взгляд, было бы безопасно интерпретировать этот код возврата ошибки как «это обычный указатель хоста». Но, конечно, если вы передадите значение мусора или нераспределенный указатель, вы получите тот же код ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...