【问题标题】:warning: calling a __host__ function from a __host__ __device__ function is not allowed警告:不允许从 __host__ __device__ 函数调用 __host__ 函数
【发布时间】:2019-01-11 21:18:54
【问题描述】:

我参考了几乎所有类似的问题,但没有找到答案。错误检查被很多人推荐,所以我尝试使用CHECKED_CALL()类型的宏来使程序强大,但是我的代码遇到了两个问题:

  1. 正如标题所说,我收到了一条警告消息,但在我使用#pragma hd_warning_disable之前,我收到了错误消息:

    cuEntityIDBuffer.cu(9): error: identifier "stderr" is undefined in device code

  2. 当我编译maintest.cpp时,我得到另一个错误:

编辑:

 g++ -c maintest.cpp -std=c++11
 cuEntityIDBuffer.h:1:27: fatal error: thrust/reduce.h: No such file or directory

但是,在编译cuEntityIDBuffer.cu时它工作正常cuEntityIDBuffer.h也包含在这个文件中。
nvcc -arch=sm_35 -Xcompiler '-fPIC' -dc cuEntityIDBuffer.cu

cuEntityIDBuffer.cumaintest.cpp #include "cuEntityIDBuffer.h",但 maintest.cpp 抛出错误,我对此没有任何想法。

代码如下:

cuEntityIDBuffer.h

#include <thrust/reduce.h>
#include <thrust/execution_policy.h>
#include <stdio.h>
#include <assert.h>
#include <cuda_runtime.h>

#ifdef __CUDACC__
#define CUDA_CALLABLE_MEMBER __host__ __device__
#else
#define CUDA_CALLABLE_MEMBER
#endif

class cuEntityIDBuffer
{
public:
    CUDA_CALLABLE_MEMBER cuEntityIDBuffer();
    CUDA_CALLABLE_MEMBER cuEntityIDBuffer(unsigned int* buffer);
    CUDA_CALLABLE_MEMBER void cuCallBackEntityIDBuffer(unsigned int* buffer);
    CUDA_CALLABLE_MEMBER ~cuEntityIDBuffer();
    CUDA_CALLABLE_MEMBER void cuTest();
private:
    size_t buffersize;
    unsigned int* cuBuffer;
};

cuEntityIDBuffer.cu

#include "cuEntityIDBuffer.h"
#include <stdio.h>
#pragma hd_warning_disable
#define nTPB 256
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess) 
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

__global__ void mykernel(unsigned int* buffer)
{
    int idx = threadIdx.x + (blockDim.x * blockIdx.x);
    buffer[idx]++;
    //other things.
}

cuEntityIDBuffer::cuEntityIDBuffer()
{
    buffersize=1024;
    gpuErrchk(cudaMalloc(&cuBuffer, buffersize * sizeof(unsigned int)));
}

cuEntityIDBuffer::cuEntityIDBuffer(unsigned int* buffer)
{
    buffersize=1024;
    gpuErrchk(cudaMalloc(&cuBuffer, buffersize * sizeof(unsigned int)));
    gpuErrchk(cudaMemcpy(cuBuffer,buffer,buffersize*sizeof(unsigned int),cudaMemcpyHostToDevice));
}

void cuEntityIDBuffer::cuCallBackEntityIDBuffer(unsigned int* buffer)
{
    gpuErrchk(cudaMemcpy(buffer,cuBuffer,buffersize*sizeof(unsigned int),cudaMemcpyDeviceToHost));
}

cuEntityIDBuffer::~cuEntityIDBuffer()
{
    gpuErrchk(cudaFree((cuBuffer)));
}

void cuEntityIDBuffer::cuTest()
{
    mykernel<<<((buffersize+nTPB-1)/nTPB),nTPB>>>(cuBuffer);
    gpuErrchk(cudaPeekAtLastError());
}

maintest.cpp

#include "cuEntityIDBuffer.h"
#include <iostream>

int main(int argc, char const *argv[])
{
    unsigned int *h_buf;
    h_buf=malloc(1024*sizeof(unsigned int));
    cuEntityIDBuffer d_buf(h_buf);
    d_buf.cuTest();
    d_buf.cuCallBackEntityIDBuffer(h_buf);
    return 0;
}

是我使用CHECKED_CALL() 类型宏的方式错误还是我的代码组织有问题?任何建议表示赞赏。

【问题讨论】:

  • 你为什么要使用 gcc 编译 main?您必须使用 nvcc 并使用 .cu 扩展名

标签: cuda


【解决方案1】:

您的方法定义为__host____device,这意味着它们将为CPU 编译一次,为设备编译一次。我认为 CPU 版本没有什么大问题。但是,您的设备版本有两个问题:

  • cuEntityIDBuffer.cu(9): error: identifier "stderr" is undefined in device code 很清楚,你尝试在设备代码中使用 CPU 变量stderr

  • warning: calling a __host__ function from a __host__ __device__ function is not allowed 是同一种问题:没有任何__host____device____global__ 属性,符号被隐式设置为__host__,这意味着在您的情况下设备版本您的一些方法正在尝试使用仅在 CPU 端的gpuAssert

对于cuEntityIDBuffer.h:1:27: fatal error: thrust/reduce.h: No such file or directory,正如@Talonmies 指出的那样,任何推力代码都必须使用nvcc 构建。

【讨论】:

  • 感谢您的重播,我似乎理解了您上面提到的第一个问题,所以,如果我想打印错误信息,我应该将gpuAssert代码放在哪里才能正确编译?第二个问题可能不像你描述的那样,因为cuEntityIDBuffer.cu文件可以用NVCC正确编译,其中还包括cuEntityIDBuffer.h。还是谢谢!
  • 在设备代码中尝试使用printf 而不是fprintf。您可以检查__CUDA_ARCH__ 宏。我不确定是否理解您评论的第二部分。你能编辑你的问题并指定什么时候出现的错误吗?
  • 是的,我想这就是我所说的,您使用的是两个不同的编译器,因此请确保它们使用相同的包含路径,以便 g++ 也可以解析 Thrust 包含。
  • @RobinThoni: 任何推力代码必须用 nvcc 编译。
猜你喜欢
  • 2021-08-30
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
相关资源
最近更新 更多