Cuda 警告:不允许从设备函数调用主机函数

Cuda 警告:不允许从设备函数调用主机函数,cuda,Cuda,我引用了几乎所有类似的问题,但没有找到答案。很多人都建议进行错误检查,因此我尝试使用CHECKED\u CALL()type宏使程序强大,但我的代码遇到了两个问题: 正如标题所说,我收到了一条警告消息,但在使用#pragma hd_warning_disable之前,我收到了错误消息: cuEntityIDBuffer.cu(9):错误:设备代码中未定义标识符“stderr” 当我编译maintest.cpp时,我遇到了另一个错误: 编辑: g++ -c maintest.cpp -std=c

我引用了几乎所有类似的问题,但没有找到答案。很多人都建议进行错误检查,因此我尝试使用
CHECKED\u CALL()
type宏使程序强大,但我的代码遇到了两个问题:

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

    cuEntityIDBuffer.cu(9):错误:设备代码中未定义标识符“stderr”

  • 当我编译
    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

    #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());
    }
    
    cuEntityIDBuffer.cu
    maintest.cpp
    都包含了“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;
    };
    
    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;
    }
    
    #包括“cuEntityIDBuffer.h”
    #包括
    int main(int argc,char const*argv[]
    {
    无符号整数*h_buf;
    h_buf=malloc(1024*sizeof(unsigned int));
    cuEntityIDBuffer d_buf(h_buf);
    最可爱的;
    d_buf.cuCallBackEntityIDBuffer(h_buf);
    返回0;
    }
    

    我使用的
    CHECKED\u CALL()
    类型宏是错误的还是我的代码组织有问题?感谢您的建议。

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

    • cuEntityIDBuffer.cu(9):错误:设备代码中未定义标识符“stderr”
      非常清楚,您试图在设备代码中使用CPU变量
      stderr

    • 警告:不允许从{uuu主机{uuu设备}函数调用{uu主机}函数
      也是同样的问题:如果没有任何
      \uuu主机{uuuu
      \uu设备}/code>或
      \uu全局}/code>属性,符号将隐式设置为
      \uu主机
      ,这意味着在您的情况下,方法的设备版本正在尝试使用仅在CPU端的
      gpuAssert


    对于
    cuEntityIDBuffer.h:1:27:致命错误:推力/减少.h:没有这样的文件或目录
    ,正如@Talonmes指出的,任何推力代码都必须使用nvcc构建。

    感谢您的重播,我似乎理解您上面提到的第一个问题,因此,如果我想打印错误消息,我应该将
    gpuAssert
    代码放在哪里才能正确编译?第二个问题可能与您描述的不同,因为可以使用NVCC正确编译
    cuEntityIDBuffer.cu
    文件,其中还包括
    cuEntityIDBuffer.h
    。无论如何谢谢你!在设备代码中尝试使用
    printf
    而不是
    fprintf
    。您可以检查
    \uuuu CUDA\u ARCH\uuuu
    宏以了解这一点。我不太明白你评论的第二部分。你能编辑你的问题并指定什么时候出现错误吗?是的,我想这就是我说的,你使用的是两个不同的编译器,所以请确保它们使用相同的包含路径,这样g++也可以解析推力包含。@Robintoni:任何推力代码都必须用nvcc编译。你为什么要用gcc编译main?您必须使用nvcc和.cu扩展名