Blame test/mpi/io/simple_collective.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2015 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/* this deceptively simple test uncovered a bug in the way certain file systems
Packit Service c5cf8c
 * dealt with tuning parmeters.  See
Packit Service c5cf8c
 * https://github.com/open-mpi/ompi/issues/158 and
Packit Service c5cf8c
 * http://trac.mpich.org/projects/mpich/ticket/2261
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * originally uncovered in Darshan:
Packit Service c5cf8c
 * http://lists.mcs.anl.gov/pipermail/darshan-users/2015-February/000256.html
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * to really exercise the bug in simple_collective,
Packit Service c5cf8c
 * we'd have to run on a Lustre or Panasas file system.
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * I am surprised src/mpi/romio/test/create_excl.c did not uncover the bug
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#include <assert.h>
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <fcntl.h>
Packit Service c5cf8c
#include <sys/types.h>
Packit Service c5cf8c
#include <sys/stat.h>
Packit Service c5cf8c
#include <unistd.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#include <sys/time.h>
Packit Service c5cf8c
#include <mpi.h>
Packit Service c5cf8c
#include <errno.h>
Packit Service c5cf8c
#include <getopt.h>
Packit Service c5cf8c
#include "mpitest.h"
Packit Service c5cf8c
Packit Service c5cf8c
static char *opt_file = NULL;
Packit Service c5cf8c
static int rank = -1;
Packit Service c5cf8c
Packit Service c5cf8c
static int parse_args(int argc, char **argv);
Packit Service c5cf8c
static void usage(const char *prog);
Packit Service c5cf8c
Packit Service c5cf8c
int test_write(char *file, int nprocs, int rank, MPI_Info info)
Packit Service c5cf8c
{
Packit Service c5cf8c
    double stime, etime, wtime, w_elapsed, w_slowest, elapsed, slowest;
Packit Service c5cf8c
    MPI_File fh;
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
    char buffer[700] = { 0 };
Packit Service c5cf8c
    MPI_Status status;
Packit Service c5cf8c
    int verbose = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
    stime = MPI_Wtime();
Packit Service c5cf8c
Packit Service c5cf8c
    ret = MPI_File_open(MPI_COMM_WORLD, file,
Packit Service c5cf8c
                        MPI_MODE_CREATE | MPI_MODE_WRONLY | MPI_MODE_EXCL, info, &fh;;
Packit Service c5cf8c
Packit Service c5cf8c
    if (ret != 0) {
Packit Service c5cf8c
        fprintf(stderr, "Error: failed to open %s\n", file);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    etime = MPI_Wtime();
Packit Service c5cf8c
Packit Service c5cf8c
    ret = MPI_File_write_at_all(fh, rank * 700, buffer, 700, MPI_BYTE, &status);
Packit Service c5cf8c
    if (ret != 0) {
Packit Service c5cf8c
        fprintf(stderr, "Error: failed to write %s\n", file);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    wtime = MPI_Wtime();
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_File_close(&fh;;
Packit Service c5cf8c
Packit Service c5cf8c
    elapsed = etime - stime;
Packit Service c5cf8c
    w_elapsed = wtime - etime;
Packit Service c5cf8c
    MPI_Reduce(&elapsed, &slowest, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
Packit Service c5cf8c
    MPI_Reduce(&w_elapsed, &w_slowest, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
Packit Service c5cf8c
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        unlink(file);
Packit Service c5cf8c
Packit Service c5cf8c
        slowest *= 1000.0;
Packit Service c5cf8c
        w_slowest *= 1000.0;
Packit Service c5cf8c
        if (verbose == 1) {
Packit Service c5cf8c
            printf("file: %s, nprocs: %d, open_time: %f ms, write_time: %f ms\n",
Packit Service c5cf8c
                   file, nprocs, slowest, w_slowest);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char **argv)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int nprocs;
Packit Service c5cf8c
    char file[256];
Packit Service c5cf8c
    MPI_Info info;
Packit Service c5cf8c
    int nr_errors = 0;
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init(&argc, &argv);
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
Packit Service c5cf8c
Packit Service c5cf8c
    /* parse the command line arguments */
Packit Service c5cf8c
    parse_args(argc, argv);
Packit Service c5cf8c
Packit Service c5cf8c
    sprintf(file, "%s", opt_file);
Packit Service c5cf8c
    MPI_Info_create(&info;;
Packit Service c5cf8c
    nr_errors += test_write(file, nprocs, rank, info);
Packit Service c5cf8c
    /* acutal value does not matter.  test only writes a small amount of data */
Packit Service c5cf8c
    MPI_Info_set(info, "striping_factor", "50");
Packit Service c5cf8c
    nr_errors += test_write(file, nprocs, rank, info);
Packit Service c5cf8c
    MPI_Info_free(&info;;
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Finalize(nr_errors);
Packit Service c5cf8c
    return MTestReturnValue(nr_errors);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int parse_args(int argc, char **argv)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int c;
Packit Service c5cf8c
Packit Service c5cf8c
    while ((c = getopt(argc, argv, "e")) != EOF) {
Packit Service c5cf8c
        switch (c) {
Packit Service c5cf8c
            case 'h':
Packit Service c5cf8c
                if (rank == 0)
Packit Service c5cf8c
                    usage(argv[0]);
Packit Service c5cf8c
                exit(0);
Packit Service c5cf8c
            case '?':  /* unknown */
Packit Service c5cf8c
                if (rank == 0)
Packit Service c5cf8c
                    usage(argv[0]);
Packit Service c5cf8c
                exit(1);
Packit Service c5cf8c
            default:
Packit Service c5cf8c
                break;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (argc - optind != 1) {
Packit Service c5cf8c
        if (rank == 0)
Packit Service c5cf8c
            usage(argv[0]);
Packit Service c5cf8c
        exit(1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    opt_file = strdup(argv[optind]);
Packit Service c5cf8c
    assert(opt_file);
Packit Service c5cf8c
Packit Service c5cf8c
    return (0);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void usage(const char *prog)
Packit Service c5cf8c
{
Packit Service c5cf8c
    printf("Usage: %s [<OPTIONS>...] <FILE NAME>\n", prog);
Packit Service c5cf8c
    printf("\n<OPTIONS> is one or more of\n");
Packit Service c5cf8c
    printf(" -h       print this help\n");
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * vim: ts=8 sts=4 sw=4 noexpandtab
Packit Service c5cf8c
 */