kamilosxd678

[SOWW][Lab2]Async

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