← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-pkg/yade/git-trunk] Rev 3960: switch to 1-thread colliding when problem detected in parallel run (fix https://bugs.launchpad.ne...

 

------------------------------------------------------------
revno: 3960
committer: Bruno Chareyre <bruno.chareyre@xxxxxxxxxxx>
timestamp: Fri 2014-05-16 16:41:07 +0200
message:
  switch to 1-thread colliding when problem detected in parallel run (fix https://bugs.launchpad.net/yade/+bug/1314736)
modified:
  pkg/common/InsertionSortCollider.cpp


--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'pkg/common/InsertionSortCollider.cpp'
--- pkg/common/InsertionSortCollider.cpp	2014-05-06 15:32:52 +0000
+++ pkg/common/InsertionSortCollider.cpp	2014-05-16 14:41:07 +0000
@@ -109,8 +109,9 @@
 	}
 	
 	///In the second sort, the chunks are connected consistently.
-	///If sorting requires to move a bound past half-chunk, the algorithm is not thread safe, if it happens we error out.
-	///Better than computing with messed up interactions
+	///If sorting requires to move a bound past half-chunk, the algorithm is not thread safe,
+	/// if it happens we roll-back and run the 1-thread sort + send warning
+	bool parallelFailed=false;
 	#pragma omp parallel for schedule(dynamic,1) num_threads(ompThreads>0 ? min(ompThreads,omp_get_max_threads()) : omp_get_max_threads())
 	for (unsigned k=1; k<nChunks;k++) {
 		
@@ -130,12 +131,20 @@
 				j--;
 			}
 			v[j+1]=viInit;
-			if (j<=long(chunks[k]-chunkSize*0.5)) LOG_ERROR("parallel sort not guaranteed to succeed; in chunk "<<k<<" of "<<nChunks<< ", bound descending past half-chunk. Consider turning ompThreads=1 for thread safety.");
+			if (j<=long(chunks[k]-chunkSize*0.5)) {
+				LOG_WARN("parallel sort not guaranteed to succeed; in chunk "<<k<<" of "<<nChunks<< ", bound descending past half-chunk. Parallel colliding aborted, starting again in single thread. Consider turning ompThreads=1 for not wasting CPU time.");
+				parallelFailed=true;}
 		}
-		if (i>=long(chunks[k]+chunkSize*0.5)) LOG_ERROR("parallel sort not guaranteed to succeed; in chunk "<<k+1<<" of "<<nChunks<< ", bound advancing past half-chunk. Consider turning ompThreads=1 for thread safety.")
+		if (i>=long(chunks[k]+chunkSize*0.5)) {
+			LOG_ERROR("parallel sort not guaranteed to succeed; in chunk "<<k+1<<" of "<<nChunks<< ", bound advancing past half-chunk. Consider turning ompThreads=1 for not wasting CPU time.");
+			parallelFailed=true;}
 	}
 	/// Check again, just to be sure...
-	for (unsigned k=1; k<nChunks;k++) if (v[chunks[k]]<v[chunks[k]-1]) LOG_ERROR("parallel sort failed, consider turning ompThreads=1");
+	for (unsigned k=1; k<nChunks;k++) if (v[chunks[k]]<v[chunks[k]-1]) {
+		LOG_ERROR("Parallel colliding failed, starting again in single thread. Consider turning ompThreads=1 for not wasting CPU time.");
+		parallelFailed=true;}
+	
+	if (parallelFailed) return insertionSort(v,interactions, scene, doCollide);
 
 	/// Now insert interactions sequentially	
 	for (int n=0;n<ompThreads;n++) for (size_t k=0, kend=newInteractions[n].size();k<kend;k++) if (!interactions->found(newInteractions[n][k].first,newInteractions[n][k].second)) interactions->insert(shared_ptr<Interaction>(new Interaction(newInteractions[n][k].first,newInteractions[n][k].second)));