我有这些模板函数可以在设备上使用cuda进行内联
template <class T> __device__ inline T& cmin(T&a,T&b){return (a<b)?(a):(b);};
template <class T> __device__ inline T& cmax(T&a,T&b){return (a>b)?(a):(b);};
在我的代码中
cmin(z[i],y[j])-cmax(x[i],z[j])
表示int数组x,y和z。我收到错误:
错误:没有函数模板“cmax”的实例与参数列表匹配
argument types are: (int, int)
我得到cmax但不是cmin的错误。如果我用
替换cmax行#define cmax(a,b) ((a)>(b))?(a):(b)
工作正常,但我不想#defines,它们是有问题的。到底发生了什么事?
编辑: 这是完整的调用功能。 times是typedef int。
__global__ void compute_integral_y_isums(times * admit, times * discharge, times * Mx, times * isums, ar_size N){
// computes the sums for each j
// blocks on j,
// threads on i since we will be summing over i.
// sumation over J should be handled by either a different kernel or on the cpu.
ar_index tid = threadIdx.x;
ar_index i = blockIdx.x; // summing for patient i
ar_index j = threadIdx.x; // across other patients j
__shared__ times cache[threadsPerBlock];
times Iy = 0;
while(j<N){
// R code: max(0,min(Mx[i],d3[j,'Discharge.time'])-max(d3[i,'Admission.time'],Mx[j]))
times imin = cmin(Mx[i],discharge[j]);
times imax = cmax(admit[i],Mx[j]);
Iy += cmax(0,imin-imax);
j += blockDim.x;
}
cache[tid] = Iy;
__syncthreads();
// reduce
/***REMOVED***/
}
答案 0 :(得分:7)
Iy += cmax(0,imin-imax);
不合法。您无法将文字0
绑定到int&
引用(但您可以const int&
引用)。
答案 1 :(得分:4)
如果x
或z
是const
数组,则其元素类型将为const int
,但不能转换为int&
。
尝试:
template<class T> __device__ inline T cmin(const T& a, const T& b)
{
return (a < b ? a : b);
}
template<class T> __device__ inline T cmax(const T& a, const T& b)
{
return (a > b ? a : b);
}
如果T
始终是int
等基本类型,您甚至可以按值传递参数:
template<class T> __device__ inline T cmin(T a, T b)
{
return (a < b ? a : b);
}
template<class T> __device__ inline T cmax(T a, T b)
{
return (a > b ? a : b);
}
编辑: @aschepler有正确答案。
答案 2 :(得分:1)
如果您的函数将引用作为参数,则应该小心返回引用。您可能会返回对临时的引用!喜欢在:
cmin(0,imin-imax);
对于int
和float
来说可能没问题,但对于非POD则很危险。
答案 3 :(得分:0)
请尝试颠倒定义顺序。
template <class T> __device__ inline T& cmax(T&a,T&b){return (a>b)?(a):(b);};
template <class T> __device__ inline T& cmin(T&a,T&b){return (a<b)?(a):(b);};
cmax然后是cmin。什么是输出?
答案 4 :(得分:0)
你的cmax和cmin正在对元素进行非const引用。也许你的数组被声明为const?
很难说,因为这个例子并不完整。
答案 5 :(得分:0)
也许您已经有一些活跃的defines
污染了您的名称空间?请尝试重命名cmin
和cmax
,或#undef cmin
和#undef cmax
。或者运行g++ -E
以查看解密码代码。
或添加::
命名空间说明符:
::cmin(z[i],y[j])-::cmax(x[i],z[j])
无论如何,您只需要定义中的所有()
。更好:
template __device__ T& cmin(const T&a,const T&b){return a<b?a:b;};
您可能也不需要inline
作为模板函数。
答案 6 :(得分:0)
在初始问题上澄清我的评论:是的,如果ona只是通过参数的引用,应该小心。以下是完整的说明:
#include <iostream> struct Thing { int data; Thing() { data = 42; } Thing(int val) { data = val; } Thing(const Thing& oth) { data = oth.data; } Thing& operator=(const Thing& oth) { if(this!=&oth) this->data = oth.data; return *this; } ~Thing() { data = 0; } // clear, destroy, release... }; bool operator<(const Thing &a, const Thing &b) { return a.data const T& refmin(const T &a, const T &b) // return a ref { return a < b ? a : b; } template const T copymin(const T &a, const T &b) // return a copy { return a < b ? a : b; }
接着是
int main(int argc, const char* []) { Thing a(11); Thing b(88); std::cerr << "Simple operation:" << std::endl; const Thing c = a + b; std::cerr << " c:" << c.data << " should be 99" << std::endl; std::cerr << "Working on temp expression (BAD):" << std::endl; const Thing &x = refmin(c, b-a); // '&x' will be gone after ';' // the next line might crash: std::cerr << " x:" << x.data << " should be 77" << std::endl; std::cerr << "Working explicit side variable (OK):" << std::endl; const Thing &d = b-a; const Thing &y = refmin(c, d); // '&y' is now same as '&d' std::cerr << " d:" << d.data << " should be 77" << std::endl; std::cerr << " y:" << y.data << " should be 77" << std::endl; std::cerr << "Working on a copy (OK):" << std::endl; const Thing &z = copymin(c, b-a); std::cerr << z:" << z.data << " should be 77" << std::endl; return 0; }
输出结果为:
$ ./minreftest Simple operation: c:99 should be 99 Working on temp expression (BAD): x:0 should be 77 Working explicit side variable (OK): d:77 should be 77 y:77 should be 77 Working on a copy (OK): z:77 should be 77
在某些机器上,我猜它甚至可能 segfault 。在Thing
s析构函数中,我将data
重置为0
,但可以轻松想象更多内容。
因此,当我们执行 BAD refmin
调用时,我们会返回对临时的引用。哪个在;
之后被销毁。因此,当我们尝试输出&x
时,它已经消失了。