QUDA v0.4.0
A library for QCD on GPUs
|
00001 #pragma once 00002 00003 __device__ inline void dsadd(volatile float2 &c, const volatile float2 &a, const volatile float2 &b) { 00004 float t1 = a.x + b.x; 00005 float e = t1 - a.x; 00006 float t2 = ((b.x - e) + (a.x - (t1 - e))) + a.y + b.y; 00007 // The result is t1 + t2, after normalization. 00008 c.x = e = t1 + t2; 00009 c.y = t2 - (e - t1); 00010 } 00011 00012 struct doublesingle { 00013 float2 a; 00014 __device__ inline doublesingle() : a(make_float2(0.0f,0.0f)) { ; } 00015 __device__ inline doublesingle(const volatile doublesingle &b) : a(make_float2(b.a.x, b.a.y)) { ; } 00016 __device__ inline doublesingle(const float a) : a(make_float2(a, 0.0)) { ; } 00017 00018 __device__ inline void operator+=(const doublesingle &b) { dsadd(this->a, this->a, b.a); } 00019 __device__ inline void operator+=(const volatile doublesingle &b) { dsadd(this->a, this->a, b.a); } 00020 __device__ inline void operator+=(const float &b) { 00021 float2 b2 = make_float2(b, 0.0); 00022 dsadd(this->a, this->a, b2); } 00023 00024 __device__ inline doublesingle& operator=(const doublesingle &b) 00025 { a.x = b.a.x; a.y = b.a.y; return *this; } 00026 00027 __device__ inline doublesingle& operator=(const float &b) 00028 { a.x = b; a.y = 0.0f; return *this; } 00029 }; 00030 00031 __device__ inline volatile doublesingle operator+=(volatile doublesingle &a, const volatile doublesingle &b) 00032 { dsadd(a.a, a.a, b.a); return a;} 00033 00034 __host__ double operator+=(double& a, doublesingle &b) { a += b.a.x; a += b.a.y; return a; } 00035 00036 struct doublesingle2 { 00037 doublesingle x; 00038 doublesingle y; 00039 __device__ inline doublesingle2& operator=(const double &a) 00040 { x = a; y = a; return *this; } 00041 __device__ inline void operator+=(const double2 &b) {x += b.x; y += b.y;} 00042 __device__ inline void operator+=(const doublesingle2 &b) {x += b.x; y += b.y;} 00043 }; 00044 00045 __host__ double2 operator+=(double2& a, doublesingle2 &b) 00046 { a.x += b.x.a.x; a.x += b.x.a.y; a.y += b.y.a.x; a.y += b.y.a.y; return a; } 00047 00048 struct doublesingle3 { 00049 doublesingle x; 00050 doublesingle y; 00051 doublesingle z; 00052 __device__ inline void operator+=(const double3 &b) {x += b.x; y += b.y; z += b.z;} 00053 __device__ inline void operator+=(const doublesingle3 &b) {x += b.x; y += b.y; z+= b.z;} 00054 }; 00055 00056 __host__ double3 operator+=(double3& a, doublesingle3 &b) 00057 { a.x += b.x.a.x; a.x += b.x.a.y; a.y += b.y.a.x; a.y += b.y.a.y; a.z += b.z.a.x; a.z += b.z.a.y; return a; }