在CUDA应用程序的自定义类int2_,float2_和double2_之间重载operator =

时间:2013-04-15 09:26:54

标签: c++ templates cuda operator-overloading

我正在定义类int2_float2_double2_来处理C ++和CUDA中的复杂算术。我想重载运算符=,以便对上述类和intfloatdouble类型的对象进行混合分配。

我的实施如下:

class float2_;
class double2_;

class int2_ {

    public:
        int x;
        int y;

        int2_() : x(), y() {}

        __host__ __device__ inline const int2_& operator=(const int a)          { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const float a)        { x = (int)a;       y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const double a)       { x = (int)a;       y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const int2_ a)        { x = a.x;          y = a.y;        return *this; }
        __host__ __device__ inline const int2_& operator=(const float2_ a);
        __host__ __device__ inline const int2_& operator=(const double2_ a);
};

class float2_ {

    public:
        float x;
        float y;

        float2_() : x(), y() {}

        __host__ __device__ inline const float2_& operator=(const int a)        { x = (float)a;     y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const float a)      { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const double a)     { x = (float)a;     y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const int2_ a)      { x = (float)a.x;   y = (float)a.y; return *this; }
        __host__ __device__ inline const float2_& operator=(const float2_ a)    { x = a.x;          y = a.y;        return *this; }
        __host__ __device__ inline const float2_& operator=(const double2_ a);
};

class double2_ {

    public:
        double x;
        double y;

        double2_() : x(), y() {}

        __host__ __device__ inline const double2_& operator=(const int a)       { x = (double)a;    y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const float a)     { x = (double)a;    y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const double a)    { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const int2_ a)     { x = (double)a.x;  y = (double)a.y;return *this; }
        __host__ __device__ inline const double2_& operator=(const float2_ a)   { x = (double)a.x;  y = (double)a.y;return *this; }
        __host__ __device__ inline const double2_& operator=(const double2_ a)  { x = a.x;          y = a.y;        return *this; }

};

__host__ __device__ inline const int2_& int2_::operator=(const float2_ a)           { x = (int)a.x;             y = (int)a.y;       return *this; }
__host__ __device__ inline const int2_& int2_::operator=(const double2_ a)      { x = (int)a.x;             y = (int)a.y;       return *this; }
__host__ __device__ inline const float2_& float2_::operator=(const double2_ a)  { x = (float)a.x;           y = (float)a.y;     return *this; }

但是,我在内核中收到编译错误

template <class A, class T1, class T2>
__global__ inline void evaluation_matrix(T1 *data_, const Expr<A,T2> e, int NumElements)
{
    const int i = blockDim.x * blockIdx.x + threadIdx.x;
    if(i < NumElements) data_[i] = e[i];
}
e是表达式时

。错误消息是

calling a __host__ function("float2_::float2_") from a __global__  
function("evaluation_matrix<BinExpr<const float *, const float2_ *, CudaOpSum, float2_> 
, double2_, float2_> ") is not allowed

在这种情况下,data_double2_个对象,efloat2_表达式。

我在处理任何intfloatdoubleint2_float2_double2_类型或data_的课程。当e表达为intfloatdouble时,我甚至不会收到任何错误消息。当e属于int2_float2_double2_时,唯一的问题就出现了。

有任何帮助吗?谢谢。

ARNE MERTZ的答案后的工作解决方案

class float2_;
class double2_;

class int2_ {

    public:
        int x;
        int y;

        __host__ __device__ int2_() : x(), y() {}

        __host__ __device__ inline const int2_& operator=(const int a)          { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const float a)        { x = (int)a;       y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const double a)       { x = (int)a;       y = 0.;         return *this; }
        __host__ __device__ inline const int2_& operator=(const int2_ a)        { x = a.x;          y = a.y;        return *this; }
        __host__ __device__ inline const int2_& operator=(const float2_ a);
        __host__ __device__ inline const int2_& operator=(const double2_ a);
};

class float2_ {

    public:
        float x;
        float y;

        __host__ __device__ float2_() : x(), y() {}

        __host__ __device__ inline const float2_& operator=(const int a)        { x = (float)a;     y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const float a)      { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const double a)     { x = (float)a;     y = 0.;         return *this; }
        __host__ __device__ inline const float2_& operator=(const int2_ a)      { x = (float)a.x;   y = (float)a.y; return *this; }
        __host__ __device__ inline const float2_& operator=(const float2_ a)    { x = a.x;          y = a.y;        return *this; }
        __host__ __device__ inline const float2_& operator=(const double2_ a);
};

class double2_ {

    public:
        double x;
        double y;

        __host__ __device__ double2_() : x(), y() {}

        __host__ __device__ inline const double2_& operator=(const int a)       { x = (double)a;    y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const float a)     { x = (double)a;    y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const double a)    { x = a;            y = 0.;         return *this; }
        __host__ __device__ inline const double2_& operator=(const int2_ a)     { x = (double)a.x;  y = (double)a.y;return *this; }
        __host__ __device__ inline const double2_& operator=(const float2_ a)   { x = (double)a.x;  y = (double)a.y;return *this; }
        __host__ __device__ inline const double2_& operator=(const double2_ a)  { x = a.x;          y = a.y;        return *this; }

};

__host__ __device__ inline const int2_& int2_::operator=(const float2_ a)           { x = (int)a.x;             y = (int)a.y;       return *this; }
__host__ __device__ inline const int2_& int2_::operator=(const double2_ a)      { x = (int)a.x;             y = (int)a.y;       return *this; }
__host__ __device__ inline const float2_& float2_::operator=(const double2_ a)  { x = (float)a.x;           y = (float)a.y;     return *this; }

1 个答案:

答案 0 :(得分:2)

好吧,错误说你无法从__host__函数调用float2_函数(在本例中是__global__类的构造函数)。乍一看,这与运营商无关,因为错误消息中没有提到它们。但如果仔细观察,可以data_[i] = e[i]

注意:这里有疯狂的猜测,因为您没有显示所有相关代码:

我猜e[i]提供了对表达式部分的引用,在本例中为float2_类型。 您将e[i]分配给double2_,相应的赋值运算符是您的double2_::__host__ __device__ inline const double2_& operator=(const float2_ a) - 除了不必要地和非常规地返回const引用之外,还需要float2_ 按值,因此编译器必须通过复制构造函数复制e[i],这似乎是用__host__声明的。显然,从编译器消息中,不允许从__host__函数调用__global__

解决方案是声明构造函数__global__或让op=通过(const)引用获取其参数,因此不需要调用复制构造函数。但是,由于operator=本身被声明为__host__,因此该调用也可能会出现相同的错误。

我不知道cuda并且不知道有关__host____global__的更多信息,而不是错误消息告诉我,但希望我可以给你一个暗示代码可能出错的地方