// Keep in private GIT // @SCALFMM_PRIVATE #include "../../Src/Utils/FGlobal.hpp" #include "../../Src/GroupTree/Core/FGroupTree.hpp" #include "../../Src/Components/FSimpleLeaf.hpp" #include "../../Src/Containers/FVector.hpp" #include "../../Src/Utils/FMath.hpp" #include "../../Src/Utils/FMemUtils.hpp" #include "../../Src/Utils/FParameters.hpp" #include "../../Src/Files/FRandomLoader.hpp" #include "../../Src/GroupTree/Core/FGroupSeqAlgorithm.hpp" #ifdef SCALFMM_USE_OMP4 #include "../../Src/GroupTree/Core/FGroupTaskDepAlgorithm.hpp" #endif #ifdef SCALFMM_USE_STARPU #include "../../Src/GroupTree/Core/FGroupTaskStarpuAlgorithm.hpp" #include "../../Src/GroupTree/StarPUUtils/FStarPUKernelCapacities.hpp" #include "../../Src/GroupTree/StarPUUtils/FStarPUCpuWrapper.hpp" #endif #include "../../Src/GroupTree/Core/FP2PGroupParticleContainer.hpp" #include "../../Src/GroupTree/Core/FGroupTaskAlgorithm.hpp" #include "../../Src/Utils/FParameterNames.hpp" #include "../../Src/Components/FTestParticleContainer.hpp" #include "../../Src/Components/FTestCell.hpp" #include "../../Src/Components/FTestKernels.hpp" #include "../../Src/GroupTree/TestKernel/FGroupTestParticleContainer.hpp" #include "../../Src/GroupTree/TestKernel/FTestCellPOD.hpp" #include "../../Src/Files/FFmaGenericLoader.hpp" #include "../../Src/Core/FFmmAlgorithm.hpp" int main(int argc, char* argv[]){ setenv("STARPU_NCPU","1",1); const FParameterNames LocalOptionBlocSize { {"-bs"}, "The size of the block of the blocked tree" }; FHelpDescribeAndExit(argc, argv, "Test the blocked tree by counting the particles.", FParameterDefinitions::OctreeHeight, FParameterDefinitions::NbParticles, FParameterDefinitions::OctreeSubHeight, LocalOptionBlocSize); typedef double FReal; // Initialize the types typedef FTestCellPODCore GroupCellSymbClass; typedef FTestCellPODData GroupCellUpClass; typedef FTestCellPODData GroupCellDownClass; typedef FTestCellPOD GroupCellClass; typedef FGroupTestParticleContainer GroupContainerClass; typedef FGroupTree< FReal, GroupCellClass, GroupCellSymbClass, GroupCellUpClass, GroupCellDownClass, GroupContainerClass, 0, 1, long long int> GroupOctreeClass; #ifdef SCALFMM_USE_STARPU typedef FStarPUAllCpuCapacities> GroupKernelClass; typedef FStarPUCpuWrapper GroupCpuWrapper; typedef FGroupTaskStarPUAlgorithm GroupAlgorithm; #elif defined(SCALFMM_USE_OMP4) typedef FTestKernels< GroupCellClass, GroupContainerClass > GroupKernelClass; typedef FGroupTaskDepAlgorithm GroupAlgorithm; #else typedef FTestKernels< GroupCellClass, GroupContainerClass > GroupKernelClass; //typedef FGroupSeqAlgorithm GroupAlgorithm; typedef FGroupTaskAlgorithm GroupAlgorithm; #endif typedef FTestCell CellClass; typedef FTestParticleContainer ContainerClass; typedef FSimpleLeaf LeafClass; typedef FOctree OctreeClass; typedef FTestKernels< CellClass, ContainerClass > KernelClass; // FFmmAlgorithmTask FFmmAlgorithmThread typedef FFmmAlgorithm FmmClass; // Get params const int NbLevels = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5); const int groupSize = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 250); //#define LOAD_FILE #ifndef LOAD_FILE const FSize NbParticles = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, FSize(20)); FRandomLoader loader(NbParticles, 1.0, FPoint(0,0,0), 0); #else // Load the particles const char* const filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, "../Data/test20k.fma"); FFmaGenericLoader loader(filename); #endif FAssertLF(loader.isOpen()); // Usual octree OctreeClass tree(NbLevels, FParameters::getValue(argc,argv,FParameterDefinitions::OctreeSubHeight.options, 2), loader.getBoxWidth(), loader.getCenterOfBox()); FTestParticleContainer allParticles; for(FSize idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){ FPoint particlePosition; #ifndef LOAD_FILE loader.fillParticle(&particlePosition); #else FReal ph; loader.fillParticle(&particlePosition, &ph); #endif 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); //GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles, false, true); GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles, false, true, 0.2); groupedTree.printInfoBlocks(); // Check tree structure at leaf level groupedTree.forEachCellLeaf([&](GroupCellClass gcell, GroupContainerClass* 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 groupkernel; GroupAlgorithm groupalgo(&groupedTree,&groupkernel); groupalgo.execute(); // Usual algorithm KernelClass kernels; // FTestKernels FBasicKernels FmmClass algo(&tree,&kernels); //FFmmAlgorithm FFmmAlgorithmThread algo.execute(); // Validate the result groupedTree.forEachCellLeaf([&](GroupCellClass cell, GroupContainerClass* leaf){ const FSize nbPartsInLeaf = leaf->getNbParticles(); if(cell.getDataUp() != nbPartsInLeaf){ std::cout << "[P2M] Error a Cell has " << cell.getDataUp() << " (it should be " << nbPartsInLeaf << ")\n"; } }); groupedTree.forEachCellLeaf([&](GroupCellClass cell, GroupContainerClass* leaf){ const FSize nbPartsInLeaf = leaf->getNbParticles(); const long long int* dataDown = leaf->getDataDown(); for(FSize idxPart = 0 ; idxPart < nbPartsInLeaf ; ++idxPart){ if(dataDown[idxPart] != loader.getNumberOfParticles()-1){ std::cout << "[Full] Error a particle has " << dataDown[idxPart] << " (it should be " << (loader.getNumberOfParticles()-1) << ") at index " << cell.getMortonIndex() << "\n"; } } }); // 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; }