Advertisement
ItsMeLucifer

Histogram with MPI

Mar 17th, 2022 (edited)
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.64 KB | None | 0 0
  1. #include <mpi.h>
  2. #include<stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include <iostream>
  7. #define MINI 0
  8. #define MAXI 10
  9. #define DATA 0
  10. #define RESULT 1
  11. #define FINISH 2
  12. #define PACKAGESIZE 3
  13.  
  14. int main(int argc, char** argv) {
  15.     int myrank, proccount;
  16.     int sentCount = 0;
  17.     int i;
  18.     MPI_Status status;
  19.     long inputArgument = 200;
  20.     int result[MAXI];
  21.     int resultTemp[MAXI];
  22.     int randomArray[10000];
  23.     int packageArray[PACKAGESIZE];
  24.     int resultSum = 0;
  25.  
  26.     // Initialize MPI
  27.     MPI_Init(&argc, &argv);
  28.  
  29.     // find out my rank
  30.     MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
  31.  
  32.     // find out the number of processes in MPI_COMM_WORLD
  33.     MPI_Comm_size(MPI_COMM_WORLD, &proccount);
  34.     for (i = MINI; i < MAXI; i++) {
  35.         result[i] = 0;
  36.         resultTemp[i] = 0;
  37.     }
  38.     for (i = 0; i < inputArgument; i++) {
  39.         randomArray[i] = 0;
  40.         //If inputArgument is not a multiple of PACKAGESIZE, fill out the redundant indexes with -1
  41.         int modulo = inputArgument % PACKAGESIZE;
  42.         if ( modulo != 0 && i > inputArgument-modulo) {
  43.             randomArray[i] = -1;
  44.         }
  45.     }
  46.     for (i = 0; i < PACKAGESIZE; i++) {
  47.         packageArray[i] = 0;
  48.     }
  49.     if (proccount < 2)
  50.     {
  51.         printf("Run with at least 2 processes");
  52.         MPI_Finalize();
  53.         return -1;
  54.     }
  55.     if (inputArgument < PACKAGESIZE * (proccount-1)) {
  56.         printf("Please give bigger number");
  57.         MPI_Finalize();
  58.         return -1;
  59.     }
  60.     if (inputArgument > 10000) {
  61.         printf("Please give smaller number");
  62.     }
  63.     // now the master will distribute the data and slave processes will perform computations
  64.     if (myrank == 0)
  65.     {
  66.         //Fill out array with random numbers 0-1000
  67.         for (i = 0; i < inputArgument; i++) {
  68.             randomArray[i] = rand() % MAXI + MINI;
  69.         }
  70.  
  71.         // first distribute some ranges to all slaves
  72.         for (i = 1; i < proccount; i++)
  73.         {
  74.             //Get part of randomArray
  75.             memcpy(packageArray, randomArray + PACKAGESIZE * sentCount, sizeof(int) * PACKAGESIZE);
  76.  
  77.             // send it to process i
  78.             MPI_Send(packageArray, PACKAGESIZE, MPI_INT, i, DATA, MPI_COMM_WORLD);
  79.             sentCount++;
  80.         }
  81.         while (sentCount * PACKAGESIZE < inputArgument)
  82.         {
  83.             // distribute remaining subranges to the processes which have completed their parts
  84.             MPI_Recv(&resultTemp, MAXI, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
  85.  
  86.             //Add resultTemp to result array
  87.             for (i = MINI; i < MAXI; i++) {
  88.                 result[i] += resultTemp[i];
  89.             }
  90.  
  91.             // check the sender and send some more data
  92.             memcpy(packageArray, randomArray + PACKAGESIZE * sentCount, sizeof(int) * PACKAGESIZE);
  93.  
  94.             MPI_Send(packageArray, PACKAGESIZE, MPI_INT, status.MPI_SOURCE, DATA, MPI_COMM_WORLD);
  95.             sentCount++;
  96.         }
  97.  
  98.         // now receive results from the processes
  99.         for (i = 0; i < (proccount - 1); i++)
  100.         {
  101.             MPI_Recv(&resultTemp, MAXI, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
  102.  
  103.             for (int i = MINI; i < MAXI; i++) {
  104.                 result[i] += resultTemp[i];
  105.             }
  106.            
  107.         }
  108.  
  109.         // shut down the slaves
  110.         for (i = 1; i < proccount; i++)
  111.         {
  112.             MPI_Send(NULL, 0, MPI_INT, i, FINISH, MPI_COMM_WORLD);
  113.         }
  114.  
  115.         // now display the result
  116.         printf("\nHi, I am process 0, the result is: ");
  117.         for (i = 0; i < MAXI; i++) {
  118.             resultSum += result[i];
  119.         }
  120.         printf("The sum: %i",resultSum);
  121.        
  122.     }
  123.     else
  124.     {   // slave
  125.         // this is easy - just receive data and do the work
  126.         do
  127.         {
  128.             for (i = MINI; i < MAXI; i++) {
  129.                 resultTemp[i] = 0;
  130.             }
  131.             MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
  132.  
  133.             if (status.MPI_TAG == DATA)
  134.             {
  135.                 MPI_Recv(packageArray, PACKAGESIZE, MPI_INT, 0, DATA, MPI_COMM_WORLD, &status);
  136.                 // compute my part
  137.                 for (i = 0; i < sizeof(packageArray) / sizeof(packageArray[0]); i++) {
  138.                     if (packageArray[i] > -1) {
  139.                         resultTemp[packageArray[i]]++;
  140.                     }
  141.                 }
  142.                 // send the result back
  143.                 MPI_Send(&resultTemp, MAXI, MPI_INT, 0, RESULT, MPI_COMM_WORLD);
  144.             }
  145.         } while (status.MPI_TAG != FINISH);
  146.     }
  147.  
  148.     // Shut down MPI
  149.     MPI_Finalize();
  150.  
  151.     return 0;
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement