簡體   English   中英

CUDA C ++:使用調用模板內核的模板函數

[英]CUDA C++: Using a template function which calls a template kernel

我有一個帶有模板功能的類。 該函數調用模板內核。 我正在Linux平台上的Nsight中進行開發。 在執行此操作時,我遇到了以下兩個相互矛盾的要求:

1-實現模板功能時,定義必須出現在* .h(或* .cu.h)文件中,因為直到需要模板才生成代碼。

2-內核代碼必須出現在* .cu中,因為當編譯器將它們放在頭文件中時,編譯器將無法識別<<<和>>>標記。

我認為可能有一種繞過第二個編譯器伏都教的方法。

當我設置模板成員函數位於* .cu.h文件中的系統時,出現以下編譯器錯誤:

錯誤:“ <”令牌之前的預期主表達式

錯誤:“>”令牌之前的預期主表達式

這似乎表明它正在解析<<和然后>>標記,而不識別<<<或>>>標記。

該代碼相關部分的結構概述如下:

在MyClass.cu.h中:

#include "MyKernels.cu.h"

class MyClass{
    template <typename T> void myFunction(T* param1, int param2);
};

template <typename T> void myFunction(T* param1, int param2){
    blocks = 16;
    blockSize = 512;
    myKernel<<<blocks, bockSize>>>(d_param1, param2);
}

在MyKernels.cu.h中:

#ifndef MYKERNELS_H_
#define MYKERNELS_H_

template <typename T>
extern __global__ void myKernel(T* param1, int param2);
#endif

在MyKernels.cu中:

#include "MyKernels.cu.h"

template<typename T>
__global__ void myKernel(T* param1, int param2){
    //Do stuff
}

編輯7/31/2015:為了使我要完成的工作的結構更加清晰,我編寫了一個小示例項目。 它公開發布在github上的以下URL:

https://github.com/nvparrish/CudaTemplateProblem

包裝函數聲明必須位於頭文件中。 函數定義沒有。

這就是我的想法:

$ cat MyClass.cuh
template <typename T> void kernel_wrapper(T*, int);
class MyClass{
  public:
    template <typename T> void myFunction(T* param1, int param2);
};

template <typename T> void MyClass::myFunction(T* param1, int param2){
    kernel_wrapper(param1, param2);
}
$ cat MyKernels.cu
#include "MyClass.cuh"
#define nTPB 256

template <typename T>
__global__ void myKernel(T* param1, int param2){

  int i = threadIdx.x+blockDim.x*blockIdx.x;
  if (i < param2){
    param1[i] += (T)param2;
  }
}

template <typename T>
void kernel_wrapper(T* param1, int param2){
  myKernel<<<(param2+nTPB-1)/nTPB,nTPB>>>(param1, param2);
  cudaDeviceSynchronize();
}

template void MyClass::myFunction(float *, int);
template void MyClass::myFunction(int *, int);

$ cat mymain.cpp
#include "MyClass.cuh"

int main(){

  MyClass A;
  float *fdata;
  int *idata, size;
  A.myFunction(fdata, size);
  A.myFunction(idata, size);
}

$ nvcc -c MyKernels.cu
$ g++ -o test mymain.cpp MyKernels.o -L/usr/local/cuda/lib64 -lcudart
$

注意強制模板實例化。 如果希望模板特化在一個編譯單元(一個內核定義所屬的.cu文件)中發生,則這是必需的,因此它可以在另一個編譯單元(一個不了解cuda語法的.cpp文件)中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM