Share Pastebin
Guest
Public paste!

LOLZ

By: a guest | Mar 18th, 2010 | Syntax: C | Size: 10.86 KB | Hits: 56 | Expires: Never
Copy text to clipboard
  1. #include "mpi.h"
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #define STRIP 0
  8. #define BLOCK 1
  9. #define NO 1
  10. #define YES 0
  11. #define TRUE 1
  12. #define FALSE 0
  13. #define EDGE 1
  14. #define INTERIOR 0
  15. #define NORTH 0
  16. #define SOUTH 1
  17. #define WEST 2
  18. #define EAST 3
  19.  
  20. #define THRESHOLD 0.05f
  21. #define AMBIENT 20.0f
  22. #define FIRE 100.0f
  23.  
  24. int p, kp, mode;
  25. int height, width;
  26. int roomSizeX, roomSizeY;
  27.  
  28. float maxChange = 0.0f;
  29.  
  30. int main(int argc, char **argv)
  31. {
  32.  
  33.         //simulation configuraton:
  34.         int roomSizeX = 16, roomSizeY = 16;
  35.         int change = YES, loop = YES;
  36.  
  37.         float room[roomSizeX][roomSizeY];
  38.         // fireplace = 1/5th of roomsize, placed center
  39.         int fireplaceA = (roomSizeX*2)/5;
  40.         int fireplaceB = (roomSizeX*3)/5;
  41.         int myid;
  42.         float maxchange;
  43.     char name[16];
  44.         int length;
  45.         MPI_Init(&argc, &argv);
  46.         MPI_Comm_size(MPI_COMM_WORLD, &p);
  47.         kp = (int)sqrt((float)p);
  48.         if (p != (kp * kp)) //the number of processes must have an integer square root
  49.                 return 1; //nonzero return
  50.         MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  51.         MPI_Get_processor_name(name, &length);
  52.         //calculate dimensions of blocks/strips
  53.         if(mode == STRIP)
  54.         {
  55.                 width = roomSizeX/p;
  56.                 height = roomSizeY;
  57.         }
  58.         else if(mode == BLOCK)
  59.         {
  60.                 width = roomSizeX/kp;
  61.                 height = roomSizeY/kp;
  62.         }
  63.         float sauna[width][height]; //strip or block
  64.         float tempSauna[width+2][height+2]; //temp array with space for "invisible" line
  65.         float west[height], east[height], south[width], north[width];
  66.         // set an ambient temperature
  67.         int i, j;
  68.         for(i=0; i<width; i++)
  69.         {
  70.                 for(j=0; j<height; j++)
  71.                 {
  72.                         sauna[i][j] = AMBIENT;
  73.                 }
  74.         }
  75.         // main loop
  76.         int count=0;
  77.         if (myid == 0)
  78.         {
  79.                 printf("Sauna Simulator v0.1 by Truls and Jon for IPDC F2010 assignment 1.\n");
  80.                 printf("Running %dx%d room simulation using %d procs with a threshold value of %g.\n", roomSizeX, roomSizeY, p, THRESHOLD);
  81.                 if (mode == BLOCK)
  82.                         printf("Block mode set, %dx%d grid per proc.\n", width, height);
  83.                 else
  84.                         printf("Strip mode set, %dx%d grid per proc.\n", width, height);
  85.         }
  86.         printf("%c: rank %d ready.\n", name[0], myid); 
  87.         while(loop == YES)
  88.         {
  89.                 count++;
  90.                 // temp working copy
  91.                 for(i=0; i<width; i++)
  92.                 {
  93.                         for(j=0; j<height; j++)
  94.                         {
  95.                                 tempSauna [i+1][j+1] = sauna[i][j];
  96.                         }
  97.                 }
  98.                 // fill outer boundary with temperatures, move out of loop FIXME
  99.                 for(i=0;i<width;i++)
  100.                 {
  101.                         if (EDGE == getBound(myid, NORTH))
  102.                         {
  103.                                 int temp = (myid * width) + i; // position in room
  104.                                 if ((fireplaceA <= temp) && (temp <= fireplaceB)) //fireplace between point A and B
  105.                                         tempSauna[i+1][0] = FIRE;
  106.                                 else
  107.                                         tempSauna[i+1][0] = AMBIENT;
  108. //                              if ((temp+1)%10==0) printf("%d:%g ",temp,tempSauna[i+1][0]);
  109. //                              fflush(stdout);
  110.                         }
  111.                         else
  112.                         {
  113.                                 north[i]=sauna[i][0];
  114.                         }
  115.                 }
  116.                 for(i=0;i<width;i++)
  117.                 {
  118.                         if (EDGE == getBound(myid, SOUTH))
  119.                         {
  120.                                 tempSauna[i+1][height+1] = AMBIENT;
  121.                         }
  122.                         else
  123.                         {
  124.                                 south[i]=sauna[i][height-1];
  125.                         }
  126.                 }
  127.                 for(j=0;j<height;j++)
  128.                 {
  129.                         if (EDGE == getBound(myid, WEST))
  130.                         {
  131.                                 tempSauna[0][j+1] = AMBIENT;
  132.                         }
  133.                         else
  134.                         {
  135.                                 west[j]=sauna[0][j];
  136.                         }
  137.                 }
  138.                 for(j=0;j<height;j++)
  139.                 {
  140.                         if (EDGE == getBound(myid, EAST))
  141.                         {
  142.                                 tempSauna[width+1][j+1] = AMBIENT;
  143.                         }
  144.                         else
  145.                         {
  146.                                 east[j]=sauna[width-1][j];
  147.                         }
  148.                 }      
  149.                 // distribute border arrays
  150.                 MPI_Request request;
  151.                 int tag = 35634;
  152.                 int interiordebug = FALSE;
  153.                 if(INTERIOR == getBound(myid,NORTH))
  154.                 {      
  155.                         if (interiordebug == TRUE) printf("%s/%d sending size %d array to %d\n",name, myid, width, myid-kp);
  156.                         MPI_Isend(&north, width, MPI_FLOAT, myid-kp, tag, MPI_COMM_WORLD, &request);
  157.                         //printf("%c#%d: sender nord array med size %d, til rank %d \n  ", name[0], count, width, myid-kp);
  158.                 }
  159.                 if(INTERIOR == getBound(myid,SOUTH))
  160.                 {      
  161.                         if (interiordebug == TRUE) printf("%s/%d sending size %d array to %d\n",name, myid, width, myid+kp);
  162.                         MPI_Isend(&south, width, MPI_FLOAT, myid+kp, tag, MPI_COMM_WORLD, &request);
  163.                         //printf("%c#%d: sender syd array med size %d, til rank %d \n   ", name[0], count, width, myid+kp);
  164.                 }
  165.                 if(INTERIOR == getBound(myid,WEST))
  166.                 {
  167.                         if (interiordebug == TRUE) printf("%s/%d sending size %d array to %d\n",name, myid, height, myid-1);
  168.                         MPI_Isend(&west, height, MPI_FLOAT, myid-1, tag, MPI_COMM_WORLD, &request);
  169.                        
  170.                         /*
  171.                         int l;
  172.                         for (l = 0; l < height; l++)
  173.                         {
  174.                                 printf("%c#%d: venstre no %d: %g \n     ", name[0], count, l, west[l]);
  175.                         }
  176.                         printf("\n");
  177.                         */
  178.                        
  179.                 }
  180.                 if(INTERIOR == getBound(myid,EAST))
  181.                 {      
  182.                         if (interiordebug == TRUE) printf("%s/%d sending size %d array to %d\n",name, myid, height, myid+1);
  183.                         MPI_Isend(&east, height, MPI_FLOAT, myid+1, tag, MPI_COMM_WORLD, &request);
  184.                         /*
  185.                         if(myid == 0)
  186.                         {
  187.                         int l;
  188.                         for (l = 0; l < height; l++)
  189.                         {
  190.                                 printf("SENDT %c#%d: hoejre no %d: %g \n", name[0], count, l,east[l]);
  191.                         }
  192.                         printf("\n");
  193.                         }
  194.                         */
  195.                 }
  196.                 // recieve border arrays
  197.                 MPI_Status status;
  198.                 if(INTERIOR == getBound(myid,NORTH))
  199.                 {      
  200.                         MPI_Recv(&north, width, MPI_FLOAT, myid-kp, tag, MPI_COMM_WORLD, &status);
  201.                         for (i = 0; i < width; i++)
  202.                         {
  203.                                 tempSauna[i+1][0] = north[i];
  204.                         }
  205.                 }
  206.                 if(INTERIOR == getBound(myid,SOUTH))
  207.                 {      
  208.                         MPI_Recv(&south, width, MPI_FLOAT, myid+kp, tag, MPI_COMM_WORLD, &status);
  209.                        
  210.                         for (i = 0; i < width; i++)
  211.                         {
  212.                                 tempSauna[i+1][height+1] = south[i];
  213.                         }
  214.                 }
  215.                 if(INTERIOR == getBound(myid,WEST))
  216.                 {
  217.                         MPI_Recv(&west, height, MPI_FLOAT, myid-1, tag, MPI_COMM_WORLD, &status);
  218.                         //printf("%s/%d ", name, myid);
  219.                         for (i = 0; i < height; i++)
  220.                         {
  221.                                 tempSauna[0][i+1] = west[i];
  222.                                 //printf("w%d:%f ", i, west[i]);
  223.                         }
  224.                         //printf("\n");
  225.                 }
  226.                 if(INTERIOR == getBound(myid,EAST))
  227.                 {
  228.                         MPI_Recv(&east, height, MPI_FLOAT, myid+1, tag, MPI_COMM_WORLD, &status);
  229.                         for (i = 0; i < height; i++)
  230.                         {
  231.                                 tempSauna[width+1][i+1] = east[i];
  232.                         }
  233.                                                 if(myid == 0)
  234.                         {
  235.                         int l;
  236.                         //for (l = 0; l < height; l++)
  237.                         //{
  238.                                 //printf("MODTAGET: %c#%d: fra venstre no %d: %g \n", name[0], count, l,east[l]);
  239.                         //}
  240.                         }
  241.                 }
  242.                 // calculate temperatures
  243.                 float temp, dif;
  244.                 for (i = 0; i < width; i++)
  245.                 {
  246.                          //printf("%c: ", name[0]);
  247.                         for (j = 0; j < height; j++)
  248.                         {
  249.                                 temp = sauna[i][j];
  250.                                 sauna[i][j] = ( tempSauna[i+1][j] +
  251.                                                                 tempSauna[i][j+1] +
  252.                                                                 tempSauna[i+2][j+1] +
  253.                                                                 tempSauna[i+1][j+2] ) / 4.0f;
  254.                                                                 //printf("%g ", sauna[i][j]);
  255.                                 temp -= sauna[i][j];
  256.  
  257.                                 // because apparently math.h doesnt work (abs)
  258.                                 if (temp < 0.0f)
  259.                                         temp *= -1.0f;
  260.                                 if (temp > maxChange)
  261.                                         maxChange = temp;
  262.                         }
  263.                 }              
  264.                 if (maxChange < THRESHOLD)
  265.                 {
  266.                         change = NO;
  267.                 }
  268.  
  269.                 maxChange = 0.0f;
  270.                 MPI_Barrier(MPI_COMM_WORLD);
  271.                 MPI_Reduce(&change, &loop, 1, MPI_INT, MPI_PROD,0, MPI_COMM_WORLD); //multiply changes, put to loop
  272.                 MPI_Bcast(&loop,1, MPI_INT, 0, MPI_COMM_WORLD); //broadcast loop from master process
  273.                
  274.                 if(loop == NO)
  275.                 {              
  276.                         printf("%c#%d: stopping.\n", name[0], count);
  277.                         float sendarray[width*height];
  278.                         int m;
  279.                         for(m=0;m<width*height;m++)
  280.                         {
  281.                                 sendarray[m] = sauna[m%width][m/height];
  282.                                 // printf("%c#%d: sendarray plads %d, værdi: %g  \n", name[0], count, m, sendarray[m]);
  283.                         }
  284.                         float temparray[roomSizeX*roomSizeY];
  285.                         MPI_Barrier(MPI_COMM_WORLD);
  286.                         MPI_Gather(&sendarray, width*height, MPI_FLOAT, &temparray, width*height, MPI_FLOAT,0,MPI_COMM_WORLD);
  287.                         if(myid==0)
  288.                         {
  289.                                 if(mode == STRIP)
  290.                                 {
  291.                                         //printf("%c#: width er: %d, heighth er %d  \n", name[0], width, height);
  292.                                         int n;
  293.                                         for(n=0;n < roomSizeX*roomSizeY; n++)
  294.                                         {      
  295.                                                 int xval = n%width +(n/(height*width))*width;
  296.                                                 int yval =  (n/width)%height;
  297.                                                 //printf("%c#: x = %d, y = %d  \n", name[0], xval, yval);
  298.                                                 room[xval][yval]=temparray[n];
  299.                                         }
  300.                                 }
  301.                                 else if(mode == BLOCK)
  302.                                 {
  303.                                         //printf("%c#: block width %d, heigth %d.\n", name[0], width, height);
  304.                                         int n;
  305.                                         for(n=0;n < roomSizeX*roomSizeY; n++)
  306.                                         {      
  307.                                                 int xval = n%width +(((n/(height*width))%kp)*width);
  308.                                                 int yval =  (n/width)%(height)+(n/(width*height*kp))*height;
  309.                                                 // printf("%c#: x = %d, y = %d  \n", name[0], xval, yval);
  310.                                                 room[xval][yval]=temparray[n];
  311.                                         }
  312.                                 }
  313.                                 printf("%c#%d: room array done.\n", name[0], count);
  314.                                 int x,y;
  315.                                 //begin bitmap write vars
  316.                                 int r, g, b;
  317.                                 int rgb;
  318.         //                      printf ("writing bitmap to file bitmap.raw\n");
  319.                                 int rawbitmap[roomSizeX*roomSizeY];
  320.                                 float scale = 256 / (FIRE - AMBIENT);
  321. //                              printf("scale:%g\n\n\n",scale);
  322.                                 int c = 0;
  323.                                 float btemp;
  324.                                 FILE * pFile;
  325.                                 pFile = fopen ("bitmap.raw", "wb");    
  326.                                 //end bitmap write vars
  327.                                 sleep(1); // to get nice text output
  328.                                 printf("Printing out results:\n");
  329.                                 for(x=0;x<roomSizeX;x++)
  330.                                 {      
  331.                                         printf("%d;", x);
  332.                                         for(y=0;y<roomSizeY;y++)
  333.                                         {
  334.                                                 printf("%g;", room[x][y]);
  335.                                                 //printf("%X%X", 0, 0);
  336.                                                 btemp = room[x][y] - AMBIENT;
  337.                                                 r = (int) (scale * btemp); r = r << 16;
  338.                                                 //printf("r=%d ",r);
  339.                                                 //printf("%X", (int) (scale * btemp));
  340.                                                 g = 30; g = g << 8;
  341.                                                 //printf("g=%d ",g);
  342.                                                 //printf("%X", 30);
  343.                                                 b = (int) (256.0f - scale * btemp);
  344.                                                 //printf("b=%d ",b);
  345.                                                 //printf("%X", (int) (256.0f - scale * btemp));
  346.                                                 rawbitmap[c] = (r + g + b);
  347.                                                 //printf("0x%X ", rawbitmap[c]);
  348.                                                 c++;
  349.                                         }
  350.                                         printf("\n");
  351.                                         fflush(stdout);
  352.                                 }
  353.                                 fwrite (rawbitmap, sizeof(rgb), roomSizeX*roomSizeY, pFile);
  354.                                 fclose (pFile);                        
  355.                                 //writeFloatArrayToRawBitmap(&room, roomSizeX, roomSizeY);
  356.                         }
  357.                 }
  358.         }
  359.         // second make the updated array
  360.         // calculate if we need too continue loop (gange loop sammen hvis nul bliv ved)
  361.         //printf("\n\n");
  362.         MPI_Finalize();
  363. }
  364.  
  365. //returns EDGE if the boundary is facing a wall/the fireplace, INTERIOR otherwise
  366. int getBound(int id,int dir)
  367. {
  368.         if(mode == STRIP)
  369.         {
  370.                 if((dir == NORTH) || (dir == SOUTH))
  371.                         return EDGE;
  372.                 else if ((dir == WEST) && (id == 0))
  373.                         return EDGE;
  374.                 else if ((dir == EAST) && (id == p - 1))
  375.                         return EDGE;
  376.         }
  377.         else if (mode == BLOCK)
  378.         {
  379.                 if ((dir == NORTH) && (0 == id/kp))
  380.                         return EDGE;
  381.                 else if ((dir == SOUTH) && (kp-1) == ((id)/kp))
  382.                         return EDGE;
  383.                 else if ((dir == WEST) && ((id % kp) == 0))
  384.                         return EDGE;
  385.                 else if ((dir == EAST) && ((id % kp) == kp - 1))
  386.                         return EDGE;
  387.         }
  388.         return INTERIOR;
  389. }
  390.  
  391. void writeFloatArrayToRawBitmap(float** fDblArr, int x, int y)
  392. {
  393.         char r, g, b;
  394.         int rgb;
  395. //      printf ("writing bitmap to file bitmap.raw\n");
  396.         int rawbitmap[x*y];
  397.         int i, j;
  398.         float scale = 256 / (FIRE - AMBIENT);
  399.         int c = 0;
  400.         float temp;
  401.  
  402. //      FILE * pFile;
  403. //      pFile = fopen ("bitmap.raw", "wb");
  404.         for (i = 0; i < x; i++)
  405.         {
  406.                 for (j = 0; j < y; j++)
  407.                 {
  408.                         temp = fDblArr[i][j];//fejl her
  409.                         r = (char) scale * temp;
  410.                         g = (char) 0;
  411.                         b = (char) (1.0f/scale) * temp;
  412.                         rawbitmap[c] = r << 16 + g << 8 + b;
  413.                         printf("%c ", rawbitmap[c]);
  414.                         c++;
  415.                 }
  416.         }
  417. //      fwrite (rawbitmap, sizeof(rgb), x*y, pFile);
  418. //      fclose (pFile);
  419. }