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; }
但是,当我尝试使用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 所以有两个问题: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
\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;
}