Commit b775a049 authored by BRAMAS Berenger's avatar BRAMAS Berenger

Add new alignement memory class (to be able to allocate for any alignement...

Add new alignement memory class (to be able to allocate for any alignement which is a power of 2) and to allocate an array of Cpp objects
parent 317ea8e2
......@@ -109,7 +109,7 @@ protected:
allocatedParticles = (FMath::Max(10,int(FReal(nbParticles+sizeInput)*1.5)) + moduloParticlesNumber - 1) & ~(moduloParticlesNumber-1);
// init with 0
const size_t allocatedBytes = (sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles;
FReal* newData = reinterpret_cast<FReal*>(FAlignedMemory::Allocate32BAligned(allocatedBytes));
FReal* newData = reinterpret_cast<FReal*>(FAlignedMemory::AllocateBytes<32>(allocatedBytes));
memset( newData, 0, allocatedBytes);
// copy memory
const char*const toDelete = reinterpret_cast<const char*>(positions[0]);
......@@ -124,7 +124,7 @@ protected:
attributes[idx] = startAddress + (idx * allocatedParticles);
}
// delete old
FAlignedMemory::Dealloc32BAligned(toDelete);
FAlignedMemory::DeallocBytes(toDelete);
}
}
......@@ -147,7 +147,7 @@ public:
/** Simply dalloc the memory using first pointer
*/
~FBasicParticleContainer(){
FAlignedMemory::Dealloc32BAligned(positions[0]);
FAlignedMemory::DeallocBytes(positions[0]);
}
/**
......@@ -391,10 +391,10 @@ public:
allocatedParticles = (FMath::Max(10,int(FReal(nbParticles+1)*1.5)) + moduloParticlesNumber - 1) & ~(moduloParticlesNumber-1);
// init with 0
const size_t allocatedBytes = (sizeof(FReal)*3 + sizeof(AttributeClass)*NbAttributesPerParticle)*allocatedParticles;
FReal* newData = reinterpret_cast<FReal*>(FAlignedMemory::Allocate32BAligned(allocatedBytes));
FReal* newData = reinterpret_cast<FReal*>(FAlignedMemory::AllocateBytes<32>(allocatedBytes));
memset( newData, 0, allocatedBytes);
FAlignedMemory::Dealloc32BAligned(positions[0]);
FAlignedMemory::DeallocBytes(positions[0]);
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx] = newData + (allocatedParticles * idx);
}
......
......@@ -67,9 +67,9 @@ public:
(&cellLocals[blockIndexesTable[idxCellPtr]])->~LocalCellClass();
}
}
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(cellMultipoles);
FAlignedMemory::Dealloc32BAligned(cellLocals);
FAlignedMemory::DeallocByte(memoryBuffer);
FAlignedMemory::DeallocBytes(cellMultipoles);
FAlignedMemory::DeallocBytes(cellLocals);
}
// Move the pointers to the correct position
allocatedMemoryInByte = (inAllocatedMemoryInByte);
......@@ -118,7 +118,7 @@ public:
// Allocate
FAssertLF(0 <= int(memoryToAlloc) && int(memoryToAlloc) < std::numeric_limits<int>::max());
allocatedMemoryInByte = memoryToAlloc;
memoryBuffer = (unsigned char*)FAlignedMemory::Allocate32BAligned(memoryToAlloc);
memoryBuffer = (unsigned char*)FAlignedMemory::AllocateByte<32>(memoryToAlloc);
FAssertLF(memoryBuffer);
memset(memoryBuffer, 0, memoryToAlloc);
......@@ -133,8 +133,8 @@ public:
blockHeader->numberOfCellsInBlock = inNumberOfCells;
blockHeader->blockIndexesTableSize = blockIndexesTableSize;
cellMultipoles = (PoleCellClass*)FAlignedMemory::Allocate32BAligned(inNumberOfCells*sizeof(PoleCellClass));
cellLocals = (LocalCellClass*)FAlignedMemory::Allocate32BAligned(inNumberOfCells*sizeof(LocalCellClass));
cellMultipoles = (PoleCellClass*)FAlignedMemory::AllocateByte<32>(inNumberOfCells*sizeof(PoleCellClass));
cellLocals = (LocalCellClass*)FAlignedMemory::AllocateByte<32>(inNumberOfCells*sizeof(LocalCellClass));
for(int idxCell = 0 ; idxCell < inNumberOfCells ; ++idxCell){
new (&cellMultipoles[idxCell]) PoleCellClass();
new (&cellLocals[idxCell]) LocalCellClass();
......@@ -156,9 +156,9 @@ public:
(&cellLocals[blockIndexesTable[idxCellPtr]])->~LocalCellClass();
}
}
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(cellMultipoles);
FAlignedMemory::Dealloc32BAligned(cellLocals);
FAlignedMemory::DeallocBytes(memoryBuffer);
FAlignedMemory::DeallocBytes(cellMultipoles);
FAlignedMemory::DeallocBytes(cellLocals);
}
}
......
......@@ -149,7 +149,7 @@ public:
// Allocate
FAssertLF(0 <= int(memoryToAlloc) && int(memoryToAlloc) < std::numeric_limits<int>::max());
allocatedMemoryInByte = memoryToAlloc;
memoryBuffer = (unsigned char*)FAlignedMemory::Allocate32BAligned(memoryToAlloc);
memoryBuffer = (unsigned char*)FAlignedMemory::AllocateByte<32>(memoryToAlloc);
FAssertLF(memoryBuffer);
memset(memoryBuffer, 0, memoryToAlloc);
......@@ -181,7 +181,7 @@ public:
symAttributes += blockHeader->nbParticlesAllocatedInGroup;
}
attributesBuffer = (AttributeClass*)FAlignedMemory::Allocate32BAligned(blockHeader->attributeOffset*NbAttributesPerParticle);
attributesBuffer = (AttributeClass*)FAlignedMemory::AllocateByte<32>(blockHeader->attributeOffset*NbAttributesPerParticle);
memset(attributesBuffer, 0, blockHeader->attributeOffset*NbAttributesPerParticle);
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
particleAttributes[idxAttribute+NbSymbAttributes] = &attributesBuffer[idxAttribute*nbParticlesAllocatedInGroup];
......@@ -196,8 +196,8 @@ public:
/** Call the destructor of leaves and dealloc block memory */
~FGroupOfParticles(){
if(deleteBuffer){
FAlignedMemory::Dealloc32BAligned(memoryBuffer);
FAlignedMemory::Dealloc32BAligned(attributesBuffer);
FAlignedMemory::DeallocBytes(memoryBuffer);
FAlignedMemory::DeallocBytes(attributesBuffer);
}
}
......
......@@ -761,12 +761,12 @@ protected:
{
if(remoteCellGroups[idxLevel][idxOtherGroup].ptrSymb == nullptr){
const int nbBytesInBlockSymb = processesBlockInfos[idxLevel][idxOtherGroup].bufferSizeSymb;
unsigned char* memoryBlockSymb = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlockSymb);
unsigned char* memoryBlockSymb = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlockSymb);
remoteCellGroups[idxLevel][idxOtherGroup].ptrSymb = memoryBlockSymb;
starpu_variable_data_register(&remoteCellGroups[idxLevel][idxOtherGroup].handleSymb, 0,
(uintptr_t)remoteCellGroups[idxLevel][idxOtherGroup].ptrSymb, nbBytesInBlockSymb);
const int nbBytesInBlockUp = processesBlockInfos[idxLevel][idxOtherGroup].bufferSizeUp;
unsigned char* memoryBlockUp = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlockUp);
unsigned char* memoryBlockUp = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlockUp);
remoteCellGroups[idxLevel][idxOtherGroup].ptrUp = memoryBlockUp;
starpu_variable_data_register(&remoteCellGroups[idxLevel][idxOtherGroup].handleUp, 0,
(uintptr_t)remoteCellGroups[idxLevel][idxOtherGroup].ptrUp, nbBytesInBlockUp);
......@@ -864,7 +864,7 @@ protected:
{
if(remoteParticleGroupss[idxOtherGroup].ptrSymb == nullptr){
const int nbBytesInBlock = processesBlockInfos[tree->getHeight()-1][idxOtherGroup].leavesBufferSize;
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlock);
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlock);
remoteParticleGroupss[idxOtherGroup].ptrSymb = memoryBlock;
starpu_variable_data_register(&remoteParticleGroupss[idxOtherGroup].handleSymb, 0,
(uintptr_t)remoteParticleGroupss[idxOtherGroup].ptrSymb, nbBytesInBlock);
......@@ -1041,12 +1041,12 @@ protected:
if(remoteCellGroups[idxLevel][idxHandle].ptrSymb){
starpu_data_unregister(remoteCellGroups[idxLevel][idxHandle].handleSymb);
starpu_data_unregister(remoteCellGroups[idxLevel][idxHandle].handleUp);
FAlignedMemory::Dealloc32BAligned(remoteCellGroups[idxLevel][idxHandle].ptrSymb);
FAlignedMemory::Dealloc32BAligned(remoteCellGroups[idxLevel][idxHandle].ptrUp);
FAlignedMemory::DeallocByte(remoteCellGroups[idxLevel][idxHandle].ptrSymb);
FAlignedMemory::DeallocByte(remoteCellGroups[idxLevel][idxHandle].ptrUp);
if(remoteCellGroups[idxLevel][idxHandle].ptrDown){
starpu_data_unregister(remoteCellGroups[idxLevel][idxHandle].handleDown);
FAlignedMemory::Dealloc32BAligned(remoteCellGroups[idxLevel][idxHandle].ptrDown);
FAlignedMemory::DeallocByte(remoteCellGroups[idxLevel][idxHandle].ptrDown);
}
}
}
......@@ -1056,7 +1056,7 @@ protected:
for(int idxHandle = 0 ; idxHandle < int(remoteParticleGroupss.size()) ; ++idxHandle){
if(remoteParticleGroupss[idxHandle].ptrSymb){
starpu_data_unregister(remoteParticleGroupss[idxHandle].handleSymb);
FAlignedMemory::Dealloc32BAligned(remoteParticleGroupss[idxHandle].ptrSymb);
FAlignedMemory::DeallocByte(remoteParticleGroupss[idxHandle].ptrSymb);
}
}
remoteParticleGroupss.clear();
......@@ -1366,13 +1366,13 @@ protected:
if(remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].ptrSymb == nullptr){
const int nbBytesInBlockSymb = processesBlockInfos[idxLevel+1][firstOtherBlock + idxBlockToRecv].bufferSizeSymb;
unsigned char* memoryBlockSymb = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlockSymb);
unsigned char* memoryBlockSymb = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlockSymb);
remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].ptrSymb = memoryBlockSymb;
starpu_variable_data_register(&remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].handleSymb, 0,
(uintptr_t)remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].ptrSymb, nbBytesInBlockSymb);
const int nbBytesInBlockUp = processesBlockInfos[idxLevel+1][firstOtherBlock + idxBlockToRecv].bufferSizeUp;
unsigned char* memoryBlockUp = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlockUp);
unsigned char* memoryBlockUp = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlockUp);
remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].ptrUp = memoryBlockUp;
starpu_variable_data_register(&remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].handleUp, 0,
(uintptr_t)remoteCellGroups[idxLevel+1][firstOtherBlock + idxBlockToRecv].ptrUp, nbBytesInBlockUp);
......@@ -1608,14 +1608,14 @@ protected:
if(remoteCellGroups[idxLevel][firstOtherBlock].ptrSymb == nullptr){
const int nbBytesInBlock = processesBlockInfos[idxLevel][firstOtherBlock].bufferSizeSymb;
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlock);
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlock);
remoteCellGroups[idxLevel][firstOtherBlock].ptrSymb = memoryBlock;
starpu_variable_data_register(&remoteCellGroups[idxLevel][firstOtherBlock].handleSymb, 0,
(uintptr_t)remoteCellGroups[idxLevel][firstOtherBlock].ptrSymb, nbBytesInBlock);
}
if(remoteCellGroups[idxLevel][firstOtherBlock].ptrDown == nullptr){
const int nbBytesInBlock = processesBlockInfos[idxLevel][firstOtherBlock].bufferSizeDown;
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::Allocate32BAligned(nbBytesInBlock);
unsigned char* memoryBlock = (unsigned char*)FAlignedMemory::AllocateByte<32>(nbBytesInBlock);
remoteCellGroups[idxLevel][firstOtherBlock].ptrDown = memoryBlock;
starpu_variable_data_register(&remoteCellGroups[idxLevel][firstOtherBlock].handleDown, 0,
(uintptr_t)remoteCellGroups[idxLevel][firstOtherBlock].ptrDown, nbBytesInBlock);
......
......@@ -9,8 +9,6 @@
#include "../../Utils/FLog.hpp"
#include "../../Utils/FTic.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../../Utils/FAssert.hpp"
#include "../Core/FOutOfBlockInteraction.hpp"
......
......@@ -11,8 +11,6 @@
#include "../../Utils/FLog.hpp"
#include "../../Utils/FTic.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../../Utils/FAssert.hpp"
#include "../Core/FOutOfBlockInteraction.hpp"
......
......@@ -9,7 +9,6 @@
#include "../../Utils/FLog.hpp"
#include "../../Utils/FTic.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../../Utils/FAssert.hpp"
#include "../Core/FOutOfBlockInteraction.hpp"
......
......@@ -12,8 +12,6 @@
#include "../../Utils/FLog.hpp"
#include "../../Utils/FTic.hpp"
#include "../../Utils/FAssert.hpp"
#include "../../Utils/FAlignedMemory.hpp"
#include "../../Utils/FAssert.hpp"
#include "../Core/FOutOfBlockInteraction.hpp"
......
......@@ -18,66 +18,83 @@
#include <cstdint>
/**
* This should be used to allocate and deallocate aligned memory.
*/
namespace FAlignedMemory {
/**
* @brief Allocate16BAligned
* @param inSize in Bytes
* @return the address of the allocated block of size inSize
*/
inline void* Allocate16BAligned(const size_t inSize){
unsigned char* memoryBlock = new unsigned char[inSize + 15 + 16];
{
unsigned char** storeRealAddress = reinterpret_cast<unsigned char**>( (reinterpret_cast<long long int>(memoryBlock) + 15) & ~0xFLL);
(*storeRealAddress) = memoryBlock;
template <std::size_t AlignementValue>
inline void* AllocateBytes(const std::size_t inSize){
if(inSize == 0){
return nullptr;
}
// Ensure it is a power of 2
static_assert(AlignementValue != 0 && ((AlignementValue-1)&AlignementValue) == 0, "Alignement must be a power of 2");
// We will need to store the adress of the real blocks
const std::size_t sizeForAddress = (AlignementValue < sizeof(unsigned char*)? sizeof(unsigned char*) : AlignementValue);
unsigned char* allocatedMemory = new unsigned char[inSize + AlignementValue-1 + sizeForAddress];
unsigned char* alignedMemoryAddress = reinterpret_cast<unsigned char*>((reinterpret_cast<std::size_t>(allocatedMemory) + AlignementValue-1 + sizeForAddress) & ~static_cast<std::size_t>(AlignementValue-1));
unsigned char* ptrForAddress = (alignedMemoryAddress - sizeof(unsigned char*));
// Save allocated adress
*reinterpret_cast<unsigned char**>(ptrForAddress) = allocatedMemory;
// Return aligned address
return reinterpret_cast<void*>(alignedMemoryAddress);
}
inline void DeallocBytes(const void* ptrToFree){
if( ptrToFree ){
const unsigned char*const* storeRealAddress = reinterpret_cast<const unsigned char*const *>(reinterpret_cast<const unsigned char*>(ptrToFree) - sizeof(unsigned char*));
delete[] reinterpret_cast<const unsigned char*>(*storeRealAddress);
}
return reinterpret_cast<void*>( (reinterpret_cast<long long int>(memoryBlock) + 16 + 15) & ~0xFLL);
}
/**
* @brief Allocate32BAligned
* @param inSize in Bytes
* @return the address of the allocated block of size inSize
*/
inline void* Allocate32BAligned(const size_t inSize){
unsigned char* memoryBlock;
int resMemAl = posix_memalign((void**)&memoryBlock,32,inSize);
if(resMemAl != 0){
fprintf(stderr,"Allocation failed : Error Code : %d",resMemAl);
template <std::size_t AlignementValue, class ArrayType>
inline ArrayType* AllocateArray(const std::size_t inNbElementsInArray){
if(inNbElementsInArray == 0){
return nullptr;
}
return memoryBlock;
}
const std::size_t inSize = (inNbElementsInArray*sizeof(ArrayType));
/**
* Allocate an array of inNbElements elements of type ObjectType.
* The objects are not initialized!
*/
template <class ObjectType>
inline ObjectType* AllocateType16BAligned(const int inNbElements){
return reinterpret_cast<ObjectType*>(Allocate16BAligned(sizeof(ObjectType) * inNbElements));
// Ensure it is a power of 2
static_assert(AlignementValue != 0 && ((AlignementValue-1)&AlignementValue) == 0, "Alignement must be a power of 2");
// We will need to store the adress of the real blocks
const std::size_t sizeForAddressAndNumber = (AlignementValue < (sizeof(unsigned char*)+sizeof(std::size_t))? (sizeof(unsigned char*)+sizeof(std::size_t)) : AlignementValue);
unsigned char* allocatedMemory = new unsigned char[inSize + AlignementValue-1 + sizeForAddressAndNumber];
unsigned char* alignedMemoryAddress = reinterpret_cast<unsigned char*>((reinterpret_cast<std::size_t>(allocatedMemory) + AlignementValue-1 + sizeForAddressAndNumber) & ~static_cast<std::size_t>(AlignementValue-1));
unsigned char* ptrForAddress = (alignedMemoryAddress - sizeof(unsigned char*));
unsigned char* ptrForNumber = (ptrForAddress - sizeof(std::size_t));
// Save allocated adress
*reinterpret_cast<unsigned char**>(ptrForAddress) = allocatedMemory;
*reinterpret_cast<std::size_t*>(ptrForNumber) = inNbElementsInArray;
// Return aligned address
ArrayType* array = reinterpret_cast<ArrayType*>(alignedMemoryAddress);
for(std::size_t idx = 0 ; idx < inNbElementsInArray ; ++idx){
new (&array[idx]) ArrayType();
}
return array;
}
/**
* Delete a block allocated with allocate16BAligned
*/
inline void Dealloc16BAligned(const void*const memoryBlock){
if( memoryBlock ){
const unsigned char*const* storeRealAddress = reinterpret_cast<const unsigned char*const *>(reinterpret_cast<const unsigned char*>(memoryBlock) - 16);
template <class ArrayType>
inline void DeallocArray(const ArrayType* ptrToFree){
if( ptrToFree ){
const std::size_t numberOfElements = (*reinterpret_cast<const std::size_t*>(reinterpret_cast<const unsigned char*>(ptrToFree) - sizeof(unsigned char*) - sizeof(std::size_t)));
for(std::size_t idx = 0 ; idx < numberOfElements ; ++idx){
ptrToFree[idx].~ArrayType();
}
const unsigned char*const* storeRealAddress = reinterpret_cast<const unsigned char*const *>(reinterpret_cast<const unsigned char*>(ptrToFree) - sizeof(unsigned char*));
delete[] reinterpret_cast<const unsigned char*>(*storeRealAddress);
}
}
/**
* Delete a block allocated with Allocate32BAligned
*/
inline void Dealloc32BAligned(const void*const memoryBlock){
const void * toBeFreed = memoryBlock;
free(const_cast<void *>(toBeFreed));
}
}
......
......@@ -58,6 +58,37 @@ void For(Args... args){
}
///////////////////////////////////////////////////////////////////////////////////////
/// FForAll : Compile all and exec all
///////////////////////////////////////////////////////////////////////////////////////
#include <functional>
namespace FForAllWithInc{
template <class IterType, const IterType CurrentIter, const IterType iterTo, template <IterType> class ClassStep,
class Func, bool IsNotOver, typename... Args>
struct Evaluator{
static void Run(Args... args){
Func::template For<CurrentIter>(args...);
Evaluator<IterType, ClassStep<CurrentIter>::NextValue, iterTo, ClassStep, Func, (ClassStep<CurrentIter>::NextValue < iterTo), Args...>::Run(args...);
}
};
template <class IterType, const IterType CurrentIter, const IterType iterTo, template <IterType> class ClassStep,
class Func, typename... Args>
struct Evaluator< IterType, CurrentIter, iterTo, ClassStep, Func, false, Args...>{
static void Run(Args... args){
}
};
template <class IterType, const IterType IterFrom, const IterType iterTo, template <IterType> class ClassStep,
class Func, typename... Args>
void For(Args... args){
Evaluator<IterType, IterFrom, iterTo, ClassStep, Func, (IterFrom<iterTo), Args...>::Run(args...);
}
}
///////////////////////////////////////////////////////////////////////////////////////
/// FForAll : Compile all and exec all
......@@ -92,6 +123,39 @@ void For(Func* object, Args... args){
}
///////////////////////////////////////////////////////////////////////////////////////
/// FForAll : Compile all and exec all
///////////////////////////////////////////////////////////////////////////////////////
#include <functional>
namespace FForAllThisWithInc{
template <class IterType, const IterType CurrentIter, const IterType iterTo, template <IterType> class ClassStep,
class Func, bool IsNotOver, typename... Args>
struct Evaluator{
static void Run(Func* object, Args... args){
object->Func::template For<CurrentIter>(args...);
Evaluator<IterType, ClassStep<CurrentIter>::NextValue, iterTo, ClassStep, Func, (ClassStep<CurrentIter>::NextValue < iterTo), Args...>::Run(object, args...);
}
};
template <class IterType, const IterType CurrentIter, const IterType iterTo, template <IterType> class ClassStep,
class Func, typename... Args>
struct Evaluator< IterType, CurrentIter, iterTo, ClassStep, Func, false, Args...>{
static void Run(Func* object, Args... args){
}
};
template <class IterType, const IterType IterFrom, const IterType iterTo, template <IterType> class ClassStep,
class Func, typename... Args>
void For(Func* object, Args... args){
Evaluator<IterType, IterFrom, iterTo, ClassStep, Func, (IterFrom<iterTo), Args...>::Run(object, args...);
}
}
///////////////////////////////////////////////////////////////////////////////////////
/// FRunIf : Compile all and exec only one (if the template variable is equal to
/// the first variable)
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#include "FUTester.hpp"
#include "../Src/Utils/FAlignedMemory.hpp"
#include "../Src/Utils/FTemplate.hpp"
/**
* This file is a unit test for the alignement class
*/
template <std::size_t Value>
struct IncClass{
static const std::size_t NextValue = (Value<<1);
};
struct CheckClass {
static int nbObjects;
int idObject;
int flag;
CheckClass(){
idObject = nbObjects;
nbObjects += 1;
flag = -1;
}
~CheckClass(){
nbObjects -= 1;
}
};
int CheckClass::nbObjects = 0;
/** this class test the bool array container */
class TestAlignement : public FUTester<TestAlignement> {
void TestSimple(){
for(std::size_t idxSize = 1 ; idxSize < 1000 ; idxSize *= 10){
{
void* ptr = FAlignedMemory::AllocateBytes<2>(idxSize);
uassert((reinterpret_cast<std::size_t>(ptr) & (2-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
{
void* ptr = FAlignedMemory::AllocateBytes<8>(idxSize);
uassert((reinterpret_cast<std::size_t>(ptr) & (8-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
{
void* ptr = FAlignedMemory::AllocateBytes<16>(idxSize);
uassert((reinterpret_cast<std::size_t>(ptr) & (16-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
{
void* ptr = FAlignedMemory::AllocateBytes<32>(idxSize);
uassert((reinterpret_cast<std::size_t>(ptr) & (22-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
{
void* ptr = FAlignedMemory::AllocateBytes<64>(idxSize);
uassert((reinterpret_cast<std::size_t>(ptr) & (64-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
}
}
public:
template <std::size_t Allign>
void For(){
for(std::size_t idxSize = 1 ; idxSize < 1000 ; idxSize *= 10){
void* ptr = FAlignedMemory::AllocateBytes<Allign>(idxSize);
//uassert((reinterpret_cast<std::size_t>(ptr) & (Allign-1)) == 0);
FAlignedMemory::DeallocBytes(ptr);
}
}
void TestAll(){
FForAllThisWithInc::For<std::size_t, 1, 128+1, IncClass, TestAlignement>(this);
}
void TestArray(){
CheckClass::nbObjects = 0;
const int nb = 5;
CheckClass* array = FAlignedMemory::AllocateArray<8, CheckClass>( nb );
uassert(CheckClass::nbObjects == nb);
for(int idx = 0 ; idx < nb ; ++idx){
uassert(array[idx].flag == -1);
uassert(array[idx].idObject == idx);
}
FAlignedMemory::DeallocArray( array );
uassert(CheckClass::nbObjects == 0);
}
// set test
void SetTests(){
AddTest(&TestAlignement::TestSimple,"Test if aligned");
AddTest(&TestAlignement::TestAll,"Test if all aligned");
AddTest(&TestAlignement::TestArray,"Test if array are correct");
}
};
// You must do this
TestClass(TestAlignement)
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