Commit cc21eddf authored by BRAMAS Berenger's avatar BRAMAS Berenger

First stage in the dissociation of symbilic and computational data

parent 0e7cc53c
......@@ -47,8 +47,13 @@ public:
positionsPointers[2] = reinterpret_cast<FReal*>(reinterpret_cast<unsigned char*>(inPositionBuffer) + inLeadingPosition*2);
// Redirect pointers to data
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
attributes[idxAttribute] = reinterpret_cast<AttributeClass*>(reinterpret_cast<unsigned char*>(inAttributesBuffer) + idxAttribute*inLeadingAttributes);
if(inAttributesBuffer){
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
attributes[idxAttribute] = reinterpret_cast<AttributeClass*>(reinterpret_cast<unsigned char*>(inAttributesBuffer) + idxAttribute*inLeadingAttributes);
}
}
else{
memset(attributes, 0, sizeof(AttributeClass*)*NbAttributesPerParticle);
}
}
......
......@@ -15,7 +15,7 @@
/**
* @brief The FGroupOfCells class manages the cells in block allocation.
*/
template <class CellClass>
template <class CompositeCellClass, class SymboleCellClass, class PoleCellClass, class LocalCellClass>
class FGroupOfCells {
/** One header is allocated at the beginning of each block */
struct alignas(FStarPUDefaultAlign::StructAlign) BlockHeader{
......@@ -36,35 +36,49 @@ protected:
//< Pointer to the indexes table inside the block memory
int* blockIndexesTable;
//< Pointer to the cells inside the block memory
CellClass* blockCells;
SymboleCellClass* blockCells;
//< This value is for not used cells
static const MortonIndex CellIsEmptyFlag = -1;
//< The multipole data
PoleCellClass* cellMultipoles;
//< The local data
LocalCellClass* cellLocals;
//< To kown if the object has to delete the memory
bool deleteBuffer;
public:
typedef CompositeCellClass CompleteCellClass;
FGroupOfCells()
: allocatedMemoryInByte(0), memoryBuffer(nullptr),
blockHeader(nullptr), blockIndexesTable(nullptr), blockCells(nullptr),
deleteBuffer(false){
cellMultipoles(nullptr), cellLocals(nullptr), deleteBuffer(false){
}
void reset(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte){
void reset(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte,
unsigned char* inCellMultipoles, unsigned char* inCellLocals){
if(deleteBuffer){
for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
(&blockCells[blockIndexesTable[idxCellPtr]])->~CellClass();
(&blockCells[blockIndexesTable[idxCellPtr]])->~SymboleCellClass();
(&cellMultipoles[blockIndexesTable[idxCellPtr]])->~PoleCellClass();
(&cellLocals[blockIndexesTable[idxCellPtr]])->~LocalCellClass();
}
}
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(cellMultipoles);
FAlignedMemory::Dealloc32BAligned(cellLocals);
}
// Move the pointers to the correct position
allocatedMemoryInByte = (inAllocatedMemoryInByte);
memoryBuffer = (inBuffer);
blockHeader = reinterpret_cast<BlockHeader*>(memoryBuffer);
blockIndexesTable = reinterpret_cast<int*>(memoryBuffer+sizeof(BlockHeader));
blockCells = reinterpret_cast<CellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockHeader->blockIndexesTableSize*sizeof(int)));
blockCells = reinterpret_cast<SymboleCellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockHeader->blockIndexesTableSize*sizeof(int)));
cellMultipoles = (PoleCellClass*)inCellMultipoles;
cellLocals = (LocalCellClass*)inCellLocals;
deleteBuffer = (false);
}
......@@ -73,14 +87,17 @@ public:
* @param inBuffer
* @param inAllocatedMemoryInByte
*/
FGroupOfCells(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte)
FGroupOfCells(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte,
unsigned char* inCellMultipoles, unsigned char* inCellLocals)
: allocatedMemoryInByte(inAllocatedMemoryInByte), memoryBuffer(inBuffer),
blockHeader(nullptr), blockIndexesTable(nullptr), blockCells(nullptr),
deleteBuffer(false){
cellMultipoles(nullptr), cellLocals(nullptr), deleteBuffer(false){
// Move the pointers to the correct position
blockHeader = reinterpret_cast<BlockHeader*>(memoryBuffer);
blockIndexesTable = reinterpret_cast<int*>(memoryBuffer+sizeof(BlockHeader));
blockCells = reinterpret_cast<CellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockHeader->blockIndexesTableSize*sizeof(int)));
blockCells = reinterpret_cast<SymboleCellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockHeader->blockIndexesTableSize*sizeof(int)));
cellMultipoles = (PoleCellClass*)inCellMultipoles;
cellLocals = (LocalCellClass*)inCellLocals;
}
/**
......@@ -91,12 +108,12 @@ public:
*/
FGroupOfCells(const MortonIndex inStartingIndex, const MortonIndex inEndingIndex, const int inNumberOfCells)
: allocatedMemoryInByte(0), memoryBuffer(nullptr), blockHeader(nullptr), blockIndexesTable(nullptr), blockCells(nullptr),
deleteBuffer(true){
cellMultipoles(nullptr), cellLocals(nullptr), deleteBuffer(true){
// Find the number of cell to allocate in the blocks
const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex);
FAssertLF(inNumberOfCells <= blockIndexesTableSize);
// Total number of bytes in the block
const size_t memoryToAlloc = sizeof(BlockHeader) + (blockIndexesTableSize*sizeof(int)) + (inNumberOfCells*sizeof(CellClass));
const size_t memoryToAlloc = sizeof(BlockHeader) + (blockIndexesTableSize*sizeof(int)) + (inNumberOfCells*sizeof(SymboleCellClass));
// Allocate
FAssertLF(0 <= int(memoryToAlloc) && int(memoryToAlloc) < std::numeric_limits<int>::max());
......@@ -108,7 +125,7 @@ public:
// Move the pointers to the correct position
blockHeader = reinterpret_cast<BlockHeader*>(memoryBuffer);
blockIndexesTable = reinterpret_cast<int*>(memoryBuffer+sizeof(BlockHeader));
blockCells = reinterpret_cast<CellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockIndexesTableSize*sizeof(int)));
blockCells = reinterpret_cast<SymboleCellClass*>(memoryBuffer+sizeof(BlockHeader)+(blockIndexesTableSize*sizeof(int)));
// Init header
blockHeader->startingIndex = inStartingIndex;
......@@ -116,6 +133,13 @@ public:
blockHeader->numberOfCellsInBlock = inNumberOfCells;
blockHeader->blockIndexesTableSize = blockIndexesTableSize;
cellMultipoles = (PoleCellClass*)FAlignedMemory::Allocate32BAligned(inNumberOfCells*sizeof(PoleCellClass));
cellLocals = (LocalCellClass*)FAlignedMemory::Allocate32BAligned(inNumberOfCells*sizeof(LocalCellClass));
for(int idxCell = 0 ; idxCell < inNumberOfCells ; ++idxCell){
new (&cellMultipoles[idxCell]) PoleCellClass();
new (&cellLocals[idxCell]) LocalCellClass();
}
// Set all index to not used
for(int idxCellPtr = 0 ; idxCellPtr < blockIndexesTableSize ; ++idxCellPtr){
blockIndexesTable[idxCellPtr] = CellIsEmptyFlag;
......@@ -127,10 +151,14 @@ public:
if(deleteBuffer){
for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
(&blockCells[blockIndexesTable[idxCellPtr]])->~CellClass();
(&blockCells[blockIndexesTable[idxCellPtr]])->~SymboleCellClass();
(&cellMultipoles[blockIndexesTable[idxCellPtr]])->~PoleCellClass();
(&cellLocals[blockIndexesTable[idxCellPtr]])->~LocalCellClass();
}
}
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(cellMultipoles);
FAlignedMemory::Dealloc32BAligned(cellLocals);
}
}
......@@ -144,6 +172,26 @@ public:
return allocatedMemoryInByte;
}
/** Give access to the buffer to send the data */
const PoleCellClass* getRawMultipoleBuffer() const{
return cellMultipoles;
}
/** The the size of the allocated buffer */
int getMultipoleBufferSizeInByte() const {
return sizeof(PoleCellClass)*blockHeader->numberOfCellsInBlock;
}
/** Give access to the buffer to send the data */
const LocalCellClass* getRawLocalBuffer() const{
return cellLocals;
}
/** The the size of the allocated buffer */
int getLocalBufferSizeInByte() const {
return sizeof(LocalCellClass)*blockHeader->numberOfCellsInBlock;
}
/** To know if the object will delete the memory block */
bool getDeleteMemory() const{
return deleteBuffer;
......@@ -180,15 +228,33 @@ public:
}
/** Return the address of the cell if it exists (or NULL) */
CellClass* getCell(const MortonIndex inIndex){
if( exists(inIndex) ) return &blockCells[blockIndexesTable[inIndex-blockHeader->startingIndex]];
else return nullptr;
CompositeCellClass getCompleteCell(const MortonIndex inIndex){
FAssertLF(cellMultipoles && cellLocals);
if( exists(inIndex) ){
const int cellPos = blockIndexesTable[inIndex-blockHeader->startingIndex];
return CompositeCellClass(&blockCells[cellPos], &cellMultipoles[cellPos], &cellLocals[cellPos]);
}
else return CompositeCellClass();
}
/** Return the address of the cell if it exists (or NULL) */
const CellClass* getCell(const MortonIndex inIndex) const {
if( exists(inIndex) ) return &blockCells[blockIndexesTable[inIndex-blockHeader->startingIndex]];
else return nullptr;
CompositeCellClass getUpCell(const MortonIndex inIndex){
FAssertLF(cellMultipoles);
if( exists(inIndex) ){
const int cellPos = blockIndexesTable[inIndex-blockHeader->startingIndex];
return CompositeCellClass(&blockCells[cellPos], &cellMultipoles[cellPos], nullptr);
}
else return CompositeCellClass();
}
/** Return the address of the cell if it exists (or NULL) */
CompositeCellClass getDownCell(const MortonIndex inIndex){
FAssertLF(cellLocals);
if( exists(inIndex) ){
const int cellPos = blockIndexesTable[inIndex-blockHeader->startingIndex];
return CompositeCellClass(&blockCells[cellPos], nullptr, &cellLocals[cellPos]);
}
else return CompositeCellClass();
}
/** Allocate a new cell by calling its constructor */
......@@ -197,24 +263,26 @@ public:
FAssertLF(isInside(inIndex));
FAssertLF(!exists(inIndex));
FAssertLF(id < blockHeader->blockIndexesTableSize);
new((void*)&blockCells[id]) CellClass(args...);
new((void*)&blockCells[id]) SymboleCellClass(args...);
blockIndexesTable[inIndex-blockHeader->startingIndex] = id;
}
/** Iterate on each allocated cells */
template<typename... FunctionParams>
void forEachCell(std::function<void(CellClass*, FunctionParams...)> function, FunctionParams... args){
void forEachCell(std::function<void(CompositeCellClass, FunctionParams...)> function, FunctionParams... args){
for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
function(&blockCells[blockIndexesTable[idxCellPtr]], args...);
const int cellPos = blockIndexesTable[idxCellPtr];
function(CompositeCellClass(&blockCells[cellPos], &cellMultipoles[cellPos], &cellLocals[cellPos]), args...);
}
}
}
void forEachCell(std::function<void(CellClass*)> function){
void forEachCell(std::function<void(CompositeCellClass)> function){
for(int idxCellPtr = 0 ; idxCellPtr < blockHeader->blockIndexesTableSize ; ++idxCellPtr){
if(blockIndexesTable[idxCellPtr] != CellIsEmptyFlag){
function(&blockCells[blockIndexesTable[idxCellPtr]]);
const int cellPos = blockIndexesTable[idxCellPtr];
function(CompositeCellClass(&blockCells[cellPos], &cellMultipoles[cellPos], &cellLocals[cellPos]));
}
}
}
......
......@@ -78,7 +78,8 @@ protected:
FReal* particlePosition[3];
//< Pointers to the particles data inside the block memory
AttributeClass* particleAttributes[NbAttributesPerParticle];
AttributeClass* attributesBuffer;
AttributeClass* particleAttributes[NbAttributesPerParticle];
/** To know if we have to delete the buffer */
bool deleteBuffer;
......@@ -89,10 +90,11 @@ public:
* @param inBuffer
* @param inAllocatedMemoryInByte
*/
FGroupOfParticles(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte)
FGroupOfParticles(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte,
unsigned char* inAttributes)
: allocatedMemoryInByte(inAllocatedMemoryInByte), memoryBuffer(inBuffer),
blockHeader(nullptr), blockIndexesTable(nullptr), leafHeader(nullptr), nbParticlesInGroup(0),
deleteBuffer(false){
attributesBuffer(nullptr), deleteBuffer(false){
// Move the pointers to the correct position
blockHeader = reinterpret_cast<BlockHeader*>(memoryBuffer);
blockIndexesTable = reinterpret_cast<int*>(memoryBuffer+sizeof(BlockHeader));
......@@ -107,10 +109,11 @@ public:
// Redirect pointer to data
blockHeader->attributeOffset = (sizeof(AttributeClass) * blockHeader->nbParticlesAllocatedInGroup);
unsigned char* previousPointer = reinterpret_cast<unsigned char*>(particlePosition[2] + blockHeader->nbParticlesAllocatedInGroup);
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
particleAttributes[idxAttribute] = reinterpret_cast<AttributeClass*>(previousPointer);
previousPointer += sizeof(AttributeClass)*blockHeader->nbParticlesAllocatedInGroup;
if(inAttributes){
attributesBuffer = (AttributeClass*)inAttributes;
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
particleAttributes[idxAttribute] = &attributesBuffer[idxAttribute*(blockHeader->nbParticlesAllocatedInGroup/sizeof(AttributeClass))];
}
}
}
......@@ -132,7 +135,7 @@ public:
const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex);
FAssertLF(inNumberOfLeaves <= blockIndexesTableSize);
// Total number of bytes in the block
const size_t sizeOfOneParticle = (3*sizeof(FReal) + NbAttributesPerParticle*sizeof(AttributeClass));
const size_t sizeOfOneParticle = (3*sizeof(FReal));
const size_t memoryToAlloc = sizeof(BlockHeader)
+ (blockIndexesTableSize*sizeof(int))
+ (inNumberOfLeaves*sizeof(LeafHeader))
......@@ -166,10 +169,11 @@ public:
// Redirect pointer to data
blockHeader->attributeOffset = (sizeof(AttributeClass) * nbParticlesAllocatedInGroup);
unsigned char* previousPointer = reinterpret_cast<unsigned char*>(particlePosition[2] + nbParticlesAllocatedInGroup);
attributesBuffer = (AttributeClass*)FAlignedMemory::Allocate32BAligned(blockHeader->attributeOffset*NbAttributesPerParticle);
memset(attributesBuffer, 0, blockHeader->attributeOffset*NbAttributesPerParticle);
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
particleAttributes[idxAttribute] = reinterpret_cast<AttributeClass*>(previousPointer);
previousPointer += sizeof(AttributeClass)*nbParticlesAllocatedInGroup;
particleAttributes[idxAttribute] = &attributesBuffer[idxAttribute*(blockHeader->nbParticlesAllocatedInGroup/sizeof(AttributeClass))];
}
// Set all index to not used
......@@ -182,6 +186,7 @@ public:
~FGroupOfParticles(){
if(deleteBuffer){
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(attributesBuffer);
}
}
......@@ -195,6 +200,16 @@ public:
return allocatedMemoryInByte;
}
/** Give access to the buffer to send the data */
const AttributeClass* getRawAttributesBuffer() const{
return attributesBuffer;
}
/** The the size of the allocated buffer */
int getAttributesBufferSizeInByte() const {
return blockHeader->attributeOffset*NbAttributesPerParticle;
}
/** To know if the object will delete the memory block */
bool getDeleteMemory() const{
return deleteBuffer;
......
......@@ -17,12 +17,13 @@
template <class CellClass, class GroupAttachedLeafClass, unsigned NbAttributesPerParticle, class AttributeClass = FReal>
template <class CompositeCellClass, class SymboleCellClass, class PoleCellClass, class LocalCellClass,
class GroupAttachedLeafClass, unsigned NbAttributesPerParticle, class AttributeClass = FReal>
class FGroupTree {
public:
typedef GroupAttachedLeafClass BasicAttachedClass;
typedef FGroupOfParticles<NbAttributesPerParticle,AttributeClass> ParticleGroupClass;
typedef FGroupOfCells<CellClass> CellGroupClass;
typedef FGroupOfCells<CompositeCellClass, SymboleCellClass, PoleCellClass, LocalCellClass> CellGroupClass;
protected:
//< This value is for not used cells
......@@ -78,7 +79,7 @@ public:
* Once allocated each cell receive its morton index and tree coordinate.
* No blocks are allocated at level 0.
*/
template<class OctreeClass>
template<class OctreeClass, class CellClass>
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)),
......@@ -119,9 +120,9 @@ public:
const CellClass*const oldNode = blockIteratorInOctree.getCurrentCell();
newBlock->newCell(oldNode->getMortonIndex(), cellIdInBlock);
CellClass* newNode = newBlock->getCell(oldNode->getMortonIndex());
newNode->setMortonIndex(oldNode->getMortonIndex());
newNode->setCoordinate(oldNode->getCoordinate());
CompositeCellClass newNode = newBlock->getCompleteCell(oldNode->getMortonIndex());
newNode.setMortonIndex(oldNode->getMortonIndex());
newNode.setCoordinate(oldNode->getCoordinate());
// Add leaf
nbParticlesOffsetBeforeLeaf = newParticleBlock->newLeaf(oldNode->getMortonIndex(), cellIdInBlock,
......@@ -168,9 +169,9 @@ public:
const CellClass*const oldNode = blockIteratorInOctree.getCurrentCell();
newBlock->newCell(oldNode->getMortonIndex(), cellIdInBlock);
CellClass* newNode = newBlock->getCell(oldNode->getMortonIndex());
newNode->setMortonIndex(oldNode->getMortonIndex());
newNode->setCoordinate(oldNode->getCoordinate());
CompositeCellClass newNode = newBlock->getCompleteCell(oldNode->getMortonIndex());
newNode.setMortonIndex(oldNode->getMortonIndex());
newNode.setCoordinate(oldNode->getCoordinate());
cellIdInBlock += 1;
blockIteratorInOctree.moveRight();
......@@ -274,11 +275,11 @@ public:
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CellClass* newNode = newBlock->getCell(currentBlockIndexes[cellIdInBlock]);
newNode->setMortonIndex(currentBlockIndexes[cellIdInBlock]);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode->setCoordinate(coord);
newNode.setCoordinate(coord);
// Add leaf
nbParticlesOffsetBeforeLeaf = newParticleBlock->newLeaf(currentBlockIndexes[cellIdInBlock], cellIdInBlock,
......@@ -344,11 +345,11 @@ public:
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CellClass* newNode = newBlock->getCell(currentBlockIndexes[cellIdInBlock]);
newNode->setMortonIndex(currentBlockIndexes[cellIdInBlock]);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode->setCoordinate(coord);
newNode.setCoordinate(coord);
}
// Keep the block
......@@ -453,11 +454,11 @@ public:
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CellClass* newNode = newBlock->getCell(currentBlockIndexes[cellIdInBlock]);
newNode->setMortonIndex(currentBlockIndexes[cellIdInBlock]);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode->setCoordinate(coord);
newNode.setCoordinate(coord);
// Add leaf
nbParticlesOffsetBeforeLeaf = newParticleBlock->newLeaf(currentBlockIndexes[cellIdInBlock], cellIdInBlock,
......@@ -537,11 +538,11 @@ public:
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CellClass* newNode = newBlock->getCell(currentBlockIndexes[cellIdInBlock]);
newNode->setMortonIndex(currentBlockIndexes[cellIdInBlock]);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode->setCoordinate(coord);
newNode.setCoordinate(coord);
}
// Keep the block
......@@ -589,7 +590,7 @@ public:
* @brief forEachLeaf iterate on the cell and apply the function
* @param function
*/
void forEachCell(std::function<void(CellClass*)> function){
void forEachCell(std::function<void(CompositeCellClass)> function){
for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
std::vector<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel];
for (CellGroupClass* block: levelBlocks){
......@@ -602,7 +603,7 @@ public:
* @brief forEachLeaf iterate on the cell and apply the function
* @param function
*/
void forEachCellWithLevel(std::function<void(CellClass*,const int)> function){
void forEachCellWithLevel(std::function<void(CompositeCellClass,const int)> function){
for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
std::vector<CellGroupClass*>& levelBlocks = cellBlocksPerLevel[idxLevel];
for (CellGroupClass* block: levelBlocks){
......@@ -616,7 +617,7 @@ public:
* @param function
*/
template<class ParticlesAttachedClass>
void forEachCellLeaf(std::function<void(CellClass*,ParticlesAttachedClass*)> function){
void forEachCellLeaf(std::function<void(CompositeCellClass,ParticlesAttachedClass*)> function){
CellGroupIterator iterCells = cellBlocksPerLevel[treeHeight-1].begin();
const CellGroupIterator iterEndCells = cellBlocksPerLevel[treeHeight-1].end();
......@@ -624,8 +625,8 @@ public:
const ParticleGroupIterator iterEndLeaves = particleBlocks.end();
while(iterCells != iterEndCells && iterLeaves != iterEndLeaves){
(*iterCells)->forEachCell([&](CellClass* aCell){
ParticlesAttachedClass aLeaf = (*iterLeaves)->template getLeaf <ParticlesAttachedClass>(aCell->getMortonIndex());
(*iterCells)->forEachCell([&](CompositeCellClass aCell){
ParticlesAttachedClass aLeaf = (*iterLeaves)->template getLeaf <ParticlesAttachedClass>(aCell.getMortonIndex());
FAssertLF(aLeaf.isAttachedToSomething());
function(aCell, &aLeaf);
});
......
......@@ -7,76 +7,85 @@
#include "../StarPUUtils/FStarPUDefaultAlign.hpp"
struct alignas(FStarPUDefaultAlign::StructAlign) FTestCellPODCore {
FTestCellPODCore(){
mortonIndex = (0);
coordinates[0] = 0;
coordinates[1] = 0;
coordinates[2] = 0;
}
MortonIndex mortonIndex;
int coordinates[3];
long long int dataUp, dataDown;
};
class alignas(FStarPUDefaultAlign::StructAlign) FTestCellPOD {
typedef long long FTestCellPODData;
class FTestCellPOD {
protected:
FTestCellPODCore data;
FTestCellPODCore* symb;
FTestCellPODData* up;
FTestCellPODData* down;
public:
FTestCellPOD() {
data.mortonIndex = (0);
data.dataUp = (0);
data.dataDown = (0);
data.coordinates[0] = 0;
data.coordinates[1] = 0;
data.coordinates[2] = 0;
FTestCellPOD(FTestCellPODCore* inSymb, FTestCellPODData* inUp,
FTestCellPODData* inDown)
: symb(inSymb), up(inUp), down(inDown){
}
FTestCellPOD()
: symb(nullptr), up(nullptr), down(nullptr){
}
/** To get the morton index */
MortonIndex getMortonIndex() const {
return data.mortonIndex;
return symb->mortonIndex;
}
/** To set the morton index */
void setMortonIndex(const MortonIndex inMortonIndex) {
data.mortonIndex = inMortonIndex;
symb->mortonIndex = inMortonIndex;
}
/** To get the position */
FTreeCoordinate getCoordinate() const {
return FTreeCoordinate(data.coordinates[0],
data.coordinates[1], data.coordinates[2]);
return FTreeCoordinate(symb->coordinates[0],
symb->coordinates[1], symb->coordinates[2]);
}
/** To set the position */
void setCoordinate(const FTreeCoordinate& inCoordinate) {
data.coordinates[0] = inCoordinate.getX();
data.coordinates[1] = inCoordinate.getY();
data.coordinates[2] = inCoordinate.getZ();
symb->coordinates[0] = inCoordinate.getX();
symb->coordinates[1] = inCoordinate.getY();
symb->coordinates[2] = inCoordinate.getZ();
}
/** To set the position from 3 FReals */
void setCoordinate(const int inX, const int inY, const int inZ) {
data.coordinates[0] = inX;
data.coordinates[1] = inY;
data.coordinates[2] = inZ;
symb->coordinates[0] = inX;
symb->coordinates[1] = inY;
symb->coordinates[2] = inZ;
}
/** When doing the upward pass */
long long int getDataUp() const {
return data.dataUp;
return (*up);
}
/** When doing the upward pass */
void setDataUp(const long long int inData){
data.dataUp = inData;
(*up) = inData;
}
/** When doing the downard pass */
long long int getDataDown() const {
return data.dataDown;
return (*down);
}
/** When doing the downard pass */
void setDataDown(const long long int inData){
data.dataDown = inData;
(*down) = inData;
}
/** Make it like the begining */
void resetToInitialState(){
data.dataDown = 0;
data.dataUp = 0;
(*down) = 0;
(*up) = 0;
}
/////////////////////////////////////////////////
......@@ -84,23 +93,23 @@ public:
/** Save the current cell in a buffer */
template <class BufferWriterClass>
void save(BufferWriterClass& buffer) const{
buffer << data.mortonIndex << data.coordinates[0]
<< data.coordinates[1] << data.coordinates[2];
buffer << data.dataDown << data.dataUp;
buffer << symb->mortonIndex << symb->coordinates[0]
<< symb->coordinates[1] << symb->coordinates[2];
buffer << (*down) << (*up);
}