Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Nov 17th, 2012  |  syntax: C  |  size: 7.45 KB  |  views: 37  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <mpi.h>
  5. #include <string.h>
  6.  
  7.  
  8. typedef struct buffers_s
  9. {
  10.     double *buf1;
  11.     double *buf2;
  12.     int size;
  13. } Buffers;
  14.  
  15.  
  16.  
  17. void BuffersMPI(Buffers *buf, MPI_Datatype *bufmpi)
  18. {
  19.     int block_lengths[2];                        // # of elt. in each block
  20.     MPI_Aint displacements[2];                   // displac.
  21.     MPI_Datatype typelist[2];                    // list of types
  22.     MPI_Aint start_address, address;            // use for calculating displac.
  23.     MPI_Datatype myType;
  24.  
  25.     block_lengths[0] = buf->size;
  26.     block_lengths[1] = buf->size;
  27.  
  28.     typelist[0] = MPI_DOUBLE;
  29.     typelist[1] = MPI_DOUBLE;
  30.  
  31.     displacements[0] = 0;
  32.     MPI_Address(buf->buf1, &start_address);
  33.     MPI_Address(buf->buf2, &address);
  34.     displacements[1] = address - start_address;
  35.  
  36.     MPI_Type_struct(2,block_lengths, displacements,typelist,bufmpi);
  37.     MPI_Type_commit(bufmpi);
  38. }
  39.  
  40.  
  41.  
  42.  
  43. void buffersmpisum(Buffers *in, Buffers *out, int *len, MPI_Datatype *typeptr)
  44. {
  45.     int i;
  46.  
  47.     for (i=0; i < *len; i++)
  48.     {
  49.         out->buf1[i] += in->buf1[i];
  50.         out->buf2[i] += in->buf2[i];
  51.     }
  52. }
  53.  
  54.  
  55.  
  56.  
  57. int main(int argc, char **argv)
  58. {
  59.     Buffers buffers_1, buffers_2;
  60.     double *pack, *unpack;
  61.     double size;
  62.     double start, end;
  63.     int pos;
  64.     int i;
  65.     int rank;
  66.     int cnt;
  67.     int ierr;
  68.     MPI_Datatype Buffers_mpi;
  69.     MPI_Op buffersumop;
  70.  
  71.     MPI_Init(&argc, &argv);
  72.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  73.  
  74.     cnt = 100000;
  75.  
  76.     size = 10;
  77.  
  78.     buffers_1.buf1   = calloc(size, sizeof *buffers_1.buf1);
  79.     buffers_1.buf2   = calloc(size, sizeof *buffers_1.buf2);
  80.     buffers_2.buf1   = calloc(size, sizeof *buffers_2.buf1);
  81.     buffers_2.buf2   = calloc(size, sizeof *buffers_2.buf2);
  82.     pack   = calloc(3*size, sizeof *pack);
  83.     unpack = calloc(3*size, sizeof *unpack);
  84.  
  85.     for (i=0; i<size; i++)
  86.     {
  87.         buffers_1.buf1[i] = 2;
  88.         buffers_1.buf2[i] = 4;
  89.     }
  90.  
  91.     MPI_Barrier(MPI_COMM_WORLD);
  92.  
  93. // ============================================================================
  94. //                      TWO CONSECUTIVE REDUCTIONS
  95. // ============================================================================
  96.  
  97.  
  98.     start = MPI_Wtime();
  99.  
  100.     for (i=0; i< cnt; i++)
  101.     {
  102.  
  103.         MPI_Reduce(buffers_1.buf1,               // send buffer
  104.                    buffers_2.buf1,               // reduced data goes here
  105.                    size,                          // size of the buffers
  106.                    MPI_DOUBLE,                    // type of the data
  107.                    MPI_SUM,                       // operation
  108.                    0,                             // proc 0 only will recieve data
  109.                    MPI_COMM_WORLD);               // all procs do the reduction
  110.  
  111.  
  112.         MPI_Reduce(buffers_1.buf2,               // send buffer
  113.                    buffers_2.buf2,               // reduced data goes here
  114.                    size,                          // size of the buffers
  115.                    MPI_DOUBLE,                    // type of the data
  116.                    MPI_SUM,                       // operation
  117.                    0,                             // proc 0 only will recieve data
  118.                    MPI_COMM_WORLD);              // all procs do the reduction
  119.  
  120.     }
  121.     end = MPI_Wtime();
  122.  
  123.     if(rank==0)
  124.     {
  125.         printf("%f seconds\n", end-start);
  126.     }
  127.  
  128.     // empty bufffers_2
  129.     memset(buffers_2.buf1, 0, size * sizeof *buffers_2.buf1);
  130.     memset(buffers_2.buf2, 0, size * sizeof *buffers_2.buf2);
  131.  
  132.  
  133.  
  134. // ============================================================================
  135. //                              PACK/UNPACK
  136. // ============================================================================
  137.  
  138.  
  139.  
  140.     MPI_Barrier(MPI_COMM_WORLD);
  141.     start = MPI_Wtime();
  142.     for(i=0; i < cnt; i++)
  143.     {
  144.         pos = 0;                           // start to pack at pack+0
  145.  
  146.         ierr = MPI_Pack(buffers_1.buf1,              // data to be packed
  147.                  size,                                // size of buf1
  148.                  MPI_DOUBLE,                          // type of these elements
  149.                  pack,                                // start adress of the pack
  150.                  2*size*sizeof *pack,                 // size of the pack buffer
  151.                  &pos,                                // pack+pos is the start position
  152.                  MPI_COMM_WORLD);                     // every proc will use 'pack'
  153.  
  154.  
  155.  
  156.     // pack the second buffer
  157.  
  158.         MPI_Pack(buffers_1.buf2,                     // data to be packed
  159.                  size,                                // size of buf1
  160.                  MPI_DOUBLE,                          // type of these elements
  161.                  pack,                                // start adress of the pack
  162.                  2*size*sizeof *pack,                 // size of the pack buffer
  163.                  &pos,                                // pack+pos is the start position
  164.                  MPI_COMM_WORLD);                     // every proc will use 'pack'
  165.  
  166.         // now reduce the pack
  167.  
  168.         MPI_Reduce(pack,               // send buffer
  169.                    unpack,             // reduced data goes here
  170.                    2*size,             // size of the buffers
  171.                    MPI_DOUBLE,         // type of the data
  172.                    MPI_SUM,            // operation
  173.                    0,                  // proc 0 only will recieve data
  174.                    MPI_COMM_WORLD);    // all procs do the reduction
  175.  
  176.     }
  177.  
  178.     end = MPI_Wtime();
  179.     if(rank==0)
  180.     {
  181.         printf("%f seconds\n", end-start);
  182.     }
  183.  
  184.  
  185.  
  186.     if (rank == 0)
  187.     {
  188.         for (i=0; i<2*size; i++)
  189.         {
  190.             printf("unpack[%d] = %f\n",i,unpack[i]);
  191.         }
  192.     }
  193.  
  194.  
  195.     // empty buffers_2
  196.     memset(buffers_2.buf1, 0, size * sizeof *buffers_2.buf1);
  197.     memset(buffers_2.buf2, 0, size * sizeof *buffers_2.buf2);
  198.  
  199.  
  200. // ============================================================================
  201. //                       MPI_Type_struct
  202. // ============================================================================
  203.  
  204.  
  205.     MPI_Barrier(MPI_COMM_WORLD);
  206.     start = MPI_Wtime();
  207.  
  208.     BuffersMPI(&buffers_1, &Buffers_mpi);
  209.     ierr = MPI_Op_create((MPI_User_function *)buffersmpisum,1,&buffersumop);
  210.  
  211.     if (ierr == MPI_SUCCESS) printf("op create success\n");
  212.  
  213.     for (i=0; i<cnt; i++)
  214.     {
  215.         MPI_Reduce(&buffers_1,               // send buffer
  216.                    &buffers_2,               // reduced data goes here
  217.                     size,                      // size of the buffers
  218.                     Buffers_mpi,                  // type of the data
  219.                     buffersumop,                     // operation
  220.                     0,                           // proc 0 only will recieve data
  221.                     MPI_COMM_WORLD);             // all procs do the reduction
  222.  
  223.     }
  224.  
  225.     end = MPI_Wtime();
  226.     if(rank==0)
  227.     {
  228.         printf("%f seconds\n", end-start);
  229.     }
  230.  
  231.  
  232.  
  233.     if (rank == 0)
  234.     {
  235.         for (i=0; i<  size; i++)
  236.         {
  237.             printf("buffers_2.buf1[%d] = %f \t buffers_2.buf2[%d] = %f\n",
  238.                     i,buffers_2.buf1[i], i, buffers_2.buf2[i]);
  239.         }
  240.     }
  241.  
  242.  
  243.  
  244.     free(buffers_1.buf1);
  245.     free(buffers_1.buf2);
  246.     free(buffers_2.buf1);
  247.     free(buffers_2.buf2);
  248.     free(pack);
  249.     free(unpack);
  250.  
  251.  
  252.     MPI_Finalize();
  253.  
  254.     return 0;
  255. }