在CUDA应用程序的自定义类int2_,float2_和double2_之间重载operator = [英] Overloading operator= between customized classes int2_, float2_ and double2_ for CUDA application

查看:2688
本文介绍了在CUDA应用程序的自定义类int2_,float2_和double2_之间重载operator =的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义类 int2 _ float2 _ double2 _ 来处理复杂的算术在C + +和CUDA。我想重载操作符 = ,用于上述类的对象和 int float double 类型。



我的实现如下: / p>

  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; }

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

 模板<类A,类T1,类T2> 
__global__ inline void evaluation_matrix(T1 * data_,const Expr e,int NumElements)
{
const int i = blockDim.x * blockIdx.x + threadIdx.x;
if(i }

一种表达。错误消息是从__global__
函数(__)调用__host__函数(float2 _ :: float2_)的错误消息

不允许

$ b,则不允许使用evaluate_matrix ,double2_,float2_>
$ b

在这种情况下, data _ double2 _ 对象和 e 是一个 float2 _ 表达式。



在处理任何 int float double int2 _ float2 _ double2 _ data _ 的类型或类。我甚至没有收到任何错误消息, e int float double 类型。唯一的问题出现在 e int2 _ float2 _ double2 _



有任何帮助吗?

 

code> 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_&运算符=(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; }


解决方案

__全局__ 函数(在本例中是 float2 _ 类的构造函数)提供了c $ c> __ host __ $ c>函数。一开始,这与操作符无关,因为它们没有在错误消息中提及。但是如果你仔细看看,有 data_ [i] = e [i]



注意:此处不能显示所有相关代码:



我猜 e [i] 提供对表达式的一部分的引用,在本例中为 float2 _
e [i] 分配给 double2 _ ,相应的赋值运算符为 double2 _ :: __ host__ __device__ inline const double2_& operator =(const float2_ a)除了不必要和非常规返回一个const引用之外,它使用 float2 _ >,因此编译器必须使用 __ host __ 来复制 e [i] 。显然,从编译器消息,不允许从 __全局__ 函数调用 __ host __



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



我不知道cuda,不知道任何更多关于 __主机__ __global __ 比错误消息告诉我,但希望我可以给你一个提示可能是错误的代码。


I'm defining the classes int2_, float2_, and double2_ to deal with complex arithmetics in C++ and CUDA. I want to overload the operator = for mixed assignments of objects of the above classes and of the int, float and double types.

My implementation is the following:

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; }

However, I receive a compilation error in the kernel

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];
}

when e is an expression. The error message is

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

In this case, data_ is a double2_ object and e is a float2_ expression.

I have no problem in dealing with any of the int, float, double, int2_, float2_ or double2_ type or class for data_. I even receive no error message when e is an expression of int, float or double type. The only problem arises when e is of class int2_, float2_ or double2_.

Any help? Thank you.

WORKING SOLUTION FOLLOWING ARNE MERTZ'S ANSWER

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; }

解决方案

Well, the error says you cannot call __host__ functions (in this case the constructor of your float2_ class) from a __global__ function. At first sight, that has nothing to do with the operators, since they are not mentioned in the error message. But if you have a closer look, there is data_[i] = e[i].

Attention: wild guesses here, since you don't show all of the relevant code:

I guess e[i] gives a reference to a part of the expression, in this case of type float2_. You are assigning that e[i] to a double2_, and the corresponding assignment operator is your double2_::__host__ __device__ inline const double2_& operator=(const float2_ a) which - apart from needlessly and unconventionally returning a const reference, takes that float2_ by value, so the compiler has to copy e[i], by a copy constructor wich seems to be declared with __host__. Apparently from the compiler message, it's not allowed to call __host__ from __global__ functions.

A solution would be to either declare the constructor __global__ or to let the op= take its parameter by (const) reference, so the copy constructor does not need to be called. However, since the operator= itself is declared __host__, you probably get the same error due to that call as well.

I have no idea about cuda and don't know anything more about __host__ and __global__ than that error message told me, but hopefully I could give you a hint what might be wrong with the code.

这篇关于在CUDA应用程序的自定义类int2_,float2_和double2_之间重载operator =的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆