From 68f27f532fc0cfd1540fb154b5c710946525841d Mon Sep 17 00:00:00 2001 From: bramas <berenger.bramas@inria.fr> Date: Thu, 3 Apr 2014 17:54:04 +0200 Subject: [PATCH] add a group algorithm (sequential and absolutly not tested) --- Src/GroupTree/FGroupSeqAlgorithm.hpp | 390 +++++++++++++++++++++++++++ Src/GroupTree/FGroupTree.hpp | 101 +++++-- Tests/Kernels/testBlockedTree.cpp | 8 +- 3 files changed, 470 insertions(+), 29 deletions(-) create mode 100644 Src/GroupTree/FGroupSeqAlgorithm.hpp diff --git a/Src/GroupTree/FGroupSeqAlgorithm.hpp b/Src/GroupTree/FGroupSeqAlgorithm.hpp new file mode 100644 index 000000000..e7976d4ca --- /dev/null +++ b/Src/GroupTree/FGroupSeqAlgorithm.hpp @@ -0,0 +1,390 @@ +#ifndef FGROUPSEQALGORITHM_HPP +#define FGROUPSEQALGORITHM_HPP + +#include "../Utils/FGlobal.hpp" +#include "../Core/FCoreCommon.hpp" +#include "../Utils/FQuickSort.hpp" +#include "../Containers/FTreeCoordinate.hpp" + +#include <list> +#include <vector> + +template <class OctreeClass, class CellContainerClass, class CellClass, class KernelClass, class ParticleContainerClass> +class FGroupSeqAlgorithm { +protected: + struct OutOfBlockInteraction{ + MortonIndex outIndex; + MortonIndex insideIndex; + int outPosition; + + operator long long() const{ + return static_cast<long long>(outIndex); + } + }; + + const int MaxThreads; //< The number of threads + OctreeClass*const tree; //< The Tree + KernelClass*const kernels; //< The kernels + +public: + FGroupSeqAlgorithm(OctreeClass*const inTree, KernelClass* inKernels) : MaxThreads(1), tree(inTree), kernels(inKernels){ + FAssertLF(tree, "tree cannot be null"); + FAssertLF(kernels, "kernels cannot be null"); + + FLOG(FLog::Controller << "FGroupSeqAlgorithm (Max Thread " << MaxThreads << ")\n"); + } + + ~FGroupSeqAlgorithm(){ + } + + void execute(const unsigned operationsToProceed = FFmmNearAndFarFields){ + if(operationsToProceed & FFmmP2M) bottomPass(); + + if(operationsToProceed & FFmmM2M) upwardPass(); + + if(operationsToProceed & FFmmM2L) transferPass(); + + if(operationsToProceed & FFmmL2L) downardPass(); + + if( (operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P) ) directPass(); + } + +protected: + void bottomPass(){ + typename std::list<ParticleContainerClass>::iterator iterParticles = tree->leavesBegin(); + const typename std::list<ParticleContainerClass>::iterator endParticles = tree->leavesEnd(); + + typename std::list<CellContainerClass>::iterator iterCells = tree->cellsBegin(tree->getHeight()-1); + const typename std::list<CellContainerClass>::iterator endCells = tree->cellsEnd(tree->getHeight()-1); + + while(iterParticles != endParticles && iterCells != endCells){ + { // Can be a task(in:iterParticles, out:iterCells) + const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterCells)->getEndingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){ + CellClass* cell = (*iterCells)->getCell(mindex); + if(cell){ + ParticleContainerClass particles = (*iterParticles)->getLeaf(mindex); + FAssertLF(particles.isAttachedToSomething()); + kernels->P2M(cell, &particles); + } + } + } + + ++iterParticles; + ++iterCells; + } + + FAssertLF(iterParticles == endParticles && iterCells == endCells); + } + + void upwardPass(){ + for(int idxLevel = tree->getHeight()-2 ; idxLevel >= 2 ; --idxLevel){ + typename std::list<CellContainerClass>::iterator iterCells = tree->cellsBegin(idxLevel); + const typename std::list<CellContainerClass>::iterator endCells = tree->cellsEnd(idxLevel); + + typename std::list<CellContainerClass>::iterator iterChildCells = tree->cellsBegin(idxLevel+1); + const typename std::list<CellContainerClass>::iterator endChildCells = tree->cellsEnd(idxLevel+1); + + while(iterCells != endCells && iterChildCells != endChildCells){ + { // Can be a task(in:iterParticles, out:iterChildCells ...) + const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterCells)->getEndingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx && iterChildCells != endChildCells; ++mindex){ + CellClass* cell = (*iterCells)->getCell(mindex); + if(cell){ + CellClass* child[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; + + for(int idxChild = 0 ; idxChild < 8 ; ++idxChild){ + while(iterChildCells != endChildCells && (*iterChildCells)->getEndingIndex() < ((mindex<<3)+idxChild) ){ + ++iterChildCells; + } + if( iterChildCells == endChildCells ){ + break; + } + child[idxChild] = (*iterChildCells)->getCell((mindex<<3)+idxChild); + } + + kernels->M2M(cell, child, idxLevel); + } + } + } + + ++iterCells; + } + + FAssertLF(iterCells == endCells && (iterChildCells == endChildCells || (++iterChildCells) == endChildCells)); + } + } + + void transferPass(){ + for(int idxLevel = tree->getHeight()-1 ; idxLevel >= 2 ; --idxLevel){ + typename std::list<CellContainerClass>::iterator iterCells = tree->cellsBegin(idxLevel); + const typename std::list<CellContainerClass>::iterator endCells = tree->cellsEnd(idxLevel); + + while(iterCells != endCells){ + std::vector<OutOfBlockInteraction> outsideInteractions; + + { // Can be a task(inout:iterCells, out:outsideInteractions) + const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterCells)->getEndingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){ + CellClass* cell = (*iterCells)->getCell(mindex); + if(cell){ + MortonIndex interactionsIndexes[189]; + int interactionsPosition[189]; + FTreeCoordinate coord(mindex, idxLevel); + int counter = coord.getInteractionNeighbors(idxLevel,interactionsIndexes,interactionsPosition); + + CellClass* interactions[343]; + memset(interactions, 0, 343*sizeof(CellClass*)); + int counterExistingCell = 0; + + for(int idxInter = 0 ; idxInter < counter ; ++idxInter){ + if( blockStartIdx <= interactionsIndexes[idxInter] && interactionsIndexes[idxInter] < blockEndIdx ){ + CellClass* interCell = (*iterCells)->getCell(interactionsIndexes[idxInter]); + if(interCell){ + interactions[interactionsPosition[idxInter]] = interCell; + counterExistingCell += 1; + } + } + else if(interactionsPosition[idxInter] < 343/2){ + OutOfBlockInteraction property; + property.insideIndex = mindex; + property.outIndex = interactionsIndexes[idxInter]; + property.outPosition = interactionsPosition[idxInter]; + outsideInteractions.push_back(property); + } + } + + kernels->M2L( cell , interactions, counterExistingCell, idxLevel); + } + } + } + + + // Manage outofblock interaction + FQuickSort<OutOfBlockInteraction, long long, int>::QsSequential(outsideInteractions.data(),outsideInteractions.size()); + + typename std::list<CellContainerClass>::iterator iterLeftCells = tree->cellsBegin(idxLevel); + int currentOutInteraction = 0; + while(iterLeftCells != iterCells && currentOutInteraction < outsideInteractions.size()){ + const MortonIndex blockStartIdx = (*iterLeftCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterLeftCells)->getEndingIndex(); + + while(outsideInteractions[currentOutInteraction].outIndex < blockStartIdx){ + currentOutInteraction += 1; + } + + int lastOutInteraction = currentOutInteraction + 1; + while(lastOutInteraction < outsideInteractions.size() && outsideInteractions[lastOutInteraction].outIndex < blockEndIdx){ + lastOutInteraction += 1; + } + + { // Can be a task(in:currentOutInteraction, in:outsideInteractions, in:lastOutInteraction, inout:iterLeftCells, inout:iterCells) + for(int outInterIdx = currentOutInteraction ; outInterIdx < lastOutInteraction ; ++outInterIdx){ + CellClass* interCell = (*iterLeftCells)->getCell(outsideInteractions[outInterIdx].outIndex); + if(interCell){ + CellClass* cell = (*iterCells)->getCell(outsideInteractions[outInterIdx].insideIndex); + FAssertLF(cell); + CellClass* interactions[343]; + memset(interactions, 0, 343*sizeof(CellClass*)); + interactions[outsideInteractions[outInterIdx].outPosition] = interCell; + const int counter = 1; + kernels->M2L( cell , interactions, counter, idxLevel); + + interactions[outsideInteractions[outInterIdx].outPosition] = NULL; + interactions[getOppositeInterIndex(outsideInteractions[outInterIdx].outPosition)] = cell; + kernels->M2L( interCell , interactions, counter, idxLevel); + } + } + } + + currentOutInteraction = lastOutInteraction; + ++iterLeftCells; + } + + ++iterCells; + } + + } + } + + void downardPass(){ + for(int idxLevel = 2 ; idxLevel <= tree->getHeight()-2 ; ++idxLevel){ + typename std::list<CellContainerClass>::iterator iterCells = tree->cellsBegin(idxLevel); + const typename std::list<CellContainerClass>::iterator endCells = tree->cellsEnd(idxLevel); + + typename std::list<CellContainerClass>::iterator iterChildCells = tree->cellsBegin(idxLevel+1); + const typename std::list<CellContainerClass>::iterator endChildCells = tree->cellsEnd(idxLevel+1); + + while(iterCells != endCells && iterChildCells != endChildCells){ + { // Can be a task(in:iterParticles, inout:iterChildCells ...) + const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterCells)->getEndingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx && iterChildCells != endChildCells; ++mindex){ + CellClass* cell = (*iterCells)->getCell(mindex); + if(cell){ + CellClass* child[8] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; + + for(int idxChild = 0 ; idxChild < 8 ; ++idxChild){ + while(iterChildCells != endChildCells && (*iterChildCells)->getEndingIndex() < ((mindex<<3)+idxChild) ){ + ++iterChildCells; + } + if( iterChildCells == endChildCells ){ + break; + } + child[idxChild] = (*iterChildCells)->getCell((mindex<<3)+idxChild); + } + + kernels->L2L(cell, child, idxLevel); + } + } + } + + ++iterCells; + } + + FAssertLF(iterCells == endCells && (iterChildCells == endChildCells || (++iterChildCells) == endChildCells)); + } + } + + void directPass(){ + { + typename std::list<ParticleContainerClass>::iterator iterParticles = tree->leavesBegin(); + const typename std::list<ParticleContainerClass>::iterator endParticles = tree->leavesEnd(); + + typename std::list<CellContainerClass>::iterator iterCells = tree->cellsBegin(tree->getHeight()-1); + const typename std::list<CellContainerClass>::iterator endCells = tree->cellsEnd(tree->getHeight()-1); + + while(iterParticles != endParticles && iterCells != endCells){ + { // Can be a task(in:iterCells, inout:iterParticles) + const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterCells)->getStartingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){ + CellClass* cell = (*iterCells)->getCell(mindex); + if(cell){ + ParticleContainerClass particles = (*iterParticles)->getLeaf(mindex); + FAssertLF(particles.isAttachedToSomething()); + kernels->P2M(cell, &particles); + } + } + } + + ++iterParticles; + ++iterCells; + } + + FAssertLF(iterParticles == endParticles && iterCells == endCells); + } + { + typename std::list<ParticleContainerClass>::iterator iterParticles = tree->leavesBegin(); + const typename std::list<ParticleContainerClass>::iterator endParticles = tree->leavesEnd(); + + while(iterParticles != endParticles){ + typename std::vector<OutOfBlockInteraction> outsideInteractions; + + { // Can be a task(inout:iterCells, out:outsideInteractions) + const MortonIndex blockStartIdx = (*iterParticles)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterParticles)->getEndingIndex(); + + for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){ + ParticleContainerClass particles = (*iterParticles)->getLeaf(mindex); + if(particles.isAttachedToSomething()){ + MortonIndex interactionsIndexes[26]; + int interactionsPosition[26]; + FTreeCoordinate coord(mindex, tree->getHeight()-1); + int counter = coord.getNeighborsIndexes(tree->getHeight(),interactionsIndexes,interactionsPosition); + + ParticleContainerClass interactionsObjects[27]; + ParticleContainerClass* interactions[27]; + memset(interactions, 0, 27*sizeof(CellClass*)); + int counterExistingCell = 0; + + for(int idxInter = 0 ; idxInter < counter ; ++idxInter){ + if( blockStartIdx <= interactionsIndexes[idxInter] && interactionsIndexes[idxInter] < blockEndIdx ){ + interactionsObjects[counterExistingCell] = (*iterParticles)->getLeaf(interactionsIndexes[idxInter]); + if(interactionsObjects[counterExistingCell].isAttachedToSomething()){ + interactions[interactionsPosition[idxInter]] = &interactionsObjects[counterExistingCell]; + counterExistingCell += 1; + } + } + else if(interactionsPosition[idxInter] < 27/2){ + OutOfBlockInteraction property; + property.insideIndex = mindex; + property.outIndex = interactionsIndexes[idxInter]; + property.outPosition = interactionsPosition[idxInter]; + outsideInteractions.push_back(property); + } + } + + kernels->P2P( coord, &particles, &particles , interactions, counterExistingCell); + } + } + } + + + // Manage outofblock interaction + FQuickSort<OutOfBlockInteraction, long long, int>::QsSequential(outsideInteractions.data(),outsideInteractions.size()); + + typename std::list<ParticleContainerClass>::iterator iterLeftParticles = tree->leavesBegin(); + int currentOutInteraction = 0; + while(iterLeftParticles != iterParticles && currentOutInteraction < outsideInteractions.size()){ + const MortonIndex blockStartIdx = (*iterLeftParticles)->getStartingIndex(); + const MortonIndex blockEndIdx = (*iterLeftParticles)->getEndingIndex(); + + while(outsideInteractions[currentOutInteraction].outIndex < blockStartIdx){ + currentOutInteraction += 1; + } + + int lastOutInteraction = currentOutInteraction + 1; + while(lastOutInteraction < outsideInteractions.size() && outsideInteractions[lastOutInteraction].outIndex < blockEndIdx){ + lastOutInteraction += 1; + } + + { // Can be a task(in:currentOutInteraction, in:outsideInteractions, in:lastOutInteraction, inout:iterLeftParticles, inout:iterParticles) + for(int outInterIdx = currentOutInteraction ; outInterIdx < lastOutInteraction ; ++outInterIdx){ + ParticleContainerClass interParticles = (*iterLeftParticles)->getLeaf(outsideInteractions[outInterIdx].outIndex); + if(interParticles.isAttachedToSomething()){ + ParticleContainerClass particles = (*iterParticles)->getLeaf(outsideInteractions[outInterIdx].insideIndex); + FAssertLF(particles.isAttachedToSomething()); + CellClass* interactions[27]; + memset(interactions, 0, 27*sizeof(CellClass*)); + interactions[outsideInteractions[outInterIdx].outPosition] = &interParticles; + const int counter = 1; + kernels->P2PRemote( FTreeCoordinate(outsideInteractions[outInterIdx].insideIndex, tree->getHeight()-1), &particles, &particles , interactions, counter); + + interactions[outsideInteractions[outInterIdx].outPosition] = NULL; + interactions[getOppositeNeighIndex(outsideInteractions[outInterIdx].outPosition)] = &particles; + kernels->P2PRemote( FTreeCoordinate(outsideInteractions[outInterIdx].outIndex, tree->getHeight()-1), &interParticles, &interParticles , interactions, counter); + } + } + } + + currentOutInteraction = lastOutInteraction; + ++iterLeftParticles; + } + + ++iterParticles; + } + } + } + + int getOppositeNeighIndex(const int index) const { + // ((idxX+1)*3 + (idxY+1)) * 3 + (idxZ+1) + return 27-index; + } + + int getOppositeInterIndex(const int index) const { + // ((( (xdiff+3) * 7) + (ydiff+3))) * 7 + zdiff + 3 + return 343-index; + } +}; + + +#endif // FGROUPSEQALGORITHM_HPP diff --git a/Src/GroupTree/FGroupTree.hpp b/Src/GroupTree/FGroupTree.hpp index 580c448be..45a5e6028 100644 --- a/Src/GroupTree/FGroupTree.hpp +++ b/Src/GroupTree/FGroupTree.hpp @@ -15,18 +15,20 @@ template <class CellClass, unsigned NbAttributesPerParticle, class AttributeClass = FReal> class FGroupTree { +public: typedef FGroupAttachedLeaf<NbAttributesPerParticle,AttributeClass> BasicAttachedClass; + typedef FGroupOfCells<CellClass> CellGroupClass; +protected: //< This value is for not used cells static const int CellIsEmptyFlag = -1; -protected: //< height of the tree (1 => only the root) const int treeHeight; //< max number of cells in a block const int nbElementsPerBlock; //< all the blocks of the tree - std::list<FGroupOfCells<CellClass>*>* cellBlocksPerLevel; + std::list<CellGroupClass*>* cellBlocksPerLevel; //< all the blocks of leaves std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*> particleBlocks; @@ -71,7 +73,7 @@ public: : treeHeight(inTreeHeight), nbElementsPerBlock(inNbElementsPerBlock), cellBlocksPerLevel(0), boxCenter(inOctreeSrc->getBoxCenter()), boxCorner(inOctreeSrc->getBoxCenter(),-(inOctreeSrc->getBoxWidth()/2)), boxWidth(inOctreeSrc->getBoxWidth()), boxWidthAtLeafLevel(inOctreeSrc->getBoxWidth()/FReal(1<<inTreeHeight)){ - cellBlocksPerLevel = new std::list<FGroupOfCells<CellClass>*>[treeHeight]; + cellBlocksPerLevel = new std::list<CellGroupClass*>[treeHeight]; // Iterate on the tree and build typename OctreeClass::Iterator octreeIterator(inOctreeSrc); @@ -92,7 +94,7 @@ public: } // Create a block with the apropriate parameters - FGroupOfCells<CellClass>*const newBlock = new FGroupOfCells<CellClass>(blockIteratorInOctree.getCurrentGlobalIndex(), + CellGroupClass*const newBlock = new CellGroupClass(blockIteratorInOctree.getCurrentGlobalIndex(), octreeIterator.getCurrentGlobalIndex()+1, sizeOfBlock); FGroupOfParticles<NbAttributesPerParticle, AttributeClass>*const newParticleBlock = new FGroupOfParticles<NbAttributesPerParticle, AttributeClass>(blockIteratorInOctree.getCurrentGlobalIndex(), @@ -148,7 +150,7 @@ public: } // Create a block with the apropriate parameters - FGroupOfCells<CellClass>*const newBlock = new FGroupOfCells<CellClass>(blockIteratorInOctree.getCurrentGlobalIndex(), + CellGroupClass*const newBlock = new CellGroupClass(blockIteratorInOctree.getCurrentGlobalIndex(), octreeIterator.getCurrentGlobalIndex()+1, sizeOfBlock); // Initialize each cell of the block @@ -191,7 +193,7 @@ public: boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth), boxWidthAtLeafLevel(inBoxWidth/FReal(1<<inTreeHeight)){ - cellBlocksPerLevel = new std::list<FGroupOfCells<CellClass>*>[treeHeight]; + cellBlocksPerLevel = new std::list<CellGroupClass*>[treeHeight]; MortonIndex* currentBlockIndexes = new MortonIndex[nbElementsPerBlock]; // First we work at leaf level @@ -248,7 +250,7 @@ public: } // Create a group - FGroupOfCells<CellClass>*const newBlock = new FGroupOfCells<CellClass>(currentBlockIndexes[0], + CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0], currentBlockIndexes[sizeOfBlock-1]+1, sizeOfBlock); FGroupOfParticles<NbAttributesPerParticle, AttributeClass>*const newParticleBlock = new FGroupOfParticles<NbAttributesPerParticle, AttributeClass>(currentBlockIndexes[0], @@ -292,8 +294,8 @@ public: // For each level from heigth - 2 to 1 for(int idxLevel = treeHeight-2; idxLevel > 0 ; --idxLevel){ - typename std::list<FGroupOfCells<CellClass>*>::const_iterator iterChildCells = cellBlocksPerLevel[idxLevel+1].begin(); - const typename std::list<FGroupOfCells<CellClass>*>::const_iterator iterChildEndCells = cellBlocksPerLevel[idxLevel+1].end(); + typename std::list<CellGroupClass*>::const_iterator iterChildCells = cellBlocksPerLevel[idxLevel+1].begin(); + const typename std::list<CellGroupClass*>::const_iterator iterChildEndCells = cellBlocksPerLevel[idxLevel+1].end(); MortonIndex currentCellIndex = (*iterChildCells)->getStartingIndex(); int sizeOfBlock = 0; @@ -322,7 +324,7 @@ public: // If group is full if(sizeOfBlock == nbElementsPerBlock || (sizeOfBlock && iterChildCells == iterChildEndCells)){ // Create a group - FGroupOfCells<CellClass>*const newBlock = new FGroupOfCells<CellClass>(currentBlockIndexes[0], + CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0], currentBlockIndexes[sizeOfBlock-1]+1, sizeOfBlock); // Init cells @@ -355,7 +357,7 @@ public: * create the block and the cells, using the constructor of * FGroupOfCells !! */ - /*FGroupOfCells<CellClass> * createBlockFromArray(MortonIndex head[]){ + /*CellGroupClass * createBlockFromArray(MortonIndex head[]){ //Store the start and end MortonIndex start = head[0]; MortonIndex end = start; @@ -371,7 +373,7 @@ public: // } } //allocation of memory - FGroupOfCells<CellClass> * newBlock = new FGroupOfCells<CellClass>(start,end+1,count); + CellGroupClass * newBlock = new CellGroupClass(start,end+1,count); //allocation of cells for(int idx=0 ; idx<count ; idx++){ newBlock->newCell(head[idx], idx); @@ -389,7 +391,7 @@ public: FGroupTree(const int inTreeHeight, const int inNbElementsPerBlock, OctreeClass*const inOctreeSrc, int FLAG): treeHeight(inTreeHeight),nbElementsPerBlock(inNbElementsPerBlock),cellBlocksPerLevel(0) { - cellBlocksPerLevel = new std::list<FGroupOfCells<CellClass>*>[treeHeight]; + cellBlocksPerLevel = new std::list<CellGroupClass*>[treeHeight]; int *nbCellPerLevel = new int[treeHeight]; inOctreeSrc->getNbCellsPerLevel(nbCellPerLevel); int nbLeaf = nbCellPerLevel[treeHeight-1]; @@ -423,7 +425,7 @@ public: idxLeafs += inNbElementsPerBlock; //creation of the block and addition to the list - FGroupOfCells<CellClass> * tempBlock = createBlockFromArray(head); + CellGroupClass * tempBlock = createBlockFromArray(head); cellBlocksPerLevel[treeHeight-1].push_back(tempBlock); } delete[] leafsIdx; @@ -438,7 +440,7 @@ public: MortonIndex previous = -1; //Iterator over the list at a deeper level (READ) - typename std::list<FGroupOfCells<CellClass>*>::const_iterator curBlockRead; + typename std::list<CellGroupClass*>::const_iterator curBlockRead; for(curBlockRead = cellBlocksPerLevel[idxLevel+1].begin() ; curBlockRead != cellBlocksPerLevel[idxLevel+1].end() ; ++curBlockRead){ //Loop over cells in READ list for(MortonIndex idxCell = (*curBlockRead)->getStartingIndex() ; idxCell < (*curBlockRead)->getEndingIndex() ; ++idxCell){ @@ -461,7 +463,7 @@ public: else{ //Creation of the block from head, then reset head, and //storage of new idx in new head - FGroupOfCells<CellClass> * tempBlock = createBlockFromArray(head); + CellGroupClass * tempBlock = createBlockFromArray(head); cellBlocksPerLevel[idxLevel].push_back(tempBlock); //Need a new block @@ -475,7 +477,7 @@ public: } } //Before changing Level, need to close current Block - FGroupOfCells<CellClass> * tempBlock = createBlockFromArray(head); + CellGroupClass * tempBlock = createBlockFromArray(head); cellBlocksPerLevel[idxLevel].push_back(tempBlock); } printf("toto \n"); @@ -490,8 +492,8 @@ public: /** This function dealloc the tree by deleting each block */ ~FGroupTree(){ for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){ - std::list<FGroupOfCells<CellClass>*>& levelBlocks = cellBlocksPerLevel[idxLevel]; - for (FGroupOfCells<CellClass>* block: levelBlocks){ + std::list<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel]; + for (CellGroupClass* block: levelBlocks){ delete block; } } @@ -524,8 +526,8 @@ public: */ void forEachCell(std::function<void(CellClass*)> function){ for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){ - std::list<FGroupOfCells<CellClass>*>& levelBlocks = cellBlocksPerLevel[idxLevel]; - for (FGroupOfCells<CellClass>* block: levelBlocks){ + std::list<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel]; + for (CellGroupClass* block: levelBlocks){ block->forEachCell(function); } } @@ -537,8 +539,8 @@ public: */ void forEachCellWithLevel(std::function<void(CellClass*,const int)> function){ for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){ - std::list<FGroupOfCells<CellClass>*>& levelBlocks = cellBlocksPerLevel[idxLevel]; - for (FGroupOfCells<CellClass>* block: levelBlocks){ + std::list<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel]; + for (CellGroupClass* block: levelBlocks){ block->forEachCell(function, idxLevel); } } @@ -550,8 +552,8 @@ public: */ template<class ParticlesAttachedClass> void forEachCellLeaf(std::function<void(CellClass*,ParticlesAttachedClass*)> function){ - typename std::list<FGroupOfCells<CellClass>*>::iterator iterCells = cellBlocksPerLevel[treeHeight-1].begin(); - const typename std::list<FGroupOfCells<CellClass>*>::iterator iterEndCells = cellBlocksPerLevel[treeHeight-1].end(); + typename std::list<CellGroupClass*>::iterator iterCells = cellBlocksPerLevel[treeHeight-1].begin(); + const typename std::list<CellGroupClass*>::iterator iterEndCells = cellBlocksPerLevel[treeHeight-1].end(); typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::iterator iterLeaves = particleBlocks.begin(); const typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::iterator iterEndLeaves = particleBlocks.end(); @@ -581,10 +583,10 @@ public: std::cout << "\t Group Size = " << nbElementsPerBlock << "\n"; std::cout << "\t Tree height = " << treeHeight << "\n"; for(int idxLevel = 1 ; idxLevel < treeHeight ; ++idxLevel){ - std::list<FGroupOfCells<CellClass>*>& levelBlocks = cellBlocksPerLevel[idxLevel]; + std::list<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel]; std::cout << "Level " << idxLevel << ", there are " << levelBlocks.size() << " groups.\n"; int idxGroup = 0; - for (const FGroupOfCells<CellClass>* block: levelBlocks){ + for (const CellGroupClass* block: levelBlocks){ std::cout << "\t Group " << (idxGroup++); std::cout << "\t Size = " << block->getNumberOfCellsInBlock(); std::cout << "\t Starting Index = " << block->getStartingIndex(); @@ -607,6 +609,51 @@ public: } std::cout << "There are " << totalNbParticles << " particles.\n"; } + + ///////////////////////////////////////////////////////// + // Algorithm function + ///////////////////////////////////////////////////////// + + int getHeight() const { + return treeHeight; + } + + typename std::list<CellGroupClass*>::iterator cellsBegin(const int atHeight){ + FAssertLF(atHeight < treeHeight); + return cellBlocksPerLevel[atHeight].begin(); + } + + typename std::list<CellGroupClass*>::const_iterator cellsBegin(const int atHeight) const { + FAssertLF(atHeight < treeHeight); + return cellBlocksPerLevel[atHeight].begin(); + } + + typename std::list<CellGroupClass*>::iterator cellsEnd(const int atHeight){ + FAssertLF(atHeight < treeHeight); + return cellBlocksPerLevel[atHeight].end(); + } + + typename std::list<CellGroupClass*>::const_iterator cellsEnd(const int atHeight) const { + FAssertLF(atHeight < treeHeight); + return cellBlocksPerLevel[atHeight].end(); + } + + + typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::iterator leavesBegin(){ + return particleBlocks.begin(); + } + + typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::const_iterator leavesBegin() const { + return particleBlocks.begin(); + } + + typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::iterator leavesEnd(){ + return particleBlocks.end(); + } + + typename std::list<FGroupOfParticles<NbAttributesPerParticle,AttributeClass>*>::const_iterator leavesEnd() const { + return particleBlocks.end(); + } }; #endif // FGROUPTREE_HPP diff --git a/Tests/Kernels/testBlockedTree.cpp b/Tests/Kernels/testBlockedTree.cpp index 5db219340..d8327f021 100644 --- a/Tests/Kernels/testBlockedTree.cpp +++ b/Tests/Kernels/testBlockedTree.cpp @@ -23,7 +23,7 @@ #include "../../Src/Files/FFmaBinLoader.hpp" - +#include "../../Src/GroupTree/FGroupSeqAlgorithm.hpp" int main(int argc, char* argv[]){ static const int P = 9; @@ -32,7 +32,6 @@ int main(int argc, char* argv[]){ typedef FSimpleLeaf< ContainerClass > LeafClass; typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass; - //typedef FRotationKernel< CellClass, ContainerClass , P> KernelClass; typedef FGroupTree< CellClass, 4, FReal> GroupOctreeClass; FTic counter; @@ -70,5 +69,10 @@ int main(int argc, char* argv[]){ groupedTree2.printInfoBlocks(); groupedTree3.printInfoBlocks(); + + + typedef FRotationKernel< CellClass, ContainerClass , P> KernelClass; + FGroupSeqAlgorithm<GroupOctreeClass, typename GroupOctreeClass::CellGroupClass, CellClass, KernelClass, typename GroupOctreeClass::BasicAttachedClass> algo(NULL,NULL); + return 0; } -- GitLab