kamilosxd678

[MGR][SEM1][SOWW] Lab2

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