Advertisement
bkit4s0

[mpi_mms.c]

Mar 11th, 2015
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.34 KB | None | 0 0
  1. #include "mpi.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define NRA 62                 /* number of rows in matrix A */
  6. #define NCA 15                 /* number of columns in matrix A */
  7. #define NCB 7                  /* number of columns in matrix B */
  8. #define MASTER 0               /* taskid of first task */
  9. #define FROM_MASTER 1          /* setting a message type */
  10. #define FROM_WORKER 2          /* setting a message type */
  11.  
  12. int main (int argc, char *argv[])
  13. {
  14. int     numtasks,              /* number of tasks in partition */
  15.         taskid,                /* a task identifier */
  16.         numworkers,            /* number of worker tasks */
  17.         source,                /* task id of message source */
  18.         dest,                  /* task id of message destination */
  19.         mtype,                 /* message type */
  20.         rows,                  /* rows of matrix A sent to each worker */
  21.         averow, extra, offset, /* used to determine rows sent to each worker */
  22.         i, j, k, rc;           /* misc */
  23. double  a[NRA][NCA],           /* matrix A to be multiplied */
  24.         b[NCA][NCB],           /* matrix B to be multiplied */
  25.         c[NRA][NCB];           /* result matrix C */
  26. MPI_Status status;
  27.  
  28. MPI_Init(&argc,&argv);
  29. MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
  30. MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
  31. if (numtasks < 2 ) {
  32.   printf("Need at least two MPI tasks. Quitting...\n");
  33.   MPI_Abort(MPI_COMM_WORLD, rc);
  34.   exit(1);
  35.   }
  36. numworkers = numtasks-1;
  37.  
  38.  
  39. /**************************** master task ************************************/
  40.    if (taskid == MASTER)
  41.    {
  42.       printf("mpi_mm has started with %d tasks.\n",numtasks);
  43.       printf("Initializing arrays...\n");
  44.       for (i=0; i<NRA; i++)
  45.          for (j=0; j<NCA; j++)
  46.             a[i][j]= i+j;
  47.       for (i=0; i<NCA; i++)
  48.          for (j=0; j<NCB; j++)
  49.             b[i][j]= i*j;
  50.  
  51.       /* Send matrix data to the worker tasks */
  52.       averow = NRA/numworkers;
  53.       extra = NRA%numworkers;
  54.       offset = 0;
  55.       mtype = FROM_MASTER;
  56.       for (dest=1; dest<=numworkers; dest++)
  57.       {
  58.          rows = (dest <= extra) ? averow+1 : averow;
  59.          printf("Sending %d rows to task %d offset=%d\n",rows,dest,offset);
  60.          MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
  61.          MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
  62.          MPI_Send(&a[offset][0], rows*NCA, MPI_DOUBLE, dest, mtype,
  63.                    MPI_COMM_WORLD);
  64.          MPI_Send(&b, NCA*NCB, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
  65.          offset = offset + rows;
  66.       }
  67.  
  68.       /* Receive results from worker tasks */
  69.       mtype = FROM_WORKER;
  70.       for (i=1; i<=numworkers; i++)
  71.       {
  72.          source = i;
  73.          MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
  74.          MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
  75.          MPI_Recv(&c[offset][0], rows*NCB, MPI_DOUBLE, source, mtype,
  76.                   MPI_COMM_WORLD, &status);
  77.          printf("Received results from task %d\n",source);
  78.       }
  79.  
  80.       /* Print results */
  81.       printf("******************************************************\n");
  82.       printf("Result Matrix:\n");
  83.       for (i=0; i<NRA; i++)
  84.       {
  85.          printf("\n");
  86.          for (j=0; j<NCB; j++)
  87.             printf("%6.2f   ", c[i][j]);
  88.       }
  89.       printf("\n******************************************************\n");
  90.       printf ("Done.\n");
  91.    }
  92.  
  93.  
  94. /**************************** worker task ************************************/
  95.    if (taskid > MASTER)
  96.    {
  97.       mtype = FROM_MASTER;
  98.       MPI_Recv(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status);
  99.       MPI_Recv(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status);
  100.       MPI_Recv(&a, rows*NCA, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
  101.       MPI_Recv(&b, NCA*NCB, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
  102.  
  103.       for (k=0; k<NCB; k++)
  104.          for (i=0; i<rows; i++)
  105.          {
  106.             c[i][k] = 0.0;
  107.         for (j=0; j<NCA; j++)
  108.                c[i][k] = c[i][k] + a[i][j] * b[j][k];
  109.          }
  110.       mtype = FROM_WORKER;
  111.       MPI_Send(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
  112.       MPI_Send(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
  113.       MPI_Send(&c, rows*NCB, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
  114.    }
  115.    MPI_Finalize();
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement