为什么cudaPointerGetAttributes()为主机指针返回无效参数?

时间:2018-05-01 12:55:14

标签: cuda

我想编写一个函数,告诉我指针是主机还是设备指针。这实际上是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 :(得分:3)

这是预期的行为。 cudaPointerGetAttributes只能内省使用CUDA运行时API以某种方式记录的指针。请参阅documentation

  

如果未分配指针,映射或注册支持统一寻址的上下文,则返回cudaErrorInvalidValue。

这就是指针必须已经返回或通过cudaMalloccudaMallocManagedcudaHostRegister等API传递,以便“被”识别“ cudaPointerGetAttributes。您必须在UVA regime,并且必须使用适当的方法获取指针。

在您的情况下,以这种方式传递裸主机指针不符合文档中规定的要求,因此错误返回是预期的。

此特定错误返回代码是“非粘性”CUDA错误,这意味着它可以通过cudaGetLastError()清除。在我看来,将此错误返回代码解释为“这是一个普通的主机指针”应该是安全的。但是,当然,如果传递垃圾值或未分配的指针,您将获得相同的错误代码。