Attention une mise à jour du serveur va être effectuée le lundi 17 mai entre 13h et 13h30. Cette mise à jour va générer une interruption du service de quelques minutes.

Commit 665b58ef authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

Changes related to efficient tree insert (main class not commited yet)

parent 0b5d3de2
......@@ -4,13 +4,13 @@
// 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.
//
// 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.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#ifndef FBASICPARTICLECONTAINER_HPP
......@@ -68,41 +68,41 @@ protected:
/** Filling call for each attributes values */
template<int index, typename... Args>
void addParticleValue(const int insertPosition, const AttributeClass value, Args... args){
// Compile test to ensure indexing
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
// insert the value
attributes[index][insertPosition] = value;
// Continue for reamining values
addParticleValue<index+1>( insertPosition, args...);
// Compile test to ensure indexing
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
// insert the value
attributes[index][insertPosition] = value;
// Continue for reamining values
addParticleValue<index+1>( insertPosition, args...);
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
void increaseSizeIfNeeded(){
if( nbParticles == allocatedParticles ){
// allocate memory
const int moduloParticlesNumber = (32/sizeof(FReal)); // We want to be rounded to 32B
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));
memset( newData, 0, allocatedBytes);
// copy memory
const char*const toDelete = reinterpret_cast<const char*>(positions[0]);
for(int idx = 0 ; idx < 3 ; ++idx){
memcpy(newData + (allocatedParticles * idx), positions[idx], sizeof(FReal) * nbParticles);
positions[idx] = newData + (allocatedParticles * idx);
}
// copy attributes
AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
memcpy(startAddress + (allocatedParticles * idx), attributes[idx], sizeof(AttributeClass) * nbParticles);
attributes[idx] = startAddress + (idx * allocatedParticles);
}
// delete old
FAlignedMemory::Dealloc32BAligned(toDelete);
}
void increaseSizeIfNeeded(FSize sizeInput = 1){
if( nbParticles+(sizeInput-1) >= allocatedParticles ){
// allocate memory
const int moduloParticlesNumber = (32/sizeof(FReal)); // We want to be rounded to 32B
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));
memset( newData, 0, allocatedBytes);
// copy memory
const char*const toDelete = reinterpret_cast<const char*>(positions[0]);
for(int idx = 0 ; idx < 3 ; ++idx){
memcpy(newData + (allocatedParticles * idx), positions[idx], sizeof(FReal) * nbParticles);
positions[idx] = newData + (allocatedParticles * idx);
}
// copy attributes
AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
memcpy(startAddress + (allocatedParticles * idx), attributes[idx], sizeof(AttributeClass) * nbParticles);
attributes[idx] = startAddress + (idx * allocatedParticles);
}
// delete old
FAlignedMemory::Dealloc32BAligned(toDelete);
}
}
public:
......@@ -117,14 +117,14 @@ public:
/** Basic contructor */
FBasicParticleContainer() : nbParticles(0), allocatedParticles(0){
memset(positions, 0, sizeof(positions[0]) * 3);
memset(attributes, 0, sizeof(attributes[0]) * NbAttributesPerParticle);
memset(positions, 0, sizeof(positions[0]) * 3);
memset(attributes, 0, sizeof(attributes[0]) * NbAttributesPerParticle);
}
/** Simply dalloc the memory using first pointer
*/
~FBasicParticleContainer(){
FAlignedMemory::Dealloc32BAligned(positions[0]);
FAlignedMemory::Dealloc32BAligned(positions[0]);
}
/**
......@@ -132,7 +132,7 @@ public:
* @return the number of particles
*/
int getNbParticles() const{
return nbParticles;
return nbParticles;
}
/**
* @brief reset the number of particles
......@@ -140,14 +140,14 @@ public:
*/
void resetNumberOfParticles()
{
nbParticles = 0 ;
nbParticles = 0 ;
}
/**
* @brief getPositions
* @return a FReal*[3] to get access to the positions
*/
const FReal*const* getPositions() const {
return positions;
return positions;
}
/**
......@@ -155,7 +155,7 @@ public:
* @return get the position in write mode
*/
FReal* const* getWPositions() {
return positions;
return positions;
}
/**
......@@ -164,7 +164,7 @@ public:
* @return the attribute at index index
*/
AttributeClass* getAttribute(const int index) {
return attributes[index];
return attributes[index];
}
/**
......@@ -173,7 +173,7 @@ public:
* @return
*/
const AttributeClass* getAttribute(const int index) const {
return attributes[index];
return attributes[index];
}
/**
......@@ -181,8 +181,8 @@ public:
*/
template <int index>
AttributeClass* getAttribute() {
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
return attributes[index];
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
return attributes[index];
}
/**
......@@ -190,29 +190,51 @@ public:
*/
template <int index>
const AttributeClass* getAttribute() const {
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
return attributes[index];
static_assert(index < NbAttributesPerParticle, "Index to get attributes is out of scope.");
return attributes[index];
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/**
* Push multiple particles
* Should have a particle position fallowed by attributes
* @param Array of position, number of parts to insert, followed by array of attribute
*/
template<typename... Args>
void pushArray(const FPoint * inParticlePosition, FSize numberOfParts, Args... args){
//Tests if enough space
increaseSizeIfNeeded(numberOfParts);
for(int idxPart = 0; idxPart<numberOfParts ; ++idxPart){
// insert particle data
positions[0][nbParticles] = inParticlePosition[idxPart].getX();
positions[1][nbParticles] = inParticlePosition[idxPart].getY();
positions[2][nbParticles] = inParticlePosition[idxPart].getZ();
// insert attribute data
addParticleValue<0>( nbParticles, args[idxPart]...);
nbParticles += 1;
}
}
/**
* Push called bu FSimpleLeaf
* Should have a particle position fallowed by attributes
*/
template<typename... Args>
void push(const FPoint& inParticlePosition, Args... args){
// enought space?
increaseSizeIfNeeded();
// insert particle data
positions[0][nbParticles] = inParticlePosition.getX();
positions[1][nbParticles] = inParticlePosition.getY();
positions[2][nbParticles] = inParticlePosition.getZ();
// insert attribute data
addParticleValue<0>( nbParticles, args...);
nbParticles += 1;
// enought space?
increaseSizeIfNeeded();
// insert particle data
positions[0][nbParticles] = inParticlePosition.getX();
positions[1][nbParticles] = inParticlePosition.getY();
positions[2][nbParticles] = inParticlePosition.getZ();
// insert attribute data
addParticleValue<0>( nbParticles, args...);
nbParticles += 1;
}
......@@ -222,18 +244,18 @@ public:
*/
template<typename... Args>
void push(const FPoint& inParticlePosition, const std::array<AttributeClass , NbAttributesPerParticle>& values){
// enought space?
increaseSizeIfNeeded();
// insert particle data
positions[0][nbParticles] = inParticlePosition.getX();
positions[1][nbParticles] = inParticlePosition.getY();
positions[2][nbParticles] = inParticlePosition.getZ();
// insert attribute data
for(int idxVal = 0 ; idxVal < NbAttributesPerParticle ; ++idxVal){
attributes[idxVal][nbParticles] = values[idxVal];
}
nbParticles += 1;
// enought space?
increaseSizeIfNeeded();
// insert particle data
positions[0][nbParticles] = inParticlePosition.getX();
positions[1][nbParticles] = inParticlePosition.getY();
positions[2][nbParticles] = inParticlePosition.getZ();
// insert attribute data
for(int idxVal = 0 ; idxVal < NbAttributesPerParticle ; ++idxVal){
attributes[idxVal][nbParticles] = values[idxVal];
}
nbParticles += 1;
}
/**
......@@ -241,12 +263,12 @@ public:
*/
template<typename... Args>
void push(const FPoint& inParticlePosition, const FParticleType /*particleType*/, Args... args){
push(inParticlePosition, args...);
push(inParticlePosition, args...);
}
/** set nb particles to 0 */
void clear(){
nbParticles = 0;
nbParticles = 0;
}
/** to enable rearranging
......@@ -254,47 +276,47 @@ public:
* it removes all the particles at position indexesToRemove
*/
void removeParticles(const int indexesToRemove[], const int nbParticlesToRemove){
int offset = 1;
int idxIndexes = 1;
int idxIns = indexesToRemove[0] + 1;
for( ; idxIns < nbParticles && idxIndexes < nbParticlesToRemove ; ++idxIns){
if( idxIns == indexesToRemove[idxIndexes] ){
idxIndexes += 1;
offset += 1;
}
else{
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx][idxIns-offset] = positions[idx][idxIns];
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx][idxIns-offset] = attributes[idx][idxIns];
}
}
}
for( ; idxIns < nbParticles ; ++idxIns){
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx][idxIns-offset] = positions[idx][idxIns];
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx][idxIns-offset] = attributes[idx][idxIns];
}
}
nbParticles -= nbParticlesToRemove;
int offset = 1;
int idxIndexes = 1;
int idxIns = indexesToRemove[0] + 1;
for( ; idxIns < nbParticles && idxIndexes < nbParticlesToRemove ; ++idxIns){
if( idxIns == indexesToRemove[idxIndexes] ){
idxIndexes += 1;
offset += 1;
}
else{
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx][idxIns-offset] = positions[idx][idxIns];
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx][idxIns-offset] = attributes[idx][idxIns];
}
}
}
for( ; idxIns < nbParticles ; ++idxIns){
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx][idxIns-offset] = positions[idx][idxIns];
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx][idxIns-offset] = attributes[idx][idxIns];
}
}
nbParticles -= nbParticlesToRemove;
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
AttributeClass* getRawData(){
return reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
return reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
}
const AttributeClass* getRawData() const {
return reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
return reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
}
int getLeadingRawData() const {
return allocatedParticles;
return allocatedParticles;
}
/////////////////////////////////////////////////////
......@@ -302,64 +324,62 @@ public:
/** The size to send a leaf */
int getSavedSize() const{
return int(sizeof(nbParticles) + nbParticles * (3 * sizeof(FReal) + NbAttributesPerParticle * sizeof(AttributeClass)));
return int(sizeof(nbParticles) + nbParticles * (3 * sizeof(FReal) + NbAttributesPerParticle * sizeof(AttributeClass)));
}
/** Save the current cell in a buffer */
template <class BufferWriterClass>
void save(BufferWriterClass& buffer) const{
buffer << nbParticles;
for(int idx = 0 ; idx < 3 ; ++idx){
buffer.write(positions[idx], nbParticles);
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
buffer.write(attributes[idx], nbParticles);
}
buffer << nbParticles;
for(int idx = 0 ; idx < 3 ; ++idx){
buffer.write(positions[idx], nbParticles);
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
buffer.write(attributes[idx], nbParticles);
}
}
/** Restore the current cell from a buffer */
template <class BufferReaderClass>
void restore(BufferReaderClass& buffer){
buffer >> nbParticles;
if( nbParticles >= allocatedParticles ){
// allocate memory
const int moduloParticlesNumber = (32/sizeof(FReal)); // We want to be rounded to 32B
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));
memset( newData, 0, allocatedBytes);
FAlignedMemory::Dealloc32BAligned(positions[0]);
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx] = newData + (allocatedParticles * idx);
}
AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx] = startAddress + (idx * allocatedParticles);
}
}
for(int idx = 0 ; idx < 3 ; ++idx){
buffer.fillArray(positions[idx], nbParticles);
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
buffer.fillArray(attributes[idx], nbParticles);
}
buffer >> nbParticles;
if( nbParticles >= allocatedParticles ){
// allocate memory
const int moduloParticlesNumber = (32/sizeof(FReal)); // We want to be rounded to 32B
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));
memset( newData, 0, allocatedBytes);
FAlignedMemory::Dealloc32BAligned(positions[0]);
for(int idx = 0 ; idx < 3 ; ++idx){
positions[idx] = newData + (allocatedParticles * idx);
}
AttributeClass* startAddress = reinterpret_cast<AttributeClass*>(positions[2] + allocatedParticles);
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
attributes[idx] = startAddress + (idx * allocatedParticles);
}
}
for(int idx = 0 ; idx < 3 ; ++idx){
buffer.fillArray(positions[idx], nbParticles);
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
buffer.fillArray(attributes[idx], nbParticles);
}
}
/** Reset the attributes to zeros */
void resetToInitialState(){
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
memset(attributes[idx], 0, sizeof(AttributeClass) * allocatedParticles);
}
for(unsigned idx = 0 ; idx < NbAttributesPerParticle ; ++idx){
memset(attributes[idx], 0, sizeof(AttributeClass) * allocatedParticles);
}
}
/** Reset the attributes to zeros */
void resetToInitialState(const int idxAttribute){
memset(attributes[idxAttribute], 0, sizeof(AttributeClass) * allocatedParticles);
memset(attributes[idxAttribute], 0, sizeof(AttributeClass) * allocatedParticles);
}
};
#endif //FBASICPARTICLECONTAINER_HPP
......@@ -4,13 +4,13 @@
// 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.
//
// 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.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#ifndef FSIMPLELEAF_HPP
......@@ -41,16 +41,28 @@ public:
*/
template<typename... Args>
void push(const FPoint& inParticlePosition, Args ... args){
// We pass every thing to the container and let it manage
this->particles.push(inParticlePosition, args...);
// We pass every thing to the container and let it manage
this->particles.push(inParticlePosition, args...);
}
/**
* To add several new particles
* @param inParticlePosition array of the positions of the parts to be stored in that leaf
* and the other parameters given by the user
*/
template<typename... Args>
void pushArray(const FPoint* inParticlePosition, int numberOfParts, Args ... args){
// We pass every thing to the container and let it manage
this->particles.pushArray(inParticlePosition,numberOfParts, args...);
}
/**
* To get all the sources in a leaf
* @return a pointer to the list of particles that are sources
*/
ContainerClass* getSrc() {
return &this->particles;
return &this->particles;
}
/**
......@@ -58,11 +70,9 @@ public:
* @return a pointer to the list of particles that are targets
*/
ContainerClass* getTargets() {
return &this->particles;
return &this->particles;
}
};
#endif //FSIMPLELEAF_HPP
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