CudaFixedConstraint.inl
Go to the documentation of this file.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_CUDAFIXEDCONSTRAINT_INL
00026 #define SOFA_GPU_CUDA_CUDAFIXEDCONSTRAINT_INL
00027
00028 #include "CudaFixedConstraint.h"
00029 #include <sofa/component/constraint/FixedConstraint.inl>
00030
00031 namespace sofa
00032 {
00033
00034 namespace gpu
00035 {
00036
00037 namespace cuda
00038 {
00039
00040 extern "C"
00041 {
00042 void FixedConstraintCuda3f_projectResponseContiguous(unsigned int size, void* dx);
00043 void FixedConstraintCuda3f_projectResponseIndexed(unsigned int size, const void* indices, void* dx);
00044 void FixedConstraintCuda3f1_projectResponseContiguous(unsigned int size, void* dx);
00045 void FixedConstraintCuda3f1_projectResponseIndexed(unsigned int size, const void* indices, void* dx);
00046
00047 }
00048
00049 }
00050
00051 }
00052
00053 namespace component
00054 {
00055
00056 namespace constraint
00057 {
00058
00059 using namespace gpu::cuda;
00060
00061 template<class TCoord, class TDeriv, class TReal>
00062 void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::init(Main* m)
00063 {
00064 Data& data = m->data;
00065 data.minIndex = -1;
00066 data.maxIndex = -1;
00067 data.cudaIndices.clear();
00068 m->core::componentmodel::behavior::Constraint<DataTypes>::init();
00069 const SetIndex& indices = m->f_indices.getValue();
00070 if (!indices.empty())
00071 {
00072
00073 std::set<int> sortedIndices;
00074 for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); it++)
00075 sortedIndices.insert(*it);
00076
00077 if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin())
00078 {
00079 data.minIndex = *sortedIndices.begin();
00080 data.maxIndex = *sortedIndices.rbegin();
00081
00082 }
00083 else
00084 {
00085
00086 data.cudaIndices.reserve(sortedIndices.size());
00087 for (std::set<int>::const_iterator it = sortedIndices.begin(); it!=sortedIndices.end(); it++)
00088 data.cudaIndices.push_back(*it);
00089 }
00090 }
00091 }
00092
00093 template<class TCoord, class TDeriv, class TReal>
00094 void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::addConstraint(Main* m, unsigned int index)
00095 {
00096 Data& data = m->data;
00097
00098 m->f_indices.beginEdit()->push_back(index);
00099 m->f_indices.endEdit();
00100 if (data.cudaIndices.empty())
00101 {
00102 if (data.minIndex == -1)
00103 {
00104
00105 data.minIndex = index;
00106 data.maxIndex = index;
00107 }
00108 else if ((int)index >= data.minIndex && (int)index <= data.maxIndex)
00109 {
00110
00111 }
00112 else if (data.minIndex == (int)index+1)
00113 {
00114 data.minIndex = index;
00115
00116 }
00117 else if (data.maxIndex == (int)index-1)
00118 {
00119 data.maxIndex = index;
00120
00121 }
00122 else
00123 {
00124 data.cudaIndices.reserve(data.maxIndex-data.minIndex+2);
00125 for (int i=data.minIndex;i<data.maxIndex;i++)
00126 data.cudaIndices.push_back(i);
00127 data.cudaIndices.push_back(index);
00128 data.minIndex = -1;
00129 data.maxIndex = -1;
00130 std::cout << "CudaFixedConstraint: new indices array size "<<data.cudaIndices.size()<<"\n";
00131 }
00132 }
00133 else
00134 {
00135 data.cudaIndices.push_back(index);
00136
00137 }
00138 }
00139
00140 template<class TCoord, class TDeriv, class TReal>
00141 void FixedConstraintInternalData< gpu::cuda::CudaVectorTypes<TCoord,TDeriv,TReal> >::removeConstraint(Main* m, unsigned int index)
00142 {
00143 Data& data = m->data;
00144 removeValue(*m->f_indices.beginEdit(),index);
00145 m->f_indices.endEdit();
00146 if (data.cudaIndices.empty())
00147 {
00148 if (data.minIndex <= (int)index && (int)index <= data.maxIndex)
00149 {
00150 if (data.minIndex == (int)index)
00151 {
00152 if (data.maxIndex == (int)index)
00153 {
00154
00155 data.minIndex = -1;
00156 data.maxIndex = -1;
00157 }
00158 else
00159 ++data.minIndex;
00160 }
00161 else if (data.maxIndex == (int)index)
00162 --data.maxIndex;
00163 else
00164 {
00165 data.cudaIndices.reserve(data.maxIndex-data.minIndex);
00166 for (int i=data.minIndex;i<data.maxIndex;i++)
00167 if (i != (int)index)
00168 data.cudaIndices.push_back(i);
00169 data.minIndex = -1;
00170 data.maxIndex = -1;
00171 }
00172 }
00173 }
00174 else
00175 {
00176 bool found = false;
00177 for (unsigned int i=0; i<data.cudaIndices.size(); i++)
00178 {
00179 if (found)
00180 data.cudaIndices[i-1] = data.cudaIndices[i];
00181 else if (data.cudaIndices[i] == (int)index)
00182 found = true;
00183 }
00184 if (found)
00185 data.cudaIndices.resize(data.cudaIndices.size()-1);
00186 }
00187 }
00188
00189
00190 template <>
00191 void FixedConstraintInternalData<gpu::cuda::CudaVec3fTypes>::projectResponse(Main* m, VecDeriv& dx)
00192 {
00193 Data& data = m->data;
00194 if (m->f_fixAll.getValue())
00195 FixedConstraintCuda3f_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite()));
00196 else if (data.minIndex >= 0)
00197 FixedConstraintCuda3f_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+3*data.minIndex);
00198 else
00199 FixedConstraintCuda3f_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite());
00200 }
00201
00202 template <>
00203 void FixedConstraintInternalData<gpu::cuda::CudaVec3f1Types>::projectResponse(Main* m, VecDeriv& dx)
00204 {
00205 Data& data = m->data;
00206 if (m->f_fixAll.getValue())
00207 FixedConstraintCuda3f1_projectResponseContiguous(dx.size(), ((float*)dx.deviceWrite()));
00208 else if (data.minIndex >= 0)
00209 FixedConstraintCuda3f1_projectResponseContiguous(data.maxIndex-data.minIndex+1, ((float*)dx.deviceWrite())+4*data.minIndex);
00210 else
00211 FixedConstraintCuda3f1_projectResponseIndexed(data.cudaIndices.size(), data.cudaIndices.deviceRead(), dx.deviceWrite());
00212 }
00213
00214
00215
00216 #define CudaFixedConstraint_ImplMethods(T) \
00217 template<> void FixedConstraint< T >::init() \
00218 { data.init(this); } \
00219 template<> void FixedConstraint< T >::addConstraint(unsigned int index) \
00220 { data.addConstraint(this, index); } \
00221 template<> void FixedConstraint< T >::removeConstraint(unsigned int index) \
00222 { data.removeConstraint(this, index); } \
00223 template<> void FixedConstraint< T >::projectResponse(VecDeriv& dx) \
00224 { data.projectResponse(this, dx); }
00225
00226 CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3fTypes);
00227 CudaFixedConstraint_ImplMethods(gpu::cuda::CudaVec3f1Types);
00228
00229
00230 #undef CudaFixedConstraint_ImplMethods
00231
00232 }
00233
00234 }
00235
00236 }
00237
00238 #endif