Author: eudoxos
Date: 2009-07-16 12:16:39 +0200 (Thu, 16 Jul 2009)
New Revision: 1870

Modified:
   trunk/core/Body.hpp
   trunk/core/InteractionContainer.cpp
   trunk/core/InteractionContainer.hpp
   trunk/core/PhysicalParameters.hpp
   trunk/extra/SConscript
   trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
   trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
   trunk/pkg/dem/ConcretePM.cpp
Log:
1. Remove mutex from requestErase (should be verified to compile on non-openMP 
machine!)
2. Add mutex to PhysicalParameters, so that body state can be locked while 
updating from the interaction loop.
3. Add linking with EngineUnits to Tetra (thans Emanuelle)



Modified: trunk/core/Body.hpp
===================================================================
--- trunk/core/Body.hpp 2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/core/Body.hpp 2009-07-16 10:16:39 UTC (rev 1870)
@@ -21,6 +21,8 @@
 #include<yade/lib-serialization/Serializable.hpp>
 #include<yade/lib-multimethods/Indexable.hpp>
 
+#define ISDYNAMIC_REDEFINED
+
 class MetaBody;
 
 /*! \brief Abstract interface for bodies stored in BodyContainer, Body 
represents the atomic element of simulation.

Modified: trunk/core/InteractionContainer.cpp
===================================================================
--- trunk/core/InteractionContainer.cpp 2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/core/InteractionContainer.cpp 2009-07-16 10:16:39 UTC (rev 1870)
@@ -9,18 +9,31 @@
 *************************************************************************/
 
 #include "InteractionContainer.hpp"
+#include<omp.h>
 
 void InteractionContainer::requestErase(body_id_t id1, body_id_t id2){
-       find(id1,id2)->reset(); bodyIdPair v(id1,id2); //v.push_back(id1); 
v.push_back(id2); 
+       find(id1,id2)->reset(); bodyIdPair v(id1,id2);
        #ifdef YADE_OPENMP
-               boost::mutex::scoped_lock lock(pendingEraseMutex);
+               threadsPendingErase[omp_get_thread_num()].push_back(v);
+       #else
+               pendingErase.push_back(v);
        #endif
-       pendingErase.push_back(v);
 }
 
-void InteractionContainer::unconditionalErasePending(){
-       FOREACH(const bodyIdPair& p, pendingErase){ erase(p[0],p[1]); }
-       pendingErase.clear();
+int InteractionContainer::unconditionalErasePending(){
+       int ret=0;
+       #ifdef YADE_OPENMP
+               // shadow this->pendingErase by the local variable, to share 
code
+               FOREACH(list<bodyIdPair>& pendingErase, threadsPendingErase){
+       #endif
+                       if(pendingErase.size()>0){
+                               FOREACH(const bodyIdPair& p, pendingErase){ 
ret++; erase(p[0],p[1]); }
+                               pendingErase.clear();
+                       }
+       #ifdef YADE_OPENMP
+               }
+       #endif
+       return ret;
 }
 
 
@@ -44,6 +57,10 @@
                for( ; i!=iEnd ; ++i )
                        interaction.push_back(*i);
                if(serializeSorted) 
std::sort(interaction.begin(),interaction.end(),compPtrInteraction());
+               #ifdef YADE_OPENMP
+                       // copy per-thread erasable pairs to the global 
attribute that will be serialized
+                       FOREACH(const list<bodyIdPair>& threadPendingErase, 
threadsPendingErase){ 
pendingErase.insert(pendingErase.end(),threadPendingErase.begin(),threadPendingErase.end());
 }
+               #endif
        }
 }
 
@@ -58,6 +75,10 @@
                for( ; it != itEnd ; ++it)
                        this->insert(*it);
                interaction.clear();
+               #ifdef YADE_OPENMP
+                       // copy global deserialized pairs to be erased to the 
list of thread #0
+                       
threadsPendingErase[0].insert(threadsPendingErase[0].end(),pendingErase.begin(),pendingErase.end());
+               #endif
        }
        else
        {

Modified: trunk/core/InteractionContainer.hpp
===================================================================
--- trunk/core/InteractionContainer.hpp 2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/core/InteractionContainer.hpp 2009-07-16 10:16:39 UTC (rev 1870)
@@ -14,6 +14,7 @@
 #include<boost/thread/mutex.hpp>
 #include<iostream>
 #include<boost/range.hpp>
+#include<omp.h>
 
 // BOOST_FOREACH compatibility
 #ifndef FOREACH
@@ -86,7 +87,11 @@
        public :
                boost::mutex    drawloopmutex;
 
-               InteractionContainer(): serializeSorted(false) { };
+               InteractionContainer(): serializeSorted(false) {
+                       #ifdef YADE_OPENMP
+                               
threadsPendingErase.resize(omp_get_max_threads());
+                       #endif
+               }
                virtual ~InteractionContainer() {};
 
                virtual bool insert(body_id_t /*id1*/,body_id_t /*id2*/)        
                        {throw;};
@@ -117,6 +122,9 @@
                        If accessed from within a parallel section, 
pendingEraseMutex must be locked (this is done inside requestErase for you)
                        If there is, at one point, a multi-threaded collider, 
pendingEraseMutex should be moved to the public part and used from there as 
well.
                */
+               #ifdef YADE_OPENMP
+                       vector<list<bodyIdPair> > threadsPendingErase;
+               #endif
                list<bodyIdPair> pendingErase;
                /*! Erase all pending interactions unconditionally.
 
@@ -126,7 +134,7 @@
 
                        This function doesn't lock pendingEraseMutex, as it is 
(supposedly) called from no-parallel sections only once per iteration
                */
-               void unconditionalErasePending();
+               int unconditionalErasePending();
                /*! Traverse all pending interactions and erase them if the 
(T*)->shouldBeErased(id1,id2) return true
                        and keep it if it return false; finally, pendingErase 
will be clear()'ed.
 
@@ -135,16 +143,23 @@
                                bool shouldBeErased(body_id_t, body_id_t) const
 
                        method which will be called for every interaction.
+
+                       Returns number of interactions, have they been erased 
or not (this is useful to check if there were some erased, after traversing 
those)
                */
-               template<class T> void erasePending(const T& t){
-                       FOREACH(const Vector2<body_id_t>& p, pendingErase){ 
if(t.shouldBeErased(p[0],p[1])) erase(p[0],p[1]); }
-                       pendingErase.clear();
+               template<class T> int erasePending(const T& t){
+                       int ret=0;
+                       #ifdef YADE_OPENMP
+                               // shadow the this->pendingErase by the local 
variable, to share the code
+                               FOREACH(list<bodyIdPair>& pendingErase, 
threadsPendingErase){
+                       #endif
+                                       FOREACH(const Vector2<body_id_t>& p, 
pendingErase){ ret++; if(t.shouldBeErased(p[0],p[1])) erase(p[0],p[1]); }
+                                       pendingErase.clear();
+                       #ifdef YADE_OPENMP
+                               }
+                       #endif
+                       return ret;
                }
        private :
-               #ifdef YADE_OPENMP
-                       // This is used only from within requestErase() for 
now, therefore it can be private
-                       boost::mutex pendingEraseMutex;
-               #endif
                // used only during serialization/deserialization
                vector<shared_ptr<Interaction> > interaction;
        protected :

Modified: trunk/core/PhysicalParameters.hpp
===================================================================
--- trunk/core/PhysicalParameters.hpp   2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/core/PhysicalParameters.hpp   2009-07-16 10:16:39 UTC (rev 1870)
@@ -19,6 +19,10 @@
                bool isDisplayed; //! False if the body is not displayed in 
this cycle (clipped, for instance)
 
                unsigned blockedDOFs; //! Bitmask for degrees of freedom where 
velocity will be always zero, regardless of applied forces
+
+               // mutex for updating the parameters from within the 
interaction loop
+               boost::mutex updateMutex;
+
                enum 
{DOF_NONE=0,DOF_X=1,DOF_Y=2,DOF_Z=4,DOF_RX=8,DOF_RY=16,DOF_RZ=32};
                static const unsigned 
DOF_ALL=DOF_X|DOF_Y|DOF_Z|DOF_RX|DOF_RY|DOF_RZ; //! shorthand for all DOFs 
blocked
                static const unsigned DOF_XYZ=DOF_X|DOF_Y|DOF_Z; //! shorthand 
for all displacements blocked

Modified: trunk/extra/SConscript
===================================================================
--- trunk/extra/SConscript      2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/extra/SConscript      2009-07-16 10:16:39 UTC (rev 1870)
@@ -10,7 +10,9 @@
          'RigidBodyParameters',
                        'ElasticBodyParameters',
                        'BodyMacroParameters',
-         'AABB']),
+         'AABB',
+                       'EngineUnits',
+                       ]),
        
        
env.SharedLibrary('TetraTestGen',['tetra/TetraTestGen.cpp'],LIBS=env['LIBS']+['Shop','Tetra']),
 

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp       
2009-07-16 10:16:39 UTC (rev 1870)
@@ -3,22 +3,36 @@
 YADE_PLUGIN("InteractionDispatchers");
 CREATE_LOGGER(InteractionDispatchers);
 
+// #define IDISP_TIMING
+
+#ifdef IDISP_TIMING
+       #define IDISP_CHECKPOINT(cpt) timingDeltas->checkpoint(cpt)
+#else
+       #define IDISP_CHECKPOINT(cpt)
+#endif
+
+
+
+
 InteractionDispatchers::InteractionDispatchers(){
        geomDispatcher=shared_ptr<InteractionGeometryMetaEngine>(new 
InteractionGeometryMetaEngine);
        physDispatcher=shared_ptr<InteractionPhysicsMetaEngine>(new 
InteractionPhysicsMetaEngine);
        constLawDispatcher=shared_ptr<ConstitutiveLawDispatcher>(new 
ConstitutiveLawDispatcher);
        alreadyWarnedNoCollider=false;
+       #ifdef IDISP_TIMING
+               timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);
+       #endif
 }
 
 #define DISPATCH_CACHE
 
 void InteractionDispatchers::action(MetaBody* rootBody){
-       if(rootBody->interactions->pendingErase.size()>0){
-               if(!alreadyWarnedNoCollider){
-                       LOG_WARN("Interactions pending erase found, no collider 
being used?");
-                       alreadyWarnedNoCollider=true;
-               }
-               rootBody->interactions->unconditionalErasePending();
+       #ifdef IDISP_TIMING
+               timingDeltas->start();
+       #endif
+       if(rootBody->interactions->unconditionalErasePending()>0 && 
!alreadyWarnedNoCollider){
+               LOG_WARN("Interactions pending erase found (erased), no 
collider being used?");
+               alreadyWarnedNoCollider=true;
        }
        #ifdef YADE_OPENMP
                const long size=rootBody->interactions->size();
@@ -29,6 +43,7 @@
                FOREACH(shared_ptr<Interaction> I, *rootBody->interactions){
        #endif
                #ifdef DISPATCH_CACHE
+
                        const shared_ptr<Body>& 
b1_=Body::byId(I->getId1(),rootBody);
                        const shared_ptr<Body>& 
b2_=Body::byId(I->getId2(),rootBody);
 
@@ -63,6 +78,7 @@
                                continue; // in any case don't care about this 
one anymore
                        }
 
+
                        // InteractionPhysicsMetaEngine
                        if(!I->functorCache.phys){
                                
I->functorCache.phys=physDispatcher->getFunctor2D(b1->physicalParameters,b2->physicalParameters,swap);
@@ -74,7 +90,6 @@
 
                        if(!wasReal) 
I->iterMadeReal=rootBody->currentIteration; // mark the interaction as created 
right now
 
-
                        // ConstitutiveLawDispatcher
                        // populating constLaw cache must be done after geom 
and physics dispatchers have been called, since otherwise the interaction
                        // would not have interactionGeometry and 
interactionPhysics yet.

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp        
2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp        
2009-07-16 10:16:39 UTC (rev 1870)
@@ -45,12 +45,9 @@
 void InteractionGeometryMetaEngine::action(MetaBody* ncb)
 {
        // Erase interaction that were requested for erase, but not processed 
by the collider, if any (and warn once about that, as it is suspicious)
-       if(ncb->interactions->pendingErase.size()>0){
-               if(!alreadyWarnedNoCollider){
-                       LOG_WARN("Interactions pending erase found, no collider 
being used?");
-                       alreadyWarnedNoCollider=true;
-               }
-               ncb->interactions->unconditionalErasePending();
+       if(ncb->interactions->unconditionalErasePending()>0 && 
!alreadyWarnedNoCollider){
+               LOG_WARN("Interactions pending erase found, no collider being 
used?");
+               alreadyWarnedNoCollider=true;
        }
 
        shared_ptr<BodyContainer>& bodies = ncb->bodies;

Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp  
2009-07-16 10:16:39 UTC (rev 1870)
@@ -132,15 +132,9 @@
        ISC_CHECKPOINT("init");
 
                #ifdef COLLIDE_STRIDED
-                       // get us ready for strides
-                       if(!strideActive && sweepLength>0){
-                               if(newton->maxVelocitySq>=0){ // maxVelocitySq 
is a really computed value
-                                       strideActive=true;
-                                       if(nBins>=1){
-                                               if(!newton->velocityBins){ 
newton->velocityBins=shared_ptr<VelocityBins>(new 
VelocityBins(nBins,newton->maxVelocitySq,binCoeff,binOverlap)); }
-                                               
if(!boundDispatcher->velocityBins) 
boundDispatcher->velocityBins=newton->velocityBins;
-                                       }
-                               }
+                       // get us ready for strides, if they were deactivated
+                       if(!strideActive && sweepLength>0 && 
newton->maxVelocitySq>=0){ // maxVelocitySq is a really computed value
+                               strideActive=true;
                        }
                        if(strideActive){
                                assert(sweepLength>0);
@@ -158,7 +152,10 @@
                                        LOG_DEBUG(rb->simulationTime<<"s: 
stride ≈"<<stride<<"; maxVelocity="<<sqrt(newton->maxVelocitySq)<<", 
sweepDist="<<boundDispatcher->sweepDist);
                                        fastestBodyMaxDist=0; // reset
                                } else { // nBins>=1
-                                       assert(newton->velocityBins); 
assert(boundDispatcher->velocityBins);
+                                       if(!newton->velocityBins){ 
newton->velocityBins=shared_ptr<VelocityBins>(new 
VelocityBins(nBins,newton->maxVelocitySq,binCoeff,binOverlap)); }
+                                       if(!boundDispatcher->velocityBins) 
boundDispatcher->velocityBins=newton->velocityBins;
+                                       newton->velocityBins->nBins=nBins; 
newton->velocityBins->binCoeff=binCoeff; 
newton->velocityBins->binOverlap=binOverlap; // update things 
+                                       boundDispatcher->sweepDist=0;
                                        // re-bin bodies
                                        
newton->velocityBins->setBins(rb,newton->maxVelocitySq,sweepLength);
                                }

Modified: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp  
2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp  
2009-07-16 10:16:39 UTC (rev 1870)
@@ -20,7 +20,7 @@
 //#define ISC_TIMING
 
 #ifdef ISC_TIMING
-       #define ISC_CHECKPOINT(cpt) timingDeltas->checkPoint(cpt)
+       #define ISC_CHECKPOINT(cpt) timingDeltas->checkpoint(cpt)
 #else
        #define ISC_CHECKPOINT(cpt)
 #endif

Modified: trunk/pkg/dem/ConcretePM.cpp
===================================================================
--- trunk/pkg/dem/ConcretePM.cpp        2009-07-15 16:46:34 UTC (rev 1869)
+++ trunk/pkg/dem/ConcretePM.cpp        2009-07-16 10:16:39 UTC (rev 1870)
@@ -197,8 +197,8 @@
                        const shared_ptr<Body>& 
body1=Body::byId(I->getId1(),rootBody), body2=Body::byId(I->getId2(),rootBody); 
assert(body1); assert(body2);
                        const shared_ptr<CpmMat>& 
rbp1=YADE_PTR_CAST<CpmMat>(body1->physicalParameters), 
rbp2=YADE_PTR_CAST<CpmMat>(body2->physicalParameters);
                        // nice article about openMP::critical vs. scoped 
locks: 
http://www.thinkingparallel.com/2006/08/21/scoped-locking-vs-critical-in-openmp-a-personal-shootout/
-                       #pragma omp critical
-                       { rbp1->numBrokenCohesive+=1; 
rbp2->numBrokenCohesive+=1; rbp1->epsPlBroken+=epsPlSum; 
rbp2->epsPlBroken+=epsPlSum; }
+                       { boost::mutex::scoped_lock lock(rbp1->updateMutex); 
rbp1->numBrokenCohesive+=1; rbp1->epsPlBroken+=epsPlSum; }
+                       { boost::mutex::scoped_lock lock(rbp2->updateMutex); 
rbp2->numBrokenCohesive+=1; rbp2->epsPlBroken+=epsPlSum; }
                }
                rootBody->interactions->requestErase(I->getId1(),I->getId2());
                return;


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to