rank_sort.c
上传用户:hhyinxing
上传日期:2013-09-10
资源大小:833k
文件大小:4k
源码类别:

并行计算

开发平台:

Unix_Linux

  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. MPI_Bcast(&DataSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
  25.                                               /*主处理器广播待排序序列的长度*/
  26. /*在各个处理器间划分任务*/
  27. MyLength=DataSize/SumID;              
  28. if(MyID==SumID-1)                     /*每个处理器确定各自要排序的序列长度*/
  29. MyLength=DataSize-MyLength*(SumID-1);
  30. data_in=(int *)malloc(DataSize*sizeof(int)); /*分配待排序序列的空间*/
  31. if(data_in==0) ErrMsg("Malloc memory error!");
  32. if(MyID==0){                     
  33. data_out=(int *)malloc(DataSize*sizeof(int)); /*主处理器分配排序后数组的空间*/
  34. if(data_out==0) ErrMsg("Malloc memory error!");
  35. rank=(int *)malloc(DataSize*sizeof(int));     /*分配序号数组的空间*/
  36. if(rank==0) ErrMsg("Malloc memory error!");
  37. }
  38. else{
  39. rank=(int *)malloc(MyLength*sizeof(int));     /*分配序号数组的空间*/
  40. if(rank==0) ErrMsg("Malloc memory error!");
  41. }
  42. if(MyID==0){
  43.         int seed;
  44.                 printf("Please Input Seed:");
  45.         scanf("%d",&seed);                       /*获得随机数的种子*/
  46. srand(seed);                          
  47. printf("Random Numbers:n"); 
  48. for(i=0;i<DataSize;i++){
  49. data_in[i]=((int)rand())%10000;  /*生成随机数,并输出*/
  50. printf("%10d ",data_in[i]);
  51. }
  52. printf("nOutput:");
  53. printf("n");
  54. }
  55. /*向各个处理器播送待排序序列,对应于算法13.2步骤(1)*/
  56. MPI_Bcast(data_in, DataSize, MPI_INT, 0, MPI_COMM_WORLD);
  57. /*各个处理器分别计算所属元素的秩,对应于算法13.2步骤(2)*/
  58. CountRank(data_in,DataSize,MyLength,rank,SumID,MyID);
  59. /*从各个处理器收集已排序好的数据,对应于算法13.2步骤(3)*/
  60. if(MyID==0){
  61. for(i=1;i<SumID;i++){
  62. if(i==SumID-1)
  63. MPI_Recv(rank+MyLength*i,DataSize-MyLength*(SumID-1),MPI_INT,i,0,MPI_COMM_WORLD,&status);
  64. else
  65. MPI_Recv(rank+MyLength*i,MyLength,MPI_INT,i,0,MPI_COMM_WORLD,&status);
  66. }
  67. }
  68. else
  69. MPI_Send(rank,MyLength,MPI_INT,0,0,MPI_COMM_WORLD);
  70. /*根据所获得的秩重新定位各个数据,对应于算法13.2步骤(4)*/
  71. if(MyID==0){
  72. for(i=0;i<DataSize;i++)
  73. data_out[rank[i]]=data_in[i];
  74. for(i=0;i<DataSize;i++){
  75. printf("%10d ",data_out[i]);
  76. }
  77. printf("n");
  78. }
  79. MPI_Finalize();   
  80.         return 1;
  81. }
  82. /*
  83.  * 函数名: CountRank
  84.  * 功能: 计算所属部分数据的秩
  85.  * 输入: data:指向待排序序列的指针
  86.  *        DataSize为待排序序列的长度
  87.           MyLength为该处理器要排序的序列的长度
  88.           rank:指向秩数组的指针
  89.           SumID:总处理器个数
  90.           MyID:处理器ID
  91.  * 输出:返回1代表程序正常结束
  92.  */
  93. int CountRank(int *data,int DataSize,int MyLength,int *rank,int SumID,int MyID)
  94. {
  95. int i, j;
  96. int start, end;
  97. start=DataSize/SumID*MyID;      /*所属部分数据起始位置*/
  98. end=start+MyLength;             /*所属部分数据结束位置*/
  99. for(j=start;j<end;j++){         /*计算所属部分数据的rank*/
  100. rank[j-start]=0;
  101. for(i=0;i<DataSize;i++){
  102. if((data[j]>data[i]) || ((data[j]==data[i]) && (j>i)))
  103. rank[j-start]++;
  104. }
  105. }
  106.      return 1;
  107. }
  108. /*
  109.  * 函数名: ErrMsg
  110.  * 功能: 读入待排序序列的长度
  111.  * 输入: 无
  112.  * 输出: 返回待排序序列的长度
  113.  */
  114. int GetDataSize()
  115. {
  116. int i;
  117. while(1){
  118. printf("Input the Data Size :");
  119. scanf("%d",&i);
  120. if((i>0) && (i<=65535))
  121. break;
  122. ErrMsg("Wrong Data Size, must between [1..65535]");
  123. }
  124. return i;
  125. }
  126. /*
  127.  * 函数名: ErrMsg
  128.  * 功能: 输出错误信息
  129.  * 输入: msg:出错信息字符串
  130.  * 输出:返回1代表程序正常结束
  131.  */
  132. int ErrMsg(char *msg)
  133. {
  134. printf("Error: %s n",msg);
  135.     return 1;
  136. }