Commit 2a73d7a0 authored by BRAMAS Berenger's avatar BRAMAS Berenger
Browse files

Add a test for cuda and offsetof to know member positions

parent ba4aad0b
......@@ -19,6 +19,9 @@
#include <cstddef>
#include "FBasicCell.hpp"
// To get access to descriptors
struct FTestCellDescriptor;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FBasicCell*
......@@ -111,6 +114,9 @@ public:
int getSavedSizeUp() {
return int(sizeof(long long int));
}
// To get access to descriptor
friend struct FTestCellDescriptor;
};
......
......@@ -6,9 +6,17 @@
// We need to describe this cell
#include "../../Components/FTestCell.hpp"
#include "../../Utils/FOffetOf.hpp"
struct FTestCellDescriptor{
static const int offset_up = 0;
static const int offset_mortonIndex = FOffsetOf(FTestCell, mortonIndex);
static const int offset_FTreeCoordinate_data = FOffsetOf(FTestCell, coordinate);
static const int offset_dataUp = FOffsetOf(FTestCell, dataUp);
static const int offset_dataDown = FOffsetOf(FTestCell, dataDown);
static const int size = alignof(FTestCell)*((offset_dataDown + sizeof(FTestCell::dataDown) + alignof(FTestCell) - 1)/alignof(FTestCell));
static_assert(size == sizeof(FTestCell), "Error in attribute shift.");
};
template< class ContainerClass >
......
// @SCALFMM_PRIVATE
#ifndef FOFFETOF_HPP
#define FOFFETOF_HPP
//#define FOffsetOf(Type,Member) reinterpret_cast<std::size_t>(&((reinterpret_cast<Type*>(0xF00))->Member)) - std::size_t(0xF00)
#define FOffsetOf(Type,Member) offsetof(Type,Member)
#endif // FOFFETOF_HPP
// Keep in private GIT
// @SCALFMM_PRIVATE
// @FUSE_STARPU
// @FUSE_CUDA
#include "../../Src/Utils/FGlobal.hpp"
#include "../../Src/GroupTree/FGroupTree.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Containers/FVector.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"
#include "../../Src/Utils/FMath.hpp"
#include "../../Src/Utils/FMemUtils.hpp"
#include "../../Src/Utils/FParameters.hpp"
#include "../../Src/Files/FRandomLoader.hpp"
#include "../../Src/GroupTree/FGroupSeqAlgorithm.hpp"
#include "../../Src/GroupTree/FGroupTaskStarpuAlgorithm.hpp"
#include "../../Src/GroupTree/FP2PGroupParticleContainer.hpp"
#include "../../Src/GroupTree/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/FGroupTestParticleContainer.hpp"
#include "../../Src/Files/FFmaGenericLoader.hpp"
#include "../../Src/Core/FFmmAlgorithm.hpp"
#include "../../Src/GroupTree/FStarPUKernelCapacities.hpp"
//#include "../../Src/GroupTree/Cuda/FCudaTestKernels.hpp"
//#include "../../Src/GroupTree/Cuda/FCudaGroupOfParticles.hpp"
//#include "../../Src/GroupTree/Cuda/FCudaGroupAttachedLeaf.hpp"
#include "../../Src/GroupTree/Cuda/FCudaGroupOfCells.hpp"
template <class ContainerClass>
class FTestCudaKernels;
template <unsigned NbAttributesPerParticle, class AttributeClass>
class FCudaGroupAttachedLeaf;
template <unsigned NbAttributesPerParticle, class AttributeClass>
class FCudaGroupOfParticles;
template <const size_t CellClassSize>
class FCudaGroupOfCells;
int main(int argc, char* argv[]){
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::NbThreads,
FParameterDefinitions::NbParticles, LocalOptionBlocSize);
// Initialize the types
typedef FTestCell GroupCellClass;
typedef FGroupTestParticleContainer GroupContainerClass;
typedef FGroupTree< GroupCellClass, GroupContainerClass, 2, long long int> GroupOctreeClass;
typedef FStarPUAllYesCapacities<FTestKernels< GroupCellClass, GroupContainerClass >> GroupKernelClass;
typedef FGroupTaskStarPUAlgorithm<GroupOctreeClass, typename GroupOctreeClass::CellGroupClass, GroupCellClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupContainerClass
, FCudaGroupOfCells<sizeof(FTestCell)>, FCudaGroupOfParticles<2, long long int>, FCudaGroupAttachedLeaf<2, long long int>, FTestCudaKernels< FCudaGroupAttachedLeaf<2, long long int> > > 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 groupSize = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 250);
//#define LOAD_FILE
#ifndef LOAD_FILE
const int NbParticles = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, 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, 2, loader.getBoxWidth(), loader.getCenterOfBox());
FP2PParticleContainer<> allParticles;
for(int 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);
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 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<FGroupTestParticleContainer>([&](GroupCellClass* cell, FGroupTestParticleContainer* leaf){
const int nbPartsInLeaf = leaf->getNbParticles();
if(cell->getDataUp() != nbPartsInLeaf){
std::cout << "[P2M] Error a Cell has " << cell->getDataUp() << " (it should be " << nbPartsInLeaf << ")\n";
}
});
groupedTree.forEachCellLeaf<FGroupTestParticleContainer>([&](GroupCellClass* cell, FGroupTestParticleContainer* leaf){
const int nbPartsInLeaf = leaf->getNbParticles();
const long long int* dataDown = leaf->getDataDown();
for(int 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;
}
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