Commit 08127185 authored by berenger-bramas's avatar berenger-bramas

Create a new system to serialize and send data in proc fmm.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@390 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 89f28df7
// ===================================================================================
// Logiciel initial: ScalFmm Version 0.5
// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
// Propriétaires : INRIA.
// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
// Initial software: ScalFmm Version 0.5
// Co-authors: Olivier Coulaud, Bérenger Bramas.
// Owners: INRIA.
// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
// ===================================================================================
#ifndef FBUFFERREADER_HPP
#define FBUFFERREADER_HPP
#include "FVector.hpp"
/** @author Berenger Bramas
* This class provide a fast way to manage a memory and convert
* the content to basic type.
*
* Specifie the needed space with reserve,
* then fill it with data
* finaly read and convert.
*/
class FBufferReader {
FVector<char> buffer; //< The memory buffer
int index; //< The current index reading position
public:
/** Construct with a memory size init to 0 */
explicit FBufferReader(const int inCapacity = 0) : buffer(inCapacity), index(0) {
if(inCapacity){
reserve(inCapacity);
}
}
/** Destructor */
virtual ~FBufferReader(){
}
/** Get the memory area */
char* data(){
return buffer.data();
}
/** Get the memory area */
const char* data() const {
return buffer.data();
}
/** Size of the meomry initialzed */
int getSize() const{
return buffer.getSize();
}
/** Move the read index to a position */
void seek(const int inIndex){
index = inIndex;
}
/** Get the read position */
int tell() const {
return index;
}
/** Reset and allocate nbBytes memory filled with 0 */
void reserve(const int nbBytes){
buffer.clear();
buffer.set( 0, nbBytes);
}
/** Move the read index to 0 */
void reset(){
buffer.clear();
index = 0;
}
/** Get a value with memory cast */
template <class ClassType>
ClassType getValue(){
ClassType value = (*reinterpret_cast<ClassType*>(&buffer[index]));
index += sizeof(ClassType);
return value;
}
/** Fill a value with memory cast */
template <class ClassType>
void fillValue(ClassType* const inValue){
(*inValue) = (*reinterpret_cast<ClassType*>(&buffer[index]));
index += sizeof(ClassType);
}
/** Fill one/many value(s) with memcpy */
template <class ClassType>
void fillArray(ClassType* const inArray, const int inSize){
memcpy( inArray, &buffer[index], sizeof(ClassType) * inSize);
index += sizeof(ClassType) * inSize;
}
/** Same as fillValue */
template <class ClassType>
FBufferReader& operator>>(ClassType& object){
fillValue(&object);
return *this;
}
};
#endif // FBUFFERREADER_HPP
// ===================================================================================
// Logiciel initial: ScalFmm Version 0.5
// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
// Propriétaires : INRIA.
// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
// Initial software: ScalFmm Version 0.5
// Co-authors: Olivier Coulaud, Bérenger Bramas.
// Owners: INRIA.
// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
// ===================================================================================
#ifndef FBUFFERWRITER_HPP
#define FBUFFERWRITER_HPP
#include "FVector.hpp"
/** @author Berenger Bramas
* This class provide a fast way to manage a memory and fill it
*
* Put some data
* then insert back if needed
* finaly use data pointer as you like
*/
class FBufferWriter {
private:
FVector<char> buffer; //< The buffer
public:
/** Constructor with a default capacity of 512 bytes */
explicit FBufferWriter(const int inCapacity = 512) : buffer(inCapacity) {
}
/** Destructor */
virtual ~FBufferWriter(){
}
/** Get allocated memory pointer */
char* data(){
return buffer.data();
}
/** Get allocated memory pointer */
const char* data() const {
return buffer.data();
}
/** Get the filled space */
int getSize() const {
return buffer.getSize();
}
/** Write data by mem cpy */
template <class ClassType>
void write(const ClassType& object){
buffer.memocopy(reinterpret_cast<const char*>(&object), sizeof(ClassType));
}
/** Write back, position + sizeof(object) has to be < size */
template <class ClassType>
void writeAt(const int position, const ClassType& object){
(*reinterpret_cast<ClassType*>(&buffer[position])) = object;
}
/** Write an array */
template <class ClassType>
void write(const ClassType* const objects, const int inSize){
buffer.memocopy(reinterpret_cast<const char*>(objects), sizeof(ClassType) * inSize);
}
/** Equivalent to write */
template <class ClassType>
FBufferWriter& operator<<(const ClassType& object){
write(object);
return *this;
}
/** Reset the writing index, but do not change the capacity */
void reset(){
buffer.clear();
}
};
#endif // FBUFFERWRITER_HPP
......@@ -18,11 +18,12 @@
*/
class FLightOctree {
// The node class
class Node {
Node* next[8]; // Child
const void* data; // Data in this cell
public:
Node(){
struct Node {
Node* next[8]; // Child
int proc; // Cell
int position;
Node() : proc(-1), position(-1) {
memset(next, 0, sizeof(Node*)*8);
}
......@@ -31,32 +32,6 @@ class FLightOctree {
delete next[idxNext];
}
}
void insert(const MortonIndex& index, const void* const cell, const int level){
if(level){
const int host = (index >> (3 * (level-1))) & 0x07;
if(!next[host]){
next[host] = new Node();
}
next[host]->insert(index, cell, level - 1);
}
else{
data = cell;
}
}
const void* getCell(const MortonIndex& index, const int level) const {
if(level){
const int host = (index >> (3 * (level-1))) & 0x07;
if(next[host]){
return next[host]->getCell(index, level - 1);
}
return 0;
}
else{
return data;
}
}
};
// Tree root
......@@ -65,13 +40,40 @@ class FLightOctree {
public:
FLightOctree(){
}
// Insert a cell
void insertCell(const MortonIndex& index, const void* const cell, const int level){
root.insert(index, cell, level);
void insertCell(const MortonIndex& index, int level, const int inProc, const int inPosition){
Node* iter = &root;
while(level){
const int host = (index >> (3 * (level-1))) & 0x07;
if(!iter->next[host]){
iter->next[host] = new Node();
}
iter = iter->next[host];
level -= 1;
}
iter->proc = inProc;
iter->position = inPosition;
}
// Retreive a cell
const void* getCell(const MortonIndex& index, const int level) const{
return root.getCell(index, level);
void getCell(const MortonIndex& index, int level, int* const inProc, int* const inPosition) const{
const Node* iter = &root;
while(level){
const int host = (index >> (3 * (level-1))) & 0x07;
if(!iter->next[host]){
*inProc = -1;
*inPosition = -1;
return;
}
iter = iter->next[host];
level -= 1;
}
*inProc = iter->proc;
*inPosition = iter->position;
}
};
......
......@@ -14,6 +14,7 @@
#include "../Utils/FGlobal.hpp"
#include <cstring>
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
......@@ -194,6 +195,22 @@ public:
new((void*)&array[index++]) ObjectType(inValue);
}
/**
* Add one value multiple time
* @param inValue the new value
* @param inRepeat the number of time the value is inserted
*/
void set( const ObjectType & inValue, const int inRepeat){
// if needed, increase the vector
if( capacity < index + inRepeat ){
setCapacity(int((index + inRepeat) * 1.5));
}
// add the new element
for( int idx = 0 ; idx < inRepeat ; ++idx){
new((void*)&array[index++]) ObjectType(inValue);
}
}
/**
*@brief Get a reference of a given value
*@param inPosition the query position
......@@ -226,6 +243,35 @@ public:
return array;
}
/** To take values from C array but copy with = operator
* @param inArray the array to copie values
* @param inSize the size of the array
*/
void extractValues(const ObjectType*const inArray, const int inSize){
// Check available memory
if(capacity < index + inSize){
setCapacity( int((index + inSize) * 1.5) );
}
// Copy values
for(int idx = 0 ; idx < inSize ; ++idx){
new((void*)&array[index++]) ObjectType(inArray[idx]);
}
}
/** To take values from C array but copy with memcpy
* @param inArray the array to copie values
* @param inSize the size of the array
*/
void memocopy(const ObjectType*const inArray, const int inSize){
// Check available memory
if(capacity < index + inSize){
setCapacity( int((index + inSize) * 1.5) );
}
// Copy values
memcpy(&array[index], inArray, inSize * sizeof(ObjectType));
index += inSize;
}
/** This class is a basic iterator
* <code>
* typename FVector<int>::ConstBasicIterator iter(myVector);<br>
......
This diff is collapsed.
// ===================================================================================
// Logiciel initial: ScalFmm Version 0.5
// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
// Propriétaires : INRIA.
// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
// Initial software: ScalFmm Version 0.5
// Co-authors: Olivier Coulaud, Bérenger Bramas.
// Owners: INRIA.
// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
// ===================================================================================
#ifndef FEXTENDFULLYSENDABLE_HPP
#define FEXTENDFULLYSENDABLE_HPP
#include "../Utils/FAbstractSerializable.hpp"
#include "../Containers/FBufferWriter.hpp"
#include "../Containers/FBufferReader.hpp"
/** @author Berenger Bramas
* This extension MUST be put as the first inherited class!
* It copy the memory in the buffer read writer
*/
template <class ClassType>
class FExtendFullySerializable : public FAbstractSerializable {
public:
/** Save current object */
void save(FBufferWriter& buffer) const {
buffer << (*reinterpret_cast<const ClassType*>(this));
}
/** Retrieve current object */
void restore(FBufferReader& buffer) {
buffer >> (*reinterpret_cast<ClassType*>(this));
}
};
#endif // FEXTENDFULLYSENDABLE_HPP
......@@ -15,9 +15,14 @@
#include "../Utils/FAbstractSendable.hpp"
#include "../Utils/FComplexe.hpp"
#include "../Utils/FMemUtils.hpp"
#include "../Extensions/FExtendCellType.hpp"
#include "../Components/FBasicCell.hpp"
#include "../Containers/FBufferWriter.hpp"
#include "../Containers/FBufferReader.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
*/
......@@ -119,39 +124,28 @@ public:
*/
class FSendableSphericalCell : public FSphericalCell , public FAbstractSendable {
public:
static int SerializedSizeDown;
static int SerializedSizeUp;
static void Init(const int inDevP){
FSphericalCell::Init(inDevP);
SerializedSizeDown = PoleSize * sizeof(FComplexe) + sizeof(FBasicCell);
SerializedSizeUp = LocalSize * sizeof(FComplexe) + sizeof(FBasicCell);
}
///////////////////////////////////////////////////////
// to extend FAbstractSendable
///////////////////////////////////////////////////////
void serializeUp(void* const buffer) const {
memcpy(buffer, (FBasicCell*)this, sizeof(FBasicCell));
memcpy((char*)(buffer) + sizeof(FBasicCell), multipole_exp, sizeof(FComplexe)*PoleSize );
void serializeUp(FBufferWriter& buffer) const{
buffer.write(multipole_exp, PoleSize);
}
void deserializeUp(const void* const buffer){
memcpy((FBasicCell*)this, buffer, sizeof(FBasicCell));
memcpy(multipole_exp, (char*)(buffer) + sizeof(FBasicCell), sizeof(FComplexe)*PoleSize );
void deserializeUp(FBufferReader& buffer){
buffer.fillArray(multipole_exp, PoleSize);
}
void serializeDown(void* const buffer) const {
memcpy(buffer, (FBasicCell*)this, sizeof(FBasicCell));
memcpy((char*)(buffer) + sizeof(FBasicCell), local_exp, sizeof(FComplexe)*LocalSize );
void serializeDown(FBufferWriter& buffer) const{
buffer.write(local_exp, LocalSize);
}
void deserializeDown(const void* const buffer){
memcpy((FBasicCell*)this, buffer, sizeof(FBasicCell));
memcpy(local_exp, (char*)(buffer) + sizeof(FBasicCell), sizeof(FComplexe)*LocalSize );
void deserializeDown(FBufferReader& buffer){
buffer.fillArray(local_exp, LocalSize);
}
};
int FSendableSphericalCell::SerializedSizeDown(-1);
int FSendableSphericalCell::SerializedSizeUp(-1);
#endif //FSPHERICALCELL_HPP
......
......@@ -16,10 +16,16 @@
#include "../Extensions/FExtendParticleType.hpp"
#include "../Components/FFmaParticle.hpp"
#include "../Extensions/FExtendFullySerializable.hpp"
class FSphericalParticle : public FExtendForces, public FFmaParticle, public FExtendPotential {
public:
};
class FSendableSphericalParticle : public FExtendFullySerializable<FSendableSphericalParticle>, public FSphericalParticle {
public:
};
class FTypedSphericalParticle : public FSphericalParticle, public FExtendParticleType {
public:
};
......
......@@ -11,27 +11,42 @@
#ifndef FABSTRACTSENDABLE_HPP
#define FABSTRACTSENDABLE_HPP
class FBufferReader;
class FBufferWriter;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractSendable
* Please read the license
*
* To make your cells are usable in the mpi fmm,
* they must provide this interface
*/
class FAbstractSendable {
protected:
/** Empty Destructor */
virtual ~FAbstractSendable(){}
//static const int SerializedSizeUp = sizeof(?);
virtual void serializeUp(void* const buffer) const = 0;
virtual void deserializeUp(const void* const buffer) = 0;
///////////////////////////////////////////////
// For Upward pass
///////////////////////////////////////////////
/** Save your data */
virtual void serializeUp(FBufferWriter&) const = 0;
/** Retrieve your data */
virtual void deserializeUp(FBufferReader&) = 0;
//static const int SerializedSizeDown = sizeof(?);
virtual void serializeDown(void* const buffer) const = 0;
virtual void deserializeDown(const void* const buffer) = 0;
///////////////////////////////////////////////
// For Downward pass
///////////////////////////////////////////////
/** Save your data */
virtual void serializeDown(FBufferWriter&) const = 0;
/** Retrieve your data */
virtual void deserializeDown(FBufferReader&) = 0;
};
#endif //FABSTRACTSENDABLE_HPP
#ifndef FABSTRACTSERIALIZABLE_HPP
#define FABSTRACTSERIALIZABLE_HPP
class FBufferReader;
class FBufferWriter;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractSendable
* Please read the license
*
* This propose an interface to save and restore a class
*
* To make your particles are usable in the mpi fmm,
* they must provide this interface
*/
class FAbstractSerializable {
protected:
/** Empty Destructor */
virtual ~FAbstractSerializable(){}
virtual void save(FBufferWriter&) const = 0;
virtual void restore(FBufferReader&) = 0;
};
#endif // FABSTRACTSERIALIZABLE_HPP
......@@ -169,7 +169,7 @@ void ValidateFMMAlgoProc(OctreeClass* const badTree,
// Simply create particles and try the kernels
int main(int argc, char ** argv){
typedef FSphericalParticle ParticleClass;
typedef FSendableSphericalParticle ParticleClass;
typedef FSendableSphericalCell CellClass;
typedef FVector<ParticleClass> ContainerClass;
......
......@@ -27,6 +27,8 @@
#include "../Src/Components/FTestCell.hpp"
#include "../Src/Components/FTestKernels.hpp"
#include "../Src/Extensions/FExtendPhysicalValue.hpp"
#include "../Src/Extensions/FExtendFullySerializable.hpp"
#include "../Src/Core/FFmmAlgorithmThreadProc.hpp"
#include "../Src/Core/FFmmAlgorithmThread.hpp"
......@@ -281,26 +283,25 @@ void print(OctreeClass* const valideTree){
/** Fmb class has to extend {FExtendForces,FExtendPotential,FExtendPhysicalValue}
* Because we use fma loader it needs {FExtendPhysicalValue}
*/
class TestParticle : public FTestParticle, public FExtendPhysicalValue {
class TestParticle : public FExtendFullySerializable<TestParticle>, public FTestParticle, public FExtendPhysicalValue {
};
class TestCell : public FTestCell , public FAbstractSendable {
public:
static const int SerializedSizeUp = sizeof(long long int);
void serializeUp(void* const buffer) const {
*(long long int*)buffer = this->dataUp;
void serializeUp(FBufferWriter& buffer) const {
buffer << this->dataUp;
}
void deserializeUp(const void* const buffer){
this->dataUp = *(long long int*)buffer;
void deserializeUp(FBufferReader& buffer){
buffer >> this->dataUp;
}
static const int SerializedSizeDown = sizeof(long long int);
void serializeDown(void* const buffer) const {
*(long long int*)buffer = this->dataDown;
void serializeDown(FBufferWriter& buffer) const {
buffer << this->dataDown;
}
void deserializeDown(const void* const buffer){
this->dataDown = *(long long int*)buffer;
void deserializeDown(FBufferReader& buffer){
buffer >> this->dataDown;
}
};
......
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