Templates nvcc处理_限制_和模板函数默认参数 下面的代码是合法C++(用g++Walk编译干净): #ifdef使编译 #定义_限制_/*空*/ #定义无前向声明 #恩迪夫 #包括 模板 结构数组 { int宽度、高度; T*ptr; }; #如果你有 模板 静态\uuuu全局\uuuuu无效genConvolve\u内核(常量T\uuuu限制\uuuu*inputImageArray、T\uu限制\uuuuu*outputImageArray、int-inputWidth、int-outputWidth) { 如果((threadIdx.x==4)和&(threadIdx.y==2)) printf(“来自CUDA的你好世界!\n”); } #恩迪夫 #如果未提交任何声明 模板 void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16); 模板 void genConvolve\u cuda\u deviceptrs(常数T\uuu restrict\uuuu*inputImageArray,T\uu restrict\uuuu*outputImageArray,int-inputWidth,int-outputWidth,int-outputhweight,int-blockWidth=16,int-blockHeight=16); #恩迪夫 模板 void genConvolve\u cuda\u deviceptrs(常数T\u限制\u*inputimagerray,T\u限制\u*outputimagerray,int-inputWidth,int-outputWidth,int-outputhweight,int-blockWidth=16,int-blockHeight=16) { #如果你有 dim3块(块宽、块高); dim3网格(1,1); genConvolve_内核(inputImageArray、outputImageArray、inputWidth、outputWidth); #否则 printf(“你好,世界!\n”); #恩迪夫 } 模板 void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16) { genConvolve_cuda_deviceptrs((常数T*)inputimagerray.ptr、outputimagerray.ptr、inputimagerray.width、outputimagerray.width、outputimagerray.height、blockWidth、blockHeight); } int main(int argc,char*argv[]) { 阵列a; genConvolve_cuda(a,a,a); #如果你有 cudaDeviceSynchronize(); #恩迪夫 返回0; }

Templates nvcc处理_限制_和模板函数默认参数 下面的代码是合法C++(用g++Walk编译干净): #ifdef使编译 #定义_限制_/*空*/ #定义无前向声明 #恩迪夫 #包括 模板 结构数组 { int宽度、高度; T*ptr; }; #如果你有 模板 静态\uuuu全局\uuuuu无效genConvolve\u内核(常量T\uuuu限制\uuuu*inputImageArray、T\uu限制\uuuuu*outputImageArray、int-inputWidth、int-outputWidth) { 如果((threadIdx.x==4)和&(threadIdx.y==2)) printf(“来自CUDA的你好世界!\n”); } #恩迪夫 #如果未提交任何声明 模板 void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16); 模板 void genConvolve\u cuda\u deviceptrs(常数T\uuu restrict\uuuu*inputImageArray,T\uu restrict\uuuu*outputImageArray,int-inputWidth,int-outputWidth,int-outputhweight,int-blockWidth=16,int-blockHeight=16); #恩迪夫 模板 void genConvolve\u cuda\u deviceptrs(常数T\u限制\u*inputimagerray,T\u限制\u*outputimagerray,int-inputWidth,int-outputWidth,int-outputhweight,int-blockWidth=16,int-blockHeight=16) { #如果你有 dim3块(块宽、块高); dim3网格(1,1); genConvolve_内核(inputImageArray、outputImageArray、inputWidth、outputWidth); #否则 printf(“你好,世界!\n”); #恩迪夫 } 模板 void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16) { genConvolve_cuda_deviceptrs((常数T*)inputimagerray.ptr、outputimagerray.ptr、inputimagerray.width、outputimagerray.width、outputimagerray.height、blockWidth、blockHeight); } int main(int argc,char*argv[]) { 阵列a; genConvolve_cuda(a,a,a); #如果你有 cudaDeviceSynchronize(); #恩迪夫 返回0; },templates,cuda,nvcc,Templates,Cuda,Nvcc,但是,当我尝试使用nvcc编译此文件时,会出现以下错误: nvcc t.cu t、 cu(39):警告:在重新声明 未引用的函数模板是非标准的 t、 cu(39):警告:重新定义默认参数 t、 cu(51):警告:在重新声明 未引用的函数模板是非标准的 t、 cu(51):警告:重新定义默认参数 t、 cu(53):错误:模板实例化导致意外错误 函数类型为“void(常量浮点*,浮点*,int,int,int,int, int)”(名称的含义可能自模板使用后发生了变化 声明——模板的类型是“vo

但是,当我尝试使用nvcc编译此文件时,会出现以下错误:

nvcc t.cu

t、 cu(39):警告:在重新声明 未引用的函数模板是非标准的

t、 cu(39):警告:重新定义默认参数

t、 cu(51):警告:在重新声明 未引用的函数模板是非标准的

t、 cu(51):警告:重新定义默认参数

t、 cu(53):错误:模板实例化导致意外错误 函数类型为“void(常量浮点*,浮点*,int,int,int,int, int)”(名称的含义可能自模板使用后发生了变化 声明——模板的类型是“void(const\uuu restrict\uuu *,uuu限制uu*,int,int,int,int,int,int 在以下期间检测到: 基于模板参数(53)实例化“genConvolve_cuda_deviceptrs”:此处 实例化“void genConvolve_cuda(常量数组&,常量数组&, 数组&,int,int)[T=float,KernelSize=3]“(60):这里

(当我在发布前清理示例时,行号会稍微偏移。)

当我定义-DMAKE_COMPILE时,警告和错误就会消失;但是,我确实希望在头文件中指定转发声明,并使用restrict

所以有两个问题:

  • 当存在默认函数参数(在我的例子中是blockWidth和blockHeight?)时,如何使用NVCC指定模板函数的前向声明
  • 如何在模板参数中正确使用u_限制_
  • 如何在模板参数中正确使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

    在与同事讨论后,有人向我指出,此
    \uuuu限制\uuuu
    使用:

    const T __restrict__ * inputImageArray ...
    
    这是值得怀疑的。为了使
    \uuuu restrict\uuuu
    产生任何效果,应将其置于星号和指针名称之间:

    const T * __restrict__ inputImageArray ...
    
    (及)

    在您所展示的非标准用法中,gcc似乎允许这样做,但默默地“放弃”了意图;在这种情况下,
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu限制
    的效果不适用。在这方面,CUDA确实不同于gcc行为。但是,由于如上所述,它的使用存在疑问,因此不太可能修改
    nvcc
    来“修复”此问题

    如果切换到标准
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    用法,可以使编译错误在显示的代码中消失。如果您的目的是向编译器声明这些实际上是受限制的指针,则建议这样做:

    #ifdef MAKE_COMPILE
    #define __restrict__ /* empty */
    #define NO_FORWARD_DECLARATIONS
    #endif
    
    #include <stdio.h>
    
    template <class T>
    struct Array
    {
    int width, height;
    T *ptr;
    };
    
    #ifdef HAVE_CUDA
    template<typename T, int KernelSize>
         static __global__ void genConvolve_kernel(const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth )
    {
        if ((threadIdx.x == 4) && (threadIdx.y == 2))
           printf("Hello world from CUDA!\n");
    }
    #endif
    
    #ifndef NO_FORWARD_DECLARATIONS
    template <typename T, int KernelSize>
         void genConvolve_cuda(const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth=16, int blockHeight=16);
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth=16, int blockHeight=16);
    #endif
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth=16, int blockHeight=16)
    {
    #ifdef HAVE_CUDA
        dim3 block(blockWidth,blockHeight);
        dim3 grid(1,1);
        genConvolve_kernel<T,KernelSize><<<grid,block>>>(inputImageArray,outputImageArray,inputWidth,outputWidth);
    #else
        printf("Hello, world!\n");
    #endif
    }
    
    template <typename T, int KernelSize>
         void genConvolve_cuda( const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth=16, int blockHeight=16)
    {
        genConvolve_cuda_deviceptrs<T,KernelSize>((const T *)inputImageArray.ptr,outputImageArray.ptr, inputImageArray.width, outputImageArray.width, outputImageArray.height, blockWidth, blockHeight);
    }
    
    int main(int argc, char *argv[])
    {
        Array<float> a;
    
        genConvolve_cuda<float,3>(a,a,a);
    #ifdef HAVE_CUDA
        cudaDeviceSynchronize();
    #endif
    
        return 0;
    }
    
    #ifdef使编译
    #定义_限制_/*空*/
    #定义无前向声明
    #恩迪夫
    #包括
    模板
    结构数组
    {
    int宽度、高度;
    T*ptr;
    };
    #如果你有
    模板
    静态\uuuu全局\uuuuu无效genConvolve\u内核(常量T*\uuuu限制\uuuuu输入图像数组、T*\uuu限制\uuuuu输出图像数组、int输入宽度、int输出宽度)
    {
    如果((threadIdx.x==4)和&(threadIdx.y==2))
    printf(“来自CUDA的你好世界!\n”);
    }
    #恩迪夫
    #如果未提交任何声明
    模板
    void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16);
    模板
    void genConvolve\u cuda\u deviceptrs(常数T*\uuuu restrict\uuuuuu inputImageArray,T*\uu restrict\uuuuu outputImageArray,int inputWidth,int outputWidth,int outputhweight,int blockWidth=16,int blockHeight=16);
    #恩迪夫
    模板
    void genConvolve\u cuda\u deviceptrs(常数T*\uuuu restrict\uuuuu inputImageArray,T*\uuu restrict\uuuuu outputImageArray,int inputWidth,int outputWidth,int outputhweight,int blockWidth=16,int blockHeight=16)
    {
    #如果你有
    dim3块(块宽、块高);
    dim3网格(1,1);
    genConvolve_内核(inputImageArray、outputImageArray、inputWidth、outputWidth);
    #否则
    printf(“你好,世界!\n”);
    #恩迪夫
    }
    模板
    void genConvolve_cuda(常量数组和内核数组,常量数组和输入图像数组,数组和输出图像数组,int blockWidth=16,int blockHeight=16)
    {
    通用电气
    
    #ifdef MAKE_COMPILE
    #define __restrict__ /* empty */
    #define NO_FORWARD_DECLARATIONS
    #endif
    
    #include <stdio.h>
    
    template <class T>
    struct Array
    {
    int width, height;
    T *ptr;
    };
    
    #ifdef HAVE_CUDA
    template<typename T, int KernelSize>
         static __global__ void genConvolve_kernel(const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth )
    {
        if ((threadIdx.x == 4) && (threadIdx.y == 2))
           printf("Hello world from CUDA!\n");
    }
    #endif
    
    #ifndef NO_FORWARD_DECLARATIONS
    template <typename T, int KernelSize>
         void genConvolve_cuda(const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth=16, int blockHeight=16);
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth=16, int blockHeight=16);
    #endif
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth=16, int blockHeight=16)
    {
    #ifdef HAVE_CUDA
        dim3 block(blockWidth,blockHeight);
        dim3 grid(1,1);
        genConvolve_kernel<T,KernelSize><<<grid,block>>>(inputImageArray,outputImageArray,inputWidth,outputWidth);
    #else
        printf("Hello, world!\n");
    #endif
    }
    
    template <typename T, int KernelSize>
         void genConvolve_cuda( const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth=16, int blockHeight=16)
    {
        genConvolve_cuda_deviceptrs<T,KernelSize>((const T *)inputImageArray.ptr,outputImageArray.ptr, inputImageArray.width, outputImageArray.width, outputImageArray.height, blockWidth, blockHeight);
    }
    
    int main(int argc, char *argv[])
    {
        Array<float> a;
    
        genConvolve_cuda<float,3>(a,a,a);
    #ifdef HAVE_CUDA
        cudaDeviceSynchronize();
    #endif
    
        return 0;
    }
    
    #ifdef MAKE_COMPILE
    #define __restrict__ /* empty */
    #define NO_FORWARD_DECLARATIONS
    #endif
    
    #include <stdio.h>
    
    template <class T>
    struct Array
    {
    int width, height;
    T *ptr;
    };
    
    #ifdef HAVE_CUDA
    template<typename T, int KernelSize>
         static __global__ void genConvolve_kernel(const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth )
    {
        if ((threadIdx.x == 4) && (threadIdx.y == 2))
           printf("Hello world from CUDA!\n");
    }
    #endif
    
    #ifndef NO_FORWARD_DECLARATIONS
    template <typename T, int KernelSize>
         void genConvolve_cuda(const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth=16, int blockHeight=16);
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth=16, int blockHeight=16);
    #endif
    
    template <typename T, int KernelSize>
         void genConvolve_cuda_deviceptrs( const T * __restrict__ inputImageArray , T * __restrict__ outputImageArray , int inputWidth , int outputWidth , int outputHeight , int blockWidth, int blockHeight)
    {
    #ifdef HAVE_CUDA
        dim3 block(blockWidth,blockHeight);
        dim3 grid(1,1);
        genConvolve_kernel<T,KernelSize><<<grid,block>>>(inputImageArray,outputImageArray,inputWidth,outputWidth);
    #else
        printf("Hello, world!\n");
    #endif
    }
    
    template <typename T, int KernelSize>
         void genConvolve_cuda( const Array<T> & kernelArray , const Array<T> & inputImageArray , Array<T> & outputImageArray , int blockWidth, int blockHeight)
    {
        genConvolve_cuda_deviceptrs<T,KernelSize>((const T *)inputImageArray.ptr,outputImageArray.ptr, inputImageArray.width, outputImageArray.width, outputImageArray.height, blockWidth, blockHeight);
    }
    
    int main(int argc, char *argv[])
    {
        Array<float> a;
    
        genConvolve_cuda<float,3>(a,a,a);
    #ifdef HAVE_CUDA
        cudaDeviceSynchronize();
    #endif
    
        return 0;
    }