MPI 枚举排序实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/laojiaqi/article/details/33317179
// 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]++;
		}
	}

}


 

猜你喜欢

转载自blog.csdn.net/laojiaqi/article/details/33317179
mpi