предупреждение: вызов функции __host__ из функции __host__ __device__ запрещен - PullRequest
0 голосов
/ 11 января 2019

Я ссылался почти на все подобные вопросы, но не нашел ответа. Проверка ошибок рекомендуется многими людьми, поэтому я попытался использовать макрос типа CHECKED_CALL(), чтобы сделать программу сильной, но мой код столкнулся с двумя проблемами:

  1. Как видно из названия, я получил предупреждение, но прежде чем использовать #pragma hd_warning_disable, я получил сообщение об ошибке:

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

  2. Когда я скомпилировал maintest.cpp, я получил еще одну ошибку:

EDIT:

 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.cu, и maintest.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() или есть проблема с моей организацией кода? Любое предложение приветствуется.

1 Ответ

0 голосов
/ 11 января 2019

Ваши методы определены как __host__ и __device, что означает, что они будут скомпилированы один раз для процессора и один раз для устройства. Я не вижу большой проблемы для версии процессора. Тем не менее, у вас есть две проблемы для версии устройства:

  • cuEntityIDBuffer.cu(9): error: identifier "stderr" is undefined in device code очень ясно, вы пытаетесь использовать переменную ЦП stderr в коде устройства.

  • warning: calling a __host__ function from a __host__ __device__ function is not allowed - такая же проблема: без атрибутов __host__, __device__ или __global__ символы неявно устанавливаются на __host__, что в вашем случае означает, что версия устройства из ваших методов пытается использовать gpuAssert, который только на стороне процессора.

Для cuEntityIDBuffer.h:1:27: fatal error: thrust/reduce.h: No such file or directory, как указал @Talonmies, любой код Thrust должен быть построен с использованием nvcc.

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