歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> MPI 實現直接選擇排序

MPI 實現直接選擇排序

日期:2017/3/1 10:13:46   编辑:Linux編程

選擇排序

1/主線程完成讀數據 分發 回收和過程控制

2/從線程完成從自己的數據集上選出最小的數值

3/主線程 從收到的數據中選出最小的更新 通知相應線程 發來新的最小值 選擇出下一個最小值 循環至完成

  1. #include "mpi.h"
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <ctype.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #define TAG 0
  8. #define INT_MAX 999999999
  9. #define ROOT 0
  10. int readValue(char* file,int* values) {
  11. int fd,size,count=0;
  12. char buffer[80],num[11];
  13. fd=open(file,O_RDONLY);
  14. do {
  15. size=read(fd,buffer,sizeof(buffer));
  16. int j=0;
  17. for(int i=0;i<size;++i) {
  18. if(buffer[i]<'9'&&buffer[i]>'0') {
  19. num[j++]=buffer[i];
  20. } else {
  21. num[j]='\0';
  22. values[count++]=atoi(num);
  23. j=0;
  24. }
  25. }
  26. } while(size!=0);
  27. close(fd);
  28. return count;
  29. }
  30. void defineIntVector(MPI_Datatype* type,int length) {
  31. MPI_Type_vector(length,1,1,MPI_INT,type);
  32. MPI_Type_commit(type);
  33. }
  34. int getMin(int *mp,int *array,int end,int ex) {
  35. int min=array[0];
  36. *mp=0;
  37. for(int i=1;i<=end;++i) {
  38. if(min>array[i]) {
  39. min=array[i];
  40. *mp=i;
  41. }
  42. }
  43. if(ex) {
  44. array[*mp]=array[end];
  45. array[end]=min;
  46. }
  47. return min;
  48. }
  49. int main(int argc,char *argv[]) {
  50. int *values;
  51. int *mins;
  52. int self,size,length,part,min,mp;
  53. MPI_Datatype MPI_VECTOR;
  54. MPI_Status status;
  55. MPI_Init(&argc,&argv);
  56. MPI_Comm_rank(MPI_COMM_WORLD,&self);
  57. MPI_Comm_size(MPI_COMM_WORLD,&size);
  58. //read value and broadcast to other processes
  59. if(0==self) {
  60. values=(int *)malloc(100*sizeof(int));
  61. length=readValue("/home/gt/parellel/sort/data.in",values);
  62. //each process recieves a part of all data data expands to a std length
  63. part=length/(size-1);
  64. if(0==length%part) {
  65. } else {
  66. part+=1;
  67. for(int i=length;i<part*(size-1);++i) {
  68. values[i]=INT_MAX;
  69. }
  70. }
  71. //broadcast length of each part
  72. MPI_Bcast(&part,1,MPI_INT,ROOT,MPI_COMM_WORLD);
  73. //minium value from each process
  74. defineIntVector(&MPI_VECTOR,part);
  75. //send out all the data
  76. for(int i=1;i<size;++i) {
  77. MPI_Ssend(&values[(i-1)*part],1,MPI_VECTOR,i,TAG,MPI_COMM_WORLD);
  78. }
  79. //gather all min from process
  80. //first
  81. mins=(int *)malloc(size*sizeof(int));
  82. min=INT_MAX;
  83. MPI_Gather(&min,1,MPI_INT,mins,1,MPI_INT,ROOT,MPI_COMM_WORLD);
  84. MPI_Barrier(MPI_COMM_WORLD);
  85. values[0]=getMin(&mp,mins,size-1,0);
  86. for(int i=1;i<length;++i) {
  87. //inform correspond process to provide another min
  88. MPI_Ssend(&mp,1,MPI_INT,mp,TAG,MPI_COMM_WORLD);
  89. //get result
  90. MPI_Recv(&mins[mp],1,MPI_INT,mp,TAG,MPI_COMM_WORLD,&status);
  91. values[i]=getMin(&mp,mins,size-1,0);
  92. }
  93. for(int i=1;i<size;++i) {
  94. mp=INT_MAX;
  95. MPI_Ssend(&mp,1,MPI_INT,i,TAG,MPI_COMM_WORLD);
  96. }
  97. for(int i=0;i<length;++i) {
  98. printf("%d ",values[i]);
  99. }
  100. printf("\n");
  101. free(mins);
  102. } else {
  103. MPI_Bcast(&part,1,MPI_INT,ROOT,MPI_COMM_WORLD);
  104. values=(int *)malloc(part*sizeof(int));
  105. defineIntVector(&MPI_VECTOR,part);
  106. MPI_Recv(values,1,MPI_VECTOR,ROOT,TAG,MPI_COMM_WORLD,&status);
  107. min=getMin(&mp,values,part-1,1);
  108. --part;
  109. MPI_Gather(&min,1,MPI_INT,mins,1,MPI_INT,ROOT,MPI_COMM_WORLD);
  110. MPI_Barrier(MPI_COMM_WORLD);
  111. while(1) {
  112. MPI_Recv(&mp,1,MPI_INT,ROOT,TAG,MPI_COMM_WORLD,&status);
  113. if(INT_MAX==mp) {//signal for end process
  114. break;
  115. }
  116. min=getMin(&mp,values,part-1,1);
  117. --part;
  118. MPI_Ssend(&min,1,MPI_INT,ROOT,TAG,MPI_COMM_WORLD);
  119. }
  120. }
  121. free(values);
  122. MPI_Finalize();
  123. return 0;
  124. }
Copyright © Linux教程網 All Rights Reserved