int ProcRank;
int ProcNum;
int main(int argc, char *argv[]) {
double *pProcData;
int ProcDataSize;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &ProcRank);
MPI_Comm_size(MPI_COMM_WORLD, &ProcNum);
DataInitialization ( &pProcData, &ProcDataSize);
ParallelHyperQuickSort ( pProcData, ProcDataSize );
ProcessTermination ( pProcData, ProcDataSize );
MPI_Finalize();
}
void DataInitialization( double **pProcData, double *ProcDataSize){
int DataSize;
double *pData;
if ( ProcRank == 0 ) {
DataSize = GetDataSize();
*pData = new double[DataSize];
DataGeneration ( pData, DataSize);
}
DataDistribution ( *pProcData, DataSize, *ProcDataSize);
}
void DataDistribution (double *pProcData, int DataSize, int *ProcDataSize) {
if ( rank == 0 ) {
*ProcDataSize = DataSize / ProcNum;
}
MPI_Bcast ( ProcDataSize, 1, MPI_INT, 0, MPI_COMM_WORLD );
*ProcData = new double[*ProcDataSize];
MPI_Scatter ( &pData[(ProcRank)*(*ProcDataSize)], *ProcDataSize,
MPI_DOUBLE, *ProcData, *ProcDataSize, MPI_DOUBLE, 0, MPI_COMM_WORLD );
}
void ParallelHyperQuickSort ( double *pProcData, int ProcDataSize) {
MPI_Status status;
int CommProcRank;
double *pData,
*pSendData,
*pRecvData,
*pMergeData;
int DataSize, SendDataSize, RecvDataSize, MergeDataSize;
int HypercubeDim = (int)ceil(log(ProcNum)/log(2));
int Mask = ProcNum;
double Pivot;
LocalDataSort ( pProcData, ProcDataSize );
for ( int i = HypercubeDim; i > 0; i-- ) {
PivotDistribution (pProcData,ProcDataSize,HypercubeDim,Mask,i,&Pivot);
Mask = Mask >> 1;
int pos = GetProcDataDivisionPos (pProcData, ProcDataSize, Pivot);
if ( ( (rank&Mask) >> (i-1) ) == 0 ) {
pSendData = & pProcData[pos+1];
SendDataSize = ProcDataSize - pos – 1;
if ( SendDataSize < 0 ) SendDataSize = 0;
CommProcRank = ProcRank + Mask
pData = & pProcData[0];
DataSize = pos + 1;
}
else {
pSendData = & pProcData[0];
SendDataSize = pos + 1;
if ( SendDataSize > ProcDataSize ) SendDataSize = pos;
CommProcRank = ProcRank – Mask
pData = & pProcData[pos+1];
DataSize = ProcDataSize - pos - 1;
if ( DataSize < 0 ) DataSize = 0;
}
MPI_Sendrecv(&SendDataSize, 1, MPI_INT, CommProcRank, 0,
&RecvDataSize, 1, MPI_INT, CommProcRank, 0, MPI_COMM_WORLD, &status);
pRecvData = new double[RecvDataSize];
MPI_Sendrecv(pSendData, SendDataSize, MPI_DOUBLE,
CommProcRank, 0, pRecvData, RecvDataSize, MPI_DOUBLE,
CommProcRank, 0, MPI_COMM_WORLD, &status);
MergeDataSize = DataSize + RecvDataSize;
pMergeData = new double[MergeDataSize];
DataMerge(pMergeData, pMergeData, pData, DataSize,
pRecvData, RecvDataSize);
delete [] pProcData;
delete [] pRecvData;
pProcData = pMergeData;
ProcDataSize = MergeDataSize;
}
}