我想编写一个函数,告诉我指针是主机还是设备指针。这实际上是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;
}
答案 0 :(得分:3)
这是预期的行为。 cudaPointerGetAttributes
只能内省使用CUDA运行时API以某种方式记录的指针。请参阅documentation:
如果未分配指针,映射或注册支持统一寻址的上下文,则返回cudaErrorInvalidValue。
这就是指针必须已经返回或通过cudaMalloc
,cudaMallocManaged
,cudaHostRegister
等API传递,以便“被”识别“ cudaPointerGetAttributes
。您必须在UVA regime,并且必须使用适当的方法获取指针。
在您的情况下,以这种方式传递裸主机指针不符合文档中规定的要求,因此错误返回是预期的。
此特定错误返回代码是“非粘性”CUDA错误,这意味着它可以通过cudaGetLastError()
清除。在我看来,将此错误返回代码解释为“这是一个普通的主机指针”应该是安全的。但是,当然,如果传递垃圾值或未分配的指针,您将获得相同的错误代码。