Commit 0dfdbfdf authored by BRAMAS Berenger's avatar BRAMAS Berenger

Debug quicksort mpi and add a unit test

parent 398c5f08
This diff is collapsed.
......@@ -53,298 +53,298 @@
class FMpi {
public:
////////////////////////////////////////////////////////
// MPI Flag
////////////////////////////////////////////////////////
enum FMpiTag {
// FMpiTreeBuilder
TagExchangeIndexs,
TagSplittedLeaf,
TagExchangeNbLeafs,
TagSandSettling,
// FQuickSort
TagQuickSort,
// FMM
TagFmmM2M,
TagFmmL2L,
TagFmmP2P,
// Bitonic,
TagBitonicMin,
TagBitonicMax,
TagBitonicMinMess,
TagBitonicMaxMess,
// Last defined tag
TagLast,
};
////////////////////////////////////////////////////////
// FComm to factorize MPI_Comm work
////////////////////////////////////////////////////////
/** This class is used to put all the usual method
////////////////////////////////////////////////////////
// MPI Flag
////////////////////////////////////////////////////////
enum FMpiTag {
// FMpiTreeBuilder
TagExchangeIndexs,
TagSplittedLeaf,
TagExchangeNbLeafs,
TagSandSettling,
// FQuickSort
TagQuickSort,
// FMM
TagFmmM2M,
TagFmmL2L,
TagFmmP2P,
// Bitonic,
TagBitonicMin,
TagBitonicMax,
TagBitonicMinMess,
TagBitonicMaxMess,
// Last defined tag
TagLast,
};
////////////////////////////////////////////////////////
// FComm to factorize MPI_Comm work
////////////////////////////////////////////////////////
/** This class is used to put all the usual method
* related mpi comm
*/
class FComm : public FNoCopyable {
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
class FComm : public FNoCopyable {
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
// 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(0);
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 = new int [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();
delete[] procsIdArray ;
}
};
////////////////////////////////////////////////////////
// FMpi methods
////////////////////////////////////////////////////////
/*
We use init with thread because of an openmpi error:
[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)
// 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__ );
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 remplace par le rang.
*/
FMpi() : communicator(nullptr) {
int provided = 0;
FMpi::Assert( MPI_Init_thread(NULL,NULL, MPI_THREAD_SERIALIZED, &provided), __LINE__);
communicator = new FComm(MPI_COMM_WORLD);
}
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();
FMpi(int inArgc, char ** inArgv ) : communicator(nullptr) {
int provided = 0;
FMpi::Assert( MPI_Init_thread(&inArgc,&inArgv, MPI_THREAD_SERIALIZED, &provided), __LINE__);
communicator = new FComm(MPI_COMM_WORLD);
}
/** Free communicator and group */
virtual ~FComm(){
FMpi::Assert( MPI_Comm_free(&communicator), __LINE__ );
FMpi::Assert( MPI_Group_free(&group), __LINE__ );
/** Delete the communicator and call mpi finalize */
~FMpi(){
delete communicator;
MPI_Finalize();
}
/** To get the mpi comm needed for communication */
MPI_Comm getComm() const {
return communicator;
/** Get the global communicator */
const FComm& global() {
return (*communicator);
}
/** The current rank */
int processId() const {
return rank;
}
////////////////////////////////////////////////////////////
// Mpi Types meta function
////////////////////////////////////////////////////////////
/** The current number of procs in the group */
int processCount() const {
return nbProc;
static const MPI_Datatype GetType(const long long&){
return MPI_LONG_LONG;
}
////////////////////////////////////////////////////////////
// Split/Chunk functions
////////////////////////////////////////////////////////////
static const MPI_Datatype GetType(const long int&){
return MPI_LONG;
}
/** 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())));
static const MPI_Datatype GetType(const double&){
return MPI_DOUBLE;
}
/** 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;
static const MPI_Datatype GetType(const float&){
return MPI_FLOAT;
}
/** 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;
static const MPI_Datatype GetType(const int&){
return MPI_INT;
}
/** 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)));
static const MPI_Datatype GetType(const char&){
return MPI_CHAR;
}
/** 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);
static const MPI_Datatype GetType(const FComplexe& a){
MPI_Datatype FMpiComplexe;
MPI_Type_contiguous(2, GetType(a.getReal()) , &FMpiComplexe);
return FMpiComplexe;
}
////////////////////////////////////////////////////////////
// Mpi interface functions
////////////////////////////////////////////////////////////
/** Reduce a value for proc == 0 */
template< class T >
T reduceSum(T data) const {
T result(0);
FMpi::Assert( MPI_Reduce( &data, &result, 1, FMpi::GetType(data), MPI_SUM, 0, communicator ), __LINE__);
return result;
/** generic mpi assert function */
static void Assert(const int test, const unsigned line, const char* const message = nullptr){
if(test != MPI_SUCCESS){
printf("[ERROR-QS] Test failled at line %d, result is %d", line, test);
if(message) printf(", message: %s",message);
printf("\n");
fflush(stdout);
MPI_Abort(MPI_COMM_WORLD, int(line) );
}
}
/** 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;
/** Compute a left index from data */
template <class T>
static T GetLeft(const T inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
return T(ceil(step * inIdProc));
}
/** Change the group size */
void groupReduce(const int from , const int to){
int * procsIdArray = new int [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();
delete procsIdArray ;
/** Compute a right index from data */
template <class T>
static T GetRight(const T inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
const T res = T(ceil(step * (inIdProc+1)));
if(res > inSize) return inSize;
else return res;
}
};
////////////////////////////////////////////////////////
// FMpi methods
////////////////////////////////////////////////////////
/*
We use init with thread because of an openmpi error:
[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 remplace par le rang.
*/
FMpi() : communicator(nullptr) {
int provided = 0;
FMpi::Assert( MPI_Init_thread(NULL,NULL, MPI_THREAD_SERIALIZED, &provided), __LINE__);
communicator = new FComm(MPI_COMM_WORLD);
}
FMpi(int inArgc, char ** inArgv ) : communicator(nullptr) {
int provided = 0;
FMpi::Assert( MPI_Init_thread(&inArgc,&inArgv, MPI_THREAD_SERIALIZED, &provided), __LINE__);
communicator = new FComm(MPI_COMM_WORLD);
}
/** Delete the communicator and call mpi finalize */
~FMpi(){
delete communicator;
MPI_Finalize();
}
/** Get the global communicator */
const FComm& global() {
return (*communicator);
}
////////////////////////////////////////////////////////////
// Mpi Types meta function
////////////////////////////////////////////////////////////
static const MPI_Datatype GetType(const long long&){
return MPI_LONG_LONG;
}
static const MPI_Datatype GetType(const long int&){
return MPI_LONG;
}
static const MPI_Datatype GetType(const double&){
return MPI_DOUBLE;
}
static const MPI_Datatype GetType(const float&){
return MPI_FLOAT;
}
static const MPI_Datatype GetType(const int&){
return MPI_INT;
}
static const MPI_Datatype GetType(const char&){
return MPI_CHAR;
}
static const MPI_Datatype GetType(const FComplexe& a){
MPI_Datatype FMpiComplexe;
MPI_Type_contiguous(2, GetType(a.getReal()) , &FMpiComplexe);
return FMpiComplexe;
}
////////////////////////////////////////////////////////////
// Mpi interface functions
////////////////////////////////////////////////////////////
/** generic mpi assert function */
static void Assert(const int test, const unsigned line, const char* const message = nullptr){
if(test != MPI_SUCCESS){
printf("[ERROR-QS] Test failled at line %d, result is %d", line, test);
if(message) printf(", message: %s",message);
printf("\n");
fflush(stdout);
MPI_Abort(MPI_COMM_WORLD, int(line) );
/** Compute a proc id from index & data */
template <class T>
static int GetProc(const T position, const T inSize, const int inNbProc) {
const double step = double(inSize) / double(inNbProc);
return int(double(position)/step);
}
}
/** Compute a left index from data */
template <class T>
static T GetLeft(const T inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
return T(ceil(step * inIdProc));
}
/** Compute a right index from data */
template <class T>
static T GetRight(const T inSize, const int inIdProc, const int inNbProc) {
const double step = (double(inSize) / inNbProc);
const T res = T(ceil(step * (inIdProc+1)));
if(res > inSize) return inSize;
else return res;
}
/** Compute a proc id from index & data */
template <class T>
static int GetProc(const T position, const T inSize, const int inNbProc) {
const double step = double(inSize) / double(inNbProc);
return int(double(position)/step);
}
/** assert if mpi error */
static void MpiAssert(const int test, const unsigned line, const char* const message = nullptr){
if(test != MPI_SUCCESS){
printf("[ERROR] Test failed at line %d, result is %d", line, test);
if(message) printf(", message: %s",message);
printf("\n");
fflush(stdout);
MPI_Abort(MPI_COMM_WORLD, int(line) );
/** assert if mpi error */
static void MpiAssert(const int test, const unsigned line, const char* const message = nullptr){
if(test != MPI_SUCCESS){
printf("[ERROR] Test failed at line %d, result is %d", line, test);
if(message) printf(", message: %s",message);
printf("\n");
fflush(stdout);
MPI_Abort(MPI_COMM_WORLD, int(line) );
}
}
}
private:
/** The original communicator */
FComm* communicator;
/** The original communicator */
FComm* communicator;
};
......
......@@ -76,31 +76,6 @@ protected:
return left;
}
/* A local iteration of qs */
static void QsLocal(SortType array[], const CompareType& pivot,
IndexType myLeft, IndexType myRight,
IndexType& prefix, IndexType& sufix){
IndexType leftIter = myLeft;
IndexType rightIter = myRight;
while(true){
while(CompareType(array[leftIter]) <= pivot && leftIter < rightIter){
++leftIter;
}
while(leftIter <= rightIter && pivot < CompareType(array[rightIter])){
--rightIter;
}
if(rightIter < leftIter) break;
Swap(array[leftIter],array[rightIter]);
++leftIter;
--rightIter;
}
prefix = leftIter - myLeft;
sufix = myRight - myLeft - prefix + 1;
}
/* The sequential qs */
static void QsSequentialStep(SortType array[], const IndexType left, const IndexType right){
......
This diff is collapsed.
......@@ -16,6 +16,7 @@
#ifndef UTESTER_HPP
#define UTESTER_HPP
#include "ScalFmmConfig.h"
#include <iostream>
#include <list>
......@@ -24,10 +25,10 @@
#define TestClass(X)\
int main(void){\
X Controller;\
return Controller.Run();\
}\
int main(void){\
X Controller;\
return Controller.Run();\
}\
/**
......@@ -44,164 +45,164 @@ int main(void){\
*/
template <class TestClass>
class FUTester{
// Test function pointer
typedef void (TestClass::*TestFunc)(void);
/** Test descriptor */
struct TestFuncDescriptor{
TestFunc func; //< Test adress
std::string name; //< Test name
};
std::list<TestFuncDescriptor> tests; //< all tests
int totalTests; //< number of tests
int currentTest; //< current processing test in the run
int currentStep; //< current processing step in the run
int failedSteps; //< number of failed step in the current test
int failedTests; //< number of failed tests
// Test function pointer
typedef void (TestClass::*TestFunc)(void);
/** Test descriptor */
struct TestFuncDescriptor{
TestFunc func; //< Test adress
std::string name; //< Test name