CudaFixedConstraint.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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 } // namespace cuda
00050 
00051 } // namespace gpu
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         // put indices in a set to sort them and remove duplicates
00073         std::set<int> sortedIndices;
00074         for (typename SetIndex::const_iterator it = indices.begin(); it!=indices.end(); it++)
00075             sortedIndices.insert(*it);
00076         // check if the indices are contiguous
00077         if (*sortedIndices.begin() + (int)sortedIndices.size()-1 == *sortedIndices.rbegin())
00078         {
00079             data.minIndex = *sortedIndices.begin();
00080             data.maxIndex = *sortedIndices.rbegin();
00081             //std::cout << "CudaFixedConstraint: "<<sortedIndices.size()<<" contiguous fixed indices, "<<data.minIndex<<" - "<<data.maxIndex<<std::endl;
00082         }
00083         else
00084         {
00085             //std::cout << "CudaFixedConstraint: "<<sortedIndices.size()<<" non-contiguous fixed indices"<<std::endl;
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     //std::cout << "CudaFixedConstraint::addConstraint("<<index<<")\n";
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             //std::cout << "CudaFixedConstraint: single index "<<index<<"\n";
00105             data.minIndex = index;
00106             data.maxIndex = index;
00107         }
00108     else if ((int)index >= data.minIndex && (int)index <= data.maxIndex)
00109     {
00110         // point already fixed
00111     }
00112         else if (data.minIndex == (int)index+1)
00113         {
00114             data.minIndex = index;
00115             //std::cout << "CudaFixedConstraint: new min index "<<index<<"\n";
00116         }
00117         else if (data.maxIndex == (int)index-1)
00118         {
00119             data.maxIndex = index;
00120             //std::cout << "CudaFixedConstraint: new max index "<<index<<"\n";
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         //std::cout << "CudaFixedConstraint: indices array size "<<data.cudaIndices.size()<<"\n";
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                     // empty set
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 // I know using macros is bad design but this is the only way not to repeat the code for all CUDA types
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 } // namespace constraint
00233 
00234 } // namespace component
00235 
00236 } // namespace sofa
00237 
00238 #endif

Generated on Sun Nov 23 03:59:21 2008 for Sofa by  doxygen 1.5.7.1