Advertisement
--sas

apr8-parteplo.c

Apr 8th, 2022
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.86 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <mpi.h>
  4. #include <math.h>
  5. #include "l17.h"
  6.  
  7. int main(int argc, char** argv) {
  8.     int rc;
  9.     rc = MPI_Init(&argc, &argv);
  10.     L17_CHECK_ERROR(MPI_Init, rc);
  11.  
  12.     int size;
  13.     rc = MPI_Comm_size(MPI_COMM_WORLD, &size);
  14.     L17_CHECK_ERROR(MPI_Comm_size, rc);
  15.  
  16.     int rank;
  17.     rc = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  18.     L17_CHECK_ERROR(MPI_Comm_rank, rc);
  19.  
  20.     double *memu, *u, *memunew, *unew, delta, maxdelta, h, tau;
  21.     double eps = 1.0e-6;
  22.     int N, i;
  23.     FILE *ff;
  24.  
  25.     if (argc != 2) {
  26.         printf("Usage: exefile npoints\n");
  27.         MPI_Abort(MPI_COMM_WORLD, 1);
  28.     }
  29.  
  30.     N = atoi(argv[1]);
  31.     if (N == 0) {
  32.         printf("Set N to 1000\n");
  33.         N = 1000;
  34.     }
  35.     else {
  36.         printf("Set N to %d\n", N);
  37.     }
  38.  
  39.     int jbeg, jend, sizej;
  40.     jbeg = rank * ((N - 1) / size) + 1;
  41.     jend = (rank == size - 1) ? (N - 1) : ((rank + 1) * ((N - 1) / size));
  42.     sizej = jend - jbeg + 1;
  43.  
  44.     if ((memu = (double*) malloc((sizej + 2) * sizeof(double))) == NULL) {
  45.         printf("Error. Couldn't allocate memory.\n");
  46.         MPI_Abort(MPI_COMM_WORLD, 2);
  47.     }
  48.  
  49.     if ((memunew = (double*) malloc((sizej + 2) * sizeof(double))) == NULL) {
  50.         free(memu);
  51.         printf("Error. Couldn't allocate memory.\n");
  52.         MPI_Abort(MPI_COMM_WORLD, 3);
  53.     }
  54.  
  55.     u = memu - jbeg + 1;
  56.     unew = memunew - jbeg + 1;
  57.  
  58.     for (i = jbeg; i <= jend; ++i)
  59.         u[i] = 0;
  60.  
  61.     if (rank == 0)
  62.         unew[0] = u[0] = 1.0;
  63.  
  64.     if (rank == size - 1)
  65.         unew[N] = u[N] = 0.0;
  66.  
  67.     h = 1.0 / (double) N;
  68.     tau = 0.5 * h * h;
  69.  
  70.     while (1) {
  71.         for (i = jbeg; i <= jend; ++i)
  72.             unew[i] = u[i] + (tau / (h * h)) * (u[i - 1] - 2.0 * u[i] + u[i + 1]);
  73.  
  74.         maxdelta = 0.0;
  75.         for (i = jbeg; i <= jend; ++i) {
  76.             delta = fabs(unew[i] - u[i]);
  77.             maxdelta = (delta > maxdelta) ? delta : maxdelta;
  78.         }
  79.  
  80.         rc = MPI_Reduce((rank == 0) ? MPI_IN_PLACE : &maxdelta,
  81.                         &maxdelta, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
  82.         L17_CHECK_ERROR(MPI_Reduce, rc);
  83.  
  84.         rc = MPI_Bcast(&maxdelta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  85.         L17_CHECK_ERROR(MPI_Reduce, rc);
  86.  
  87.         if (maxdelta < eps)
  88.             break;
  89.  
  90.         for (i = jbeg; i <= jend; ++i)
  91.             u[i] = unew[i];
  92.  
  93.         if (rank > 0) {
  94.             rc = MPI_Send(u + jbeg, 1, MPI_DOUBLE, rank - 1, 1, MPI_COMM_WORLD);
  95.             L17_CHECK_ERROR(MPI_Reduce, rc);
  96.         }
  97.  
  98.         if (rank < size - 1) {
  99.             rc = MPI_Recv(u + jend + 1, 1, MPI_DOUBLE, rank + 1, MPI_ANY_TAG, MPI_COMM_WORLD, NULL);
  100.             L17_CHECK_ERROR(MPI_Reduce, rc);
  101.         }
  102.  
  103.         if (rank < size - 1) {
  104.             rc = MPI_Send(u + jend, 1, MPI_DOUBLE, rank + 1, 1, MPI_COMM_WORLD);
  105.             L17_CHECK_ERROR(MPI_Reduce, rc);
  106.         }
  107.  
  108.         if (rank > 0) {
  109.             rc = MPI_Recv(u + jbeg - 1, 1, MPI_DOUBLE, rank - 1, MPI_ANY_TAG, MPI_COMM_WORLD, NULL);
  110.             L17_CHECK_ERROR(MPI_Reduce, rc);
  111.         }
  112.     }
  113.  
  114.     free(memu);
  115.  
  116.     int* recvcounts;
  117.     if (rank == 0) {
  118.         if ((recvcounts = (int*) malloc(size * sizeof(int))) == NULL) {
  119.             printf("Error. Couldn't allocate memory.\n");
  120.             free(memunew);
  121.             MPI_Abort(MPI_COMM_WORLD, 4);
  122.         }
  123.     }
  124.  
  125.     rc = MPI_Gather(&sizej, 1, MPI_INT, recvcounts, 1, MPI_INT, 0, MPI_COMM_WORLD);
  126.     L17_CHECK_ERROR(MPI_Gather, rc);
  127.  
  128.     int* displs;
  129.     if (rank == 0) {
  130.         if ((displs = (int*) malloc(size * sizeof(int))) == NULL) {
  131.             printf("Error. Couldn't allocate memory.\n");
  132.             free(memunew);
  133.             free(recvcounts);
  134.             MPI_Abort(MPI_COMM_WORLD, 5);
  135.         }
  136.  
  137.         displs[0] = 1;
  138.         for (i = 1; i < size; ++i)
  139.             displs[i] = displs[i - 1] + recvcounts[i - 1];
  140.     }
  141.  
  142.     double *recvbuf;
  143.     if (rank == 0) {
  144.         if ((recvbuf = (double*) malloc((N + 1) * sizeof(double))) == NULL) {
  145.             printf("Error. Couldn't allocate memory.\n");
  146.             free(memunew);
  147.             free(recvcounts);
  148.             free(displs);
  149.             MPI_Abort(MPI_COMM_WORLD, 6);
  150.         }
  151.     }
  152.  
  153.     rc = MPI_Gatherv(unew + jbeg, sizej, MPI_DOUBLE, recvbuf, recvcounts, displs, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  154.     L17_CHECK_ERROR(MPI_Gatherv, rc);
  155.  
  156.     free(memunew);
  157.     if (rank == 0) {
  158.         recvbuf[0] = 1.0;
  159.         recvbuf[N] = 0.0;
  160.  
  161.         free(recvcounts);
  162.         free(displs);
  163.  
  164.         ff = fopen("apr8-parteplo.dat", "w+");
  165.         if (ff == NULL) {
  166.             printf("Couldn't open file.\n");
  167.             free(recvbuf);
  168.             MPI_Abort(MPI_COMM_WORLD, 7);
  169.         }
  170.  
  171.         for (i = 0; i <= N; ++i)
  172.             fprintf(ff, "%f ", recvbuf[i]);
  173.  
  174.         free(recvbuf);
  175.         fclose(ff);
  176.     }
  177.  
  178.     MPI_Finalize();
  179.  
  180.     return 0;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement