Commit 6bed706f authored by berenger-bramas's avatar berenger-bramas

Make a conditional system to compile with or without blas or mpi.

@FUSE_BLAS
@FUSE_MPI
If one of this keyword appear in the cpp file it will be compiled if possible.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@438 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 179277ee
......@@ -12,7 +12,7 @@
#define FMPITREEBUILDER_H
#include "../Utils/FMpi.hpp"
#include "../Utils/FQuickSort.hpp"
#include "../Utils/FQuickSortMpi.hpp"
#include "../Utils/FBitonicSort.hpp"
#include "../Utils/FMemUtils.hpp"
......@@ -87,7 +87,7 @@ private:
// sort particles
if(type == QuickSort){
FQuickSort<IndexedParticle,MortonIndex, FSize>::QsMpi(realParticlesIndexed, loader.getNumberOfParticles(), *outputArray, *outputSize,communicator);
FQuickSortMpi<IndexedParticle,MortonIndex, FSize>::QsMpi(realParticlesIndexed, loader.getNumberOfParticles(), *outputArray, *outputSize,communicator);
delete [] (realParticlesIndexed);
}
else {
......@@ -122,7 +122,7 @@ private:
// sort particles
if(type == QuickSort){
FQuickSort<IndexedParticle,MortonIndex, FSize>::QsMpi(realParticlesIndexed, size, *outputArray, *outputSize,communicator);
FQuickSortMpi<IndexedParticle,MortonIndex, FSize>::QsMpi(realParticlesIndexed, size, *outputArray, *outputSize,communicator);
delete [] (realParticlesIndexed);
}
else {
......
......@@ -27,135 +27,8 @@
/////////////////////////////////////////////////////////////////////////////////////////
#ifdef SCALFMM_USE_MPI
#include <mpi.h>
#else
struct MPI_Request{};
struct MPI_Status{ int MPI_SOURCE; };
typedef int MPI_Datatype;
typedef long long MPI_Offset;
typedef int MPI_Comm;
typedef int MPI_Group;
typedef int MPI_File;
typedef int MPI_Op;
typedef int MPI_Info;
typedef int MPI_File;
MPI_Status* MPI_STATUSES_IGNORE = 0;
MPI_Status* MPI_STATUS_IGNORE = 0;
enum{
MPI_SUCCESS,
MPI_LONG_LONG,
MPI_LONG,
MPI_DOUBLE,
MPI_FLOAT,
MPI_INT,
MPI_COMM_WORLD,
MPI_BYTE,
MPI_SUM,
MPI_THREAD_MULTIPLE,
MPI_ANY_SOURCE,
MPI_MODE_RDONLY,
MPI_INFO_NULL,
MPI_MODE_WRONLY,
MPI_MODE_CREATE
};
int MPI_Barrier( MPI_Comm comm ){ return 0; }
int MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf,
int count, MPI_Datatype datatype, MPI_Status *status){ return 0;}
int MPI_File_set_view(MPI_File fh, MPI_Offset disp,
MPI_Datatype etype, MPI_Datatype filetype,
char *datarep, MPI_Info info){ return 0; }
int MPI_Comm_rank( MPI_Comm comm, int *rank ){ return 0; }
int MPI_Comm_size( MPI_Comm comm, int *size ){ return 0; }
int MPI_Probe( int source, int tag, MPI_Comm comm, MPI_Status *status ){ return 0; }
int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm){ return 0; }
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group){ return 0; }
int MPI_Comm_free(MPI_Comm *comm){ return 0; }
int MPI_Group_free(MPI_Group *group){ return 0; }
int MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup){ return 0; }
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm){ return 0; }
int MPI_Init_thread(int *argc, char ***argv, int required, int *provided ){ return 0; }
int MPI_Finalize(){ return 0; }
int MPI_Abort(MPI_Comm comm, int errorcode){ return 0; }
int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
MPI_Op op, int root, MPI_Comm comm){ return 0; }
int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm){ return 0; }
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,
int tag, MPI_Comm comm, MPI_Request *request){ return 0; }
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag,
MPI_Comm comm, MPI_Status *status){ return 0; }
int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request *request){ return 0; }
int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm){ return 0; }
int MPI_Alltoallv(void *sendbuf, int *sendcnts, int *sdispls,
MPI_Datatype sendtype, void *recvbuf, int *recvcnts,
int *rdispls, MPI_Datatype recvtype, MPI_Comm comm){ return 0; }
int MPI_Wait(MPI_Request *request, MPI_Status *status){ return 0; }
int MPI_Waitany(int count, MPI_Request array_of_requests[], int *index,
MPI_Status *status){ return 0; }
int MPI_Waitall(int count, MPI_Request array_of_requests[],
MPI_Status array_of_statuses[]){ return 0; }
int MPI_Waitsome(int incount, MPI_Request array_of_requests[],
int *outcount, int array_of_indices[],
MPI_Status array_of_statuses[]){ return 0; }
int MPI_File_open(MPI_Comm comm, char *filename, int amode,
MPI_Info info, MPI_File *fh){ return 0; }
int MPI_File_read(MPI_File mpi_fh, void *buf, int count,
MPI_Datatype datatype, MPI_Status *status){ return 0; }
int MPI_File_get_position(MPI_File mpi_fh, MPI_Offset *offset){ return 0; }
int MPI_File_get_size(MPI_File mpi_fh, MPI_Offset *size){ return 0; }
int MPI_File_read_at(MPI_File mpi_fh, MPI_Offset offset, void *buf,
int count, MPI_Datatype datatype, MPI_Status *status){ return 0; }
int MPI_Get_count( MPI_Status *status, MPI_Datatype datatype, int *count ){ return 0; }
int MPI_File_close(MPI_File *mpi_fh){ return 0; }
int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int dest, int sendtag,
void *recvbuf, int recvcount, MPI_Datatype recvtype,
int source, int recvtag,
MPI_Comm comm, MPI_Status *status){ return 0; }
int MPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
int dest, int sendtag, int source, int recvtag,
MPI_Comm comm, MPI_Status *status){ return 0; }
int MPI_Bcast( void *buffer, int count, MPI_Datatype datatype, int root,
MPI_Comm comm ){ return 0; }
#endif
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
......
......@@ -20,7 +20,6 @@
#include "FGlobal.hpp"
#include "FMemUtils.hpp"
#include "FTrace.hpp"
#include "FMpi.hpp"
#include "FOmpBarrier.hpp"
......@@ -36,10 +35,33 @@
template <class SortType, class CompareType, class IndexType>
class FQuickSort {
protected:
////////////////////////////////////////////////////////////
// Miscialenous functions
////////////////////////////////////////////////////////////
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);
}
/** swap to value */
template <class NumType>
static inline void Swap(NumType& value, NumType& other){
......@@ -154,8 +176,8 @@ class FQuickSort {
{
const int myThreadId = omp_get_thread_num();
IndexType myLeft = FMpi::GetLeft(size, myThreadId, omp_get_num_threads());
IndexType myRight = FMpi::GetRight(size, myThreadId, omp_get_num_threads()) - 1;
IndexType myLeft = GetLeft(size, myThreadId, omp_get_num_threads());
IndexType myRight = GetRight(size, myThreadId, omp_get_num_threads()) - 1;
IndexType startIndex = 0;
IndexType endIndex = size - 1;
......@@ -209,7 +231,7 @@ class FQuickSort {
barriers[firstProc].wait();
// find my next QsLocal part
int splitProc = FMpi::GetProc(sufoffset - startIndex, nbElements, lastProc - firstProc + 1) + firstProc;
int splitProc = GetProc(sufoffset - startIndex, nbElements, lastProc - firstProc + 1) + firstProc;
if(splitProc == lastProc){
--splitProc;
}
......@@ -223,8 +245,8 @@ class FQuickSort {
firstProc = splitProc + 1;
}
myLeft = FMpi::GetLeft(endIndex - startIndex + 1, myThreadId - firstProc, lastProc - firstProc + 1) + startIndex;
myRight = FMpi::GetRight(endIndex - startIndex + 1, myThreadId - firstProc, lastProc - firstProc + 1) + startIndex - 1;
myLeft = GetLeft(endIndex - startIndex + 1, myThreadId - firstProc, lastProc - firstProc + 1) + startIndex;
myRight = GetRight(endIndex - startIndex + 1, myThreadId - firstProc, lastProc - firstProc + 1) + startIndex - 1;
}
QsSequentialStep(array,myLeft,myRight);
......@@ -254,219 +276,6 @@ public:
#endif
}
/* the mpi qs */
static void QsMpi(const SortType originalArray[], IndexType size, SortType* & outputArray, IndexType& outputSize, const FMpi::FComm& originalComm){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Quicksort" , __FILE__ , __LINE__) );
// We need a structure see the algorithm detail to know more
struct Fix{
IndexType pre;
IndexType suf;
};
// first we copy data into our working buffer : outputArray
outputArray = new SortType[size];
FMemUtils::memcpy(outputArray, originalArray, sizeof(SortType) * size);
outputSize = size;
// alloc outputArray to store pre/sufixe, maximum needed is nb procs[comm world] + 1
Fix fixes[originalComm.processCount() + 1];
Fix fixesSum[originalComm.processCount() + 1];
memset(fixes,0,sizeof(Fix) * originalComm.processCount());
memset(fixesSum,0,sizeof(Fix) * (originalComm.processCount() + 1) );
// receiving buffer
IndexType bufferSize = 0;
SortType* buffer = 0;
// Create the first com
FMpi::FComm currentComm(originalComm.getComm());
// While I am not working alone on my own data
while( currentComm.processCount() != 1 ){
const int currentRank = currentComm.processId();
const int currentNbProcs = currentComm.processCount();
MPI_Request requests[currentNbProcs * 2];
int iterRequest = 0;
/////////////////////////////////////////////////
// Local sort
/////////////////////////////////////////////////
// sort QsLocal part of the outputArray
const CompareType pivot = currentComm.reduceAverageAll( CompareType(outputArray[size/2]) );
Fix myFix;
QsLocal(outputArray, pivot, 0, size - 1, myFix.pre, myFix.suf);
// exchange fixes
FMpi::Assert( MPI_Allgather( &myFix, sizeof(Fix), MPI_BYTE, fixes, sizeof(Fix), MPI_BYTE, currentComm.getComm()), __LINE__ );
// each procs compute the summation
fixesSum[0].pre = 0;
fixesSum[0].suf = 0;
for(int idxProc = 0 ; idxProc < currentNbProcs ; ++idxProc){
fixesSum[idxProc + 1].pre = fixesSum[idxProc].pre + fixes[idxProc].pre;
fixesSum[idxProc + 1].suf = fixesSum[idxProc].suf + fixes[idxProc].suf;
}
// then I need to know which procs will be in the middle
int splitProc = FMpi::GetProc(fixesSum[currentNbProcs].pre - 1, fixesSum[currentNbProcs].pre + fixesSum[currentNbProcs].suf, currentNbProcs);
if(splitProc == currentNbProcs - 1){
--splitProc;
}
/////////////////////////////////////////////////
// Send my data
/////////////////////////////////////////////////
// above pivot (right part)
if( fixes[currentRank].suf ){
const int procsInSuf = currentNbProcs - 1 - splitProc;
const int firstProcInSuf = splitProc + 1;
const IndexType elementsInSuf = fixesSum[currentNbProcs].suf;
const int firstProcToSend = FMpi::GetProc(fixesSum[currentRank].suf, elementsInSuf, procsInSuf) + firstProcInSuf;
const int lastProcToSend = FMpi::GetProc(fixesSum[currentRank + 1].suf - 1, elementsInSuf, procsInSuf) + firstProcInSuf;
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const IndexType thisProcRight = FMpi::GetRight(elementsInSuf, idxProc - firstProcInSuf, procsInSuf);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].suf - sent;
if(sendToProc + sent > fixes[currentRank].suf){
sendToProc = fixes[currentRank].suf - sent;
}
if( sendToProc ){
FMpi::Assert( MPI_Isend(&outputArray[sent + fixes[currentRank].pre], int(sendToProc * sizeof(SortType)), MPI_BYTE , idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
sent += sendToProc;
}
}
// under pivot (left part)
if( fixes[currentRank].pre ){
const int procsInPre = splitProc + 1;
const IndexType elementsInPre = fixesSum[currentNbProcs].pre;
const int firstProcToSend = FMpi::GetProc(fixesSum[currentRank].pre, elementsInPre, procsInPre);
const int lastProcToSend = FMpi::GetProc(fixesSum[currentRank + 1].pre - 1, elementsInPre, procsInPre);
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const IndexType thisProcRight = FMpi::GetRight(elementsInPre, idxProc, procsInPre);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].pre - sent;
if(sendToProc + sent > fixes[currentRank].pre){
sendToProc = fixes[currentRank].pre - sent;
}
if(sendToProc){
FMpi::Assert( MPI_Isend(&outputArray[sent], int(sendToProc * sizeof(SortType)), MPI_BYTE , idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
sent += sendToProc;
}
}
/////////////////////////////////////////////////
// Receive data that belong to me
/////////////////////////////////////////////////
if( currentRank <= splitProc ){
// I am in S-Part (smaller than pivot)
const int procsInPre = splitProc + 1;
const IndexType elementsInPre = fixesSum[currentNbProcs].pre;
IndexType myLeft = FMpi::GetLeft(elementsInPre, currentRank, procsInPre);
IndexType myRightLimit = FMpi::GetRight(elementsInPre, currentRank, procsInPre);
size = myRightLimit - myLeft;
if(bufferSize < size){
bufferSize = size;
delete[] buffer;
buffer = new SortType[bufferSize];
}
int idxProc = 0;
while( idxProc < currentNbProcs && fixesSum[idxProc + 1].pre <= myLeft ){
++idxProc;
}
IndexType indexArray = 0;
while( idxProc < currentNbProcs && indexArray < myRightLimit - myLeft){
const IndexType firstIndex = FMath::Max(myLeft , fixesSum[idxProc].pre );
const IndexType endIndex = FMath::Min(fixesSum[idxProc + 1].pre, myRightLimit);
if( (endIndex - firstIndex) ){
FMpi::Assert( MPI_Irecv(&buffer[indexArray], int((endIndex - firstIndex) * sizeof(SortType)), MPI_BYTE, idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
indexArray += endIndex - firstIndex;
++idxProc;
}
// Proceed all send/receive
FMpi::Assert( MPI_Waitall(iterRequest, requests, MPI_STATUSES_IGNORE), __LINE__ );
currentComm.groupReduce( 0, splitProc);
}
else{
// I am in L-Part (larger than pivot)
const int procsInSuf = currentNbProcs - 1 - splitProc;
const IndexType elementsInSuf = fixesSum[currentNbProcs].suf;
const int rankInL = currentRank - splitProc - 1;
IndexType myLeft = FMpi::GetLeft(elementsInSuf, rankInL, procsInSuf);
IndexType myRightLimit = FMpi::GetRight(elementsInSuf, rankInL, procsInSuf);
size = myRightLimit - myLeft;
if(bufferSize < size){
bufferSize = size;
delete[] buffer;
buffer = new SortType[bufferSize];
}
int idxProc = 0;
while( idxProc < currentNbProcs && fixesSum[idxProc + 1].suf <= myLeft ){
++idxProc;
}
IndexType indexArray = 0;
while( idxProc < currentNbProcs && indexArray < myRightLimit - myLeft){
const IndexType firstIndex = FMath::Max(myLeft , fixesSum[idxProc].suf );
const IndexType endIndex = FMath::Min(fixesSum[idxProc + 1].suf, myRightLimit);
if( (endIndex - firstIndex) ){
FMpi::Assert( MPI_Irecv(&buffer[indexArray], int((endIndex - firstIndex) * sizeof(SortType)), MPI_BYTE, idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
indexArray += endIndex - firstIndex;
++idxProc;
}
// Proceed all send/receive
FMpi::Assert( MPI_Waitall(iterRequest, requests, MPI_STATUSES_IGNORE), __LINE__ );
currentComm.groupReduce( splitProc + 1, currentNbProcs - 1);
}
// Copy res into outputArray
if(outputSize < size){
delete[] outputArray;
outputArray = new SortType[size];
outputSize = size;
}
FMemUtils::memcpy(outputArray, buffer, sizeof(SortType) * size);
}
/////////////////////////////////////////////////
// End QsMpi sort
/////////////////////////////////////////////////
// Clean
delete[] buffer;
// Normal Quick sort
QsOmp(outputArray, size);
outputSize = size;
}
};
......
// ===================================================================================
// 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 FQUICKSORTMPI_HPP
#define FQUICKSORTMPI_HPP
#include "FQuickSort.hpp"
#include "FMpi.hpp"
template <class SortType, class CompareType, class IndexType>
class FQuickSortMpi : public FQuickSort< SortType, CompareType, IndexType> {
public:
/* the mpi qs */
static void QsMpi(const SortType originalArray[], IndexType size, SortType* & outputArray, IndexType& outputSize, const FMpi::FComm& originalComm){
FTRACE( FTrace::FFunction functionTrace(__FUNCTION__, "Quicksort" , __FILE__ , __LINE__) );
// We need a structure see the algorithm detail to know more
struct Fix{
IndexType pre;
IndexType suf;
};
// first we copy data into our working buffer : outputArray
outputArray = new SortType[size];
FMemUtils::memcpy(outputArray, originalArray, sizeof(SortType) * size);
outputSize = size;
// alloc outputArray to store pre/sufixe, maximum needed is nb procs[comm world] + 1
Fix fixes[originalComm.processCount() + 1];
Fix fixesSum[originalComm.processCount() + 1];
memset(fixes,0,sizeof(Fix) * originalComm.processCount());
memset(fixesSum,0,sizeof(Fix) * (originalComm.processCount() + 1) );
// receiving buffer
IndexType bufferSize = 0;
SortType* buffer = 0;
// Create the first com
FMpi::FComm currentComm(originalComm.getComm());
// While I am not working alone on my own data
while( currentComm.processCount() != 1 ){
const int currentRank = currentComm.processId();
const int currentNbProcs = currentComm.processCount();
MPI_Request requests[currentNbProcs * 2];
int iterRequest = 0;
/////////////////////////////////////////////////
// Local sort
/////////////////////////////////////////////////
// sort QsLocal part of the outputArray
const CompareType pivot = currentComm.reduceAverageAll( CompareType(outputArray[size/2]) );
Fix myFix;
QsLocal(outputArray, pivot, 0, size - 1, myFix.pre, myFix.suf);
// exchange fixes
FMpi::Assert( MPI_Allgather( &myFix, sizeof(Fix), MPI_BYTE, fixes, sizeof(Fix), MPI_BYTE, currentComm.getComm()), __LINE__ );
// each procs compute the summation
fixesSum[0].pre = 0;
fixesSum[0].suf = 0;
for(int idxProc = 0 ; idxProc < currentNbProcs ; ++idxProc){
fixesSum[idxProc + 1].pre = fixesSum[idxProc].pre + fixes[idxProc].pre;
fixesSum[idxProc + 1].suf = fixesSum[idxProc].suf + fixes[idxProc].suf;
}
// then I need to know which procs will be in the middle
int splitProc = FMpi::GetProc(fixesSum[currentNbProcs].pre - 1, fixesSum[currentNbProcs].pre + fixesSum[currentNbProcs].suf, currentNbProcs);
if(splitProc == currentNbProcs - 1){
--splitProc;
}
/////////////////////////////////////////////////
// Send my data
/////////////////////////////////////////////////
// above pivot (right part)
if( fixes[currentRank].suf ){
const int procsInSuf = currentNbProcs - 1 - splitProc;
const int firstProcInSuf = splitProc + 1;
const IndexType elementsInSuf = fixesSum[currentNbProcs].suf;
const int firstProcToSend = FMpi::GetProc(fixesSum[currentRank].suf, elementsInSuf, procsInSuf) + firstProcInSuf;
const int lastProcToSend = FMpi::GetProc(fixesSum[currentRank + 1].suf - 1, elementsInSuf, procsInSuf) + firstProcInSuf;
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const IndexType thisProcRight = FMpi::GetRight(elementsInSuf, idxProc - firstProcInSuf, procsInSuf);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].suf - sent;
if(sendToProc + sent > fixes[currentRank].suf){
sendToProc = fixes[currentRank].suf - sent;
}
if( sendToProc ){
FMpi::Assert( MPI_Isend(&outputArray[sent + fixes[currentRank].pre], int(sendToProc * sizeof(SortType)), MPI_BYTE , idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
sent += sendToProc;
}
}
// under pivot (left part)
if( fixes[currentRank].pre ){
const int procsInPre = splitProc + 1;
const IndexType elementsInPre = fixesSum[currentNbProcs].pre;
const int firstProcToSend = FMpi::GetProc(fixesSum[currentRank].pre, elementsInPre, procsInPre);
const int lastProcToSend = FMpi::GetProc(fixesSum[currentRank + 1].pre - 1, elementsInPre, procsInPre);
IndexType sent = 0;
for(int idxProc = firstProcToSend ; idxProc <= lastProcToSend ; ++idxProc){
const IndexType thisProcRight = FMpi::GetRight(elementsInPre, idxProc, procsInPre);
IndexType sendToProc = thisProcRight - fixesSum[currentRank].pre - sent;
if(sendToProc + sent > fixes[currentRank].pre){
sendToProc = fixes[currentRank].pre - sent;
}
if(sendToProc){
FMpi::Assert( MPI_Isend(&outputArray[sent], int(sendToProc * sizeof(SortType)), MPI_BYTE , idxProc, FMpi::TagQuickSort, currentComm.getComm(), &requests[iterRequest++]), __LINE__ );
}
sent += sendToProc;
}
}
/////////////////////////////////////////////////
// Receive data that belong to me
/////////////////////////////////////////////////
if( currentRank <= splitProc ){
// I am in S-Part (smaller than pivot)
const int procsInPre = splitProc + 1;
const IndexType elementsInPre = fix