Une MAJ de sécurité est nécessaire sur notre version actuelle. Elle sera effectuée lundi 02/08 entre 12h30 et 13h. L'interruption de service devrait durer quelques minutes (probablement moins de 5 minutes).

Commit b86f1ffd authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

Add a way to choose the separation criteria (2 or 1 - default- or 0 or -1)

parent 26a0f75b
...@@ -808,8 +808,8 @@ public: ...@@ -808,8 +808,8 @@ public:
* @return the number of neighbors * @return the number of neighbors
*/ */
int getInteractionNeighbors(const CellClass* inNeighbors[343], int getInteractionNeighbors(const CellClass* inNeighbors[343],
const FTreeCoordinate& workingCell, const FTreeCoordinate& workingCell,
const int inLevel) const{ const int inLevel, const int neighSeparation = 1) const{
// reset // reset
memset(inNeighbors, 0, sizeof(CellClass*) * 343); memset(inNeighbors, 0, sizeof(CellClass*) * 343);
...@@ -848,7 +848,7 @@ public: ...@@ -848,7 +848,7 @@ public:
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ(); const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ();
// Test if it is a direct neighbor // Test if it is a direct neighbor
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){ if(FMath::Abs(xdiff) > neighSeparation || FMath::Abs(ydiff) > neighSeparation || FMath::Abs(zdiff) > neighSeparation){
// add to neighbors // add to neighbors
inNeighbors[ (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3] = cells[idxCousin]; inNeighbors[ (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3] = cells[idxCousin];
++idxNeighbors; ++idxNeighbors;
...@@ -875,8 +875,8 @@ public: ...@@ -875,8 +875,8 @@ public:
* @return the number of neighbors * @return the number of neighbors
*/ */
int getFullNeighborhood(const CellClass* inNeighbors[343], int getFullNeighborhood(const CellClass* inNeighbors[343],
const FTreeCoordinate& workingCell, const FTreeCoordinate& workingCell,
const int inLevel) const{ const int inLevel) const{
// reset // reset
memset(inNeighbors, 0, sizeof(CellClass*) * 343); memset(inNeighbors, 0, sizeof(CellClass*) * 343);
...@@ -935,10 +935,8 @@ public: ...@@ -935,10 +935,8 @@ public:
* @return the number of neighbors * @return the number of neighbors
*/ */
int getPeriodicInteractionNeighbors(const CellClass* inNeighbors[343], int getPeriodicInteractionNeighbors(const CellClass* inNeighbors[343],
const FTreeCoordinate& workingCell, const FTreeCoordinate& workingCell,
const int inLevel, const int inDirection) const{ const int inLevel, const int inDirection, const int neighSeparation = 1) const{
// TODO : REMOVE NEXT COMMENTS
// std::cout << " Begin in getPeriodicInteractionNeighbors"<<std::endl;
// Then take each child of the parent's neighbors if not in directNeighbors // Then take each child of the parent's neighbors if not in directNeighbors
// Father coordinate // Father coordinate
...@@ -963,11 +961,7 @@ public: ...@@ -963,11 +961,7 @@ public:
const int endY = (TestPeriodicCondition(inDirection, DirPlusY) || parentCell.getY() != boxLimite - 1 ?1:0); const int endY = (TestPeriodicCondition(inDirection, DirPlusY) || parentCell.getY() != boxLimite - 1 ?1:0);
const int startZ = (TestPeriodicCondition(inDirection, DirMinusZ) || parentCell.getZ() != 0 ?-1:0); const int startZ = (TestPeriodicCondition(inDirection, DirMinusZ) || parentCell.getZ() != 0 ?-1:0);
const int endZ = (TestPeriodicCondition(inDirection, DirPlusZ) || parentCell.getZ() != boxLimite - 1 ?1:0); const int endZ = (TestPeriodicCondition(inDirection, DirPlusZ) || parentCell.getZ() != boxLimite - 1 ?1:0);
// TODO : REMOVE NEXT COMMENTS
// std::cout << " -- startX " << startX << " endX "<< endX<< std::endl ;
// std::cout << " -- startY " << startY << " endX "<< endY<< std::endl ;
// std::cout << " -- startZ " << startZ << " endX "<< endZ<< std::endl ;
// std::cout << " boxLimite "<< boxLimite<<std::endl;
int idxNeighbors = 0; int idxNeighbors = 0;
// We test all cells around // We test all cells around
for(int idxX = startX ; idxX <= endX ; ++idxX){ for(int idxX = startX ; idxX <= endX ; ++idxX){
...@@ -1018,15 +1012,10 @@ public: ...@@ -1018,15 +1012,10 @@ public:
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ(); const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ();
// Test if it is a direct neighbor // Test if it is a direct neighbor
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){ if(FMath::Abs(xdiff) > neighSeparation || FMath::Abs(ydiff) > neighSeparation || FMath::Abs(zdiff) > neighSeparation){
// add to neighbors // add to neighbors
// TODO : REMOVE NEXT COMMENTS
// std::cout << " Voisin numero "<< idxNeighbors
// << " indexinTab "<< (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3
// << " idxXousin " << idxCousin<< std::endl;
inNeighbors[ (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3] = cells[idxCousin]; inNeighbors[ (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3] = cells[idxCousin];
++idxNeighbors; ++idxNeighbors;
} }
} }
} }
......
...@@ -342,7 +342,8 @@ public: ...@@ -342,7 +342,8 @@ public:
return idxNeig; return idxNeig;
} }
int getInteractionNeighbors(const int inLevel, MortonIndex inNeighbors[189], int inNeighborsPosition[189]) const{ int getInteractionNeighbors(const int inLevel, MortonIndex inNeighbors[/*189+26+1*/216], int inNeighborsPosition[/*189+26+1*/216],
const int neighSeparation = 1) const{
// Then take each child of the parent's neighbors if not in directNeighbors // Then take each child of the parent's neighbors if not in directNeighbors
// Father coordinate // Father coordinate
const FTreeCoordinate parentCell(this->getX()>>1,this->getY()>>1,this->getZ()>>1); const FTreeCoordinate parentCell(this->getX()>>1,this->getY()>>1,this->getZ()>>1);
...@@ -373,7 +374,7 @@ public: ...@@ -373,7 +374,7 @@ public:
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - this->getZ(); const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - this->getZ();
// Test if it is a direct neighbor // Test if it is a direct neighbor
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){ if(FMath::Abs(xdiff) > neighSeparation || FMath::Abs(ydiff) > neighSeparation || FMath::Abs(zdiff) > neighSeparation){
// add to neighbors // add to neighbors
inNeighborsPosition[idxNeighbors] = ((( (xdiff+3) * 7) + (ydiff+3))) * 7 + zdiff + 3; inNeighborsPosition[idxNeighbors] = ((( (xdiff+3) * 7) + (ydiff+3))) * 7 + zdiff + 3;
inNeighbors[idxNeighbors++] = (mortonOther << 3) | idxCousin; inNeighbors[idxNeighbors++] = (mortonOther << 3) | idxCousin;
...@@ -387,7 +388,7 @@ public: ...@@ -387,7 +388,7 @@ public:
return idxNeighbors; return idxNeighbors;
} }
int getInteractionNeighbors(const int inLevel, MortonIndex inNeighbors[189]) const{ int getInteractionNeighbors(const int inLevel, MortonIndex inNeighbors[/*189+26+1*/216], const int neighSeparation = 1) const{
// Then take each child of the parent's neighbors if not in directNeighbors // Then take each child of the parent's neighbors if not in directNeighbors
// Father coordinate // Father coordinate
const FTreeCoordinate parentCell(this->getX()>>1,this->getY()>>1,this->getZ()>>1); const FTreeCoordinate parentCell(this->getX()>>1,this->getY()>>1,this->getZ()>>1);
...@@ -418,7 +419,7 @@ public: ...@@ -418,7 +419,7 @@ public:
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - this->getZ(); const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - this->getZ();
// Test if it is a direct neighbor // Test if it is a direct neighbor
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){ if(FMath::Abs(xdiff) > neighSeparation || FMath::Abs(ydiff) > neighSeparation || FMath::Abs(zdiff) > neighSeparation){
// add to neighbors // add to neighbors
inNeighbors[idxNeighbors++] = (mortonOther << 3) | idxCousin; inNeighbors[idxNeighbors++] = (mortonOther << 3) | idxCousin;
} }
......
...@@ -47,6 +47,7 @@ class FFmmAlgorithm : public FAbstractAlgorithm, public FAlgorithmTimers { ...@@ -47,6 +47,7 @@ class FFmmAlgorithm : public FAbstractAlgorithm, public FAlgorithmTimers {
const int OctreeHeight; ///< The height of the given tree. const int OctreeHeight; ///< The height of the given tree.
const int leafLevelSeperationCriteria;
public: public:
/** Class constructor /** Class constructor
* *
...@@ -56,8 +57,8 @@ public: ...@@ -56,8 +57,8 @@ public:
* *
* \except An exception is thrown if one of the arguments is NULL. * \except An exception is thrown if one of the arguments is NULL.
*/ */
FFmmAlgorithm(OctreeClass* const inTree, KernelClass* const inKernels) FFmmAlgorithm(OctreeClass* const inTree, KernelClass* const inKernels, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(inKernels), OctreeHeight(tree->getHeight()) { : tree(inTree) , kernels(inKernels), OctreeHeight(tree->getHeight()), leafLevelSeperationCriteria(inLeafLevelSeperationCriteria) {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
FAssertLF(kernels, "kernels cannot be null"); FAssertLF(kernels, "kernels cannot be null");
...@@ -190,13 +191,16 @@ protected: ...@@ -190,13 +191,16 @@ protected:
const CellClass* neighbors[343]; const CellClass* neighbors[343];
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
FLOG(FTic counterTimeLevel); FLOG(FTic counterTimeLevel);
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
// for each cells // for each cells
do{ do{
const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel); const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
FLOG(computationCounter.tic()); FLOG(computationCounter.tic());
if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, idxLevel); if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, idxLevel);
FLOG(computationCounter.tac()); FLOG(computationCounter.tac());
......
...@@ -51,6 +51,7 @@ class FFmmAlgorithmPeriodic : public FAbstractAlgorithm{ ...@@ -51,6 +51,7 @@ class FFmmAlgorithmPeriodic : public FAbstractAlgorithm{
const int nbLevelsAboveRoot; //< The nb of level the user ask to go above the tree (>= -1) const int nbLevelsAboveRoot; //< The nb of level the user ask to go above the tree (>= -1)
const int offsetRealTree; //< nbLevelsAboveRoot GetFackLevel const int offsetRealTree; //< nbLevelsAboveRoot GetFackLevel
const int leafLevelSeperationCriteria;
public: public:
/** The constructor need the octree and the kernels used for computation /** The constructor need the octree and the kernels used for computation
...@@ -60,9 +61,9 @@ public: ...@@ -60,9 +61,9 @@ public:
* @param inUpperLevel this parameter defines the behavior of the periodicity refer to the main doc * @param inUpperLevel this parameter defines the behavior of the periodicity refer to the main doc
* *
*/ */
FFmmAlgorithmPeriodic(OctreeClass* const inTree, const int inUpperLevel = 0) FFmmAlgorithmPeriodic(OctreeClass* const inTree, const int inUpperLevel = 0, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(nullptr), OctreeHeight(tree->getHeight()), : tree(inTree) , kernels(nullptr), OctreeHeight(tree->getHeight()),
nbLevelsAboveRoot(inUpperLevel), offsetRealTree(inUpperLevel + 3) { nbLevelsAboveRoot(inUpperLevel), offsetRealTree(inUpperLevel + 3), leafLevelSeperationCriteria(inLeafLevelSeperationCriteria) {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
FAssertLF(-1 <= inUpperLevel, "inUpperLevel cannot be < -1"); FAssertLF(-1 <= inUpperLevel, "inUpperLevel cannot be < -1");
...@@ -254,9 +255,10 @@ protected: ...@@ -254,9 +255,10 @@ protected:
for(int idxLevel = 1 ; idxLevel < OctreeHeight ; ++idxLevel ){ for(int idxLevel = 1 ; idxLevel < OctreeHeight ; ++idxLevel ){
FLOG(FTic counterTimeLevel); FLOG(FTic counterTimeLevel);
const int fackLevel = idxLevel + offsetRealTree; const int fackLevel = idxLevel + offsetRealTree;
const int separationCriteria = (idxLevel != OctreeHeight-1 ? 1 : leafLevelSeperationCriteria);
// for each cells // for each cells
do{ do{
const int counter = tree->getPeriodicInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, AllDirs); const int counter = tree->getPeriodicInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, AllDirs, separationCriteria);
FLOG(computationCounter.tic()); FLOG(computationCounter.tic());
if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, fackLevel); if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, fackLevel);
FLOG(computationCounter.tac()); FLOG(computationCounter.tac());
......
...@@ -49,15 +49,16 @@ class FFmmAlgorithmSectionTask : public FAbstractAlgorithm{ ...@@ -49,15 +49,16 @@ class FFmmAlgorithmSectionTask : public FAbstractAlgorithm{
const int OctreeHeight; const int OctreeHeight;
const int leafLevelSeperationCriteria;
public: public:
/** The constructor need the octree and the kernels used for computation /** The constructor need the octree and the kernels used for computation
* @param inTree the octree to work on * @param inTree the octree to work on
* @param inKernels the kernels to call * @param inKernels the kernels to call
* An assert is launched if one of the arguments is null * An assert is launched if one of the arguments is null
*/ */
FFmmAlgorithmSectionTask(OctreeClass* const inTree, KernelClass* const inKernels) FFmmAlgorithmSectionTask(OctreeClass* const inTree, KernelClass* const inKernels, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(0), : tree(inTree) , kernels(0),
MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()) MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()), leafLevelSeperationCriteria(inLeafLevelSeperationCriteria)
{ {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
...@@ -214,9 +215,10 @@ protected: ...@@ -214,9 +215,10 @@ protected:
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
FLOG(FTic counterTimeLevel); FLOG(FTic counterTimeLevel);
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
// for each cells // for each cells
do{ do{
int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel); const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter){ if(counter){
#pragma omp task firstprivate(octreeIterator, neighbors, counter) shared(idxLevel) #pragma omp task firstprivate(octreeIterator, neighbors, counter) shared(idxLevel)
{ {
......
...@@ -49,15 +49,16 @@ class FFmmAlgorithmTask : public FAbstractAlgorithm, public FAlgorithmTimers { ...@@ -49,15 +49,16 @@ class FFmmAlgorithmTask : public FAbstractAlgorithm, public FAlgorithmTimers {
const int OctreeHeight; const int OctreeHeight;
const int leafLevelSeperationCriteria;
public: public:
/** The constructor need the octree and the kernels used for computation /** The constructor need the octree and the kernels used for computation
* @param inTree the octree to work on * @param inTree the octree to work on
* @param inKernels the kernels to call * @param inKernels the kernels to call
* An assert is launched if one of the arguments is null * An assert is launched if one of the arguments is null
*/ */
FFmmAlgorithmTask(OctreeClass* const inTree, KernelClass* const inKernels) FFmmAlgorithmTask(OctreeClass* const inTree, KernelClass* const inKernels, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(nullptr), : tree(inTree) , kernels(nullptr),
MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()) MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()), leafLevelSeperationCriteria(inLeafLevelSeperationCriteria)
{ {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
...@@ -228,9 +229,10 @@ protected: ...@@ -228,9 +229,10 @@ protected:
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
FLOG(FTic counterTimeLevel); FLOG(FTic counterTimeLevel);
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
// for each cells // for each cells
do{ do{
int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel); const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter){ if(counter){
#pragma omp task firstprivate(octreeIterator, neighbors, counter) shared(idxLevel) #pragma omp task firstprivate(octreeIterator, neighbors, counter) shared(idxLevel)
{ {
......
...@@ -62,6 +62,8 @@ class FFmmAlgorithmThread : public FAbstractAlgorithm, public FAlgorithmTimers{ ...@@ -62,6 +62,8 @@ class FFmmAlgorithmThread : public FAbstractAlgorithm, public FAlgorithmTimers{
const bool staticSchedule; const bool staticSchedule;
const int leafLevelSeperationCriteria;
template <class NumType> template <class NumType>
NumType getChunkSize(const NumType inSize) const { NumType getChunkSize(const NumType inSize) const {
if(staticSchedule){ if(staticSchedule){
...@@ -83,10 +85,10 @@ public: ...@@ -83,10 +85,10 @@ public:
* \except An exception is thrown if one of the arguments is NULL. * \except An exception is thrown if one of the arguments is NULL.
*/ */
FFmmAlgorithmThread(OctreeClass* const inTree, KernelClass* const inKernels, FFmmAlgorithmThread(OctreeClass* const inTree, KernelClass* const inKernels,
const bool inStaticSchedule = true) const bool inStaticSchedule = true, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(nullptr), iterArray(nullptr), leafsNumber(0), : tree(inTree) , kernels(nullptr), iterArray(nullptr), leafsNumber(0),
MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()), MaxThreads(omp_get_max_threads()), OctreeHeight(tree->getHeight()),
staticSchedule(inStaticSchedule) { staticSchedule(inStaticSchedule), leafLevelSeperationCriteria(inLeafLevelSeperationCriteria) {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
...@@ -278,6 +280,7 @@ protected: ...@@ -278,6 +280,7 @@ protected:
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
FLOG(FTic counterTimeLevel); FLOG(FTic counterTimeLevel);
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
int numberOfCells = 0; int numberOfCells = 0;
// for each cells // for each cells
do{ do{
...@@ -297,7 +300,7 @@ protected: ...@@ -297,7 +300,7 @@ protected:
#pragma omp for schedule(dynamic, chunkSize) nowait #pragma omp for schedule(dynamic, chunkSize) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){ for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel); const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel); if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
} }
......
...@@ -81,6 +81,7 @@ class FFmmAlgorithmThreadProc : public FAbstractAlgorithm, public FAlgorithmTime ...@@ -81,6 +81,7 @@ class FFmmAlgorithmThreadProc : public FAbstractAlgorithm, public FAlgorithmTime
const int OctreeHeight; //<Height of the tree const int OctreeHeight; //<Height of the tree
const int leafLevelSeperationCriteria;
/** An interval is the morton index interval /** An interval is the morton index interval
* that a proc use (it holds data in this interval) * that a proc use (it holds data in this interval)
...@@ -134,10 +135,12 @@ public: ...@@ -134,10 +135,12 @@ public:
* @param inKernels the kernels to call * @param inKernels the kernels to call
* An assert is launched if one of the arguments is null * An assert is launched if one of the arguments is null
*/ */
FFmmAlgorithmThreadProc(const FMpi::FComm& inComm, OctreeClass* const inTree, KernelClass* const inKernels) FFmmAlgorithmThreadProc(const FMpi::FComm& inComm, OctreeClass* const inTree, KernelClass* const inKernels, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(nullptr), comm(inComm), iterArray(nullptr),iterArrayComm(nullptr),numberOfLeafs(0), : tree(inTree) , kernels(nullptr), comm(inComm), iterArray(nullptr),iterArrayComm(nullptr),numberOfLeafs(0),
MaxThreads(omp_get_max_threads()), nbProcess(inComm.processCount()), idProcess(inComm.processId()), MaxThreads(omp_get_max_threads()), nbProcess(inComm.processCount()), idProcess(inComm.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[inComm.processCount()]), OctreeHeight(tree->getHeight()),
leafLevelSeperationCriteria(inLeafLevelSeperationCriteria),
intervals(new Interval[inComm.processCount()]),
workingIntervalsPerLevel(new Interval[inComm.processCount() * tree->getHeight()]) workingIntervalsPerLevel(new Interval[inComm.processCount() * tree->getHeight()])
{ {
FAssertLF(tree, "tree cannot be null"); FAssertLF(tree, "tree cannot be null");
...@@ -622,6 +625,9 @@ protected: ...@@ -622,6 +625,9 @@ protected:
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator); typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
if(!procHasWorkAtLevel(idxLevel, idProcess)){ if(!procHasWorkAtLevel(idxLevel, idProcess)){
avoidGotoLeftIterator.moveDown(); avoidGotoLeftIterator.moveDown();
octreeIterator = avoidGotoLeftIterator; octreeIterator = avoidGotoLeftIterator;
...@@ -646,10 +652,10 @@ protected: ...@@ -646,10 +652,10 @@ protected:
// Which cell potentialy needs other data and in the same time // Which cell potentialy needs other data and in the same time
// are potentialy needed by other // are potentialy needed by other
MortonIndex neighborsIndexes[189]; MortonIndex neighborsIndexes[/*189+26+1*/216];
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){ for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// Find the M2L neigbors of a cell // Find the M2L neigbors of a cell
const int counter = iterArrayLocal[idxCell].getCurrentGlobalCoordinate().getInteractionNeighbors(idxLevel, neighborsIndexes); const int counter = iterArrayLocal[idxCell].getCurrentGlobalCoordinate().getInteractionNeighbors(idxLevel, neighborsIndexes, separationCriteria);
memset(alreadySent, false, sizeof(bool) * nbProcess); memset(alreadySent, false, sizeof(bool) * nbProcess);
bool needOther = false; bool needOther = false;
...@@ -778,6 +784,8 @@ protected: ...@@ -778,6 +784,8 @@ protected:
// Now we can compute all the data // Now we can compute all the data
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
if(!procHasWorkAtLevel(idxLevel, idProcess)){ if(!procHasWorkAtLevel(idxLevel, idProcess)){
avoidGotoLeftIterator.moveDown(); avoidGotoLeftIterator.moveDown();
octreeIterator = avoidGotoLeftIterator; octreeIterator = avoidGotoLeftIterator;
...@@ -807,7 +815,7 @@ protected: ...@@ -807,7 +815,7 @@ protected:
const int nbCellToCompute = FMath::Min(chunckSize, numberOfCells-idxCell); const int nbCellToCompute = FMath::Min(chunckSize, numberOfCells-idxCell);
for(int idxCellToCompute = idxCell ; idxCellToCompute < idxCell+nbCellToCompute ; ++idxCellToCompute){ for(int idxCellToCompute = idxCell ; idxCellToCompute < idxCell+nbCellToCompute ; ++idxCellToCompute){
const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCellToCompute].getCurrentGlobalCoordinate(), idxLevel); const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCellToCompute].getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter) myThreadkernels->M2L( iterArray[idxCellToCompute].getCurrentCell() , neighbors, counter, idxLevel); if(counter) myThreadkernels->M2L( iterArray[idxCellToCompute].getCurrentCell() , neighbors, counter, idxLevel);
} }
} }
...@@ -843,6 +851,8 @@ protected: ...@@ -843,6 +851,8 @@ protected:
// compute the second time // compute the second time
// for each levels // for each levels
for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){ for(int idxLevel = FAbstractAlgorithm::upperWorkingLevel ; idxLevel < FAbstractAlgorithm::lowerWorkingLevel ; ++idxLevel ){
const int separationCriteria = (idxLevel != FAbstractAlgorithm::lowerWorkingLevel-1 ? 1 : leafLevelSeperationCriteria);
if(!procHasWorkAtLevel(idxLevel, idProcess)){ if(!procHasWorkAtLevel(idxLevel, idProcess)){
avoidGotoLeftIterator.moveDown(); avoidGotoLeftIterator.moveDown();
octreeIterator = avoidGotoLeftIterator; octreeIterator = avoidGotoLeftIterator;
...@@ -900,15 +910,15 @@ protected: ...@@ -900,15 +910,15 @@ protected:
#pragma omp parallel #pragma omp parallel
{ {
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()]; KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
MortonIndex neighborsIndex[189]; MortonIndex neighborsIndex[/*189+26+1*/216];
int neighborsPosition[189]; int neighborsPosition[/*189+26+1*/216];
const CellClass* neighbors[343]; const CellClass* neighbors[343];
#pragma omp for schedule(static) nowait #pragma omp for schedule(static) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){ for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// compute indexes // compute indexes
memset(neighbors, 0, 343 * sizeof(CellClass*)); memset(neighbors, 0, 343 * sizeof(CellClass*));
const int counterNeighbors = iterArray[idxCell].getCurrentGlobalCoordinate().getInteractionNeighbors(idxLevel, neighborsIndex, neighborsPosition); const int counterNeighbors = iterArray[idxCell].getCurrentGlobalCoordinate().getInteractionNeighbors(idxLevel, neighborsIndex, neighborsPosition, separationCriteria);
int counter = 0; int counter = 0;
// does we receive this index from someone? // does we receive this index from someone?
......
...@@ -83,6 +83,8 @@ class FFmmAlgorithmThreadProcPeriodic : public FAbstractAlgorithm { ...@@ -83,6 +83,8 @@ class FFmmAlgorithmThreadProcPeriodic : public FAbstractAlgorithm {
const int OctreeHeight; const int OctreeHeight;
const int leafLevelSeperationCriteria;
public: public:
struct Interval{ struct Interval{
MortonIndex leftIndex; MortonIndex leftIndex;
...@@ -139,12 +141,13 @@ public: ...@@ -139,12 +141,13 @@ public:
* An assert is launched if one of the arguments is null * An assert is launched if one of the arguments is null
*/ */
FFmmAlgorithmThreadProcPeriodic(const FMpi::FComm& inComm, OctreeClass* const inTree, FFmmAlgorithmThreadProcPeriodic(const FMpi::FComm& inComm, OctreeClass* const inTree,
const int inUpperLevel = 2) const int inUpperLevel = 2, const int inLeafLevelSeperationCriteria = 1)
: tree(inTree) , kernels(nullptr), comm(inComm), nbLevelsAboveRoot(inUpperLevel), offsetRealTree(inUpperLevel + 3), : tree(inTree) , kernels(nullptr), comm(inComm), nbLevelsAboveRoot(inUpperLevel), offsetRealTree(inUpperLevel + 3),
numberOfLeafs(0), numberOfLeafs(0),
MaxThreads(omp_get_max_threads()), nbProcess(inComm.processCount()), idProcess(inComm.processId()), MaxThreads(omp_get_max_threads()), nbProcess(inComm.processCount()), idProcess(inComm.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[inComm.processCount()]), OctreeHeight(tree->getHeight()),intervals(new Interval[inComm.processCount()]),