Advertisement
Guest User

Untitled

a guest
Aug 12th, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.78 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include <string.h>
  4. #include <sys/time.h>
  5. #include <mpi.h>
  6. #include <omp.h>
  7.  
  8. #define X 2000
  9. #define Y 50000
  10. #define NUMSTEPS 10
  11. #define AMBIENTTEMP 20
  12. #define HEATTEMP 200
  13.  
  14. //Array and Column Creation
  15. double** Make2DdoubleArray(int arraySizeX, int arraySizeY);
  16. double* makeCol(void);
  17.  
  18. //Array and Column Ops
  19. void initArray(double** sourceArray, int totalCols);
  20. void initCol(double* col);
  21. void removeArray(double** sourceArray, int cols);
  22. void applyHeat(double** sourceArray, int totalCols);
  23. void printArray(double** sourceArray, int totalCols);
  24.  
  25. //Temp Evaluation
  26. void evalTemp(double** sourceArray, double** resultArray, double* readLeft, double* sendLeft, double* readRight, double* sendRight, int totalCols, int ID, int NoProc);
  27.  
  28. int main(int argc, char **argv)
  29. {
  30.  
  31.         //Total Processes, Process ID, Remainder of Cols, Cols per Node, Cols Assigned, Start and End Cols, Total Cols with Buf, Switch, Loop Control Vars, Print Sync
  32.         int NoProc, ID, remainder, perNode, colsAssigned, startCol, endCol,totalCols, cycleSwitch, i, j, Num;
  33.         MPI_Status Status;
  34.  
  35.         //Used for node synchronization
  36.         int go = 0;
  37.  
  38.         //Pointers for the arrays
  39.         double** sourceArray;
  40.         double** resultArray;
  41.         double* readLeft;
  42.         double* sendLeft;
  43.         double* readRight;
  44.         double* sendRight;
  45.  
  46.         //Initialise
  47.         MPI_Init(&argc,&argv);
  48.         MPI_Comm_size(MPI_COMM_WORLD,&NoProc);
  49.         MPI_Comm_rank(MPI_COMM_WORLD,&ID);
  50.  
  51. ///////////////////////////////////////////////////////////////////////////////////////////////Break up the cols per node //////////////////////////////////////////////////////////
  52.     //Divide up the cols
  53.         remainder = X%NoProc;
  54.         perNode = ((X - remainder)/NoProc);
  55.  
  56.         if(remainder ==  0)
  57.         {
  58.                 colsAssigned = perNode;
  59.                 //Find the start and end collumn for this nodes range
  60.                 if (ID != 0)
  61. DONE!           {
  62. Total time taken to complete in seconds is 5.901662ID);
  63. Message from xz015489@compute-0-11.local on pts/5 at 15:02 ...
  64.                 }
  65.                 else
  66.                 {
  67.                         startCol = 0;
  68.                         endCol = startCol + colsAssigned - 1;
  69.                 }
  70.         }
  71.         else
  72.         {
  73.                 //Distribute the remaining cols evenly
  74.                 if(ID != 0)
  75.                 {
  76.                         if (ID < remainder)
  77.                         {
  78.                                 colsAssigned = perNode + 1;
  79.                                 startCol = (colsAssigned * ID);
  80.                                 endCol = startCol + colsAssigned - 1;
  81.                         }
  82.                         else
  83.                         {
  84.                                 colsAssigned = perNode;
  85.                                 startCol = (((perNode + 1) * remainder) + ((ID - remainder) * perNode));
  86.                                 endCol = startCol + colsAssigned - 1;
  87.                         }
  88.                 }
  89.                 else
  90.                 {
  91.                         colsAssigned = perNode + 1;
  92.                         startCol = 0;
  93.                         endCol = startCol + colsAssigned - 1;
  94.                 }
  95.         }
  96. /////////////////////////////////////////////////////////////Done breaking up the columns, making arrays.../////////////////////////////////////////////////////////////////////
  97.  
  98.         //Is this node one of the ones on the end as they only have one buffer col
  99.         if((ID == 0) || (ID == (NoProc - 1)))
  100.         {
  101.                 //Only have a node to the right/left respecticly so only need to be 1 unit bigger
  102.                 sourceArray = Make2DdoubleArray((colsAssigned + 2), (Y + 2));
  103.                 resultArray = Make2DdoubleArray((colsAssigned + 2), (Y + 2));
  104.                 totalCols = colsAssigned + 2;
  105.         }
  106.         else //Give the node 2 buffer cols for left and right
  107.         {
  108.                 //These need to be bigger as they are in the middle and have nodes either side
  109.                 sourceArray = Make2DdoubleArray((colsAssigned + 2), (Y + 2));
  110.                 resultArray = Make2DdoubleArray((colsAssigned + 2), (Y + 2));
  111.                 totalCols = colsAssigned + 2;
  112.         }
  113.         //Cols for sending/recieving left/right
  114.         readLeft = makeCol();
  115.         sendLeft = makeCol();
  116.         readRight = makeCol();
  117.         sendRight = makeCol();
  118.  
  119.         //Initialise the arrays to the ambient temps
  120.         initArray(sourceArray, totalCols);
  121.         initArray(resultArray, totalCols);
  122.         initCol(readLeft);
  123.         initCol(sendLeft);
  124.         initCol(readRight);
  125.         initCol(sendRight);
  126.  
  127.         //Apply heat to the edges
  128.         applyHeat(sourceArray, totalCols);
  129. //      printArray(sourceArray, totalCols);
  130. ////////////////////////////////////////////////////////////////////Done Making Arrays, Processing///////////////////////////////////////////////////////////////////////
  131.  
  132.         // Gets the current time and saves it
  133.         struct timeval stimev;
  134.         struct timeval itimev;
  135.         unsigned long int itaken;
  136.         gettimeofday(&stimev, NULL);
  137.  
  138.         go = 0;
  139.         if (ID == 0)
  140.         {
  141.                 go = 1;
  142.         }
  143.         if(NoProc > 1)
  144.         {
  145.                 cycleSwitch = 0;
  146.                 for(i = 0; i < NUMSTEPS; i++)
  147.                 {
  148.                         //Synchronize all nodes
  149. //                      MPI_Bcast(&go, 1, MPI_INT, 0, MPI_COMM_WORLD);
  150.  
  151.                         if(ID != 0)
  152.                         {
  153.                                 go = 0;
  154.         if (ID == 0)
  155.         {
  156.                 go = 1;
  157.         }
  158.         if(NoProc > 1)
  159.         {
  160.                 cycleSwitch = 0;
  161.                 for(i = 0; i < NUMSTEPS; i++)
  162.                 {
  163.                         //Synchronize all nodes
  164. //                      MPI_Bcast(&go, 1, MPI_INT, 0, MPI_COMM_WORLD);
  165.  
  166.                         if(ID != 0)
  167.                         {
  168.                                 go = 0;
  169.                                 if(cycleSwitch == 0)
  170.                                 {
  171.                                         evalTemp(sourceArray, resultArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  172.                                         cycleSwitch = 1;
  173.                                 }
  174.                                 else
  175.                                 {
  176.                                         evalTemp(resultArray, sourceArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  177.                                         cycleSwitch = 0;
  178.                                 }
  179. //                              MPI_Send(&go, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
  180.                                 continue;
  181.                         }
  182.                         else
  183.                         {
  184.                                 printf("Entering Step %d\n", i);
  185.                                 if(cycleSwitch == 0)
  186.                                 {
  187.                                         evalTemp(sourceArray, resultArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  188.                                         cycleSwitch = 1;
  189.                                 }
  190.                                 else
  191.                                 {
  192.                                         evalTemp(resultArray, sourceArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  193.                                         cycleSwitch = 0;
  194.                                 }
  195.                 for(i = 0; i < NUMSTEPS; i++)
  196.                 {
  197.                         printf("Node 0 entering step %d\n", i);
  198.                          if(cycleSwitch == 0)
  199.                                 {
  200.                                         evalTemp(sourceArray, resultArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  201.                                         cycleSwitch = 1;
  202.                                 }
  203.                                 else
  204.                                 {
  205.                                         evalTemp(resultArray, sourceArray, readLeft, sendLeft, readRight, sendRight, totalCols, ID, NoProc);
  206.                                         cycleSwitch = 0;
  207.                                 }
  208.                 }
  209.         }
  210. /*
  211. DONE!   //Round Robin Approach to Synchronizing Printing
  212.         Num = ID;
  213.         if(ID == 0)
  214.         {
  215.                 printf("###NODE %d ###", ID);
  216.                 printArray(sourceArray, totalCols);
  217.                 printArray(resultArray, totalCols);
  218.                 printf("\n");
  219.                 MPI_Send(&Num, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
  220.                 MPI_Recv(&Num, 1, MPI_INT, (NoProc - 1), MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  221.         }
  222.  
  223.         if((ID >= 1)&& (ID < (NoProc - 1)))
  224.         {
  225.                 MPI_Recv(&Num, 1, MPI_INT, (ID - 1), MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  226.                 printf("###NODE %d ###", ID);
  227.                 printArray(sourceArray, totalCols);
  228.                 printArray(resultArray, totalCols);
  229.                 printf("\n");
  230.                 MPI_Send(&Num, 1, MPI_INT, (ID + 1), 0, MPI_COMM_WORLD);
  231.         }
  232.  
  233.         if(ID == (NoProc - 1))
  234.         {
  235.                 MPI_Recv(&Num, 1, MPI_INT, (ID - 1), MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  236.                 printf("###NODE %d ###", ID);
  237.                 printArray(sourceArray, totalCols);
  238.                 printArray(resultArray, totalCols);
  239.                 printf("\n");
  240.                 MPI_Send(&Num, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
  241.         }
  242. */
  243.                 //Re-Measure The Time and Print It
  244.                 gettimeofday(&itimev, NULL);
  245.                 itaken  = ((itimev.tv_sec * 1000000) + itimev.tv_usec) - ((stimev.tv_sec * 1000000) + stimev.tv_usec);
  246.                 printf("Total time taken to complete in seconds is %ld.%06ld by node %d for %d cols\n", itaken / 1000000, itaken % 1000000, ID, totalCols);
  247.  
  248. //////////////////////////////////////////////////////////Cleaning Arrays and Finishing////////////////////////////////////////////////////////////////
  249.         removeArray(sourceArray, totalCols);
  250.         removeArray(resultArray, totalCols);
  251.         free(readLeft);
  252.         free(readRight);
  253.         free(sendLeft);
  254.         free(sendRight);
  255.  
  256.         MPI_Finalize();
  257. }
  258.  
  259. ///////////////////////////////////////////////////////////////////END OF MAIN//////////////////////////////////////////////////////////
  260.  
  261. void initArray(double** sourceArray, int totalCols)
  262. {
  263.         int i = 0;
  264.         int j = 0;
  265.         for (i = 0; i < (Y + 2); i++)
  266.         {
  267.                 for (j = 0; j < totalCols; j++)
  268.                 {
  269.                         sourceArray[j][i] = AMBIENTTEMP;
  270.                 }
  271. DONE!   }
  272. }
  273.  
  274. void initCol(double* col)
  275. {
  276.         int i = 0;
  277.         for(i = 0; i < Y; i++)
  278.         {
  279.                 col[i] = AMBIENTTEMP;
  280.         }
  281.         col[0] = HEATTEMP;
  282. }
  283.  
  284. double** Make2DdoubleArray(int arraySizeX, int arraySizeY)
  285. {
  286.         double** newArray;
  287.         int i = 0;
  288.         newArray = (double**) malloc(arraySizeX*sizeof(double*));
  289.         for (i = 0; i < arraySizeX; i++)
  290.         {
  291.                 newArray[i] = (double*) malloc(arraySizeY*sizeof(double));
  292.         }
  293.         return newArray;
  294. }
  295.  
  296. double* makeCol(void)
  297. {
  298.         double* newArray;
  299.         newArray = (double*)malloc(Y*sizeof(double));
  300.         return newArray;
  301. }
  302.  
  303. void removeArray(double** sourceArray, int cols)
  304. {
  305.         int i = 0;
  306.         for (i = 0; i < cols; i++)
  307.         {
  308.                 free(sourceArray[i]);
  309.         }
  310. }
  311.  
  312. void applyHeat(double** sourceArray, int totalCols)
  313. {
  314.         int i = 0;
  315.         double val;
  316.         for (i = 1; i < (totalCols - 1); i++)
  317.         {
  318.                 sourceArray[i][1] = HEATTEMP;
  319.         }
  320. }
  321.  
  322. void printArray(double** sourceArray, int totalCols)
  323. {
  324.         int i = 0;
  325.         int j = 0;
  326.         for (i = 0; i < (Y + 2); i++)
  327.         {
  328.                 for (j = 0; j < totalCols; j++)
  329.                 {
  330.                         if (j == 0)
  331.                         {
  332.                                 printf("\n");
  333.                         }
  334.                         printf("%f ", sourceArray[j][i]);
  335.                 }
  336.         }
  337.         printf("\n");
  338. }
  339. void evalTemp(double** sourceArray, double** resultArray, double* readLeft, double* sendLeft, double* readRight, double* sendRight, int totalCols, int ID, int NoProc)
  340. {
  341.  
  342. //Used for calculating and sending
  343.         double prevT;
  344.         double prevTup;
  345. //MPI Values
  346.         MPI_Status Status;
  347.         double prevTdown;
  348.         double prevTleft;
  349.         double prevTright;
  350.  
  351. //Values to send to and recieve from
  352.         int sendID;
  353.         int recieveID;
  354.  
  355. //Loop control
  356.         int i = 0;
  357.         int j = 0;
  358.  
  359. //      #pragma omp parallel
  360.          for (i = 1; i < (Y + 1); i++)
  361.          {
  362.                 for (j = 1; j < (totalCols - 1); j++)
  363.                 {
  364.                         {
  365.                                 resultArray[j][i] = ((sourceArray[j][i] + sourceArray[(j - 1)][i] + sourceArray[(j + 1)][i] + sourceArray[j][(i - 1)] + sourceArray[j][(i + 1)]) / 5);
  366.                         }
  367.                 }
  368.         }
  369.         //Synced send doesnt return until matching recieve
  370.         if(NoProc > 1)
  371.         {
  372.                 if(ID == 0)
  373.                 {
  374.                         //Send the right hand col right
  375.                         MPI_Send(resultArray[(totalCols - 2)],Y, MPI_DOUBLE, ID+1, 0, MPI_COMM_WORLD);
  376.                         //Recieve next nodes left hand col
  377.                         MPI_Recv(resultArray[(totalCols - 1)],Y, MPI_DOUBLE, ID+1, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  378.                 }
  379.                 else if(ID == NoProc-1)
  380.                 {
  381.                         //Recieve previous nodes right hand col
  382.                         MPI_Recv(resultArray[0],Y, MPI_DOUBLE, ID-1, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  383.                         //Send the right hand col right
  384.                         MPI_Send(resultArray[1],Y, MPI_DOUBLE, ID-1, 0, MPI_COMM_WORLD);
  385.                 }
  386.                 else
  387.                 {
  388.                         //Recieve previous nodes right hand col
  389.                         MPI_Recv(resultArray[0],Y, MPI_DOUBLE, ID-1, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  390.                         //Send left hand col to previous node
  391.                         MPI_Send(resultArray[1],Y, MPI_DOUBLE, ID-1, 0, MPI_COMM_WORLD);
  392.  
  393.                         //Send right hand col to next node
  394.                         MPI_Send(resultArray[(totalCols - 2)],Y, MPI_DOUBLE, ID+1, 0, MPI_COMM_WORLD);
  395.                         //Recieve left hand col from next node
  396.                         MPI_Recv(resultArray[(totalCols - 1)],Y, MPI_DOUBLE, ID+1, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);
  397.                 }
  398.         }
  399. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement