Commit 1b82a810 authored by berenger-bramas's avatar berenger-bramas
Browse files

Update, refactor, comment and clean the mpi code!

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@224 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 4d47c78d
......@@ -80,12 +80,12 @@ public:
* @param inKernels the kernels to call
* An assert is launched if one of the arguments is null
*/
FFmmAlgorithmThreadProc(FMpi& inApp, OctreeClass* const inTree, KernelClass* const inKernels)
FFmmAlgorithmThreadProc(const FMpi::FComm& comm, OctreeClass* const inTree, KernelClass* const inKernels)
: tree(inTree) , kernels(0), numberOfLeafs(0),
MaxThreads(omp_get_max_threads()), nbProcess(inApp.processCount()), idProcess(inApp.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[inApp.processCount()]),
realIntervalsPerLevel(new Interval[inApp.processCount() * tree->getHeight()]),
workingIntervalsPerLevel(new Interval[inApp.processCount() * tree->getHeight()]){
MaxThreads(omp_get_max_threads()), nbProcess(comm.processCount()), idProcess(comm.processId()),
OctreeHeight(tree->getHeight()),intervals(new Interval[comm.processCount()]),
realIntervalsPerLevel(new Interval[comm.processCount() * tree->getHeight()]),
workingIntervalsPerLevel(new Interval[comm.processCount() * tree->getHeight()]){
fassert(tree, "tree cannot be null", __LINE__, __FILE__);
......
......@@ -54,112 +54,115 @@ public:
* @param filename the name of the file to open
* you can test if file is successfuly open by calling hasNotFinished()
*/
FMpiFmaLoader(const char* const filename, FMpi& app)
FMpiFmaLoader(const char* const filename, const FMpi::FComm& comm, const bool useMpiIO = false)
: boxWidth(0), totalNbParticles(0), nbParticles(0), isOpenFlag(false), particles(0), idxParticles(0) {
/*char nonConstFilename[512];
strcpy(nonConstFilename,filename);
MPI_File file;
if(MPI_File_open(MPI::COMM_WORLD, nonConstFilename, MPI::MODE_RDONLY, MPI::INFO_NULL, &file) == MPI_SUCCESS){
int sizeOfElement(0);
FReal xyzBoxWidth[4];
MPI_Status status;
if( MPI_File_read(file, &sizeOfElement, 1, MPI_INT, &status) == MPI_SUCCESS
&& MPI_File_read(file, &this->totalNbParticles, 1, MPI_LONG_LONG, &status) == MPI_SUCCESS
&& MPI_File_read(file, xyzBoxWidth, 4, MPI_FLOAT, &status) == MPI_SUCCESS ){
FDEBUG(if(sizeOfElement != sizeof(FReal)){)
if( useMpiIO ){
char nonConstFilename[512];
strcpy(nonConstFilename,filename);
MPI_File file;
if(MPI_File_open(MPI::COMM_WORLD, nonConstFilename, MPI::MODE_RDONLY, MPI::INFO_NULL, &file) == MPI_SUCCESS){
int sizeOfElement(0);
FReal xyzBoxWidth[4];
MPI_Status status;
if( MPI_File_read(file, &sizeOfElement, 1, MPI_INT, &status) == MPI_SUCCESS
&& MPI_File_read(file, &this->totalNbParticles, 1, MPI_LONG_LONG, &status) == MPI_SUCCESS
&& MPI_File_read(file, xyzBoxWidth, 4, MPI_FLOAT, &status) == MPI_SUCCESS ){
FDEBUG(if(sizeOfElement != sizeof(FReal)){)
FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
FDEBUG(})
this->boxWidth = xyzBoxWidth[3];
this->centerOfBox.setPosition(xyzBoxWidth[0],xyzBoxWidth[1],xyzBoxWidth[2]);
this->boxWidth *= 2;
this->isOpenFlag = true;
// load my particles
MPI_Offset headDataOffSet(0);
MPI_File_get_position(file, &headDataOffSet);
MPI_Offset filesize(0);
MPI_File_get_size(file, &filesize); // in bytes
filesize = (filesize - headDataOffSet) / sizeof(FReal);
if(filesize/4 != this->totalNbParticles){
printf("Error fileSize %lld, nbPart %lld\n",filesize/4, this->totalNbParticles);
}
// in number of floats
const FSize startPart = comm.getLeft(this->totalNbParticles);
const FSize endPart = comm.getRight(this->totalNbParticles);
nbParticles = (endPart - startPart);
const FSize bufsize = nbParticles * 4;
// local number to read
particles = new FReal[bufsize];
if( sizeof(FReal) == sizeof(float) ){
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_FLOAT, &status);
}
else{
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_DOUBLE, &status);
}
// check if needed
int count(0);
MPI_Get_count(&status, MPI_INT, &count);
FDEBUG(if(count / 4 != this->nbParticles){)
FDEBUG( FDebug::Controller<< "Error read " << count << " data, nbPart is " << this->nbParticles << __LINE__ << " " << __FILE__ << "\n"; )
FDEBUG(})
}
else{
this->totalNbParticles = 0;
}
MPI_File_close(&file);
}
}
else {
FILE* file(fopen(filename, "rb"));
int removeWarning(0);
// test if open
if(file != NULL) {
int sizeOfElement(0);
removeWarning += fread(&sizeOfElement, sizeof(int), 1, file);
FDEBUG(if(sizeOfElement != int(sizeof(FReal)) ){)
FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
printf("%d sizeofelement\n",sizeOfElement);
FDEBUG(})
removeWarning += fread(&this->totalNbParticles, sizeof(FSize), 1, file);
this->boxWidth = xyzBoxWidth[3];
this->centerOfBox.setPosition(xyzBoxWidth[0],xyzBoxWidth[1],xyzBoxWidth[2]);
removeWarning += fread(&this->boxWidth, sizeof(FReal), 1, file);
this->boxWidth *= 2;
FReal x,y,z;
removeWarning += fread(&x, sizeof(FReal), 1, file);
removeWarning += fread(&y, sizeof(FReal), 1, file);
removeWarning += fread(&z, sizeof(FReal), 1, file);
this->centerOfBox.setPosition(x,y,z);
this->isOpenFlag = true;
// load my particles
MPI_Offset headDataOffSet(0);
MPI_File_get_position(file, &headDataOffSet);
const long int headDataOffSet = ftell(file);
fseek(file, 0L, SEEK_END);
const long int filesize = (ftell(file) - headDataOffSet) / sizeof(FReal);
MPI_Offset filesize(0);
MPI_File_get_size(file, &filesize); // in bytes
filesize = (filesize - headDataOffSet) / sizeof(FReal);
if(filesize/4 != this->totalNbParticles){
printf("Error fileSize %lld, nbPart %lld\n",filesize/4, this->totalNbParticles);
printf("Error fileSize %ld, nbPart %lld\n", filesize/4, this->totalNbParticles);
}
// in number of floats
const FSize startPart = app.getLeft(this->totalNbParticles);
const FSize endPart = app.getRight(this->totalNbParticles);
const FSize startPart = comm.getLeft(this->totalNbParticles);
const FSize endPart = comm.getRight(this->totalNbParticles);
nbParticles = (endPart - startPart);
const FSize bufsize = nbParticles * 4;
// local number to read
particles = new FReal[bufsize];
if( sizeof(FReal) == sizeof(float) ){
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_FLOAT, &status);
}
else{
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_DOUBLE, &status);
}
fseek(file, long(headDataOffSet + startPart * 4 * sizeof(FReal)), SEEK_SET);
removeWarning += fread(particles, sizeof(FReal), int(bufsize), file);
// check if needed
int count(0);
MPI_Get_count(&status, MPI_INT, &count);
FDEBUG(if(count / 4 != this->nbParticles){)
FDEBUG( FDebug::Controller<< "Error read " << count << " data, nbPart is " << this->nbParticles << __LINE__ << " " << __FILE__ << "\n"; )
FDEBUG(})
}
else{
this->totalNbParticles = 0;
}
MPI_File_close(&file);
}*/
FILE* file(fopen(filename, "rb"));
int removeWarning(0);
// test if open
if(file != NULL) {
int sizeOfElement(0);
removeWarning += fread(&sizeOfElement, sizeof(int), 1, file);
FDEBUG(if(sizeOfElement != int(sizeof(FReal)) ){)
FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
printf("%d sizeofelement\n",sizeOfElement);
FDEBUG(})
removeWarning += fread(&this->totalNbParticles, sizeof(FSize), 1, file);
removeWarning += fread(&this->boxWidth, sizeof(FReal), 1, file);
this->boxWidth *= 2;
FReal x,y,z;
removeWarning += fread(&x, sizeof(FReal), 1, file);
removeWarning += fread(&y, sizeof(FReal), 1, file);
removeWarning += fread(&z, sizeof(FReal), 1, file);
this->centerOfBox.setPosition(x,y,z);
this->isOpenFlag = true;
const long int headDataOffSet = ftell(file);
fseek(file, 0L, SEEK_END);
const long int filesize = (ftell(file) - headDataOffSet) / sizeof(FReal);
if(filesize/4 != this->totalNbParticles){
printf("Error fileSize %ld, nbPart %lld\n", filesize/4, this->totalNbParticles);
fclose(file);
}
// in number of floats
const FSize startPart = app.getLeft(this->totalNbParticles);
const FSize endPart = app.getRight(this->totalNbParticles);
nbParticles = (endPart - startPart);
const FSize bufsize = nbParticles * 4;
// local number to read
particles = new FReal[bufsize];
fseek(file, long(headDataOffSet + startPart * 4 * sizeof(FReal)), SEEK_SET);
removeWarning += fread(particles, sizeof(FReal), int(bufsize), file);
fclose(file);
}
}
......
This diff is collapsed.
......@@ -10,6 +10,13 @@
#include "FMpi.hpp"
#include "FQuickSort.hpp"
/** This class is a parallel bitonic sort
* it is based on the paper :
* Library Support for Parallel Sorting in Scientific Computations
* Holger Dachsel1 , Michael Hofmann2, , and Gudula R ̈nger2
*/
template <class SortType, class CompareType, class IndexType>
class FBitonicSort {
private:
......@@ -17,22 +24,15 @@ private:
// Bitonic parallel sort !
////////////////////////////////////////////////////////////////
// Mpi flag
static const int FlagMin = 5;
static const int FlagMax = 6;
static const int FlagMinMess = 4;
static const int FlagMaxMess = 3;
// This function exchange data with the other rank,
// its send the max value and receive min value
template <class SortType, class CompareType, class IndexType>
static void sendMaxAndGetMin(SortType array[], const IndexType size, const int otherRank){
static void SendMaxAndGetMin(SortType array[], const IndexType size, const int otherRank){
IndexType left = -1;
IndexType right = size - 1;
IndexType pivot = left + (right - left + 1)/2;
CompareType otherValue = -1;
CompareType tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMin,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMax,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
while( pivot != left && pivot != right && array[pivot] != otherValue) {
......@@ -45,19 +45,19 @@ private:
pivot = left + (right - left + 1)/2;
tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMin,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMax,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
}
if( otherValue <= array[pivot] ){
MPI_Sendrecv_replace(&array[pivot], int((size - pivot) * sizeof(SortType)) , MPI_BYTE,
otherRank, FlagMinMess, otherRank, FlagMaxMess,
otherRank, FMpi::TagBitonicMinMess, otherRank, FMpi::TagBitonicMaxMess,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
else if( array[pivot] < otherValue){
if(pivot != size - 1){
MPI_Sendrecv_replace(&array[pivot + 1], int((size - pivot - 1) * sizeof(SortType)) , MPI_BYTE,
otherRank, FlagMinMess, otherRank, FlagMaxMess,
otherRank, FMpi::TagBitonicMinMess, otherRank, FMpi::TagBitonicMaxMess,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
......@@ -66,14 +66,13 @@ private:
// This function exchange data with the other rank,
// its send the min value and receive max value
template <class SortType, class CompareType, class IndexType>
static void sendMinAndGetMax(SortType array[], const IndexType size, const int otherRank){
static void SendMinAndGetMax(SortType array[], const IndexType size, const int otherRank){
IndexType left = 0;
IndexType right = size ;
IndexType pivot = left + (right - left)/2;
CompareType otherValue = -1;
CompareType tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMax,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMin,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
while( pivot != left && array[pivot] != otherValue) {
......@@ -85,19 +84,19 @@ private:
}
pivot = left + (right - left)/2;
tempCompareValue = CompareType(array[pivot]);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMax,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FlagMin,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Sendrecv(&tempCompareValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMax,&otherValue,sizeof(CompareType),MPI_BYTE,otherRank,FMpi::TagBitonicMin,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
}
if( array[pivot] <= otherValue ){
MPI_Sendrecv_replace(&array[0], int((pivot + 1) * sizeof(SortType)) , MPI_BYTE,
otherRank, FlagMaxMess, otherRank, FlagMinMess,
otherRank, FMpi::TagBitonicMaxMess, otherRank, FMpi::TagBitonicMinMess,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
else if( otherValue < array[pivot]){
if(pivot != 0){
MPI_Sendrecv_replace(&array[0], int((pivot) * sizeof(SortType)) , MPI_BYTE,
otherRank, FlagMaxMess, otherRank, FlagMinMess,
otherRank, FMpi::TagBitonicMaxMess, otherRank, FMpi::TagBitonicMinMess,
MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}
......@@ -127,9 +126,10 @@ public:
endfor
endfor
*/
template <class SortType, class CompareType, class IndexType>
static void sort(SortType array[], const IndexType size, const int np, const int rank){
static void Sort(SortType array[], const IndexType size, const FMpi::FComm& comm){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Bitonic" , __FILE__ , __LINE__) );
const int np = comm.processCount();
const int rank = comm.processId();
FQuickSort<SortType,CompareType,IndexType>::QsOmp(array, size);
......@@ -146,10 +146,10 @@ public:
const int otherRank = rank ^ (1 << otherBit);
if( diBit != myOtherBit ){
sendMinAndGetMax<SortType,CompareType>(array, size, otherRank);
SendMinAndGetMax(array, size, otherRank);
}
else{
sendMaxAndGetMin<SortType,CompareType>(array, size, otherRank);
SendMaxAndGetMin(array, size, otherRank);
}
// A merge sort is possible since the array is composed
// by two part already sorted, but we want to do this in space
......@@ -157,17 +157,6 @@ public:
}
}
}
template <class SortType, class CompareType, class IndexType>
static void sort(SortType array[], const IndexType size){
int rank = 0;
int nprocs = 0;
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
sort<SortType, CompareType>(array, size, nprocs, rank);
}
};
#endif // BITONICSORT_HPP
......@@ -2,7 +2,6 @@
#define FMPI_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "FGlobal.hpp"
#include "FMath.hpp"
......@@ -15,13 +14,13 @@
* @class FMpi
* Please read the license
*
* This namespace is to compile with or without mpi
* It defines a class to access MPI data, if the lib is compiled
* without mpi support then simulate data.
*/
class FMpi {
public:
////////////////////////////////////////////////////////
// MPI Flag
////////////////////////////////////////////////////////
enum FMpiTag {
// FMpiTreeBuilder
TagExchangeIndexs,
......@@ -37,294 +36,255 @@ public:
TagFmmL2L,
TagFmmP2P,
// Bitonic,
TagBitonicMin,
TagBitonicMax,
TagBitonicMinMess,
TagBitonicMaxMess,
// Last defined tag
TagLast,
};
#ifdef SCALFMM_USE_MPI
////////////////////////////////////////////////////////
// FComm to factorize MPI_Comm work
////////////////////////////////////////////////////////
/** This class is used to put all the usual method
* related mpi comm
*/
class FComm {
int rank; //< rank related to the comm
int nbProc; //< nb proc in this group
MPI_Comm communicator; //< current mpi communicator
MPI_Group group; //< current mpi group
// Forbid copy
FComm(const FComm&){}
FComm& operator=(const FComm&){return *this;}
// reset : get rank and nb proc from mpi
void reset(){
FMpi::Assert( MPI_Comm_rank(communicator,&rank), __LINE__ );
FMpi::Assert( MPI_Comm_size(communicator,&nbProc), __LINE__ );
}
public:
/** Constructor : dup the comm given in parameter */
explicit FComm(MPI_Comm inCommunicator ) {
FMpi::Assert( MPI_Comm_dup(inCommunicator, &communicator), __LINE__ , "comm dup");
FMpi::Assert( MPI_Comm_group(communicator, &group), __LINE__ , "comm group");
reset();
}
/** Free communicator and group */
virtual ~FComm(){
FMpi::Assert( MPI_Comm_free(&communicator), __LINE__ );
FMpi::Assert( MPI_Group_free(&group), __LINE__ );
}
/** To get the mpi comm needed for communication */
MPI_Comm getComm() const {
return communicator;
}
/** The current rank */
int processId() const {
return rank;
}
/** The current number of procs in the group */
int processCount() const {
return nbProc;
}
////////////////////////////////////////////////////////////
// Split/Chunk functions
////////////////////////////////////////////////////////////
/** Get a left index related to a size */
template< class T >
T getLeft(const T inSize) const {
const double step = (double(inSize) / double(processCount()));
return T(FMath::Ceil(step * double(processId())));
}
/** Get a right index related to a size */
template< class T >
T getRight(const T inSize) const {
const double step = (double(inSize) / double(processCount()));
const T res = T(FMath::Ceil(step * double(processId()+1)));
if(res > inSize) return inSize;
else return res;
}
/** Get a right index related to a size and another id */
template< class T >
T getOtherRight(const T inSize, const int other) const {
const double step = (double(inSize) / double(processCount()));
const T res = T(FMath::Ceil(step * double(other+1)));
if(res > inSize) return inSize;
else return res;
}
/** Get a left index related to a size and another id */
template< class T >
T getOtherLeft(const T inSize, const int other) const {
const double step = (double(inSize) / double(processCount()));
return T(FMath::Ceil(step * double(other)));
}
/** Get a proc id from and index */
template< class T >
int getProc(const int position, const T inSize) const {
const double step = (double(inSize) / processCount());
return int(position/step);
}
////////////////////////////////////////////////////////////
// Mpi interface functions
////////////////////////////////////////////////////////////
/** Reduce a value for proc == 0 */
template< class T >
T reduceSum(T data) const {
T result;
FMpi::Assert( MPI_Reduce( &data, &result, 1, FMpi::GetType(data), MPI_SUM, 0, communicator ), __LINE__);
return result;
}
/** Reduce an average */
template< class T >
T reduceAverageAll(T data) const {
T result[processCount()];
FMpi::Assert( MPI_Allgather( &data, 1, FMpi::GetType(data), result, 1, FMpi::GetType(data), getComm()), __LINE__ );
T average = 0;
for(int idxProc = 0 ; idxProc < processCount() ;++idxProc){
average += result[idxProc] / processCount();
}
return average;
}
/** Change the group size */
void groupReduce(const int from , const int to){
int procsIdArray[to - from + 1];
for(int idxProc = from ;idxProc <= to ; ++idxProc){
procsIdArray[idxProc - from] = idxProc;
}
MPI_Group previousGroup = group;
FMpi::Assert( MPI_Group_incl(previousGroup, to - from + 1 , procsIdArray, &group), __LINE__ );
MPI_Comm previousComm = communicator;
FMpi::Assert( MPI_Comm_create(previousComm, group, &communicator), __LINE__ );
MPI_Comm_free(&previousComm);
MPI_Group_free(&previousGroup);
reset();
}
};
////////////////////////////////////////////////////////
// Use MPI
// FMpi methods
////////////////////////////////////////////////////////
typedef MPI_Request Request;
/*
[fourmi062:15896] [[13237,0],1]-[[13237,1],1] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
[fourmi056:04597] [[13237,0],3]-[[13237,1],3] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
[fourmi053:08571] [[13237,0],5]-[[13237,1],5] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
We use init with thread because of an openmpi error:
Erreur pour le proc1
[[13237,1],1][btl_openib_component.c:3227:handle_wc] from fourmi062 to: fourmi056 error polling LP CQ with status LOCAL LENGTH ERROR status number 1 for wr_id 7134664 opcode 0 vendor error 105 qp_idx 3
Tous on la meme erreur le 2e 1 est remplacé par le rang.
*/
FMpi(int inArgc, char ** inArgv ) {
[fourmi062:15896] [[13237,0],1]-[[13237,1],1] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
[fourmi056:04597] [[13237,0],3]-[[13237,1],3] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
[fourmi053:08571] [[13237,0],5]-[[13237,1],5] mca_oob_tcp_msg_recv: readv failed: Connection reset by peer (104)
Erreur pour le proc1
[[13237,1],1][btl_openib_component.c:3227:handle_wc] from fourmi062 to: fourmi056 error polling LP CQ with status LOCAL LENGTH ERROR status number 1 for wr_id 7134664 opcode 0 vendor error 105 qp_idx 3
Tous on la meme erreur le 2e 1 est remplacé par le rang.
*/
FMpi(int inArgc, char ** inArgv ) : communicator(0) {
int provided = 0;
MPI_Init_thread(&inArgc,&inArgv, MPI_THREAD_MULTIPLE, &provided);
FMpi::Assert( MPI_Init_thread(&inArgc,&inArgv, MPI_THREAD_MULTIPLE, &provided), __LINE__);
communicator = new FComm(MPI_COMM_WORLD);
}
/** Delete the communicator and call mpi finalize */
~FMpi(){
delete communicator;
MPI_Finalize();
}
void allgather(void* const sendbuf, const int sendcount, void* const recvbuf, const int recvcount, MPI_Datatype datatype = MPI_INT){
MPI_Allgather( sendbuf, sendcount, datatype, recvbuf, recvcount, datatype, MPI_COMM_WORLD);
/** Get the global communicator */
const FComm& global() {
return (*communicator);