Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
solverstack
ScalFMM
Commits
648e2966
Commit
648e2966
authored
Apr 03, 2015
by
BRAMAS Berenger
Browse files
Add dynanimc block tree and a test
parent
b37776ec
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Src/GroupTree/Core/FGroupAttachedLeafDyn.hpp
0 → 100644
View file @
648e2966
// @SCALFMM_PRIVATE
#ifndef FGROUPATTACHEDLEAFDYN_HPP
#define FGROUPATTACHEDLEAFDYN_HPP
#include "../../Utils/FGlobal.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FPoint.hpp"
template
<
class
FReal
>
struct
UnknownDescriptor
{
FPoint
<
FReal
>
pos
;
FSize
originalIndex
;
MortonIndex
mindex
;
};
template
<
class
FReal
>
class
FGroupAttachedLeafDyn
{
protected:
unsigned
char
*
symbPart
;
unsigned
char
*
downPart
;
public:
/** Empty constructor to point to nothing */
FGroupAttachedLeafDyn
()
:
symbPart
(
nullptr
),
downPart
(
nullptr
)
{
}
FGroupAttachedLeafDyn
(
unsigned
char
*
inSymbPart
,
unsigned
char
*
inDownPart
)
:
symbPart
(
inSymbPart
),
downPart
(
inDownPart
){
}
const
unsigned
char
*
getSymbPart
()
const
{
return
symbPart
;
}
unsigned
char
*
getSymbPart
()
{
return
symbPart
;
}
const
unsigned
char
*
getDownPart
()
const
{
return
downPart
;
}
unsigned
char
*
getDownPart
()
{
return
downPart
;
}
/** Return true if it has been attached to a memoy block */
bool
isAttachedToSomething
()
const
{
return
symbPart
!=
nullptr
;
}
/** Allocate a new leaf by calling its constructor */
template
<
class
ParticleClassContainer
>
void
copyFromContainer
(
const
MortonIndex
/*inMindex*/
,
const
ParticleClassContainer
*
/*particles*/
){
static_assert
(
sizeof
(
ParticleClassContainer
)
==
0
,
"copyFromContainer should be implemented by the subclass"
);
}
virtual
void
init
(
const
MortonIndex
inIndex
,
const
UnknownDescriptor
<
FReal
>
inParticles
[],
const
FSize
inNbParticles
,
const
size_t
inSymbSize
,
const
size_t
inDownSize
)
=
0
;
};
#endif // FGROUPATTACHEDLEAFDYN_HPP
Src/GroupTree/Core/FGroupOfCellsDyn.hpp
0 → 100644
View file @
648e2966
// @SCALFMM_PRIVATE
#ifndef FGROUPOFCELLSDYN_HPP
#define FGROUPOFCELLSDYN_HPP
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../../Containers/FTreeCoordinate.hpp"
#include "../StarPUUtils/FStarPUDefaultAlign.hpp"
#include <list>
#include <functional>
/**
* @brief The FGroupOfCellsDyn class manages the cells in block allocation.
*/
template
<
class
CompositeCellClass
>
class
FGroupOfCellsDyn
{
/** One header is allocated at the beginning of each block */
struct
alignas
(
FStarPUDefaultAlign
::
StructAlign
)
BlockHeader
{
MortonIndex
startingIndex
;
MortonIndex
endingIndex
;
int
numberOfCellsInBlock
;
int
blockIndexesTableSize
;
};
struct
alignas
(
FStarPUDefaultAlign
::
StructAlign
)
CellClassSizes
{
size_t
symbCellClassSize
;
size_t
poleCellClassSize
;
size_t
localCellClassSize
;
};
protected:
//< This value is for not used cells
static
const
MortonIndex
CellIsEmptyFlag
=
-
1
;
//< The size of the memoryBuffer
size_t
allocatedMemoryInByte
;
//< Pointer to a block memory
unsigned
char
*
memoryBuffer
;
//< Pointer to the header inside the block memory
BlockHeader
*
blockHeader
;
CellClassSizes
*
cellSizes
;
//< Pointer to the indexes table inside the block memory
int
*
blockIndexesTable
;
//< Pointer to the cells inside the block memory
unsigned
char
*
blockCells
;
//< The multipole data
unsigned
char
*
cellMultipoles
;
//< The local data size
unsigned
char
*
cellLocals
;
//< To kown if the object has to delete the memory
bool
deleteBuffer
;
public:
typedef
CompositeCellClass
CompleteCellClass
;
FGroupOfCellsDyn
()
:
allocatedMemoryInByte
(
0
),
memoryBuffer
(
nullptr
),
blockHeader
(
nullptr
),
cellSizes
(
nullptr
),
blockIndexesTable
(
nullptr
),
blockCells
(
nullptr
),
cellMultipoles
(
nullptr
),
cellLocals
(
nullptr
),
deleteBuffer
(
false
){
}
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
){
const
int
cellPos
=
blockIndexesTable
[
idxCellPtr
];
CompositeCellClass
cell
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]);
cell
.
release
();
}
}
FAlignedMemory
::
DeallocBytes
(
memoryBuffer
);
FAlignedMemory
::
DeallocBytes
(
cellMultipoles
);
FAlignedMemory
::
DeallocBytes
(
cellLocals
);
}
// Move the pointers to the correct position
allocatedMemoryInByte
=
(
inAllocatedMemoryInByte
);
memoryBuffer
=
(
inBuffer
);
blockHeader
=
reinterpret_cast
<
BlockHeader
*>
(
inBuffer
);
inBuffer
+=
sizeof
(
BlockHeader
);
cellSizes
=
reinterpret_cast
<
CellClassSizes
*>
(
inBuffer
);
inBuffer
+=
sizeof
(
CellClassSizes
);
blockIndexesTable
=
reinterpret_cast
<
int
*>
(
inBuffer
);
inBuffer
+=
(
blockHeader
->
blockIndexesTableSize
*
sizeof
(
int
));
blockCells
=
reinterpret_cast
<
unsigned
char
*>
(
inBuffer
);
inBuffer
+=
(
cellSizes
->
symbCellClassSize
*
blockHeader
->
numberOfCellsInBlock
);
FAssertLF
(
size_t
(
inBuffer
-
memoryBuffer
)
==
allocatedMemoryInByte
);
cellMultipoles
=
inCellMultipoles
;
cellLocals
=
inCellLocals
;
deleteBuffer
=
(
false
);
}
/**
* Init from a given buffer
* @param inBuffer
* @param inAllocatedMemoryInByte
*/
FGroupOfCellsDyn
(
unsigned
char
*
inBuffer
,
const
size_t
inAllocatedMemoryInByte
,
unsigned
char
*
inCellMultipoles
,
unsigned
char
*
inCellLocals
)
:
allocatedMemoryInByte
(
inAllocatedMemoryInByte
),
memoryBuffer
(
inBuffer
),
blockHeader
(
nullptr
),
cellSizes
(
nullptr
),
blockIndexesTable
(
nullptr
),
blockCells
(
nullptr
),
cellMultipoles
(
nullptr
),
cellLocals
(
nullptr
),
deleteBuffer
(
false
){
// Move the pointers to the correct position
allocatedMemoryInByte
=
(
inAllocatedMemoryInByte
);
memoryBuffer
=
(
inBuffer
);
blockHeader
=
reinterpret_cast
<
BlockHeader
*>
(
inBuffer
);
inBuffer
+=
sizeof
(
BlockHeader
);
cellSizes
=
reinterpret_cast
<
CellClassSizes
*>
(
inBuffer
);
inBuffer
+=
sizeof
(
CellClassSizes
);
blockIndexesTable
=
reinterpret_cast
<
int
*>
(
inBuffer
);
inBuffer
+=
(
blockHeader
->
blockIndexesTableSize
*
sizeof
(
int
));
blockCells
=
reinterpret_cast
<
unsigned
char
*>
(
inBuffer
);
inBuffer
+=
(
cellSizes
->
symbCellClassSize
*
blockHeader
->
numberOfCellsInBlock
);
FAssertLF
(
size_t
(
inBuffer
-
memoryBuffer
)
==
allocatedMemoryInByte
);
cellMultipoles
=
inCellMultipoles
;
cellLocals
=
inCellLocals
;
}
/**
* @brief FGroupOfCellsDyn
* @param inStartingIndex first cell morton index
* @param inEndingIndex last cell morton index + 1
* @param inNumberOfCells total number of cells in the interval (should be <= inEndingIndex-inEndingIndex)
*/
FGroupOfCellsDyn
(
const
MortonIndex
inStartingIndex
,
const
MortonIndex
inEndingIndex
,
const
int
inNumberOfCells
,
const
size_t
inSymbCellClassSize
,
const
size_t
inPoleCellClassSize
,
const
size_t
inLocalCellClassSize
)
:
allocatedMemoryInByte
(
0
),
memoryBuffer
(
nullptr
),
blockHeader
(
nullptr
),
cellSizes
(
nullptr
),
blockIndexesTable
(
nullptr
),
blockCells
(
nullptr
),
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
)
+
sizeof
(
CellClassSizes
)
+
(
blockIndexesTableSize
*
sizeof
(
int
))
+
(
inNumberOfCells
*
inSymbCellClassSize
);
// Allocate
FAssertLF
(
0
<=
int
(
memoryToAlloc
)
&&
int
(
memoryToAlloc
)
<
std
::
numeric_limits
<
int
>::
max
());
allocatedMemoryInByte
=
memoryToAlloc
;
memoryBuffer
=
(
unsigned
char
*
)
FAlignedMemory
::
AllocateBytes
<
32
>
(
memoryToAlloc
);
FAssertLF
(
memoryBuffer
);
memset
(
memoryBuffer
,
0
,
memoryToAlloc
);
// Move the pointers to the correct position
unsigned
char
*
bufferPtr
=
memoryBuffer
;
blockHeader
=
reinterpret_cast
<
BlockHeader
*>
(
bufferPtr
);
bufferPtr
+=
sizeof
(
BlockHeader
);
cellSizes
=
reinterpret_cast
<
CellClassSizes
*>
(
bufferPtr
);
bufferPtr
+=
sizeof
(
CellClassSizes
);
blockIndexesTable
=
reinterpret_cast
<
int
*>
(
bufferPtr
);
bufferPtr
+=
(
blockIndexesTableSize
*
sizeof
(
int
));
blockCells
=
reinterpret_cast
<
unsigned
char
*>
(
bufferPtr
);
bufferPtr
+=
(
inNumberOfCells
*
inSymbCellClassSize
);
FAssertLF
(
size_t
(
bufferPtr
-
memoryBuffer
)
==
allocatedMemoryInByte
);
// Init header
blockHeader
->
startingIndex
=
inStartingIndex
;
blockHeader
->
endingIndex
=
inEndingIndex
;
blockHeader
->
numberOfCellsInBlock
=
inNumberOfCells
;
blockHeader
->
blockIndexesTableSize
=
blockIndexesTableSize
;
cellSizes
->
symbCellClassSize
=
inSymbCellClassSize
;
cellSizes
->
poleCellClassSize
=
inPoleCellClassSize
;
cellSizes
->
localCellClassSize
=
inLocalCellClassSize
;
cellMultipoles
=
(
unsigned
char
*
)
FAlignedMemory
::
AllocateBytes
<
32
>
(
inNumberOfCells
*
cellSizes
->
poleCellClassSize
);
memset
(
cellMultipoles
,
0
,
inNumberOfCells
*
cellSizes
->
poleCellClassSize
);
cellLocals
=
(
unsigned
char
*
)
FAlignedMemory
::
AllocateBytes
<
32
>
(
inNumberOfCells
*
cellSizes
->
poleCellClassSize
);
memset
(
cellLocals
,
0
,
inNumberOfCells
*
cellSizes
->
poleCellClassSize
);
// Set all index to not used
for
(
int
idxCellPtr
=
0
;
idxCellPtr
<
blockIndexesTableSize
;
++
idxCellPtr
){
blockIndexesTable
[
idxCellPtr
]
=
CellIsEmptyFlag
;
}
}
/** Call the destructor of cells and dealloc block memory */
~
FGroupOfCellsDyn
(){
if
(
deleteBuffer
){
for
(
int
idxCellPtr
=
0
;
idxCellPtr
<
blockHeader
->
blockIndexesTableSize
;
++
idxCellPtr
){
if
(
blockIndexesTable
[
idxCellPtr
]
!=
CellIsEmptyFlag
){
const
int
cellPos
=
blockIndexesTable
[
idxCellPtr
];
CompositeCellClass
cell
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]);
cell
.
release
();
}
}
FAlignedMemory
::
DeallocBytes
(
memoryBuffer
);
FAlignedMemory
::
DeallocBytes
(
cellMultipoles
);
FAlignedMemory
::
DeallocBytes
(
cellLocals
);
}
}
/** Give access to the buffer to send the data */
const
unsigned
char
*
getRawBuffer
()
const
{
return
memoryBuffer
;
}
/** The the size of the allocated buffer */
size_t
getBufferSizeInByte
()
const
{
return
allocatedMemoryInByte
;
}
/** Give access to the buffer to send the data */
const
unsigned
char
*
getRawMultipoleBuffer
()
const
{
return
cellMultipoles
;
}
/** Give access to the buffer to send the data */
unsigned
char
*
getRawMultipoleBuffer
()
{
return
cellMultipoles
;
}
/** The the size of the allocated buffer */
size_t
getMultipoleBufferSizeInByte
()
const
{
return
cellSizes
->
poleCellClassSize
*
blockHeader
->
numberOfCellsInBlock
;
}
/** Give access to the buffer to send the data */
unsigned
char
*
getRawLocalBuffer
(){
return
cellLocals
;
}
/** Give access to the buffer to send the data */
const
unsigned
char
*
getRawLocalBuffer
()
const
{
return
cellLocals
;
}
/** The the size of the allocated buffer */
size_t
getLocalBufferSizeInByte
()
const
{
return
cellSizes
->
localCellClassSize
*
blockHeader
->
numberOfCellsInBlock
;
}
/** To know if the object will delete the memory block */
bool
getDeleteMemory
()
const
{
return
deleteBuffer
;
}
/** The index of the fist cell (set from the constructor) */
MortonIndex
getStartingIndex
()
const
{
return
blockHeader
->
startingIndex
;
}
/** The index of the last cell + 1 (set from the constructor) */
MortonIndex
getEndingIndex
()
const
{
return
blockHeader
->
endingIndex
;
}
/** The number of cell (set from the constructor) */
int
getNumberOfCellsInBlock
()
const
{
return
blockHeader
->
numberOfCellsInBlock
;
}
/** The size of the interval endingIndex-startingIndex (set from the constructor) */
int
getSizeOfInterval
()
const
{
return
blockHeader
->
blockIndexesTableSize
;
}
/** Return true if inIndex should be located in the current block */
bool
isInside
(
const
MortonIndex
inIndex
)
const
{
return
blockHeader
->
startingIndex
<=
inIndex
&&
inIndex
<
blockHeader
->
endingIndex
;
}
/** Return true if inIndex is located in the current block and is not empty */
bool
exists
(
const
MortonIndex
inIndex
)
const
{
return
isInside
(
inIndex
)
&&
(
blockIndexesTable
[
inIndex
-
blockHeader
->
startingIndex
]
!=
CellIsEmptyFlag
);
}
/** Return the address of the cell if it exists (or NULL) */
CompositeCellClass
getCompleteCell
(
const
MortonIndex
inIndex
){
FAssertLF
(
cellMultipoles
&&
cellLocals
);
if
(
exists
(
inIndex
)
){
const
int
cellPos
=
blockIndexesTable
[
inIndex
-
blockHeader
->
startingIndex
];
return
CompositeCellClass
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]);
}
else
return
CompositeCellClass
();
}
/** Return the address of the cell if it exists (or NULL) */
CompositeCellClass
getUpCell
(
const
MortonIndex
inIndex
){
FAssertLF
(
cellMultipoles
);
if
(
exists
(
inIndex
)
){
const
int
cellPos
=
blockIndexesTable
[
inIndex
-
blockHeader
->
startingIndex
];
return
CompositeCellClass
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
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
*
cellSizes
->
symbCellClassSize
],
nullptr
,
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]);
}
else
return
CompositeCellClass
();
}
/** Allocate a new cell by calling its constructor */
template
<
typename
...
CellConstructorParams
>
void
newCell
(
const
MortonIndex
inIndex
,
const
int
id
,
CellConstructorParams
...
args
){
FAssertLF
(
isInside
(
inIndex
));
FAssertLF
(
!
exists
(
inIndex
));
FAssertLF
(
id
<
blockHeader
->
blockIndexesTableSize
);
CompositeCellClass
cell
(
&
blockCells
[
id
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
id
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
id
*
cellSizes
->
localCellClassSize
]);
cell
.
init
(
args
...);
blockIndexesTable
[
inIndex
-
blockHeader
->
startingIndex
]
=
id
;
}
/** Iterate on each allocated cells */
template
<
typename
...
FunctionParams
>
void
forEachCell
(
std
::
function
<
void
(
CompositeCellClass
,
FunctionParams
...)
>
function
,
FunctionParams
...
args
){
for
(
int
idxCellPtr
=
0
;
idxCellPtr
<
blockHeader
->
blockIndexesTableSize
;
++
idxCellPtr
){
if
(
blockIndexesTable
[
idxCellPtr
]
!=
CellIsEmptyFlag
){
const
int
cellPos
=
blockIndexesTable
[
idxCellPtr
];
function
(
CompositeCellClass
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]),
args
...);
}
}
}
void
forEachCell
(
std
::
function
<
void
(
CompositeCellClass
)
>
function
){
for
(
int
idxCellPtr
=
0
;
idxCellPtr
<
blockHeader
->
blockIndexesTableSize
;
++
idxCellPtr
){
if
(
blockIndexesTable
[
idxCellPtr
]
!=
CellIsEmptyFlag
){
const
int
cellPos
=
blockIndexesTable
[
idxCellPtr
];
function
(
CompositeCellClass
(
&
blockCells
[
cellPos
*
cellSizes
->
symbCellClassSize
],
&
cellMultipoles
[
cellPos
*
cellSizes
->
poleCellClassSize
],
&
cellLocals
[
cellPos
*
cellSizes
->
localCellClassSize
]));
}
}
}
};
#endif // FGROUPOFCELLSDYN_HPP
Src/GroupTree/Core/FGroupOfParticlesDyn.hpp
0 → 100644
View file @
648e2966
// @SCALFMM_PRIVATE
#ifndef FGROUPOFPARTICLESDYN_HPP
#define FGROUPOFPARTICLESDYN_HPP
#include "../../Utils/FGlobal.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Containers/FTreeCoordinate.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../StarPUUtils/FStarPUDefaultAlign.hpp"
#include <list>
#include <functional>
/**
* @brief The FGroupOfParticlesDyn class manages the leaves in block allocation.
*/
class
FGroupOfParticlesDyn
{
/** One header is allocated at the beginning of each block */
struct
alignas
(
FStarPUDefaultAlign
::
StructAlign
)
BlockHeader
{
MortonIndex
startingIndex
;
MortonIndex
endingIndex
;
int
numberOfLeavesInBlock
;
int
blockIndexesTableSize
;
size_t
offsetSymbPart
;
};
/** Information about a leaf */
struct
alignas
(
FStarPUDefaultAlign
::
StructAlign
)
LeafHeader
{
size_t
offSetSymb
;
size_t
offSetDown
;
size_t
sizeSymb
;
size_t
sizeDown
;
};
protected:
static
const
int
MemoryAlignementBytes
=
FP2PDefaultAlignement
;
//< This value is for not used leaves
static
const
int
LeafIsEmptyFlag
=
-
1
;
//< The size of memoryBuffer in byte
size_t
allocatedMemoryInByteSymb
;
//< Pointer to a block memory
unsigned
char
*
memoryBuffer
;
//< Pointer to the header inside the block memory
BlockHeader
*
blockHeader
;
//< Pointer to the indexes table inside the block memory
int
*
blockIndexesTable
;
//< Pointer to leaves information
LeafHeader
*
leafHeader
;
//< Pointers to particle position x, y, z
unsigned
char
*
symbPart
;
//< Pointers to the particles data inside the block memory
unsigned
char
*
downPart
;
size_t
allocatedMemoryInByteDown
;
/** To know if we have to delete the buffer */
bool
deleteBuffer
;
public:
/**
* Init from a given buffer
* @param inBuffer
* @param inAllocatedMemoryInByte
*/
FGroupOfParticlesDyn
(
unsigned
char
*
inBuffer
,
const
size_t
inAllocatedMemoryInByte
,
unsigned
char
*
inAttributes
)
:
allocatedMemoryInByteSymb
(
inAllocatedMemoryInByte
),
memoryBuffer
(
inBuffer
),
blockHeader
(
nullptr
),
blockIndexesTable
(
nullptr
),
leafHeader
(
nullptr
),
symbPart
(
nullptr
),
downPart
(
nullptr
),
allocatedMemoryInByteDown
(
0
),
deleteBuffer
(
false
){
// Move the pointers to the correct position
blockHeader
=
reinterpret_cast
<
BlockHeader
*>
(
inBuffer
);
inBuffer
+=
sizeof
(
BlockHeader
);
blockIndexesTable
=
reinterpret_cast
<
int
*>
(
inBuffer
);
inBuffer
+=
(
blockHeader
->
blockIndexesTableSize
*
sizeof
(
int
));
leafHeader
=
reinterpret_cast
<
LeafHeader
*>
(
inBuffer
);
inBuffer
+=
(
sizeof
(
LeafHeader
)
*
blockHeader
->
numberOfLeavesInBlock
);
symbPart
=
reinterpret_cast
<
unsigned
char
*>
(
blockHeader
)
+
blockHeader
->
offsetSymbPart
;
downPart
=
inAttributes
;
}
/**
* @brief FGroupOfParticlesDyn
* @param inStartingIndex first leaf morton index
* @param inEndingIndex last leaf morton index + 1
* @param inNumberOfLeaves total number of leaves in the interval (should be <= inEndingIndex-inEndingIndex)
*/
FGroupOfParticlesDyn
(
const
MortonIndex
inStartingIndex
,
const
MortonIndex
inEndingIndex
,
const
int
inNumberOfLeaves
,
const
size_t
sizePerLeafSymb
[],
const
size_t
sizePerLeafDown
[])
:
allocatedMemoryInByteSymb
(
0
),
memoryBuffer
(
nullptr
),
blockHeader
(
nullptr
),
blockIndexesTable
(
nullptr
),
leafHeader
(
nullptr
),
symbPart
(
nullptr
),
downPart
(
nullptr
),
allocatedMemoryInByteDown
(
0
),
deleteBuffer
(
true
){
size_t
totalSymb
=
0
;
size_t
totalDown
=
0
;
for
(
int
idxLeaf
=
0
;
idxLeaf
<
inNumberOfLeaves
;
++
idxLeaf
){
totalSymb
+=
sizePerLeafSymb
[
idxLeaf
];
totalDown
+=
sizePerLeafDown
[
idxLeaf
];
}
// Find the number of leaf to allocate in the blocks
const
int
blockIndexesTableSize
=
int
(
inEndingIndex
-
inStartingIndex
);
FAssertLF
(
inNumberOfLeaves
<=
blockIndexesTableSize
);
// Total number of bytes in the block
const
size_t
memoryToAllocSymb
=
sizeof
(
BlockHeader
)
+
(
blockIndexesTableSize
*
sizeof
(
int
))
+
(
inNumberOfLeaves
*
sizeof
(
LeafHeader
))
+
(
totalSymb
+
MemoryAlignementBytes
-
1
);
// Allocate
allocatedMemoryInByteSymb
=
memoryToAllocSymb
;
memoryBuffer
=
(
unsigned
char
*
)
FAlignedMemory
::
AllocateBytes
<
MemoryAlignementBytes
>
(
memoryToAllocSymb
);
FAssertLF
(
memoryBuffer
);
memset
(
memoryBuffer
,
0
,
memoryToAllocSymb
);
allocatedMemoryInByteDown
=
totalDown
;
downPart
=
(
unsigned
char
*
)
FAlignedMemory
::
AllocateBytes
<
MemoryAlignementBytes
>
(
allocatedMemoryInByteDown
);
FAssertLF
(
downPart
);
memset
(
downPart
,
0
,
allocatedMemoryInByteDown
);
// Move the pointers to the correct position
unsigned
char
*
bufferPtr
=
memoryBuffer
;
blockHeader
=
reinterpret_cast
<
BlockHeader
*>
(
bufferPtr
);
bufferPtr
+=
sizeof
(
BlockHeader
);
blockIndexesTable
=
reinterpret_cast
<
int
*>
(
bufferPtr
);
bufferPtr
+=
(
blockIndexesTableSize
*
sizeof
(
int
));
leafHeader
=
reinterpret_cast
<
LeafHeader
*>
(
bufferPtr
);
bufferPtr
+=
(
inNumberOfLeaves
*
sizeof
(
LeafHeader
));
symbPart
=
reinterpret_cast
<
unsigned
char
*>
(
size_t
(
bufferPtr
+
MemoryAlignementBytes
-
1
)
&
~
size_t
(
MemoryAlignementBytes
-
1
));
FAssertLF
(
size_t
(
bufferPtr
-
memoryBuffer
)
<=
allocatedMemoryInByteSymb
);
// Init header
blockHeader
->
startingIndex
=
inStartingIndex
;
blockHeader
->
endingIndex
=
inEndingIndex
;
blockHeader
->
numberOfLeavesInBlock
=
inNumberOfLeaves
;
blockHeader
->
blockIndexesTableSize
=
blockIndexesTableSize
;
blockHeader
->
offsetSymbPart
=
size_t
(
symbPart
)
-
size_t
(
blockHeader
);
if
(
inNumberOfLeaves
){
leafHeader
[
0
].
sizeSymb
=
sizePerLeafSymb
[
0
];
leafHeader
[
0
].
sizeDown
=
sizePerLeafDown
[
0
];
leafHeader
[
0
].
offSetSymb
=
0
;
leafHeader
[
0
].
offSetDown
=
0
;
for
(
int
idxLeaf
=
1
;
idxLeaf
<
inNumberOfLeaves
;
++
idxLeaf
){
leafHeader
[
idxLeaf
].
sizeSymb
=
sizePerLeafSymb
[
idxLeaf
];
leafHeader
[
idxLeaf
].
sizeDown
=
sizePerLeafDown
[
idxLeaf
];
leafHeader
[
idxLeaf
].
offSetSymb
=
leafHeader
[
idxLeaf
-
1
].
sizeSymb
+
leafHeader
[
idxLeaf
-
1
].
offSetSymb
;
leafHeader
[
idxLeaf
].
offSetDown
=
leafHeader
[
idxLeaf
-
1
].
sizeDown
+
leafHeader
[
idxLeaf
-
1
].
offSetDown
;
}
FAssertLF
(
leafHeader
[
inNumberOfLeaves
-
1
].
offSetSymb
+
leafHeader
[
inNumberOfLeaves
-
1
].
sizeSymb
==
totalSymb
);
FAssertLF
(
leafHeader
[
inNumberOfLeaves
-
1
].
offSetDown
+
leafHeader
[
inNumberOfLeaves
-
1
].
sizeDown
==
totalDown
);
}
// Set all index to not used
for
(
int
idxLeafPtr
=
0
;
idxLeafPtr
<
blockIndexesTableSize
;
++
idxLeafPtr
){
blockIndexesTable
[
idxLeafPtr
]
=
LeafIsEmptyFlag
;
}
}
/** Call the destructor of leaves and dealloc block memory */
~
FGroupOfParticlesDyn
(){
if
(
deleteBuffer
){
FAlignedMemory
::
DeallocBytes
(
memoryBuffer
);
FAlignedMemory
: