00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef CUDAMATH_H
00026 #define CUDAMATH_H
00027
00028 #include <cuda_runtime.h>
00029
00030 template<class real>
00031 class CudaVec2;
00032
00033 template<class real>
00034 class CudaVec3;
00035
00036 template<class real>
00037 class CudaVec4;
00038
00039 template<>
00040 class CudaVec2<float> : public float2
00041 {
00042 public:
00043 typedef float Real;
00044 static __inline__ __device__ __host__ CudaVec2<float> make(Real x, Real y)
00045 {
00046 CudaVec2<float> r; r.x = x; r.y = y; return r;
00047 }
00048 static __inline__ __device__ __host__ CudaVec2<float> make(float2 v)
00049 {
00050 CudaVec2<float> r; r.x = v.x; r.y = v.y; return r;
00051 }
00052 static __inline__ __device__ __host__ CudaVec2<float> make(float3 v)
00053 {
00054 CudaVec2<float> r; r.x = v.x; r.y = v.y; return r;
00055 }
00056 };
00057
00058 template<>
00059 class CudaVec3<float> : public float3
00060 {
00061 public:
00062 typedef float Real;
00063 static __inline__ __device__ __host__ CudaVec3<float> make(Real x, Real y, Real z=0)
00064 {
00065 CudaVec3<float> r; r.x = x; r.y = y; r.z = z; return r;
00066 }
00067 static __inline__ __device__ __host__ CudaVec3<float> make(float2 v, Real z=0)
00068 {
00069 CudaVec3<float> r; r.x = v.x; r.y = v.y; r.z = z; return r;
00070 }
00071 static __inline__ __device__ __host__ CudaVec3<float> make(float3 v)
00072 {
00073 CudaVec3<float> r; r.x = v.x; r.y = v.y; r.z = v.z; return r;
00074 }
00075 static __inline__ __device__ __host__ CudaVec3<float> make(float4 v)
00076 {
00077 CudaVec3<float> r; r.x = v.x; r.y = v.y; r.z = v.z; return r;
00078 }
00079 };
00080
00081 template<>
00082 class CudaVec4<float> : public float4
00083 {
00084 public:
00085 typedef float Real;
00086 static __inline__ __device__ __host__ CudaVec4<float> make(Real x, Real y, Real z, Real w=0)
00087 {
00088 CudaVec4<float> r; r.x = x; r.y = y; r.z = z; r.w = w; return r;
00089 }
00090 static __inline__ __device__ __host__ CudaVec4<float> make(float3 v, Real w=0)
00091 {
00092 CudaVec4<float> r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = w; return r;
00093 }
00094 static __inline__ __device__ __host__ CudaVec4<float> make(float4 v)
00095 {
00096 CudaVec4<float> r; r.x = v.x; r.y = v.y; r.z = v.z; r.w = v.w; return r;
00097 }
00098 };
00099
00100 typedef CudaVec2<float> CudaVec2f;
00101 typedef CudaVec3<float> CudaVec3f;
00102 typedef CudaVec4<float> CudaVec4f;
00103
00104
00105 template<class real>
00106 __device__ CudaVec3<real> operator+(CudaVec3<real> a, CudaVec3<real> b)
00107 {
00108 return CudaVec3<real>::make(a.x+b.x, a.y+b.y, a.z+b.z);
00109 }
00110
00111 template<class real>
00112 __device__ void operator+=(CudaVec3<real>& a, CudaVec3<real> b)
00113 {
00114 a.x += b.x;
00115 a.y += b.y;
00116 a.z += b.z;
00117 }
00118
00119 template<class real>
00120 __device__ void operator+=(CudaVec3<real>& a, real b)
00121 {
00122 a.x += b;
00123 a.y += b;
00124 a.z += b;
00125 }
00126
00127 template<class real>
00128 __device__ CudaVec3<real> operator-(CudaVec3<real> a, CudaVec3<real> b)
00129 {
00130 return CudaVec3<real>::make(a.x-b.x, a.y-b.y, a.z-b.z);
00131 }
00132
00133 template<class real>
00134 __device__ void operator-=(CudaVec3<real>& a, CudaVec3<real> b)
00135 {
00136 a.x -= b.x;
00137 a.y -= b.y;
00138 a.z -= b.z;
00139 }
00140
00141 template<class real>
00142 __device__ void operator-=(CudaVec3<real>& a, real b)
00143 {
00144 a.x -= b;
00145 a.y -= b;
00146 a.z -= b;
00147 }
00148
00149 template<class real>
00150 __device__ CudaVec3<real> operator-(CudaVec3<real>& a)
00151 {
00152 return CudaVec3<real>::make(-a.x, -a.y, -a.z);
00153 }
00154
00155 template<class real>
00156 __device__ CudaVec3<real> operator*(CudaVec3<real> a, real b)
00157 {
00158 return CudaVec3<real>::make(a.x*b, a.y*b, a.z*b);
00159 }
00160
00161 template<class real>
00162 __device__ CudaVec3<real> operator/(CudaVec3<real> a, real b)
00163 {
00164 return CudaVec3<real>::make(a.x/b, a.y/b, a.z/b);
00165 }
00166
00167 template<class real>
00168 __device__ void operator*=(CudaVec3<real>& a, real b)
00169 {
00170 a.x *= b;
00171 a.y *= b;
00172 a.z *= b;
00173 }
00174
00175 template<class real>
00176 __device__ CudaVec3<real> operator*(real a, CudaVec3<real> b)
00177 {
00178 return CudaVec3<real>::make(a*b.x, a*b.y, a*b.z);
00179 }
00180
00181 template<class real>
00182 __device__ CudaVec3<real> mul(CudaVec3<real> a, CudaVec3<real> b)
00183 {
00184 return CudaVec3<real>::make(a.x*b.x, a.y*b.y, a.z*b.z);
00185 }
00186
00187 template<class real>
00188 __device__ real dot(CudaVec3<real> a, CudaVec3<real> b)
00189 {
00190 return a.x*b.x + a.y*b.y + a.z*b.z;
00191 }
00192
00193 template<class real>
00194 __device__ CudaVec3<real> cross(CudaVec3<real> a, CudaVec3<real> b)
00195 {
00196 return CudaVec3<real>::make(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);
00197 }
00198
00199 template<class real>
00200 __device__ real norm2(CudaVec3<real> a)
00201 {
00202 return a.x*a.x+a.y*a.y+a.z*a.z;
00203 }
00204
00205 template<class real>
00206 __device__ real norm(CudaVec3<real> a)
00207 {
00208 return sqrtf(norm2(a));
00209 }
00210
00211 template<class real>
00212 __device__ real invnorm(CudaVec3<real> a)
00213 {
00214 return rsqrtf(norm2(a));
00215 }
00216
00217 template<class real>
00218 class matrix3
00219 {
00220 public:
00221 CudaVec3<real> x,y,z;
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 __device__ CudaVec3<real> operator*(CudaVec3<real> v)
00240 {
00241 return CudaVec3<real>::make(dot(x,v),dot(y,v),dot(z,v));
00242 }
00243 __device__ CudaVec3<real> mulT(CudaVec3<real> v)
00244 {
00245 return x*v.x+y*v.y+z*v.z;
00246 }
00247 __device__ real mulX(CudaVec3<real> v)
00248 {
00249 return dot(x,v);
00250 }
00251 __device__ real mulY(CudaVec3<real> v)
00252 {
00253 return dot(y,v);
00254 }
00255 __device__ real mulZ(CudaVec3<real> v)
00256 {
00257 return dot(z,v);
00258 }
00259 __device__ void readAoS(const real* data)
00260 {
00261 x.x=*data; data+=blockDim.x;
00262 x.y=*data; data+=blockDim.x;
00263 x.z=*data; data+=blockDim.x;
00264 y.x=*data; data+=blockDim.x;
00265 y.y=*data; data+=blockDim.x;
00266 y.z=*data; data+=blockDim.x;
00267 z.x=*data; data+=blockDim.x;
00268 z.y=*data; data+=blockDim.x;
00269 z.z=*data; data+=blockDim.x;
00270 }
00271 __device__ void writeAoS(real* data)
00272 {
00273 *data=x.x; data+=blockDim.x;
00274 *data=x.y; data+=blockDim.x;
00275 *data=x.z; data+=blockDim.x;
00276 *data=y.x; data+=blockDim.x;
00277 *data=y.y; data+=blockDim.x;
00278 *data=y.z; data+=blockDim.x;
00279 *data=z.x; data+=blockDim.x;
00280 *data=z.y; data+=blockDim.x;
00281 *data=z.z; data+=blockDim.x;
00282 }
00283 };
00284
00285 #endif