Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1006475
  • 博文数量: 96
  • 博客积分: 1553
  • 博客等级: 上尉
  • 技术积分: 1871
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-25 14:50
个人简介

专注点,细心点,耐心点 知行合一

文章分类

全部博文(96)

文章存档

2018年(1)

2014年(4)

2013年(31)

2012年(56)

2011年(4)

分类: C/C++

2013-01-11 11:21:21

ranksort算法大致思想:
将待排序的样本进行顺序分割。每个并行处理器处理部分数据。每个并行处理器的工作就是计算该部分的rank值。之后将所有的rank值进行汇总,就可以对其进行排序了。

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>

  4. /*
  5.   * 函数名: main
  6.   * 功能: 主函数,实现枚举排序
  7.   * 输入:argc为命令行参数个数;
  8.   * argv为每个命令行参数组成的字符串数组
  9.   * 输出:返回1代表程序正常结束
  10. */
  11. int main(int argc,char *argv[])
  12. {
  13.     int DataSize, MyLength; /*DataSize:数组长度;MyLength:处理器分配到的数据长度*/
  14.     int *data_in, *data_out; /*输入和输出数组指针*/
  15.     int *rank; /*秩数组*/
  16.     int MyID, SumID;
  17.     int i, j;

  18.     MPI_Status status;

  19.     MPI_Init(&argc,&argv); /*MPI 初始化*/
  20.     MPI_Comm_rank(MPI_COMM_WORLD,&MyID); /*每个处理器确定各自ID*/
  21.     MPI_Comm_size(MPI_COMM_WORLD,&SumID); /*每个处理器确定总处理器个数*/

  22.     if(MyID==0) /*主处理器*/
  23.         DataSize=GetDataSize(); /*读入待排序序列的长度*/
  24.     
  25.     MPI_Bcast(&DataSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
  26.                                               /*主处理器广播待排序序列的长度*/
  27.     /*在各个处理器间划分任务*/
  28.     MyLength=DataSize/SumID;
  29.     if(MyID==SumID-1) /*每个处理器确定各自要排序的序列长度*/
  30.         MyLength=DataSize-MyLength*(SumID-1);

  31.     data_in=(int *)malloc(DataSize*sizeof(int)); /*分配待排序序列的空间*/
  32.     if(data_in==0) ErrMsg("Malloc memory error!");

  33.     if(MyID==0){
  34.         data_out=(int *)malloc(DataSize*sizeof(int)); /*主处理器分配排序后数组的空间*/
  35.         if(data_out==0) ErrMsg("Malloc memory error!");

  36.         rank=(int *)malloc(DataSize*sizeof(int)); /*分配序号数组的空间*/
  37.         if(rank==0) ErrMsg("Malloc memory error!");
  38.     }
  39.     else{
  40.         rank=(int *)malloc(MyLength*sizeof(int)); /*分配序号数组的空间*/
  41.         if(rank==0) ErrMsg("Malloc memory error!");
  42.     }

  43.     if(MyID==0){
  44.         int seed;
  45.         printf("Please Input Seed:");
  46.         scanf("%d",&seed); /*获得随机数的种子*/
  47.         srand(seed);
  48.         printf("Random Numbers:\n");
  49.         for(i=0;i<DataSize;i++){
  50.             data_in[i]=((int)rand())%10000; /*生成随机数,并输出*/
  51.             printf("%10d ",data_in[i]);
  52.         }
  53.         printf("\nOutput:");
  54.         printf("\n");
  55.     }

  56.     /*向各个处理器播送待排序序列,对应于算法13.2步骤(1)*/
  57.     MPI_Bcast(data_in, DataSize, MPI_INT, 0, MPI_COMM_WORLD);

  58.     /*各个处理器分别计算所属元素的秩,对应于算法13.2步骤(2)*/
  59.     CountRank(data_in,DataSize,MyLength,rank,SumID,MyID);

  60.     /*从各个处理器收集已排序好的数据,对应于算法13.2步骤(3)*/
  61.     if(MyID==0){
  62.         for(i=1;i<SumID;i++){
  63.             if(i==SumID-1)
  64.                 MPI_Recv(rank+MyLength*i,DataSize-MyLength*(SumID-1),MPI_INT,i,0,MPI_COMM_WORLD,&status);
  65.             else
  66.                 MPI_Recv(rank+MyLength*i,MyLength,MPI_INT,i,0,MPI_COMM_WORLD,&status);
  67.         }
  68.     }
  69.     else
  70.         MPI_Send(rank,MyLength,MPI_INT,0,0,MPI_COMM_WORLD);

  71.     /*根据所获得的秩重新定位各个数据*/
  72.     if(MyID==0){
  73.         for(i=0;i<DataSize;i++)
  74.             data_out[rank[i]]=data_in[i];

  75.         for(i=0;i<DataSize;i++){
  76.             printf("%10d ",data_out[i]);
  77.         }
  78.         printf("\n");
  79.     }

  80.     MPI_Finalize();
  81.     return 1;
  82. }

  83. /*
  84.  * 函数名: CountRank
  85.  * 功能: 计算所属部分数据的秩
  86.  * 输入: data:指向待排序序列的指针
  87.  * DataSize为待排序序列的长度
  88.           MyLength为该处理器要排序的序列的长度
  89.           rank:指向秩数组的指针
  90.           SumID:总处理器个数
  91.           MyID:处理器ID
  92.  * 输出:返回1代表程序正常结束
  93.  */
  94. int CountRank(int *data,int DataSize,int MyLength,int *rank,int SumID,int MyID)
  95. {
  96.     int i, j;
  97.     int start, end;

  98.     start=DataSize/SumID*MyID; /*所属部分数据起始位置*/
  99.     end=start+MyLength; /*所属部分数据结束位置*/

  100.     for(j=start;j<end;j++){ /*计算所属部分数据的rank*/
  101.         rank[j-start]=0;
  102.         for(i=0;i<DataSize;i++){
  103.             if((data[j]>data[i]) || ((data[j]==data[i]) && (j>i)))
  104.                 rank[j-start]++;
  105.         }
  106.     }
  107.      return 1;
  108. }

  109. /*
  110.  * 函数名: ErrMsg
  111.  * 功能: 读入待排序序列的长度
  112.  * 输入: 无
  113.  * 输出: 返回待排序序列的长度
  114.  */
  115. int GetDataSize()
  116. {
  117.     int i;

  118.     while(1){
  119.         printf("Input the Data Size :");
  120.         scanf("%d",&i);
  121.         if((i>0) && (i<=65535))
  122.             break;
  123.         ErrMsg("Wrong Data Size, must between [1..65535]");
  124.     }
  125.     return i;
  126. }
  127. /*
  128.  * 函数名: ErrMsg
  129.  * 功能: 输出错误信息
  130.  * 输入: msg:出错信息字符串
  131.  * 输出:返回1代表程序正常结束
  132.  */
  133. int ErrMsg(char *msg)
  134. {
  135.     printf("Error: %s \n",msg);
  136.     return 1;
  137. }

编译和执行
mpicc ranksort.c
mpirun -np 10 ./a.out

阅读(2734) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~