Commit dabe2e5d authored by COULAUD Olivier's avatar COULAUD Olivier

Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm

# By bramas
# Via bramas
* 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm:
  Finish debugging and add a complete test (including comparing with usual octree)
  Remove a i from the cmake
  Continue to debug the block group tree
parents a2645877 d2507d90
......@@ -415,7 +415,7 @@ CONFIGURE_FILE(${ScalFMM_SOURCE_DIR}/ScalFMMConfig.cmake.in
INSTALL(FILES
${ScalFMM_BINARY_DIR}/ScalFMMConfig.cmake
DESTINATION lib/
)i
)
IF( NOT ScalFMM_BUILD_ONLY_LIB)
INSTALL(FILES
${ScalFMM_SOURCE_DIR}/Data/test20k.fma
......
......@@ -40,7 +40,7 @@ protected:
*/
template <class NumClass>
static NumClass RoundToUpperParticles(const NumClass& nbParticles){
return nbParticles + (MemoryAlignementParticles - (nbParticles%MemoryAlignementParticles)%MemoryAlignementParticles);
return nbParticles + (MemoryAlignementParticles - (nbParticles%MemoryAlignementParticles));
}
//< This value is for not used leaves
......@@ -177,12 +177,13 @@ public:
FAssertLF(isInside(inIndex));
FAssertLF(!exists(inIndex));
FAssertLF(id < blockHeader->blockIndexesTableSize);
FAssertLF(offsetInGroup < size_t(nbParticlesAllocatedInGroup));
blockIndexesTable[inIndex-blockHeader->startingIndex] = id;
leafHeader[id].nbParticles = nbParticles;
leafHeader[id].offSet = offsetInGroup;
const size_t nextLeafOffsetInGroup = RoundToUpperParticles(offsetInGroup+nbParticles);
FAssertLF(nextLeafOffsetInGroup <= size_t(nbParticlesAllocatedInGroup));
FAssertLF(nextLeafOffsetInGroup <= size_t(nbParticlesAllocatedInGroup + MemoryAlignementParticles));
return nextLeafOffsetInGroup;
}
......
......@@ -74,7 +74,7 @@ public:
FGroupTree(const int inTreeHeight, const int inNbElementsPerBlock, OctreeClass*const inOctreeSrc)
: treeHeight(inTreeHeight), nbElementsPerBlock(inNbElementsPerBlock), cellBlocksPerLevel(nullptr),
boxCenter(inOctreeSrc->getBoxCenter()), boxCorner(inOctreeSrc->getBoxCenter(),-(inOctreeSrc->getBoxWidth()/2)),
boxWidth(inOctreeSrc->getBoxWidth()), boxWidthAtLeafLevel(inOctreeSrc->getBoxWidth()/FReal(1<<inTreeHeight)){
boxWidth(inOctreeSrc->getBoxWidth()), boxWidthAtLeafLevel(inOctreeSrc->getBoxWidth()/FReal(1<<(inTreeHeight-1))){
cellBlocksPerLevel = new std::list<CellGroupClass*>[treeHeight];
// Iterate on the tree and build
......@@ -192,7 +192,7 @@ public:
const int inNbElementsPerBlock, ParticleContainer* inParticlesContainer, const bool particlesAreSorted = false):
treeHeight(inTreeHeight),nbElementsPerBlock(inNbElementsPerBlock),cellBlocksPerLevel(nullptr),
boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth),
boxWidthAtLeafLevel(inBoxWidth/FReal(1<<inTreeHeight)){
boxWidthAtLeafLevel(inBoxWidth/FReal(1<<(inTreeHeight-1))){
cellBlocksPerLevel = new std::list<CellGroupClass*>[treeHeight];
......@@ -264,6 +264,7 @@ public:
// Init cells
size_t nbParticlesOffsetBeforeLeaf = 0;
int offsetParticles = firstParticle;
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
......@@ -280,8 +281,9 @@ public:
BasicAttachedClass attachedLeaf = newParticleBlock->template getLeaf<BasicAttachedClass>(currentBlockIndexes[cellIdInBlock]);
// Copy each particle from the original position
for(int idxPart = 0 ; idxPart < nbParticlesPerLeaf[cellIdInBlock] ; ++idxPart){
attachedLeaf.setParticle(idxPart, particlesToSort[idxPart + firstParticle].originalIndex, inParticlesContainer);
attachedLeaf.setParticle(idxPart, particlesToSort[idxPart + offsetParticles].originalIndex, inParticlesContainer);
}
offsetParticles += nbParticlesPerLeaf[cellIdInBlock];
}
// Keep the block
......@@ -306,21 +308,23 @@ public:
// We need to proceed each group in sub level
while(iterChildCells != iterChildEndCells){
// Count until end of sub group is reached or we have enough cells
while(sizeOfBlock < nbElementsPerBlock && currentCellIndex != (*iterChildCells)->getEndingIndex()){
while(sizeOfBlock < nbElementsPerBlock && iterChildCells != iterChildEndCells ){
if((sizeOfBlock == 0 || currentBlockIndexes[sizeOfBlock-1] != (currentCellIndex>>3))
&& (*iterChildCells)->exists(currentCellIndex)){
currentBlockIndexes[sizeOfBlock] = (currentCellIndex>>3);
sizeOfBlock += 1;
currentCellIndex = (((currentCellIndex>>3)+1)<<3);
}
currentCellIndex += 1;
}
// If we are at the end of the sub group, move to next
if(currentCellIndex == (*iterChildCells)->getEndingIndex()){
++iterChildCells;
// Update morton index
if(iterChildCells != iterChildEndCells){
currentCellIndex = (*iterChildCells)->getStartingIndex();
else{
currentCellIndex += 1;
}
// If we are at the end of the sub group, move to next
while(iterChildCells != iterChildEndCells && (*iterChildCells)->getEndingIndex() <= currentCellIndex){
++iterChildCells;
// Update morton index
if(iterChildCells != iterChildEndCells && currentCellIndex < (*iterChildCells)->getStartingIndex()){
currentCellIndex = (*iterChildCells)->getStartingIndex();
}
}
}
......
......@@ -15,10 +15,13 @@
#include "../../Src/Utils/FParameterNames.hpp"
#include "../../Src/Components/FTestParticleContainer.hpp"
#include "../../Src/Components/FTestCell.hpp"
#include "../../Src/Components/FTestKernels.hpp"
#include "../Src/GroupTree/FGroupTestParticleContainer.hpp"
#include "../../Src/Core/FFmmAlgorithm.hpp"
int main(int argc, char* argv[]){
const FParameterNames LocalOptionBlocSize {
{"-bs"},
......@@ -30,10 +33,19 @@ int main(int argc, char* argv[]){
// Initialize the types
typedef FTestCell GroupCellClass;
typedef FGroupTestParticleContainer GroupContainerClass;
typedef FSimpleLeaf< GroupContainerClass > LeafClass;
typedef FGroupTree< GroupCellClass, GroupContainerClass, 2, long long int> GroupOctreeClass;
typedef FTestKernels< GroupCellClass, GroupContainerClass > GroupKernelClass;
typedef FGroupSeqAlgorithm<GroupOctreeClass, typename GroupOctreeClass::CellGroupClass, GroupCellClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupContainerClass > GroupAlgorithm;
typedef FTestCell CellClass;
typedef FTestParticleContainer ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass;
typedef FTestKernels< CellClass, ContainerClass > KernelClass;
// FFmmAlgorithmTask FFmmAlgorithmThread
typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass;
// Get params
const int NbLevels = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5);
const int NbParticles = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, 20);
......@@ -42,20 +54,44 @@ int main(int argc, char* argv[]){
// Load the particles
FRandomLoader loader(NbParticles, 1.0, FPoint(0,0,0), 0);
FAssertLF(loader.isOpen());
// Usual octree
OctreeClass tree(NbLevels, 2, loader.getBoxWidth(), loader.getCenterOfBox());
FP2PParticleContainer<> allParticles;
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
FPoint particlePosition;
loader.fillParticle(&particlePosition);
allParticles.push(particlePosition);
tree.insert(particlePosition);
}
// Put the data into the tree
//GroupOctreeClass groupedTree(NbLevels, groupSize, &tree);
GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles);
groupedTree.printInfoBlocks();
// Check tree structure at leaf level
groupedTree.forEachCellLeaf<FGroupTestParticleContainer>([&](GroupCellClass* gcell, FGroupTestParticleContainer* gleaf){
const ContainerClass* src = tree.getLeafSrc(gcell->getMortonIndex());
if(src == nullptr){
std::cout << "[PartEmpty] Error cell should not exist " << gcell->getMortonIndex() << "\n";
}
else {
if(src->getNbParticles() != gleaf->getNbParticles()){
std::cout << "[Part] Nb particles is different at index " << gcell->getMortonIndex() << " is " << gleaf->getNbParticles() << " should be " << src->getNbParticles() << "\n";
}
}
});
// Run the algorithm
GroupKernelClass kernel;
GroupAlgorithm algo(&groupedTree,&kernel);
GroupKernelClass groupkernel;
GroupAlgorithm groupalgo(&groupedTree,&groupkernel);
groupalgo.execute();
// Usual algorithm
KernelClass kernels; // FTestKernels FBasicKernels
FmmClass algo(&tree,&kernels); //FFmmAlgorithm FFmmAlgorithmThread
algo.execute();
// Validate the result
......@@ -74,6 +110,21 @@ int main(int argc, char* argv[]){
}
}
});
// Compare the results
groupedTree.forEachCellWithLevel([&](GroupCellClass* gcell, const int level){
const CellClass* cell = tree.getCell(gcell->getMortonIndex(), level);
if(cell == nullptr){
std::cout << "[Empty] Error cell should not exist " << gcell->getMortonIndex() << "\n";
}
else {
if(gcell->getDataUp() != cell->getDataUp()){
std::cout << "[Up] Up is different at index " << gcell->getMortonIndex() << " level " << level << " is " << gcell->getDataUp() << " should be " << cell->getDataUp() << "\n";
}
if(gcell->getDataDown() != cell->getDataDown()){
std::cout << "[Down] Down is different at index " << gcell->getMortonIndex() << " level " << level << " is " << gcell->getDataDown() << " should be " << cell->getDataDown() << "\n";
}
}
});
return 0;
}
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