home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / test / io / bmi / driver-latency.c < prev    next >
C/C++ Source or Header  |  2006-06-27  |  13KB  |  563 lines

  1. /*
  2.  * (C) 2001 Clemson University and The University of Chicago
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <errno.h>
  11. #include "gossip.h"
  12. #include <mpi.h>
  13. #include "bmi.h"
  14. #include "bench-initialize.h"
  15. #include "bench-args.h"
  16. #include "bench-mem.h"
  17.  
  18. #define ITERATIONS 1000
  19.  
  20. static int bmi_server(
  21.     struct bench_options *opts,
  22.     struct mem_buffers *bmi_recv_bufs,
  23.     struct mem_buffers *bmi_send_bufs,
  24.     PVFS_BMI_addr_t addr,
  25.     enum bmi_buffer_type buffer_type,
  26.     double *wtime,
  27.     bmi_context_id context);
  28. static int bmi_client(
  29.     struct bench_options *opts,
  30.     struct mem_buffers *bmi_recv_bufs,
  31.     struct mem_buffers *bmi_send_bufs,
  32.     PVFS_BMI_addr_t addr,
  33.     enum bmi_buffer_type buffer_type,
  34.     double *wtime,
  35.     bmi_context_id context);
  36. static int mpi_server(
  37.     struct bench_options *opts,
  38.     struct mem_buffers *mpi_recv_bufs,
  39.     struct mem_buffers *mpi_send_bufs,
  40.     int addr,
  41.     double *wtime);
  42. static int mpi_client(
  43.     struct bench_options *opts,
  44.     struct mem_buffers *mpi_recv_bufs,
  45.     struct mem_buffers *mpi_send_bufs,
  46.     int addr,
  47.     double *wtime);
  48.  
  49. int main(
  50.     int argc,
  51.     char *argv[])
  52. {
  53.     int ret = -1;
  54.     int world_rank = 0;
  55.     MPI_Comm comm;
  56.     PVFS_BMI_addr_t *bmi_peer_array;
  57.     int *mpi_peer_array;
  58.     int num_clients;
  59.     struct bench_options opts;
  60.     struct mem_buffers mpi_send_bufs;
  61.     struct mem_buffers mpi_recv_bufs;
  62.     struct mem_buffers bmi_send_bufs;
  63.     struct mem_buffers bmi_recv_bufs;
  64.     enum bmi_buffer_type buffer_type = BMI_EXT_ALLOC;
  65.     double mpi_time, bmi_time;
  66.     bmi_context_id context;
  67.  
  68.     /* start up benchmark environment */
  69.     ret = bench_init(&opts, argc, argv, &num_clients, &world_rank, &comm,
  70.              &bmi_peer_array, &mpi_peer_array, &context);
  71.     if (ret < 0)
  72.     {
  73.     fprintf(stderr, "bench_init() failure.\n");
  74.     return (-1);
  75.     }
  76.  
  77.     /* verify that we didn't get any weird parameters */
  78.     if (num_clients > 1 || opts.num_servers > 1)
  79.     {
  80.     fprintf(stderr, "Too many procs specified.\n");
  81.     return (-1);
  82.     }
  83.  
  84.     /* setup MPI buffers */
  85.     ret = alloc_buffers(&mpi_send_bufs, ITERATIONS, opts.message_len);
  86.     ret += alloc_buffers(&mpi_recv_bufs, ITERATIONS, opts.message_len);
  87.     if (ret < 0)
  88.     {
  89.     fprintf(stderr, "alloc_buffers() failure.\n");
  90.     return (-1);
  91.     }
  92.  
  93.     /* setup BMI buffers (differs depending on command line args) */
  94.     if (opts.flags & BMI_ALLOCATE_MEMORY)
  95.     {
  96.     buffer_type = BMI_PRE_ALLOC;
  97.     ret = BMI_alloc_buffers(&bmi_send_bufs, ITERATIONS, opts.message_len,
  98.                 bmi_peer_array[0], BMI_SEND);
  99.     ret += BMI_alloc_buffers(&bmi_recv_bufs, ITERATIONS, opts.message_len,
  100.                  bmi_peer_array[0], BMI_RECV);
  101.     if (ret < 0)
  102.     {
  103.         fprintf(stderr, "BMI_alloc_buffers() failure.\n");
  104.         return (-1);
  105.     }
  106.     }
  107.     else
  108.     {
  109.     buffer_type = BMI_EXT_ALLOC;
  110.     ret = alloc_buffers(&bmi_send_bufs, ITERATIONS, opts.message_len);
  111.     ret += alloc_buffers(&bmi_recv_bufs, ITERATIONS, opts.message_len);
  112.     if (ret < 0)
  113.     {
  114.         fprintf(stderr, "alloc_buffers() failure.\n");
  115.         return (-1);
  116.     }
  117.     }
  118.  
  119.     /* mark all send buffers */
  120.     ret = mark_buffers(&bmi_send_bufs);
  121.     ret += mark_buffers(&mpi_send_bufs);
  122.     if (ret < 0)
  123.     {
  124.     fprintf(stderr, "mark_buffers() failure.\n");
  125.     return (-1);
  126.     }
  127.  
  128.     /******************************************************************/
  129.     /* Actually measure some stuff */
  130.  
  131.     /* BMI series */
  132.     if (world_rank == 0)
  133.     {
  134.     ret = bmi_server(&opts, &bmi_recv_bufs, &bmi_send_bufs,
  135.              bmi_peer_array[0], buffer_type, &bmi_time, context);
  136.     }
  137.     else
  138.     {
  139.     ret = bmi_client(&opts, &bmi_recv_bufs, &bmi_send_bufs,
  140.              bmi_peer_array[0], buffer_type, &bmi_time, context);
  141.     }
  142.     if (ret < 0)
  143.     {
  144.     return (-1);
  145.     }
  146.  
  147.     /* MPI series */
  148.     if (world_rank == 0)
  149.     {
  150.     ret = mpi_server(&opts, &mpi_recv_bufs, &mpi_send_bufs,
  151.              mpi_peer_array[0], &mpi_time);
  152.     }
  153.     else
  154.     {
  155.     ret = mpi_client(&opts, &mpi_recv_bufs, &mpi_send_bufs,
  156.              mpi_peer_array[0], &mpi_time);
  157.     }
  158.     if (ret < 0)
  159.     {
  160.     return (-1);
  161.     }
  162.  
  163.  
  164.     /******************************************************************/
  165. #if 0
  166.     if (!(opts.flags & REUSE_BUFFERS))
  167.     {
  168.     /* verify received buffers */
  169.     ret = check_buffers(&mpi_recv_bufs);
  170.     if (ret < 0)
  171.     {
  172.         fprintf(stderr, "MPI buffer verification failed.\n");
  173.         return (-1);
  174.     }
  175.     ret = check_buffers(&bmi_recv_bufs);
  176.     if (ret < 0)
  177.     {
  178.         fprintf(stderr, "BMI buffer verification failed.\n");
  179.         return (-1);
  180.     }
  181.     }
  182. #endif
  183.     /* print out results */
  184.  
  185.  
  186.     if (world_rank == 0)
  187.     {
  188.     bench_args_dump(&opts);
  189.     printf("number of iterations: %d\n", ITERATIONS);
  190.     printf
  191.         ("all times measure round trip in seconds unless otherwise noted\n");
  192.     printf("\"ave\" field is computed as (total time)/iterations\n");
  193.     }
  194.  
  195.     /* enforce output ordering */
  196.     fflush(stdout);
  197.     MPI_Barrier(MPI_COMM_WORLD);
  198.  
  199.     if (world_rank != 0)
  200.     {
  201.     printf("%d\t%f\t%f\t(size,total,ave)", bmi_recv_bufs.size,
  202.            bmi_time, (bmi_time / ITERATIONS));
  203.     printf(" bmi server\n");
  204.  
  205.     printf("%d\t%f\t%f\t(size,total,ave)", mpi_recv_bufs.size,
  206.            mpi_time, (mpi_time / ITERATIONS));
  207.     printf(" mpi server\n");
  208.     }
  209.  
  210.     /* enforce output ordering */
  211.     fflush(stdout);
  212.     MPI_Barrier(MPI_COMM_WORLD);
  213.  
  214.     if (world_rank == 0)
  215.     {
  216.     printf("%d\t%f\t%f\t(size,total,ave)", bmi_recv_bufs.size,
  217.            bmi_time, (bmi_time / ITERATIONS));
  218.     printf(" bmi client\n");
  219.  
  220.     printf("%d\t%f\t%f\t(size,total,ave)", mpi_recv_bufs.size,
  221.            mpi_time, (mpi_time / ITERATIONS));
  222.     printf(" mpi client\n");
  223.     }
  224.     /* free buffers */
  225.     free_buffers(&mpi_send_bufs);
  226.     free_buffers(&mpi_recv_bufs);
  227.  
  228.     if (opts.flags & BMI_ALLOCATE_MEMORY)
  229.     {
  230.     BMI_free_buffers(&bmi_send_bufs, bmi_peer_array[0], BMI_SEND);
  231.     BMI_free_buffers(&bmi_recv_bufs, bmi_peer_array[0], BMI_RECV);
  232.     }
  233.     else
  234.     {
  235.     free_buffers(&bmi_send_bufs);
  236.     free_buffers(&bmi_recv_bufs);
  237.     }
  238.  
  239.     /* shutdown interfaces */
  240.     BMI_close_context(context);
  241.     BMI_finalize();
  242.     MPI_Finalize();
  243.     return 0;
  244. }
  245.  
  246. static int bmi_server(
  247.     struct bench_options *opts,
  248.     struct mem_buffers *bmi_recv_bufs,
  249.     struct mem_buffers *bmi_send_bufs,
  250.     PVFS_BMI_addr_t addr,
  251.     enum bmi_buffer_type buffer_type,
  252.     double *wtime,
  253.     bmi_context_id context)
  254. {
  255.     int i = 0;
  256.     bmi_size_t actual_size;
  257.     bmi_op_id_t bmi_id;
  258.     void *send_buffer = NULL;
  259.     void *recv_buffer = NULL;
  260.     int ret = -1;
  261.     int outcount;
  262.     int error_code;
  263.     double time1, time2;
  264.  
  265.     MPI_Barrier(MPI_COMM_WORLD);
  266.     time1 = MPI_Wtime();
  267.  
  268.     for (i = 0; i < ITERATIONS; i++)
  269.     {
  270.     /* set buffer to use */
  271.     if (opts->flags & REUSE_BUFFERS)
  272.     {
  273.         recv_buffer = bmi_recv_bufs->buffers[0];
  274.         send_buffer = bmi_send_bufs->buffers[0];
  275.     }
  276.     else
  277.     {
  278.         recv_buffer = bmi_recv_bufs->buffers[i];
  279.         send_buffer = bmi_send_bufs->buffers[i];
  280.     }
  281.  
  282.     /* receive a message */
  283.     error_code = 0;
  284.     ret = BMI_post_recv(&bmi_id, addr, recv_buffer,
  285.                 bmi_recv_bufs->size, &actual_size, buffer_type, 0,
  286.                 NULL, context);
  287.     if (ret == 0)
  288.     {
  289.         do
  290.         {
  291.         ret = BMI_test(bmi_id, &outcount, &error_code, &actual_size,
  292.                    NULL, 0, context);
  293.         } while (ret == 0 && outcount == 0);
  294.     }
  295.     if (ret < 0 || error_code != 0)
  296.     {
  297.         fprintf(stderr, "Server: BMI recv error.\n");
  298.         return (-1);
  299.     }
  300.  
  301.     /* send a message */
  302.     error_code = 0;
  303.     ret = BMI_post_send(&bmi_id, addr, send_buffer,
  304.                 bmi_send_bufs->size, buffer_type, 0, NULL, context);
  305.     if (ret == 0)
  306.     {
  307.         do
  308.         {
  309.         ret = BMI_test(bmi_id, &outcount, &error_code, &actual_size,
  310.                    NULL, 0, context);
  311.         } while (ret == 0 && outcount == 0);
  312.     }
  313.     if (ret < 0 || error_code != 0)
  314.     {
  315.         fprintf(stderr, "Server: BMI send error.\n");
  316.         return (-1);
  317.     }
  318.     }
  319.  
  320.     time2 = MPI_Wtime();
  321.  
  322.     *wtime = time2 - time1;
  323.     return (0);
  324. }
  325.  
  326.  
  327. static int bmi_client(
  328.     struct bench_options *opts,
  329.     struct mem_buffers *bmi_recv_bufs,
  330.     struct mem_buffers *bmi_send_bufs,
  331.     PVFS_BMI_addr_t addr,
  332.     enum bmi_buffer_type buffer_type,
  333.     double *wtime,
  334.     bmi_context_id context)
  335. {
  336.     int i = 0;
  337.     bmi_size_t actual_size;
  338.     bmi_op_id_t bmi_id;
  339.     void *send_buffer = NULL;
  340.     void *recv_buffer = NULL;
  341.     int ret = -1;
  342.     int outcount;
  343.     int error_code;
  344.     double time1, time2;
  345.  
  346.     MPI_Barrier(MPI_COMM_WORLD);
  347.     time1 = MPI_Wtime();
  348.     for (i = 0; i < ITERATIONS; i++)
  349.     {
  350.     /* set buffer to use */
  351.     if (opts->flags & REUSE_BUFFERS)
  352.     {
  353.         recv_buffer = bmi_recv_bufs->buffers[0];
  354.         send_buffer = bmi_send_bufs->buffers[0];
  355.     }
  356.     else
  357.     {
  358.         recv_buffer = bmi_recv_bufs->buffers[i];
  359.         send_buffer = bmi_send_bufs->buffers[i];
  360.     }
  361.  
  362.     /* send a message */
  363.     error_code = 0;
  364.     ret = BMI_post_send(&bmi_id, addr, send_buffer,
  365.                 bmi_send_bufs->size, buffer_type, 0, NULL, context);
  366.     if (ret == 0)
  367.     {
  368.         do
  369.         {
  370.         ret = BMI_test(bmi_id, &outcount, &error_code, &actual_size,
  371.                    NULL, 0, context);
  372.         } while (ret == 0 && outcount == 0);
  373.     }
  374.     if (ret < 0 || error_code != 0)
  375.     {
  376.         fprintf(stderr, "Client: BMI send error.\n");
  377.         return (-1);
  378.     }
  379.  
  380.     /* receive a message */
  381.     error_code = 0;
  382.     ret = BMI_post_recv(&bmi_id, addr, recv_buffer,
  383.                 bmi_recv_bufs->size, &actual_size, buffer_type, 0,
  384.                 NULL, context);
  385.     if (ret == 0)
  386.     {
  387.         do
  388.         {
  389.         ret = BMI_test(bmi_id, &outcount, &error_code, &actual_size,
  390.                    NULL, 0, context);
  391.         } while (ret == 0 && outcount == 0);
  392.     }
  393.     if (ret < 0 || error_code != 0)
  394.     {
  395.         fprintf(stderr, "Client: BMI recv error.\n");
  396.         return (-1);
  397.     }
  398.     }
  399.     time2 = MPI_Wtime();
  400.  
  401.     *wtime = time2 - time1;
  402.     return (0);
  403. }
  404.  
  405. static int mpi_server(
  406.     struct bench_options *opts,
  407.     struct mem_buffers *mpi_recv_bufs,
  408.     struct mem_buffers *mpi_send_bufs,
  409.     int addr,
  410.     double *wtime)
  411. {
  412.     int i = 0;
  413.     void *send_buffer = NULL;
  414.     void *recv_buffer = NULL;
  415.     int ret = -1;
  416.     int flag;
  417.     MPI_Request request;
  418.     MPI_Status status;
  419.     double time1, time2;
  420.  
  421.     MPI_Barrier(MPI_COMM_WORLD);
  422.     time1 = MPI_Wtime();
  423.     for (i = 0; i < ITERATIONS; i++)
  424.     {
  425.     /* set buffer to use */
  426.     if (opts->flags & REUSE_BUFFERS)
  427.     {
  428.         recv_buffer = mpi_recv_bufs->buffers[0];
  429.         send_buffer = mpi_send_bufs->buffers[0];
  430.     }
  431.     else
  432.     {
  433.         recv_buffer = mpi_recv_bufs->buffers[i];
  434.         send_buffer = mpi_send_bufs->buffers[i];
  435.     }
  436.  
  437.     /* recv a message */
  438.     ret = MPI_Irecv(recv_buffer, mpi_recv_bufs->size, MPI_BYTE, addr,
  439.             0, MPI_COMM_WORLD, &request);
  440.     if (ret != MPI_SUCCESS)
  441.     {
  442.         fprintf(stderr, "MPI_Irecv() failure.\n");
  443.         return (-1);
  444.     }
  445.     do
  446.     {
  447.         ret = MPI_Test(&request, &flag, &status);
  448.     } while (ret == MPI_SUCCESS && flag == 0);
  449.     if (ret != MPI_SUCCESS)
  450.     {
  451.         fprintf(stderr, "MPI_Test() failure.\n");
  452.         return (-1);
  453.     }
  454.  
  455.     /* send a message */
  456.     ret = MPI_Isend(send_buffer, mpi_recv_bufs->size, MPI_BYTE, addr,
  457.             0, MPI_COMM_WORLD, &request);
  458.     if (ret != MPI_SUCCESS)
  459.     {
  460.         fprintf(stderr, "MPI_Isend() failure.\n");
  461.         return (-1);
  462.     }
  463.     do
  464.     {
  465.         ret = MPI_Test(&request, &flag, &status);
  466.     } while (ret == MPI_SUCCESS && flag == 0);
  467.     if (ret != MPI_SUCCESS)
  468.     {
  469.         fprintf(stderr, "MPI_Test() failure.\n");
  470.         return (-1);
  471.     }
  472.  
  473.     }
  474.     time2 = MPI_Wtime();
  475.  
  476.     *wtime = time2 - time1;
  477.     return (0);
  478. }
  479.  
  480. static int mpi_client(
  481.     struct bench_options *opts,
  482.     struct mem_buffers *mpi_recv_bufs,
  483.     struct mem_buffers *mpi_send_bufs,
  484.     int addr,
  485.     double *wtime)
  486. {
  487.     int i = 0;
  488.     void *send_buffer = NULL;
  489.     void *recv_buffer = NULL;
  490.     int ret = -1;
  491.     int flag;
  492.     MPI_Request request;
  493.     MPI_Status status;
  494.     double time1, time2;
  495.  
  496.     MPI_Barrier(MPI_COMM_WORLD);
  497.     time1 = MPI_Wtime();
  498.     for (i = 0; i < ITERATIONS; i++)
  499.     {
  500.     /* set buffer to use */
  501.     if (opts->flags & REUSE_BUFFERS)
  502.     {
  503.         recv_buffer = mpi_recv_bufs->buffers[0];
  504.         send_buffer = mpi_send_bufs->buffers[0];
  505.     }
  506.     else
  507.     {
  508.         recv_buffer = mpi_recv_bufs->buffers[i];
  509.         send_buffer = mpi_send_bufs->buffers[i];
  510.     }
  511.  
  512.     /* send a message */
  513.     ret = MPI_Isend(send_buffer, mpi_recv_bufs->size, MPI_BYTE, addr,
  514.             0, MPI_COMM_WORLD, &request);
  515.     if (ret != MPI_SUCCESS)
  516.     {
  517.         fprintf(stderr, "MPI_Isend() failure.\n");
  518.         return (-1);
  519.     }
  520.     do
  521.     {
  522.         ret = MPI_Test(&request, &flag, &status);
  523.     } while (ret == MPI_SUCCESS && flag == 0);
  524.     if (ret != MPI_SUCCESS)
  525.     {
  526.         fprintf(stderr, "MPI_Test() failure.\n");
  527.         return (-1);
  528.     }
  529.  
  530.     /* recv a message */
  531.     ret = MPI_Irecv(recv_buffer, mpi_recv_bufs->size, MPI_BYTE, addr,
  532.             0, MPI_COMM_WORLD, &request);
  533.     if (ret != MPI_SUCCESS)
  534.     {
  535.         fprintf(stderr, "MPI_Irecv() failure.\n");
  536.         return (-1);
  537.     }
  538.     do
  539.     {
  540.         ret = MPI_Test(&request, &flag, &status);
  541.     } while (ret == MPI_SUCCESS && flag == 0);
  542.     if (ret != MPI_SUCCESS)
  543.     {
  544.         fprintf(stderr, "MPI_Test() failure.\n");
  545.         return (-1);
  546.     }
  547.  
  548.     }
  549.     time2 = MPI_Wtime();
  550.  
  551.     *wtime = time2 - time1;
  552.     return (0);
  553. }
  554.  
  555. /*
  556.  * Local variables:
  557.  *  c-indent-level: 4
  558.  *  c-basic-offset: 4
  559.  * End:
  560.  *
  561.  * vim: ts=8 sts=4 sw=4 expandtab
  562.  */
  563.