Commit 04108166 authored by BRAMAS Berenger's avatar BRAMAS Berenger

Updated comments and refactored the code, now all mpi function are based on an...

Updated comments and refactored the code, now all mpi function are based on an independant communicator
parent f3889b01
......@@ -19,6 +19,11 @@
/** This class is an arranger, it move the particles that need
* to be hosted in a different leaf
* \n
* For example, if a simulation has been executed and the position
* of the particles have been changed, then it may be better
* to move the particles in the tree instead of building a new
* tree.
*/
template <class OctreeClass, class ContainerClass, class ParticleClass>
class FOctreeArranger : FAssertable {
......
......@@ -18,7 +18,12 @@
/** This class is an arranger, it move the particles that need
* to be hosted in a different leaf
* This is the parallel version.
* This is the parallel version that use MPI.
* \n
* For example, if a simulation has been executed and the position
* of the particles have been changed, then it may be better
* to move the particles in the tree instead of building a new
* tree.
*/
template <class OctreeClass, class ContainerClass, class ParticleClass>
class FOctreeArrangerProc : FAssertable {
......
......@@ -18,12 +18,11 @@
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractCell
* @brief
* Please read the license
*
* This class define the method that every cell class
* has to implement.
*
* In fact FOctree & FFmmAlgorithm need this function to be implemented.
* This class define the methods that every cell class
* has to implement to be insertable in the tree.
* \n
* In fact FOctree & FFmmAlgorithm need this functions to be implemented.
* But you cannot use this interface with the extension (as an example :
* because the compiler will faill to know if getMortonIndex is coming
* from this interface or from the extension)
......@@ -37,9 +36,9 @@ public:
}
/**
* Must be implemented by each user Cell class
* @return the position of the current cell
*/
* Must be implemented by each user Cell class
* @return the position of the current cell
*/
virtual MortonIndex getMortonIndex() const = 0;
......
......@@ -71,10 +71,11 @@ public:
/**
* L2L
* Local to local
* @param the father to take value from
* @param the child to downward values (child may have already been impacted by M2L)
* @param level the current level of computation
* @param local the father to take value from
* @param child the child to downward values (child may have already been impacted by M2L)
* @param inLevel the current level of computation
* the child array has a size of 8 elements (address if exists or 0 otherwise).
* Children are ordering in the morton index way.
* You must test if a pointer is 0 to know if an element exists inside this array
*/
virtual void L2L(const CellClass* const FRestrict local, CellClass* FRestrict * const FRestrict child, const int inLevel) = 0;
......
......@@ -6,7 +6,7 @@ class FBufferWriter;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractSendable
* @class FAbstractSerializable
* Please read the license
*
* This propose an interface to save and restore a class
......
......@@ -33,10 +33,12 @@ public:
virtual ~FBasicCell(){
}
/** Save the current cell in a buffer */
void save(FBufferWriter& buffer) const{
FExtendMortonIndex::save(buffer);
FExtendCoordinate::save(buffer);
}
/** Restore the current cell from a buffer */
void restore(FBufferReader& buffer){
FExtendMortonIndex::restore(buffer);
FExtendCoordinate::restore(buffer);
......
......@@ -14,8 +14,6 @@
#include "FAbstractKernels.hpp"
#include "../Utils/FGlobal.hpp"
#include "../Utils/FTrace.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
......@@ -23,8 +21,7 @@
* @brief
* Please read the license
*
* This kernels simply shows the details of the information
* it receives (in debug)
* This kernels is empty and does nothing.
*/
template< class ParticleClass, class CellClass, class ContainerClass>
class FBasicKernels : public FAbstractKernels<ParticleClass,CellClass,ContainerClass> {
......
......@@ -27,9 +27,11 @@
*/
class FBasicParticle : public FExtendPosition{
public:
/** Save the current cell in a buffer */
void save(FBufferWriter& buffer) const{
FExtendPosition::save(buffer);
}
/** Restore the current cell from a buffer */
void restore(FBufferReader& buffer){
FExtendPosition::restore(buffer);
}
......
......@@ -12,7 +12,7 @@
#define FFmaPARTICLE_HPP
#include "FBasicParticle.hpp"
#include "../Extensions/FExtendPosition.hpp"
#include "../Extensions/FExtendPhysicalValue.hpp"
/**
......@@ -23,14 +23,16 @@
* This class defines a particle for FMA loader.
* As defined in FFmaLoader it needs {FBasicParticle,FExtendPhysicalValue}
*/
class FFmaParticle : public FBasicParticle, public FExtendPhysicalValue {
class FFmaParticle : public FExtendPosition, public FExtendPhysicalValue {
public:
/** Save the current cell in a buffer */
void save(FBufferWriter& buffer) const{
FBasicParticle::save(buffer);
FExtendPosition::save(buffer);
FExtendPhysicalValue::save(buffer);
}
/** Restore the current cell from a buffer */
void restore(FBufferReader& buffer){
FBasicParticle::restore(buffer);
FExtendPosition::restore(buffer);
FExtendPhysicalValue::restore(buffer);
}
};
......
......@@ -33,7 +33,7 @@ public:
/**
* To add a new particle in the leaf
* @param particle the new particle
* @param particle the new particle to store in the current leaf
*/
void push(const ParticleClass& particle){
this->particles.push(particle);
......
......@@ -20,7 +20,7 @@
* Please read the license
*
* This class is used in the FTestKernels, please
* look at this class to know what it is.
* look at this class to know how to customize a cell.
*
* This cell simply store the data when up/down
*/
......@@ -51,25 +51,36 @@ public:
this->dataDown = inData;
}
/////////////////////////////////////////////////
/** Save the current cell in a buffer */
void save(FBufferWriter& buffer) const{
FBasicCell::save(buffer);
buffer << dataDown << dataUp;
}
/** Restore the current cell from a buffer */
void restore(FBufferReader& buffer){
FBasicCell::restore(buffer);
buffer >> dataDown >> dataUp;
}
/////////////////////////////////////////////////
/** Serialize only up data in a buffer */
void serializeUp(FBufferWriter& buffer) const {
buffer << this->dataUp;
}
/** Deserialize only up data in a buffer */
void deserializeUp(FBufferReader& buffer){
buffer >> this->dataUp;
}
/** Serialize only down data in a buffer */
void serializeDown(FBufferWriter& buffer) const {
buffer << this->dataDown;
}
/** Deserialize only up data in a buffer */
void deserializeDown(FBufferReader& buffer){
buffer >> this->dataDown;
}
......
......@@ -27,7 +27,9 @@
*
* This kernels is a virtual kernels to validate that the fmm algorithm is
* correctly done on particles.
* It used FTestCell and FTestParticle
* It should use FTestCell and FTestParticle.
* A the end of a computation, the particles should host then number of particles
* in the simulation (-1).
*/
template< class ParticleClass, class CellClass, class ContainerClass>
class FTestKernels : public FAbstractKernels<ParticleClass,CellClass,ContainerClass> {
......@@ -38,14 +40,12 @@ public:
/** Before upward */
void P2M(CellClass* const pole, const ContainerClass* const particles) {
// the pole represents all particles under
pole->setDataUp(pole->getDataUp() + particles->getSize());
}
/** During upward */
void M2M(CellClass* const FRestrict pole, const CellClass *const FRestrict *const FRestrict child, const int /*level*/) {
// A parent represents the sum of the child
for(int idx = 0 ; idx < 8 ; ++idx){
if(child[idx]){
......@@ -56,7 +56,6 @@ public:
/** Before Downward */
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343], const int /*size*/, const int /*level*/) {
// The pole is impacted by what represent other poles
for(int idx = 0 ; idx < 343 ; ++idx){
if(distantNeighbors[idx]){
......@@ -67,7 +66,6 @@ public:
/** During Downward */
void L2L(const CellClass*const FRestrict local, CellClass* FRestrict *const FRestrict child, const int /*level*/) {
// Each child is impacted by the father
for(int idx = 0 ; idx < 8 ; ++idx){
if(child[idx]){
......@@ -79,7 +77,6 @@ public:
/** After Downward */
void L2P(const CellClass* const local, ContainerClass*const particles){
// The particles is impacted by the parent cell
typename ContainerClass::BasicIterator iter(*particles);
while( iter.hasNotFinished() ){
......@@ -94,7 +91,6 @@ public:
void P2P(const FTreeCoordinate& ,
ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27], const int ){
// Each particles targeted is impacted by the particles sources
long long int inc = sources->getSize();
if(targets == sources){
......@@ -118,7 +114,6 @@ public:
void P2PRemote(const FTreeCoordinate& ,
ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27], const int ){
// Each particles targeted is impacted by the particles sources
long long int inc = 0;
for(int idx = 0 ; idx < 27 ; ++idx){
......
......@@ -22,7 +22,8 @@
* This class is used in the FTestKernels, please
* look at this class to know whit it is.
*
* Particles just need the data down.
* Particles just need the data down (after and run with FTestKernel the
* value shoud be NB PARTICLES (-1)).
*/
class FTestParticle : public FBasicParticle {
protected:
......@@ -46,10 +47,15 @@ public:
this->dataDown = inData;
}
//////////////////////////////////////////////////
/** Save the current cell in a buffer */
void save(FBufferWriter& buffer) const{
FBasicParticle::save(buffer);
buffer << dataDown;
}
/** Restore the current cell from a buffer */
void restore(FBufferReader& buffer){
FBasicParticle::restore(buffer);
buffer >> dataDown;
......
......@@ -21,12 +21,14 @@
* @brief
* Please read the license
* This class is used to enable the use of typed particles
* (source XOR target) or simple system (source AND target)
* (source XOR target) or simple system (source AND target).
*
* Particles should be typed to enable targets/sources difference.
*/
template< class ParticleClass , class ContainerClass>
class FTypedLeaf : public FAbstractLeaf<ParticleClass,ContainerClass>, public FAssertable {
ContainerClass sources;
ContainerClass targets;
ContainerClass sources; //< The sources containers
ContainerClass targets; //< The targets containers
public:
/** Default destructor */
......@@ -38,6 +40,7 @@ public:
* @param particle the new particle
*/
void push(const ParticleClass& particle){
// Test if is source or target particle
if(particle.isTarget()) this->targets.push(particle);
else if(particle.isSource()) this->sources.push(particle);
else fassert(false, "Error particle has undefined type.", __LINE__, __FILE__);
......
......@@ -21,22 +21,24 @@
* Please read the license
*
* A bool array is a dynamique allocated array that used 1 bit per value.
* Under the wood, it use bit operations to acess/set value in an array of
* native type.
*/
class FBoolArray{
/** Size of a unsigned long */
const static int SizeOfLong = sizeof(unsigned long);
const static int BytesInBlock = sizeof(unsigned long);
const static int SizeOfBlock = BytesInBlock * 8;
/** Size of the array => number of real elements */
const int size;
/** The array to store bits */
unsigned long* const array;
/** Size of the memory allocated */
const int memSize;
/** Size of the array => number of real elements */
const int size;
/** get size to number of long */
int LongFromSize(const int inSize){
const int nbLong = (inSize / (SizeOfLong * 8) );
return nbLong + 1;
return ((inSize + SizeOfBlock - 1) / SizeOfBlock);
}
/** Alloc an array */
......@@ -46,12 +48,12 @@ class FBoolArray{
public :
/** Constructor with size */
FBoolArray(const int inSize) : size(inSize), array(AllocArray(inSize)), memSize(LongFromSize(inSize)*SizeOfLong) {
FBoolArray(const int inSize) : array(AllocArray(inSize)), memSize(LongFromSize(inSize)*BytesInBlock), size(inSize) {
setToZeros();
}
/** Constructor form another array */
FBoolArray(const FBoolArray& other): size(other.size), array(AllocArray(other.size)), memSize(other.memSize){
FBoolArray(const FBoolArray& other): array(AllocArray(other.size)), memSize(other.memSize), size(other.size){
*this = other;
}
......@@ -87,14 +89,14 @@ public :
/** To get a value */
bool get(const int inPos) const {
const int posInArray = inPos / (SizeOfLong*8);
const int posInArray = inPos / SizeOfBlock;
const int bytePosition = inPos - (posInArray * 8);
return (array[posInArray] >> bytePosition) & 1;
}
/** To set a value */
void set(const int inPos, const bool inVal){
const int posInArray = inPos / (SizeOfLong*8);
const int posInArray = inPos / SizeOfBlock;
const int bytePosition = inPos - (posInArray * 8);
if(inVal) array[posInArray] |= (1UL << bytePosition);
else array[posInArray] &= ~(1UL << bytePosition);
......
......@@ -18,8 +18,7 @@
* 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
* Specifie the needed space with reserve, then fill it with data
* finaly read and convert.
*/
class FBufferReader {
......
......@@ -15,6 +15,8 @@
* @author Berenger Bramas (berenger.bramas@inria.fr)This class is a light octree
* It is just a linked list with 8 pointers per node
* it is used to store small data in an octree way.
* @warning It can only store one level of data!
* As it is linked, the acess is always made fro the top.
*/
template <class CellClass>
class FLightOctree {
......
......@@ -23,7 +23,7 @@
* This class is a linked list container.
* It is a very basic list to enable strong performance.
*
* Please refere to unit test flistUTest.cpp to know more.
* Please refere to unit test utestList.cpp to know more.
*/
template< class Object >
class FList {
......
......@@ -31,29 +31,33 @@
* This class is an octree container.
*
* Please refere to testOctree.cpp to see an example.
* <code>
* @code
* // can be used as : <br>
* FOctree<TestParticle, TestCell> tree(1.0,FPoint(0.5,0.5,0.5));
* </code>
* @endcode
*
* Particles and cells has to respect the Abstract class definition.
* Particle must extend {FExtendPosition}
* Cell must extend extend {FTreeCoordinate,FExtendMortonIndex}
*
* If the octree as an height H, then it goes from 0 to H-1
* at level 0 the space is not split
*/
template< class ParticleClass, class CellClass, class ContainerClass, class LeafClass>
class FOctree : protected FAssertable, public FNoCopyable {
FReal*const boxWidthAtLevel; //< to store the width of each boxs at all levels
FAbstractSubOctree< ParticleClass, CellClass , ContainerClass, LeafClass>* root; //< root suboctree
FReal*const boxWidthAtLevel; //< to store the width of each boxs at all levels
const int height; //< tree height
const int subHeight; //< tree height
const int leafIndex; //< index of leaf int array
FAbstractSubOctree< ParticleClass, CellClass , ContainerClass, LeafClass>* root; //< root suboctree
const FPoint boxCenter; //< the space system center
const FPoint boxCorner; //< the space system corner (used to compute morton index)
const FReal boxWidth; //< the space system width
const FReal boxWidth; //< the space system width
/**
......@@ -89,15 +93,17 @@ class FOctree : protected FAssertable, public FNoCopyable {
public:
/**
* Constructor
* @param inBoxWidth box width for this simulation
* @param inBoxCenter box center for this simulation
*/
* Constructor
* @param inHeight the octree height
* @param inSubHeight the octree subheight
* @param inBoxWidth box width for this simulation
* @param inBoxCenter box center for this simulation
*/
FOctree(const int inHeight, const int inSubHeight,
const FReal inBoxWidth, const FPoint& inBoxCenter)
: boxWidthAtLevel(new FReal[inHeight]),
: root(0), boxWidthAtLevel(new FReal[inHeight]),
height(inHeight) , subHeight(inSubHeight), leafIndex(this->height-1),
root(0), boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth)
boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth)
{
fassert(subHeight <= height - 1, "Subheight cannot be greater than height", __LINE__, __FILE__ );
// Does we only need one suboctree?
......@@ -178,15 +184,15 @@ public:
}
/** Remove a leaf from its morton index
* @param the index of the leaf to remove
*/
* @param indexToRemove the index of the leaf to remove
*/
void removeLeaf(const MortonIndex indexToRemove ){
root->removeLeaf( indexToRemove , this->height);
}
/**
* Get a morton index from a real position
* @param a position to compute MI
* @param position a position to compute MI
* @return the morton index
*/
MortonIndex getMortonFromPosition(const FPoint& position) const {
......@@ -219,7 +225,7 @@ public:
* It simply stores an pointer on a suboctree and moves to right/left/up/down.
* Please refere to testOctreeIter file to see how it works.
*
* <code>
* @code
* FOctree<TestParticle, TestCell, NbLevels, NbSubLevels>::Iterator octreeIterator(&tree); <br>
* octreeIterator.gotoBottomLeft(); <br>
* for(int idx = 0 ; idx < NbLevels - 1; ++idx ){ <br>
......@@ -229,7 +235,7 @@ public:
* octreeIterator.moveUp(); <br>
* octreeIterator.gotoLeft(); <br>
* } <br>
* <code>
* @endcode
* Remark :
* It uses the left right limit on each suboctree and their morton index.
* Please have a look to the move functions to understand how the system is working.
......@@ -237,13 +243,13 @@ public:
class Iterator : protected FAssertable {
SubOctreeTypes current; //< Current suboctree
int currentLocalIndex; //< Current index (array position) in the current_suboctree.cells[ currentLocalLevel ]
int currentLocalIndex; //< Current index (array position) in the current_suboctree.cells[ currentLocalLevel ]
int currentLocalLevel; //< Current level in the current suboctree
/**
* To know what is the left limit on the current level on the current subtree
* @retrun suboctree.left_limit >> 3 * diff(leaf_index, current_index).
*/
* To know what is the left limit on the current level on the current subtree
* @return suboctree.left_limit >> 3 * diff(leaf_index, current_index).
*/
static int TransposeIndex(const int indexInLeafLevel, const int distanceFromLeafLevel) {
return indexInLeafLevel >> (3 * distanceFromLeafLevel);
}
......
......@@ -49,10 +49,10 @@ protected:
CellClass*** cells; //< Potential cells, cells are allocated only if needed
FAbstractSubOctree* const parent; //< Parent suboctree (null for root)
const int indexInParent; //< This is the index of the current octree in the parent's array
const int indexInParent; //< This is the index of the current octree in the parent's array
int leftLeafIndex; //< The leaf at the left position (this is the array index to start when iterate)
int rightLeafIndex; //< The leaf at the right position (this is the last array index when iterate)
int leftLeafIndex; //< The leaf at the left position (this is the array index to start when iterate)
int rightLeafIndex; //< The leaf at the right position (this is the last array index when iterate)
const int subOctreeHeight; //< Height of this suboctree
const int subOctreePosition; //< Level of the current suboctree in the global tree (0 if node)
......
......@@ -24,7 +24,8 @@
*
* This class represents tree coordinate. It is used to save
* the position in "box unit" (not system/space unit!).
* It is directly related to morton index
* It is directly related to morton index, as interleaves
* bits from this coordinate make the morton index
*/
class FTreeCoordinate{
private:
......
......@@ -24,7 +24,7 @@
* This class is a vector container.
* It is a very basic vector to enable strong performance.
*
* Please refere to unit test utestFVector.cpp to know more.
* Please refere to unit test utestVector.cpp to know more.
*/
template<class ObjectType>
class FVector {
......
......@@ -58,6 +58,8 @@ class FFmmAlgorithmThreadProc : protected FAssertable {
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
const FMpi::FComm& comm; //< MPI comm
typename OctreeClass::Iterator* iterArray;
int numberOfLeafs; //< To store the size at the previous level
......@@ -96,11 +98,11 @@ public:
* @param inKernels the kernels to call
* An assert is launched if one of the arguments is null
*/
FFmmAlgorithmThreadProc(const FMpi::FComm& comm, OctreeClass* const inTree, KernelClass* const inKernels)
: tree(inTree) , kernels(0), numberOfLeafs(0),
MaxThreads(omp_get_max_threads()), nbProcess(comm.processCount()), idProcess(comm.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[comm.processCount()]),
workingIntervalsPerLevel(new Interval[comm.processCount() * tree->getHeight()]){
FFmmAlgorithmThreadProc(const FMpi::FComm& inComm, OctreeClass* const inTree, KernelClass* const inKernels)
: tree(inTree) , kernels(0), comm(inComm), numberOfLeafs(0),
MaxThreads(omp_get_max_threads()), nbProcess(inComm.processCount()), idProcess(inComm.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[inComm.processCount()]),
workingIntervalsPerLevel(new Interval[inComm.processCount() * tree->getHeight()]){
fassert(tree, "tree cannot be null", __LINE__, __FILE__);
......@@ -150,7 +152,7 @@ public:
fassert(iterArray, "iterArray bad alloc", __LINE__, __FILE__);
// We get the min/max indexes from each procs
FMpi::MpiAssert( MPI_Allgather( &myLastInterval, sizeof(Interval), MPI_BYTE, intervals, sizeof(Interval), MPI_BYTE, MPI_COMM_WORLD), __LINE__ );
FMpi::MpiAssert( MPI_Allgather( &myLastInterval, sizeof(Interval), MPI_BYTE, intervals, sizeof(Interval), MPI_BYTE, comm.getComm()), __LINE__ );
Interval*const myIntervals = new Interval[OctreeHeight];
myIntervals[OctreeHeight - 1] = myLastInterval;
......@@ -177,7 +179,7 @@ public:
// We get the min/max indexes from each procs
FMpi::MpiAssert( MPI_Allgather( myIntervals, int(sizeof(Interval)) * OctreeHeight, MPI_BYTE,
workingIntervalsPerLevel, int(sizeof(Interval)) * OctreeHeight, MPI_BYTE, MPI_COMM_WORLD), __LINE__ );
workingIntervalsPerLevel, int(sizeof(Interval)) * OctreeHeight, MPI_BYTE, comm.getComm()), __LINE__ );
delete[] myIntervals;
}
......@@ -318,7 +320,7 @@ private:
--sendToProc;
}
MPI_Isend(sendBuffer.data(), sendBuffer.getSize(), MPI_BYTE, sendToProc, FMpi::TagFmmM2M, MPI_COMM_WORLD, &requests[iterRequests++]);
MPI_Isend(sendBuffer.data(), sendBuffer.getSize(), MPI_BYTE, sendToProc, FMpi::TagFmmM2M, comm.getComm(), &requests[iterRequests++]);
}
// We may need to receive something
......@@ -347,7 +349,7 @@ private:
for(int idxProc = firstProcThatSend ; idxProc < endProcThatSend ; ++idxProc ){
MPI_Irecv(&recvBuffer.data()[idxProc * recvBufferOffset], recvBufferOffset, MPI_BYTE,
idxProc, FMpi::TagFmmM2M, MPI_COMM_WORLD, &requests[iterRequests++]);
idxProc, FMpi::TagFmmM2M, comm.getComm(), &requests[iterRequests++]);
}
}
}
......@@ -546,7 +548,7 @@ private:
// what the will send to who
int*const globalReceiveMap = new int[nbProcess * nbProcess * OctreeHeight];
memset(globalReceiveMap, 0, sizeof(int) * nbProcess * nbProcess * OctreeHeight);
FMpi::MpiAssert( MPI_Allgather( indexToSend, nbProcess * OctreeHeight, MPI_INT, globalReceiveMap, nbProcess * OctreeHeight, MPI_INT, MPI_COMM_WORLD), __LINE__ );
FMpi::MpiAssert( MPI_Allgather( indexToSend, nbProcess * OctreeHeight, MPI_INT, globalReceiveMap, nbProcess * OctreeHeight, MPI_INT, comm.getComm()), __LINE__ );
FDEBUG(gatherCounter.tac());
......@@ -583,7 +585,7 @@ private:
}
FMpi::MpiAssert( MPI_Isend( sendBuffer[idxLevel * nbProcess + idxProc]->data(), sendBuffer[idxLevel * nbProcess + idxProc]->getSize()
, MPI_BYTE , idxProc, FMpi::TagLast + idxLevel, MPI_COMM_WORLD, &requests[iterRequest++]) , __LINE__ );
, MPI_BYTE , idxProc, FMpi::TagLast + idxLevel, comm.getComm(), &requests[iterRequest++]) , __LINE__ );
}
const int toReceiveFromProcAtLevel = globalReceiveMap[(idxProc * nbProcess * OctreeHeight) + idxLevel * nbProcess + idProcess];
......@@ -591,7 +593,7 @@ private:
recvBuffer[idxLevel * nbProcess + idxProc] = new FBufferReader(toReceiveFromProcAtLevel * SizeOfCellToSend);
FMpi::MpiAssert( MPI_Irecv(recvBuffer[idxLevel * nbProcess + idxProc]->data(), recvBuffer[idxLevel * nbProcess + idxProc]->getSize(), MPI_BYTE,
idxProc, FMpi::TagLast + idxLevel, MPI_COMM_WORLD, &requests[iterRequest++]) , __LINE__ );
idxProc, FMpi::TagLast + idxLevel, comm.getComm(), &requests[iterRequest++]) , __LINE__ );
}
}
}
......@@ -839,7 +841,7 @@ private:
MPI_Irecv( recvBuffer.data(), recvBuffer.getSize(), MPI_BYTE, MPI_ANY_SOURCE,
FMpi::TagFmmL2L, MPI_COMM_WORLD, &requests[iterRequests++]);
FMpi::TagFmmL2L, comm.getComm(), &requests[iterRequests++]);
}
<