Commit f0200156 authored by berenger-bramas's avatar berenger-bramas

Rmove UnsafeFMM, put the unsafe method in the FmmThread as a unused method.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@251 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 3f3686ea
......@@ -397,6 +397,46 @@ private:
}
/** P2P */
void directPassUnsafe(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
FDEBUG( FDebug::Controller.write("\tStart Direct Pass\n").write(FDebug::Flush); );
FDEBUG(FTic counterTime);
int numberOfLeafs = 0;
{
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
// for each numberOfLeafs
do{
iterArray[numberOfLeafs] = octreeIterator;
++numberOfLeafs;
} while(octreeIterator.moveRight());
}
const int heightMinusOne = OctreeHeight - 1;
FDEBUG(FTic computationCounter);
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
// There is a maximum of 26 neighbors
ContainerClass* neighbors[26];
#pragma omp for schedule(dynamic)
for(int idxLeafs = 0 ; idxLeafs < numberOfLeafs ; ++idxLeafs){
myThreadkernels->L2P(iterArray[idxLeafs].getCurrentCell(), iterArray[idxLeafs].getCurrentListTargets());
// need the current particles and neighbors particles
const int counter = tree->getLeafsNeighbors(neighbors, iterArray[idxLeafs].getCurrentGlobalIndex(),heightMinusOne);
myThreadkernels->P2P( iterArray[idxLeafs].getCurrentListTargets(), iterArray[idxLeafs].getCurrentListSrc() , neighbors, counter);
}
}
FDEBUG(computationCounter.tac());
FDEBUG( FDebug::Controller << "\tFinished (@Direct Pass (L2P + P2P) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation L2P + P2P : " << computationCounter.elapsed() << " s\n" );
}
};
......
......@@ -40,7 +40,7 @@ class FFmmAlgorithmThreadTsm : protected FAssertable{
const int OctreeHeight;
public:
public:
/** The constructor need the octree and the kernels used for computation
* @param inTree the octree to work on
* @param inKernels the kernels to call
......@@ -95,7 +95,7 @@ public:
delete [] iterArray;
iterArray = 0;
}
/** P2M */
......@@ -136,7 +136,7 @@ public:
FDEBUG( counterTime.tac() );
FDEBUG( FDebug::Controller << "\tFinished (@Bottom Pass (P2M) = " << counterTime.elapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.elapsed() << " s\n" );
}
/** M2M */
......@@ -195,7 +195,7 @@ public:
FDEBUG( counterTime.tac() );
FDEBUG( FDebug::Controller << "\tFinished (@Upward Pass (M2M) = " << counterTime.elapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
}
/** M2L L2L */
......@@ -304,7 +304,7 @@ public:
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
}
}
/** P2P */
......@@ -345,7 +345,7 @@ public:
FDEBUG( counterTime.tac() );
FDEBUG( FDebug::Controller << "\tFinished (@Direct Pass (L2P + P2P) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation L2P + P2P : " << computationCounter.elapsed() << " s\n" );
}
};
......
#ifndef FFMMALGORITHMTHREADUS_HPP
#define FFMMALGORITHMTHREADUS_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Utils/FAssertable.hpp"
#include "../Utils/FDebug.hpp"
#include "../Utils/FTrace.hpp"
#include "../Utils/FTic.hpp"
#include "../Utils/FGlobal.hpp"
#include "../Containers/FOctree.hpp"
#include <omp.h>
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FFmmAlgorithmThreadUs
* @brief
* Please read the license
*
* This class is a threaded FMM algorithm
* It just iterates on a tree and call the kernels with good arguments.
* It used the inspector-executor model :
* iterates on the tree and builds an array to work in parallel on this array
*
* Of course this class does not deallocate pointer given in arguements.
*
* This algorithms is unsafe for P2P, if you need to write on neigbors
* this can be a problem.
*/
template<class OctreeClass, class ParticleClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmThreadUs : protected FAssertable{
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
typename OctreeClass::Iterator* iterArray;
const int MaxThreads;
const int OctreeHeight;
public:
/** The constructor need the octree and the kernels used for computation
* @param inTree the octree to work on
* @param inKernels the kernels to call
* An assert is launched if one of the arguments is null
*/
FFmmAlgorithmThreadUs(OctreeClass* const inTree, KernelClass* const inKernels)
: tree(inTree), kernels(0), iterArray(0),
MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()) {
fassert(tree, "tree cannot be null", __LINE__, __FILE__);
this->kernels = new KernelClass*[MaxThreads];
for(int idxThread = 0 ; idxThread < MaxThreads ; ++idxThread){
this->kernels[idxThread] = new KernelClass(*inKernels);
}
FDEBUG(FDebug::Controller << "FFmmAlgorithmThreadUs\n");
}
/** Default destructor */
virtual ~FFmmAlgorithmThreadUs(){
for(int idxThread = 0 ; idxThread < MaxThreads ; ++idxThread){
delete this->kernels[idxThread];
}
delete [] this->kernels;
}
/**
* To execute the fmm algorithm
* Call this function to run the complete algorithm
*/
void execute(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
// Count leaf
int numberOfLeafs = 0;
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
do{
++numberOfLeafs;
} while(octreeIterator.moveRight());
iterArray = new typename OctreeClass::Iterator[numberOfLeafs];
fassert(iterArray, "iterArray bad alloc", __LINE__, __FILE__);
for(int idxThread = 0 ; idxThread < MaxThreads ; ++idxThread){
this->kernels[idxThread]->init();
}
bottomPass();
upwardPass();
downardPass();
directPass();
delete [] iterArray;
iterArray = 0;
}
/** P2M */
void bottomPass(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
FDEBUG( FDebug::Controller.write("\tStart Bottom Pass\n").write(FDebug::Flush) );
FDEBUG(FTic counterTime);
typename OctreeClass::Iterator octreeIterator(tree);
int numberOfLeafs = 0;
// Iterate on leafs
octreeIterator.gotoBottomLeft();
do{
iterArray[numberOfLeafs] = octreeIterator;
++numberOfLeafs;
} while(octreeIterator.moveRight());
FDEBUG(FTic computationCounter);
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
#pragma omp for nowait
for(int idxLeafs = 0 ; idxLeafs < numberOfLeafs ; ++idxLeafs){
// We need the current cell that represent the leaf
// and the list of particles
myThreadkernels->P2M( iterArray[idxLeafs].getCurrentCell() , iterArray[idxLeafs].getCurrentListSrc());
}
}
FDEBUG(computationCounter.tac());
FDEBUG( FDebug::Controller << "\tFinished (@Bottom Pass (P2M) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.elapsed() << " s\n" );
}
/** M2M */
void upwardPass(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
FDEBUG( FDebug::Controller.write("\tStart Upward Pass\n").write(FDebug::Flush); );
FDEBUG(FTic counterTime);
FDEBUG(FTic computationCounter);
// Start from leal level - 1
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
octreeIterator.moveUp();
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
// for each levels
for(int idxLevel = OctreeHeight - 2 ; idxLevel > 1 ; --idxLevel ){
int numberOfCells = 0;
// for each cells
do{
iterArray[numberOfCells] = octreeIterator;
++numberOfCells;
} while(octreeIterator.moveRight());
avoidGotoLeftIterator.moveUp();
octreeIterator = avoidGotoLeftIterator;// equal octreeIterator.moveUp(); octreeIterator.gotoLeft();
FDEBUG(computationCounter.tic());
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
#pragma omp for nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// We need the current cell and the child
// child is an array (of 8 child) that may be null
myThreadkernels->M2M( iterArray[idxCell].getCurrentCell() , iterArray[idxCell].getCurrentChild(), idxLevel);
}
}
FDEBUG(computationCounter.tac());
}
FDEBUG( FDebug::Controller << "\tFinished (@Upward Pass (M2M) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
}
/** M2L L2L */
void downardPass(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
{ // first M2L
FDEBUG( FDebug::Controller.write("\tStart Downward Pass (M2L)\n").write(FDebug::Flush); );
FDEBUG(FTic counterTime);
FDEBUG(FTic computationCounter);
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.moveDown();
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
// for each levels
for(int idxLevel = 2 ; idxLevel < OctreeHeight ; ++idxLevel ){
int numberOfCells = 0;
// for each cells
do{
iterArray[numberOfCells] = octreeIterator;
++numberOfCells;
} while(octreeIterator.moveRight());
avoidGotoLeftIterator.moveDown();
octreeIterator = avoidGotoLeftIterator;
FDEBUG(computationCounter.tic());
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
CellClass* neighbors[189];
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getDistantNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
}
}
FDEBUG(computationCounter.tac());
}
FDEBUG( FDebug::Controller << "\tFinished (@Downward Pass (M2L) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
}
{ // second L2L
FDEBUG( FDebug::Controller.write("\tStart Downward Pass (L2L)\n").write(FDebug::Flush); );
FDEBUG(FTic counterTime);
FDEBUG(FTic computationCounter);
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.moveDown();
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
const int heightMinusOne = OctreeHeight - 1;
// for each levels exepted leaf level
for(int idxLevel = 2 ; idxLevel < heightMinusOne ; ++idxLevel ){
int numberOfCells = 0;
// for each cells
do{
iterArray[numberOfCells] = octreeIterator;
++numberOfCells;
} while(octreeIterator.moveRight());
avoidGotoLeftIterator.moveDown();
octreeIterator = avoidGotoLeftIterator;
FDEBUG(computationCounter.tic());
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
#pragma omp for nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
myThreadkernels->L2L( iterArray[idxCell].getCurrentCell() , iterArray[idxCell].getCurrentChild(), idxLevel);
}
}
FDEBUG(computationCounter.tac());
}
FDEBUG( FDebug::Controller << "\tFinished (@Downward Pass (L2L) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
}
}
/** P2P */
void directPass(){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Fmm" , __FILE__ , __LINE__) );
FDEBUG( FDebug::Controller.write("\tStart Direct Pass\n").write(FDebug::Flush); );
FDEBUG(FTic counterTime);
int numberOfLeafs = 0;
{
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
// for each numberOfLeafs
do{
iterArray[numberOfLeafs] = octreeIterator;
++numberOfLeafs;
} while(octreeIterator.moveRight());
}
const int heightMinusOne = OctreeHeight - 1;
FDEBUG(FTic computationCounter);
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
// There is a maximum of 26 neighbors
ContainerClass* neighbors[26];
#pragma omp for schedule(dynamic)
for(int idxLeafs = 0 ; idxLeafs < numberOfLeafs ; ++idxLeafs){
myThreadkernels->L2P(iterArray[idxLeafs].getCurrentCell(), iterArray[idxLeafs].getCurrentListTargets());
// need the current particles and neighbors particles
const int counter = tree->getLeafsNeighbors(neighbors, iterArray[idxLeafs].getCurrentGlobalIndex(),heightMinusOne);
myThreadkernels->P2P( iterArray[idxLeafs].getCurrentListTargets(), iterArray[idxLeafs].getCurrentListSrc() , neighbors, counter);
}
}
FDEBUG(computationCounter.tac());
FDEBUG( FDebug::Controller << "\tFinished (@Direct Pass (L2P + P2P) = " << counterTime.tacAndElapsed() << "s)\n" );
FDEBUG( FDebug::Controller << "\t\t Computation L2P + P2P : " << computationCounter.elapsed() << " s\n" );
}
};
#endif //FFMMALGORITHMTHREADUS_HPP
// [--LICENSE--]
......@@ -13,7 +13,6 @@
#include "../Src/Core/FFmmAlgorithm.hpp"
#include "../Src/Core/FFmmAlgorithmThread.hpp"
#include "../Src/Core/FFmmAlgorithmThreadUs.hpp"
#include "../Src/Fmb/FFmbKernels.hpp"
#include "../Src/Fmb/FFmbComponents.hpp"
......
......@@ -21,7 +21,6 @@
#include "../Src/Core/FFmmAlgorithm.hpp"
#include "../Src/Core/FFmmAlgorithmThread.hpp"
#include "../Src/Core/FFmmAlgorithmThreadUs.hpp"
#include "../Src/Components/FSimpleLeaf.hpp"
......
......@@ -20,7 +20,6 @@
#include "../Src/Core/FFmmAlgorithm.hpp"
#include "../Src/Core/FFmmAlgorithmThread.hpp"
#include "../Src/Core/FFmmAlgorithmThreadUs.hpp"
#include "../Src/Components/FSimpleLeaf.hpp"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment