Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4. #include <math.h>
  5. #define PRECISION 0.000001
  6. #define RANGESIZE 1
  7. #define DATA 0
  8. #define RESULT 1
  9. #define FINISH 2
  10. #define QUEUESIZE 5
  11. //#define DEBUG
  12.  
  13. struct Node {
  14. double range[2];
  15. struct Node* next;
  16. };
  17.  
  18. struct Node* front = NULL;
  19. struct Node* rear = NULL;
  20.  
  21. void Enqueue(double rangeStart, double rangeEnd) {
  22. struct Node* temp =
  23. (struct Node*)malloc(sizeof(struct Node));
  24. temp->range[0] = rangeStart;
  25. temp->range[1] = rangeEnd;
  26. temp->next = NULL;
  27. if(front == NULL && rear == NULL){
  28. front = rear = temp;
  29. return;
  30. }
  31. rear->next = temp;
  32. rear = temp;
  33. }
  34.  
  35. // To Dequeue an integer.
  36. void Dequeue() {
  37. struct Node* temp = front;
  38. if(front == NULL) {
  39. printf("Queue is Empty\n");
  40. return;
  41. }
  42. if(front == rear) {
  43. front = rear = NULL;
  44. }
  45. else {
  46. front = front->next;
  47. }
  48. free(temp);
  49. }
  50.  
  51. double* Front() {
  52. if(front == NULL) {
  53. printf("Queue is empty\n");
  54. return;
  55. }
  56. return front->range;
  57. }
  58.  
  59. void Print() {
  60. struct Node* temp = front;
  61. while(temp != NULL) {
  62. printf("%f %f; ",temp->range[0], temp->range[1]);
  63. temp = temp->next;
  64. }
  65. printf("\n");
  66. }
  67.  
  68. double f(double x) {
  69. return sin(x);
  70. }
  71. double SimpleIntegration(double a,double b) {
  72. double i;
  73. double sum=0;
  74. for (i=a;i<b;i+=PRECISION)
  75. sum+=f(i)*PRECISION;
  76. return sum;
  77. }
  78. int main(int argc, char **argv) {
  79. int myrank,proccount;
  80. double a=0,b=100*M_PI;
  81. double range[2];
  82. double result=0,resulttemp;
  83. int sentcount=0;
  84. int i, j;
  85.  
  86. MPI_Status status;
  87. // Initialize MPI
  88. MPI_Init(&argc, &argv);
  89. // find out my rank
  90. MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  91. // find out the number of processes in MPI_COMM_WORLD
  92. MPI_Comm_size(MPI_COMM_WORLD, &proccount);
  93. if (proccount<2) {
  94. printf("Run with at least 2 processes");
  95. MPI_Finalize();
  96. return -1;
  97. }
  98. if (((b-a)/RANGESIZE)<2*(proccount-1)) {
  99. printf("More subranges needed");
  100. MPI_Finalize();
  101. return -1;
  102. }
  103. // now the master will distribute the data and slave processes will perform computations
  104. if (myrank==0) {
  105. range[0]=a;
  106. // first distribute some ranges to all slaves
  107. //for(j=0;j<QUEUESIZE;j++)
  108. //{
  109. for(i=1;i<proccount;i++) {
  110. range[1]=range[0]+RANGESIZE;
  111. #ifdef DEBUG
  112. printf("\nMaster sending range %f,%f to process %d",range[0],range[1],i);
  113. fflush(stdout);
  114. #endif
  115. MPI_Request sendRequest;
  116. // send it to process i
  117. MPI_Isend(range,2,MPI_DOUBLE,i,DATA,MPI_COMM_WORLD, &sendRequest);
  118. MPI_Status myStatus;
  119. MPI_Wait(&sendRequest, &myStatus);
  120. sentcount++;
  121. range[0]=range[1];
  122. }
  123. //}
  124. do {
  125. // distribute remaining subranges to the processes which have completed their parts
  126. MPI_Recv(&resulttemp,1,MPI_DOUBLE,MPI_ANY_SOURCE,RESULT,MPI_COMM_WORLD,&status);
  127. sentcount--;
  128. result+=resulttemp;
  129. #ifdef DEBUG
  130. printf("\nMaster received result %f from process %d",resulttemp,status.MPI_SOURCE);
  131. fflush(stdout);
  132. #endif
  133. // check the sender and send some more data
  134. range[1]=range[0]+RANGESIZE;
  135. if (range[1]>b) range[1]=b;
  136. #ifdef DEBUG
  137. printf("\nMaster sending range %f,%f to process %d",range[0],range[1],status.MPI_SOURCE);
  138. fflush(stdout);
  139. #endif
  140. MPI_Send(range,2,MPI_DOUBLE,status.MPI_SOURCE,DATA,MPI_COMM_WORLD);
  141. sentcount++;
  142. range[0]=range[1];
  143. } while (range[1]<b);
  144. // now receive results from the processes
  145. //for(i=0;i<(proccount-1);i++)
  146. while(sentcount>0){
  147. MPI_Recv(&resulttemp,1,MPI_DOUBLE,MPI_ANY_SOURCE,RESULT,MPI_COMM_WORLD,&status);
  148. sentcount--;
  149. #ifdef DEBUG
  150. printf("\nMaster received result %f from process %d",resulttemp,status.MPI_SOURCE);
  151. fflush(stdout);
  152. #endif
  153. result+=resulttemp;
  154. }
  155. // shut down the slaves
  156. for(i=1;i<proccount;i++) {
  157. MPI_Send(NULL,0,MPI_DOUBLE,i,FINISH,MPI_COMM_WORLD);
  158. }
  159. // now display the result
  160. printf("\nHirange, I am process 0, the result is %.20f\n",result);
  161. } else { // slave
  162. // this is easy - just receive data and do the work
  163.  
  164. do {
  165. int flag;
  166. MPI_Request receive_request;
  167. MPI_Iprobe(0,MPI_ANY_TAG,MPI_COMM_WORLD,&flag,&status);
  168.  
  169. if (flag && status.MPI_TAG==DATA) {
  170. MPI_Irecv(range,2,MPI_DOUBLE,0,DATA,MPI_COMM_WORLD,&receive_request);
  171. // compute my part
  172. //resulttemp=SimpleIntegration(range[0],range[1]);
  173. // send the result back
  174. //MPI_Send(&resulttemp,1,MPI_DOUBLE,0,RESULT,MPI_COMM_WORLD);
  175. //printf("Test %d\n", myrank);
  176. MPI_Status myStatus;
  177. MPI_Wait(&receive_request, &myStatus);
  178. //printf("Test2 %f %f; %d\n",range[0], range[1], myrank);
  179. Enqueue(range[0], range[1]);
  180. double* test = Front();
  181. //printf("Test3 %f %f; %d\n",test[0], test[1], myrank);
  182. //Print();
  183. }
  184. if(front != NULL)
  185. {
  186. double* curRange = Front();
  187.  
  188. //printf("slave calculating range: %f, %f/n", curRange[0],curRange[1]);
  189. resulttemp=SimpleIntegration(curRange[0],curRange[1]);
  190. Dequeue();
  191. // send the result back
  192. MPI_Send(&resulttemp,1,MPI_DOUBLE,0,RESULT,MPI_COMM_WORLD);
  193. //Print();
  194. }
  195.  
  196.  
  197.  
  198. } while (status.MPI_TAG!=FINISH);
  199. }
  200. // Shut down MPI
  201. MPI_Finalize();
  202. return 0;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement