// DFDFDFSSFD.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "mpi.h"
void countRank(int * rank,int perLen,int len,int * p,int * total,int mypid,int size,int flag);
//rank:存放數據的rank值,perLen:rank數組的長度 ,p:保存數據的素組(部分),total:全部數據數組,mypid:進程的ID號,size:進程個數,flag:標誌位,//用以區分兩種不同的情況
int main(int argc, char *argv[])
{
int *total=0;//0進程
int *p;/*每個進程*/
int *rank;
int *sumRank;
int flag;//整除則爲0,否則爲1
int mypid,size,len,perLen;//
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&mypid);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(mypid==0)
{
printf("input number\n");
scanf("%d",&len);
if(len%size==0)//分成兩種情況,第一種 任務可以平均分給不同的進程;第二種不能平均分
{
perLen=len/size;
flag=0;
}
else
{
perLen=(len+size-len%size)/size;
flag=1;
}
}
MPI_Bcast(&len,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&flag,1,MPI_INT,0,MPI_COMM_WORLD);//broadcast
MPI_Bcast(&perLen,1,MPI_INT,0,MPI_COMM_WORLD);//broadcast
total=(int*)malloc((perLen*size)*sizeof(int));
if(mypid==0)//輸入數據
{
int i=0;
for(i=0;i<len;i++)
scanf("%d",&total[i]);
}
MPI_Bcast(total,len,MPI_INT,0,MPI_COMM_WORLD);//broadcast
p=(int *)malloc(perLen*sizeof(int));
rank=(int *)malloc(perLen*sizeof(int));
sumRank=(int *)malloc((perLen*size)*sizeof(int));
MPI_Scatter(total,perLen,MPI_INT,p,perLen,MPI_INT,0,MPI_COMM_WORLD);//0進程向其他進程分發需要排序的數據
countRank(rank,perLen,len,p,total,mypid,size,flag);//每個進程對發下來的任務,計算每個數的rank值
MPI_Gather(rank,perLen,MPI_INT,sumRank,perLen,MPI_INT,0,MPI_COMM_WORLD);//收集每個進程負責的數據的rank值
if(mypid==0)
{
int i=0;
int *out=(int *)malloc((perLen*size)*sizeof(int));
for(i=0;i<len;i++)//重新排序
{
out[sumRank[i]]=total[i];
}
for(i=0;i<len;i++)//輸出
printf("%d ",out[i]);
}
MPI_Finalize();
}
void countRank(int * rank,int perLen,int len,int *p,int * total,int mypid,int size,int flag)//計算rank值
{
int i,j;
if(flag==0||mypid<size-1)//若滿足這兩個條件之一,就進行計算
{
for(i=0;i<perLen;i++)
{
rank[i]=0;
for(j=0;j<len;j++)
if(p[i]>total[j]||(p[i]==total[j]&&i>j))//第二個條件,是爲了滿足穩定排序。
rank[i]++;
}
}
else//不能整除的情況,最後一個進程負責的數據
{
for(i=0;i<len%size;i++)
{
rank[i]=0;
for(j=0;j<len;j++)
if(p[i]>total[j]||(p[i]==total[j]&&i>j))
rank[i]++;
}
}
}