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 SOFA_GPU_CUDA_CUDAMECHANICALOBJECT_INL
00026 #define SOFA_GPU_CUDA_CUDAMECHANICALOBJECT_INL
00027
00028 #include "CudaMechanicalObject.h"
00029 #include <sofa/component/MechanicalObject.inl>
00030
00031
00032 namespace sofa
00033 {
00034
00035 namespace gpu
00036 {
00037
00038 namespace cuda
00039 {
00040
00041 extern "C"
00042 {
00043 void MechanicalObjectCudaVec3f_vAssign(unsigned int size, void* res, const void* a);
00044 void MechanicalObjectCudaVec3f_vClear(unsigned int size, void* res);
00045 void MechanicalObjectCudaVec3f_vMEq(unsigned int size, void* res, float f);
00046 void MechanicalObjectCudaVec3f_vEqBF(unsigned int size, void* res, const void* b, float f);
00047 void MechanicalObjectCudaVec3f_vPEq(unsigned int size, void* res, const void* a);
00048 void MechanicalObjectCudaVec3f_vPEqBF(unsigned int size, void* res, const void* b, float f);
00049 void MechanicalObjectCudaVec3f_vAdd(unsigned int size, void* res, const void* a, const void* b);
00050 void MechanicalObjectCudaVec3f_vOp(unsigned int size, void* res, const void* a, const void* b, float f);
00051 void MechanicalObjectCudaVec3f_vIntegrate(unsigned int size, const void* a, void* v, void* x, float f_v_v, float f_v_a, float f_x_x, float f_x_v);
00052 void MechanicalObjectCudaVec3f_vPEqBF2(unsigned int size, void* res1, const void* b1, float f1, void* res2, const void* b2, float f2);
00053 void MechanicalObjectCudaVec3f_vPEq4BF2(unsigned int size, void* res1, const void* b11, float f11, const void* b12, float f12, const void* b13, float f13, const void* b14, float f14,
00054 void* res2, const void* b21, float f21, const void* b22, float f22, const void* b23, float f23, const void* b24, float f24);
00055 void MechanicalObjectCudaVec3f_vOp2(unsigned int size, void* res1, const void* a1, const void* b1, float f1, void* res2, const void* a2, const void* b2, float f2);
00056 int MechanicalObjectCudaVec3f_vDotTmpSize(unsigned int size);
00057 void MechanicalObjectCudaVec3f_vDot(unsigned int size, float* res, const void* a, const void* b, void* tmp, float* cputmp);
00058 void MechanicalObjectCudaVec3f1_vAssign(unsigned int size, void* res, const void* a);
00059 void MechanicalObjectCudaVec3f1_vClear(unsigned int size, void* res);
00060 void MechanicalObjectCudaVec3f1_vMEq(unsigned int size, void* res, float f);
00061 void MechanicalObjectCudaVec3f1_vEqBF(unsigned int size, void* res, const void* b, float f);
00062 void MechanicalObjectCudaVec3f1_vPEq(unsigned int size, void* res, const void* a);
00063 void MechanicalObjectCudaVec3f1_vPEqBF(unsigned int size, void* res, const void* b, float f);
00064 void MechanicalObjectCudaVec3f1_vAdd(unsigned int size, void* res, const void* a, const void* b);
00065 void MechanicalObjectCudaVec3f1_vOp(unsigned int size, void* res, const void* a, const void* b, float f);
00066 void MechanicalObjectCudaVec3f1_vIntegrate(unsigned int size, const void* a, void* v, void* x, float f_v_v, float f_v_a, float f_x_x, float f_x_v);
00067 void MechanicalObjectCudaVec3f1_vPEqBF2(unsigned int size, void* res1, const void* b1, float f1, void* res2, const void* b2, float f2);
00068 void MechanicalObjectCudaVec3f1_vPEq4BF2(unsigned int size, void* res1, const void* b11, float f11, const void* b12, float f12, const void* b13, float f13, const void* b14, float f14,
00069 void* res2, const void* b21, float f21, const void* b22, float f22, const void* b23, float f23, const void* b24, float f24);
00070 void MechanicalObjectCudaVec3f1_vOp2(unsigned int size, void* res1, const void* a1, const void* b1, float f1, void* res2, const void* a2, const void* b2, float f2);
00071 int MechanicalObjectCudaVec3f1_vDotTmpSize(unsigned int size);
00072 void MechanicalObjectCudaVec3f1_vDot(unsigned int size, float* res, const void* a, const void* b, void* tmp, float* cputmp);
00073
00074
00075 }
00076
00077 template<>
00078 class CudaKernelsMechanicalObject<CudaVec3fTypes>
00079 {
00080 public:
00081 static void vAssign(unsigned int size, void* res, const void* a)
00082 { MechanicalObjectCudaVec3f_vAssign(size, res, a); }
00083 static void vClear(unsigned int size, void* res)
00084 { MechanicalObjectCudaVec3f_vClear(size, res); }
00085 static void vMEq(unsigned int size, void* res, float f)
00086 { MechanicalObjectCudaVec3f_vMEq(size, res, f); }
00087 static void vEqBF(unsigned int size, void* res, const void* b, float f)
00088 { MechanicalObjectCudaVec3f_vEqBF(size, res, b, f); }
00089 static void vPEq(unsigned int size, void* res, const void* a)
00090 { MechanicalObjectCudaVec3f_vPEq(size, res, a); }
00091 static void vPEqBF(unsigned int size, void* res, const void* b, float f)
00092 { MechanicalObjectCudaVec3f_vPEqBF(size, res, b, f); }
00093 static void vAdd(unsigned int size, void* res, const void* a, const void* b)
00094 { MechanicalObjectCudaVec3f_vAdd(size, res, a, b); }
00095 static void vOp(unsigned int size, void* res, const void* a, const void* b, float f)
00096 { MechanicalObjectCudaVec3f_vOp(size, res, a, b, f); }
00097 static void vIntegrate(unsigned int size, const void* a, void* v, void* x, float f_v_v, float f_v_a, float f_x_x, float f_x_v)
00098 { MechanicalObjectCudaVec3f_vIntegrate(size, a, v, x, f_v_v, f_v_a, f_x_x, f_x_v); }
00099 static void vPEqBF2(unsigned int size, void* res1, const void* b1, float f1, void* res2, const void* b2, float f2)
00100 { MechanicalObjectCudaVec3f_vPEqBF2(size, res1, b1, f1, res2, b2, f2); }
00101 static void vPEq4BF2(unsigned int size, void* res1, const void* b11, float f11, const void* b12, float f12, const void* b13, float f13, const void* b14, float f14,
00102 void* res2, const void* b21, float f21, const void* b22, float f22, const void* b23, float f23, const void* b24, float f24)
00103 { MechanicalObjectCudaVec3f_vPEq4BF2(size, res1, b11, f11, b12, f12, b13, f13, b14, f14,
00104 res2, b21, f21, b22, f22, b23, f23, b24, f24); }
00105 static void vOp2(unsigned int size, void* res1, const void* a1, const void* b1, float f1, void* res2, const void* a2, const void* b2, float f2)
00106 { MechanicalObjectCudaVec3f_vOp2(size, res1, a1, b1, f1, res2, a2, b2, f2); }
00107 static int vDotTmpSize(unsigned int size)
00108 { return MechanicalObjectCudaVec3f_vDotTmpSize(size); }
00109 static void vDot(unsigned int size, float* res, const void* a, const void* b, void* tmp, float* cputmp)
00110 { MechanicalObjectCudaVec3f_vDot(size, res, a, b, tmp, cputmp); }
00111 };
00112
00113 template<>
00114 class CudaKernelsMechanicalObject<CudaVec3f1Types>
00115 {
00116 public:
00117 static void vAssign(unsigned int size, void* res, const void* a)
00118 { MechanicalObjectCudaVec3f1_vAssign(size, res, a); }
00119 static void vClear(unsigned int size, void* res)
00120 { MechanicalObjectCudaVec3f1_vClear(size, res); }
00121 static void vMEq(unsigned int size, void* res, float f)
00122 { MechanicalObjectCudaVec3f1_vMEq(size, res, f); }
00123 static void vEqBF(unsigned int size, void* res, const void* b, float f)
00124 { MechanicalObjectCudaVec3f1_vEqBF(size, res, b, f); }
00125 static void vPEq(unsigned int size, void* res, const void* a)
00126 { MechanicalObjectCudaVec3f1_vPEq(size, res, a); }
00127 static void vPEqBF(unsigned int size, void* res, const void* b, float f)
00128 { MechanicalObjectCudaVec3f1_vPEqBF(size, res, b, f); }
00129 static void vAdd(unsigned int size, void* res, const void* a, const void* b)
00130 { MechanicalObjectCudaVec3f1_vAdd(size, res, a, b); }
00131 static void vOp(unsigned int size, void* res, const void* a, const void* b, float f)
00132 { MechanicalObjectCudaVec3f1_vOp(size, res, a, b, f); }
00133 static void vIntegrate(unsigned int size, const void* a, void* v, void* x, float f_v_v, float f_v_a, float f_x_x, float f_x_v)
00134 { MechanicalObjectCudaVec3f1_vIntegrate(size, a, v, x, f_v_v, f_v_a, f_x_x, f_x_v); }
00135 static void vPEqBF2(unsigned int size, void* res1, const void* b1, float f1, void* res2, const void* b2, float f2)
00136 { MechanicalObjectCudaVec3f1_vPEqBF2(size, res1, b1, f1, res2, b2, f2); }
00137 static void vPEq4BF2(unsigned int size, void* res1, const void* b11, float f11, const void* b12, float f12, const void* b13, float f13, const void* b14, float f14,
00138 void* res2, const void* b21, float f21, const void* b22, float f22, const void* b23, float f23, const void* b24, float f24)
00139 { MechanicalObjectCudaVec3f1_vPEq4BF2(size, res1, b11, f11, b12, f12, b13, f13, b14, f14,
00140 res2, b21, f21, b22, f22, b23, f23, b24, f24); }
00141 static void vOp2(unsigned int size, void* res1, const void* a1, const void* b1, float f1, void* res2, const void* a2, const void* b2, float f2)
00142 { MechanicalObjectCudaVec3f1_vOp2(size, res1, a1, b1, f1, res2, a2, b2, f2); }
00143 static int vDotTmpSize(unsigned int size)
00144 { return MechanicalObjectCudaVec3f1_vDotTmpSize(size); }
00145 static void vDot(unsigned int size, float* res, const void* a, const void* b, void* tmp, float* cputmp)
00146 { MechanicalObjectCudaVec3f1_vDot(size, res, a, b, tmp, cputmp); }
00147 };
00148
00149
00150 }
00151
00152 }
00153
00154 namespace component
00155 {
00156
00157 using namespace gpu::cuda;
00158
00159 template<class TCoord, class TDeriv, class TReal>
00160 void MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::accumulateForce(Main* m)
00161 {
00162 if (!m->externalForces->empty())
00163 {
00164 Kernels::vAssign(m->externalForces->size(), m->f->deviceWrite(), m->externalForces->deviceRead());
00165 }
00166 }
00167
00168 template<class TCoord, class TDeriv, class TReal>
00169 void MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::vAlloc(Main* m, VecId v)
00170 {
00171 if (v.type == VecId::V_COORD && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
00172 {
00173 VecCoord* vec = m->getVecCoord(v.index);
00174 vec->fastResize(m->vsize);
00175 }
00176 else if (v.type == VecId::V_DERIV && v.index >= VecId::V_FIRST_DYNAMIC_INDEX)
00177 {
00178 VecDeriv* vec = m->getVecDeriv(v.index);
00179 vec->fastResize(m->vsize);
00180 }
00181 else
00182 {
00183 std::cerr << "Invalid alloc operation ("<<v<<")\n";
00184 return;
00185 }
00186
00187 }
00188
00189 template<class TCoord, class TDeriv, class TReal>
00190 void MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::vOp(Main* m, VecId v, VecId a, VecId b, double f)
00191 {
00192 if(v.isNull())
00193 {
00194
00195 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00196 return;
00197 }
00198
00199 if (a.isNull())
00200 {
00201 if (b.isNull())
00202 {
00203
00204 if (v.type == VecId::V_COORD)
00205 {
00206 VecCoord* vv = m->getVecCoord(v.index);
00207 vv->fastResize(m->vsize);
00208 Kernels::vClear(vv->size(), vv->deviceWrite());
00209 }
00210 else
00211 {
00212 VecDeriv* vv = m->getVecDeriv(v.index);
00213 vv->fastResize(m->vsize);
00214 Kernels::vClear(vv->size(), vv->deviceWrite());
00215 }
00216 }
00217 else
00218 {
00219 if (b.type != v.type)
00220 {
00221
00222 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00223 return;
00224 }
00225 if (v == b)
00226 {
00227
00228 if (v.type == VecId::V_COORD)
00229 {
00230 VecCoord* vv = m->getVecCoord(v.index);
00231 Kernels::vMEq(vv->size(), vv->deviceWrite(), (Real) f);
00232 }
00233 else
00234 {
00235 VecDeriv* vv = m->getVecDeriv(v.index);
00236 Kernels::vMEq(vv->size(), vv->deviceWrite(), (Real) f);
00237 }
00238 }
00239 else
00240 {
00241
00242 if (v.type == VecId::V_COORD)
00243 {
00244 VecCoord* vv = m->getVecCoord(v.index);
00245 VecCoord* vb = m->getVecCoord(b.index);
00246 vv->fastResize(vb->size());
00247 Kernels::vEqBF(vv->size(), vv->deviceWrite(), vb->deviceRead(), (Real) f);
00248 }
00249 else
00250 {
00251 VecDeriv* vv = m->getVecDeriv(v.index);
00252 VecDeriv* vb = m->getVecDeriv(b.index);
00253 vv->fastResize(vb->size());
00254 Kernels::vEqBF(vv->size(), vv->deviceWrite(), vb->deviceRead(), (Real) f);
00255 }
00256 }
00257 }
00258 }
00259 else
00260 {
00261 if (a.type != v.type)
00262 {
00263
00264 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00265 return;
00266 }
00267 if (b.isNull())
00268 {
00269
00270 if (v.type == VecId::V_COORD)
00271 {
00272 VecCoord* vv = m->getVecCoord(v.index);
00273 VecCoord* va = m->getVecCoord(a.index);
00274 vv->fastResize(va->size());
00275 Kernels::vAssign(vv->size(), vv->deviceWrite(), va->deviceRead());
00276 }
00277 else
00278 {
00279 VecDeriv* vv = m->getVecDeriv(v.index);
00280 VecDeriv* va = m->getVecDeriv(a.index);
00281 vv->fastResize(va->size());
00282 Kernels::vAssign(vv->size(), vv->deviceWrite(), va->deviceRead());
00283 }
00284 }
00285 else
00286 {
00287 if (v == a)
00288 {
00289 if (f==1.0)
00290 {
00291
00292 if (v.type == VecId::V_COORD)
00293 {
00294 VecCoord* vv = m->getVecCoord(v.index);
00295 if (b.type == VecId::V_COORD)
00296 {
00297 VecCoord* vb = m->getVecCoord(b.index);
00298 vv->resize(vb->size());
00299 Kernels::vPEq(vv->size(), vv->deviceWrite(), vb->deviceRead());
00300 }
00301 else
00302 {
00303 VecDeriv* vb = m->getVecDeriv(b.index);
00304 vv->resize(vb->size());
00305 Kernels::vPEq(vv->size(), vv->deviceWrite(), vb->deviceRead());
00306 }
00307 }
00308 else if (b.type == VecId::V_DERIV)
00309 {
00310 VecDeriv* vv = m->getVecDeriv(v.index);
00311 VecDeriv* vb = m->getVecDeriv(b.index);
00312 vv->resize(vb->size());
00313 Kernels::vPEq(vv->size(), vv->deviceWrite(), vb->deviceRead());
00314 }
00315 else
00316 {
00317
00318 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00319 return;
00320 }
00321 }
00322 else
00323 {
00324
00325 if (v.type == VecId::V_COORD)
00326 {
00327 VecCoord* vv = m->getVecCoord(v.index);
00328 if (b.type == VecId::V_COORD)
00329 {
00330 VecCoord* vb = m->getVecCoord(b.index);
00331 vv->resize(vb->size());
00332 Kernels::vPEqBF(vv->size(), vv->deviceWrite(), vb->deviceRead(), (Real)f);
00333 }
00334 else
00335 {
00336 VecDeriv* vb = m->getVecDeriv(b.index);
00337 vv->resize(vb->size());
00338 Kernels::vPEqBF(vv->size(), vv->deviceWrite(), vb->deviceRead(), (Real)f);
00339 }
00340 }
00341 else if (b.type == VecId::V_DERIV)
00342 {
00343 VecDeriv* vv = m->getVecDeriv(v.index);
00344 VecDeriv* vb = m->getVecDeriv(b.index);
00345 vv->resize(vb->size());
00346 Kernels::vPEqBF(vv->size(), vv->deviceWrite(), vb->deviceRead(), (Real)f);
00347 }
00348 else
00349 {
00350
00351 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00352 return;
00353 }
00354 }
00355 }
00356 else
00357 {
00358 if (f==1.0)
00359 {
00360
00361 if (v.type == VecId::V_COORD)
00362 {
00363 VecCoord* vv = m->getVecCoord(v.index);
00364 VecCoord* va = m->getVecCoord(a.index);
00365 vv->fastResize(va->size());
00366 if (b.type == VecId::V_COORD)
00367 {
00368 VecCoord* vb = m->getVecCoord(b.index);
00369 Kernels::vAdd(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead());
00370 }
00371 else
00372 {
00373 VecDeriv* vb = m->getVecDeriv(b.index);
00374 Kernels::vAdd(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead());
00375 }
00376 }
00377 else if (b.type == VecId::V_DERIV)
00378 {
00379 VecDeriv* vv = m->getVecDeriv(v.index);
00380 VecDeriv* va = m->getVecDeriv(a.index);
00381 VecDeriv* vb = m->getVecDeriv(b.index);
00382 vv->fastResize(va->size());
00383 Kernels::vAdd(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead());
00384 }
00385 else
00386 {
00387
00388 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00389 return;
00390 }
00391 }
00392 else
00393 {
00394
00395 if (v.type == VecId::V_COORD)
00396 {
00397 VecCoord* vv = m->getVecCoord(v.index);
00398 VecCoord* va = m->getVecCoord(a.index);
00399 vv->fastResize(va->size());
00400 if (b.type == VecId::V_COORD)
00401 {
00402 VecCoord* vb = m->getVecCoord(b.index);
00403 Kernels::vOp(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead(), (Real)f);
00404 }
00405 else
00406 {
00407 VecDeriv* vb = m->getVecDeriv(b.index);
00408 Kernels::vOp(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead(), (Real)f);
00409 }
00410 }
00411 else if (b.type == VecId::V_DERIV)
00412 {
00413 VecDeriv* vv = m->getVecDeriv(v.index);
00414 VecDeriv* va = m->getVecDeriv(a.index);
00415 VecDeriv* vb = m->getVecDeriv(b.index);
00416 vv->fastResize(va->size());
00417 Kernels::vOp(vv->size(), vv->deviceWrite(), va->deviceRead(), vb->deviceRead(), (Real)f);
00418 }
00419 else
00420 {
00421
00422 std::cerr << "Invalid vOp operation ("<<v<<','<<a<<','<<b<<','<<f<<")\n";
00423 return;
00424 }
00425 }
00426 }
00427 }
00428 }
00429
00430 }
00431
00432 template<class TCoord, class TDeriv, class TReal>
00433 void MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::vMultiOp(Main* m, const VMultiOp& ops)
00434 {
00435
00436 if (ops.size() == 2 && ops[0].second.size() == 2 && ops[0].first == ops[0].second[0].first && ops[0].first.type == VecId::V_DERIV && ops[0].second[1].first.type == VecId::V_DERIV
00437 && ops[1].second.size() == 2 && ops[1].first == ops[1].second[0].first && ops[0].first == ops[1].second[1].first && ops[1].first.type == VecId::V_COORD)
00438 {
00439 VecDeriv* va = m->getVecDeriv(ops[0].second[1].first.index);
00440 VecDeriv* vv = m->getVecDeriv(ops[0].first.index);
00441 VecCoord* vx = m->getVecCoord(ops[1].first.index);
00442 const unsigned int n = vx->size();
00443 const double f_v_v = ops[0].second[0].second;
00444 const double f_v_a = ops[0].second[1].second;
00445 const double f_x_x = ops[1].second[0].second;
00446 const double f_x_v = ops[1].second[1].second;
00447 Kernels::vIntegrate(n, va->deviceRead(), vv->deviceWrite(), vx->deviceWrite(), (Real)f_v_v, (Real)f_v_a, (Real)f_x_x, (Real)f_x_v);
00448 }
00449
00450 else if (ops.size() == 2 && ops[0].second.size() == 2 && ops[0].first == ops[0].second[0].first && ops[0].second[0].second == 1.0 && ops[0].first.type == VecId::V_DERIV && ops[0].second[1].first.type == VecId::V_DERIV
00451 && ops[1].second.size() == 2 && ops[1].first == ops[1].second[0].first && ops[1].second[0].second == 1.0 && ops[1].first.type == VecId::V_DERIV && ops[1].second[1].first.type == VecId::V_DERIV)
00452 {
00453 VecDeriv* vv1 = m->getVecDeriv(ops[0].second[1].first.index);
00454 VecDeriv* vres1 = m->getVecDeriv(ops[0].first.index);
00455 VecDeriv* vv2 = m->getVecDeriv(ops[1].second[1].first.index);
00456 VecDeriv* vres2 = m->getVecDeriv(ops[1].first.index);
00457 const unsigned int n = vres1->size();
00458 const double f1 = ops[0].second[1].second;
00459 const double f2 = ops[1].second[1].second;
00460 Kernels::vPEqBF2(n, vres1->deviceWrite(), vv1->deviceRead(), f1, vres2->deviceWrite(), vv2->deviceRead(), f2);
00461 }
00462
00463 else if (ops.size()==2 && ops[0].second.size()==2 && ops[0].second[0].second == 1.0 && ops[1].second.size()==2 && ops[1].second[0].second == 1.0)
00464 {
00465 const unsigned int n = m->getSize();
00466 Kernels::vOp2(n,
00467 (ops[0].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].first.index)->deviceWrite() : m->getVecDeriv(ops[0].first.index)->deviceWrite(),
00468 (ops[0].second[0].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[0].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[0].first.index)->deviceRead(),
00469 (ops[0].second[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[1].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[1].first.index)->deviceRead(),
00470 ops[0].second[1].second,
00471 (ops[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].first.index)->deviceWrite() : m->getVecDeriv(ops[1].first.index)->deviceWrite(),
00472 (ops[1].second[0].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[0].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[0].first.index)->deviceRead(),
00473 (ops[1].second[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[1].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[1].first.index)->deviceRead(),
00474 ops[1].second[1].second);
00475 }
00476
00477 else if (ops.size()==2 && ops[0].second.size()==5 && ops[0].second[0].first == ops[0].first && ops[0].second[0].second == 1.0 &&
00478 ops[1].second.size()==5 && ops[1].second[0].first == ops[1].first && ops[1].second[0].second == 1.0)
00479 {
00480 const unsigned int n = m->getSize();
00481 Kernels::vPEq4BF2(n,
00482 (ops[0].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].first.index)->deviceWrite() : m->getVecDeriv(ops[0].first.index)->deviceWrite(),
00483 (ops[0].second[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[1].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[1].first.index)->deviceRead(),
00484 ops[0].second[1].second,
00485 (ops[0].second[2].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[2].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[2].first.index)->deviceRead(),
00486 ops[0].second[2].second,
00487 (ops[0].second[3].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[3].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[3].first.index)->deviceRead(),
00488 ops[0].second[3].second,
00489 (ops[0].second[4].first.type == VecId::V_COORD) ? m->getVecCoord(ops[0].second[4].first.index)->deviceRead() : m->getVecDeriv(ops[0].second[4].first.index)->deviceRead(),
00490 ops[0].second[4].second,
00491 (ops[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].first.index)->deviceWrite() : m->getVecDeriv(ops[1].first.index)->deviceWrite(),
00492 (ops[1].second[1].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[1].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[1].first.index)->deviceRead(),
00493 ops[1].second[1].second,
00494 (ops[1].second[2].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[2].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[2].first.index)->deviceRead(),
00495 ops[1].second[2].second,
00496 (ops[1].second[3].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[3].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[3].first.index)->deviceRead(),
00497 ops[1].second[3].second,
00498 (ops[1].second[4].first.type == VecId::V_COORD) ? m->getVecCoord(ops[1].second[4].first.index)->deviceRead() : m->getVecDeriv(ops[1].second[4].first.index)->deviceRead(),
00499 ops[1].second[4].second);
00500 }
00501 else
00502 {
00503 std::cout << "CUDA: unoptimized vMultiOp:"<<std::endl;
00504 for (unsigned int i=0;i<ops.size();++i)
00505 {
00506 std::cout << ops[i].first << " =";
00507 if (ops[i].second.empty())
00508 std::cout << "0";
00509 else
00510 for (unsigned int j=0;j<ops[i].second.size();++j)
00511 {
00512 if (j) std::cout << " + ";
00513 std::cout << ops[i].second[j].first << "*" << ops[i].second[j].second;
00514 }
00515 std::cout << endl;
00516 }
00517 {
00518 using namespace sofa::core::componentmodel::behavior;
00519 m->BaseMechanicalState::vMultiOp(ops);
00520 }
00521 }
00522 }
00523
00524 template<class TCoord, class TDeriv, class TReal>
00525 double MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::vDot(Main* m, VecId a, VecId b)
00526 {
00527 Real r = 0.0f;
00528 if (a.type == VecId::V_COORD && b.type == VecId::V_COORD)
00529 {
00530 VecCoord* va = m->getVecCoord(a.index);
00531 VecCoord* vb = m->getVecCoord(b.index);
00532 int tmpsize = Kernels::vDotTmpSize(va->size());
00533 if (tmpsize == 0)
00534 {
00535 Kernels::vDot(va->size(), &r, va->deviceRead(), vb->deviceRead(), NULL, NULL);
00536 }
00537 else
00538 {
00539 m->data.tmpdot.fastResize(tmpsize);
00540 Kernels::vDot(va->size(), &r, va->deviceRead(), vb->deviceRead(), m->data.tmpdot.deviceWrite(), (Real*)(&(m->data.tmpdot.getCached(0))));
00541 }
00542 }
00543 else if (a.type == VecId::V_DERIV && b.type == VecId::V_DERIV)
00544 {
00545 VecDeriv* va = m->getVecDeriv(a.index);
00546 VecDeriv* vb = m->getVecDeriv(b.index);
00547 int tmpsize = Kernels::vDotTmpSize(va->size());
00548 if (tmpsize == 0)
00549 {
00550 Kernels::vDot(va->size(), &r, va->deviceRead(), vb->deviceRead(), NULL, NULL);
00551 }
00552 else
00553 {
00554 m->data.tmpdot.fastResize(tmpsize);
00555 Kernels::vDot(va->size(), &r, va->deviceRead(), vb->deviceRead(), m->data.tmpdot.deviceWrite(), (Real*)(&(m->data.tmpdot.getCached(0))));
00556 }
00557 #ifndef NDEBUG
00558
00559
00560
00561
00562
00563 #endif
00564 }
00565 else
00566 {
00567 std::cerr << "Invalid dot operation ("<<a<<','<<b<<")\n";
00568 }
00569 return r;
00570 }
00571
00572 template<class TCoord, class TDeriv, class TReal>
00573 void MechanicalObjectInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::resetForce(Main* m)
00574 {
00575 VecDeriv& f= *m->getF();
00576 Kernels::vClear(f.size(), f.deviceWrite());
00577 }
00578
00579
00580 #define CudaMechanicalObject_ImplMethods(T) \
00581 template<> void MechanicalObject< T >::accumulateForce() \
00582 { data.accumulateForce(this); } \
00583 template<> void MechanicalObject< T >::vOp(VecId v, VecId a, VecId b, double f) \
00584 { data.vOp(this, v, a, b, f); } \
00585 template<> void MechanicalObject< T >::vMultiOp(const VMultiOp& ops) \
00586 { data.vMultiOp(this, ops); } \
00587 template<> double MechanicalObject< T >::vDot(VecId a, VecId b) \
00588 { return data.vDot(this, a, b); } \
00589 template<> void MechanicalObject< T >::resetForce() \
00590 { data.resetForce(this); }
00591
00592 CudaMechanicalObject_ImplMethods(gpu::cuda::CudaVec3fTypes);
00593 CudaMechanicalObject_ImplMethods(gpu::cuda::CudaVec3f1Types);
00594
00595
00596 #undef CudaMechanicalObject_ImplMethods
00597
00598 }
00599
00600 }
00601
00602 #endif