Blame src/mpi/romio/test/aggregation1.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2007 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/* Test case from John Bent (ROMIO req #835)
Packit Service c5cf8c
 * Aggregation code was not handling certain access patterns when collective
Packit Service c5cf8c
 * buffering forced */
Packit Service c5cf8c
#define _XOPEN_SOURCE 500       /* strdup not in string.h otherwsie */
Packit Service c5cf8c
#include <unistd.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <mpi.h>
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
Packit Service c5cf8c
#define NUM_OBJS 4
Packit Service c5cf8c
#define OBJ_SIZE 1048576
Packit Service c5cf8c
Packit Service c5cf8c
extern char *optarg;
Packit Service c5cf8c
extern int optind, opterr, optopt;
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
char *prog = NULL;
Packit Service c5cf8c
int debug = 0;
Packit Service c5cf8c
Packit Service c5cf8c
static void Usage(int line)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int rank;
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        fprintf(stderr,
Packit Service c5cf8c
                "Usage (line %d): %s [-d] [-h] -f filename\n"
Packit Service c5cf8c
                "\t-d for debugging\n"
Packit Service c5cf8c
                "\t-h to turn on the hints to force collective aggregation\n", line, prog);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    exit(0);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void fatal_error(int mpi_ret, MPI_Status * mpi_stat, const char *msg)
Packit Service c5cf8c
{
Packit Service c5cf8c
    fprintf(stderr, "Fatal error %s: %d\n", msg, mpi_ret);
Packit Service c5cf8c
    MPI_Abort(MPI_COMM_WORLD, -1);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void print_hints(int rank, MPI_File * mfh)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Info info;
Packit Service c5cf8c
    int nkeys;
Packit Service c5cf8c
    int i, dummy_int;
Packit Service c5cf8c
    char key[1024];
Packit Service c5cf8c
    char value[1024];
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        MPI_File_get_info(*mfh, &info;;
Packit Service c5cf8c
        MPI_Info_get_nkeys(info, &nkeys);
Packit Service c5cf8c
Packit Service c5cf8c
        printf("HINTS:\n");
Packit Service c5cf8c
        for (i = 0; i < nkeys; i++) {
Packit Service c5cf8c
            MPI_Info_get_nthkey(info, i, key);
Packit Service c5cf8c
            printf("%35s -> ", key);
Packit Service c5cf8c
            MPI_Info_get(info, key, 1024, value, &dummy_int);
Packit Service c5cf8c
            printf("%s\n", value);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        MPI_Info_free(&info;;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MPI_Barrier(MPI_COMM_WORLD);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void fill_buffer(char *buffer, int bufsize, int rank, MPI_Offset offset)
Packit Service c5cf8c
{
Packit Service c5cf8c
    memset((void *) buffer, 0, bufsize);
Packit Service c5cf8c
    snprintf(buffer, bufsize, "Hello from %d at %lld\n", rank, offset);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static MPI_Offset get_offset(int rank, int num_objs, int obj_size, int which_obj)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Offset offset;
Packit Service c5cf8c
    offset = (MPI_Offset) rank *num_objs * obj_size + which_obj * obj_size;
Packit Service c5cf8c
    return offset;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void write_file(char *target, int rank, MPI_Info * info)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_File wfh;
Packit Service c5cf8c
    MPI_Status mpi_stat;
Packit Service c5cf8c
    int mpi_ret;
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    char *buffer;
Packit Service c5cf8c
Packit Service c5cf8c
    buffer = malloc(OBJ_SIZE);
Packit Service c5cf8c
Packit Service c5cf8c
    if (debug)
Packit Service c5cf8c
        printf("%d writing file %s\n", rank, target);
Packit Service c5cf8c
Packit Service c5cf8c
    if ((mpi_ret = MPI_File_open(MPI_COMM_WORLD, target,
Packit Service c5cf8c
                                 MPI_MODE_WRONLY | MPI_MODE_CREATE, *info, &wfh))
Packit Service c5cf8c
        != MPI_SUCCESS) {
Packit Service c5cf8c
        fatal_error(mpi_ret, NULL, "open for write");
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < NUM_OBJS; i++) {
Packit Service c5cf8c
        MPI_Offset offset = get_offset(rank, NUM_OBJS, OBJ_SIZE, i);
Packit Service c5cf8c
        fill_buffer(buffer, OBJ_SIZE, rank, offset);
Packit Service c5cf8c
        if (debug)
Packit Service c5cf8c
            printf("%s", buffer);
Packit Service c5cf8c
        if ((mpi_ret = MPI_File_write_at_all(wfh, offset, buffer, OBJ_SIZE,
Packit Service c5cf8c
                                             MPI_CHAR, &mpi_stat)) != MPI_SUCCESS) {
Packit Service c5cf8c
            fatal_error(mpi_ret, &mpi_stat, "write");
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (debug)
Packit Service c5cf8c
        print_hints(rank, &wfh;;
Packit Service c5cf8c
Packit Service c5cf8c
    if ((mpi_ret = MPI_File_close(&wfh)) != MPI_SUCCESS) {
Packit Service c5cf8c
        fatal_error(mpi_ret, NULL, "close for write");
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (debug)
Packit Service c5cf8c
        printf("%d wrote file %s\n", rank, target);
Packit Service c5cf8c
    free(buffer);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int reduce_corruptions(int corrupt_blocks)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_ret;
Packit Service c5cf8c
    int sum;
Packit Service c5cf8c
    if ((mpi_ret = MPI_Reduce(&corrupt_blocks, &sum, 1,
Packit Service c5cf8c
                              MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD)) != MPI_SUCCESS) {
Packit Service c5cf8c
        fatal_error(mpi_ret, NULL, "MPI_Reduce");
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return sum;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void read_file(char *target, int rank, MPI_Info * info, int *corrupt_blocks)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_File rfh;
Packit Service c5cf8c
    MPI_Status mpi_stat;
Packit Service c5cf8c
    int mpi_ret;
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    char *buffer;
Packit Service c5cf8c
    char *verify_buf = NULL;
Packit Service c5cf8c
    buffer = malloc(OBJ_SIZE);
Packit Service c5cf8c
    verify_buf = (char *) malloc(OBJ_SIZE);
Packit Service c5cf8c
Packit Service c5cf8c
    if (debug)
Packit Service c5cf8c
        printf("%d reading file %s\n", rank, target);
Packit Service c5cf8c
Packit Service c5cf8c
    if ((mpi_ret = MPI_File_open(MPI_COMM_WORLD, target,
Packit Service c5cf8c
                                 MPI_MODE_RDONLY, *info, &rfh)) != MPI_SUCCESS) {
Packit Service c5cf8c
        fatal_error(mpi_ret, NULL, "open for read");
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < NUM_OBJS; i++) {
Packit Service c5cf8c
        MPI_Offset offset = get_offset(rank, NUM_OBJS, OBJ_SIZE, i);
Packit Service c5cf8c
        fill_buffer(verify_buf, OBJ_SIZE, rank, offset);
Packit Service c5cf8c
        if (debug)
Packit Service c5cf8c
            printf("Expecting %s", buffer);
Packit Service c5cf8c
        if ((mpi_ret = MPI_File_read_at_all(rfh, offset, buffer, OBJ_SIZE,
Packit Service c5cf8c
                                            MPI_CHAR, &mpi_stat)) != MPI_SUCCESS) {
Packit Service c5cf8c
            fatal_error(mpi_ret, &mpi_stat, "read");
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (memcmp(verify_buf, buffer, OBJ_SIZE) != 0) {
Packit Service c5cf8c
            (*corrupt_blocks)++;
Packit Service c5cf8c
            printf("Corruption at %lld\n", offset);
Packit Service c5cf8c
            if (debug) {
Packit Service c5cf8c
                printf("\tExpecting %s\n" "\tRecieved  %s\n", verify_buf, buffer);
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if ((mpi_ret = MPI_File_close(&rfh)) != MPI_SUCCESS) {
Packit Service c5cf8c
        fatal_error(mpi_ret, NULL, "close for read");
Packit Service c5cf8c
    }
Packit Service c5cf8c
    free(buffer);
Packit Service c5cf8c
    free(verify_buf);
Packit Service c5cf8c
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static void set_hints(MPI_Info * info)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Info_set(*info, "romio_cb_write", "enable");
Packit Service c5cf8c
    MPI_Info_set(*info, "romio_no_indep_rw", "1");
Packit Service c5cf8c
    MPI_Info_set(*info, "cb_nodes", "1");
Packit Service c5cf8c
    MPI_Info_set(*info, "cb_buffer_size", "4194304");
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
void
Packit Service c5cf8c
set_hints(MPI_Info *info, char *hints) {
Packit Service c5cf8c
    char *delimiter = " ";
Packit Service c5cf8c
    char *hints_cp  = strdup(hints);
Packit Service c5cf8c
    char *key = strtok(hints_cp, delimiter);
Packit Service c5cf8c
    char *val;
Packit Service c5cf8c
    while (key) {
Packit Service c5cf8c
        val = strtok(NULL, delimiter);
Packit Service c5cf8c
        if (debug) printf("HINT: %s = %s\n", key, val);
Packit Service c5cf8c
        if (! val) {
Packit Service c5cf8c
            Usage(__LINE__);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        MPI_Info_set(*info, key, val);
Packit Service c5cf8c
        key = strtok(NULL, delimiter);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    free(hints_cp);
Packit Service c5cf8c
}
Packit Service c5cf8c
*/
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int nproc = 1, rank = 0;
Packit Service c5cf8c
    char *target = NULL;
Packit Service c5cf8c
    int c;
Packit Service c5cf8c
    MPI_Info info;
Packit Service c5cf8c
    int mpi_ret;
Packit Service c5cf8c
    int corrupt_blocks = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Init(&argc, &argv);
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
Packit Service c5cf8c
    if ((mpi_ret = MPI_Info_create(&info)) != MPI_SUCCESS) {
Packit Service c5cf8c
        if (rank == 0)
Packit Service c5cf8c
            fatal_error(mpi_ret, NULL, "MPI_info_create.\n");
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    prog = strdup(argv[0]);
Packit Service c5cf8c
Packit Service c5cf8c
    while ((c = getopt(argc, argv, "df:h")) != EOF) {
Packit Service c5cf8c
        switch (c) {
Packit Service c5cf8c
            case 'd':
Packit Service c5cf8c
                debug = 1;
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            case 'f':
Packit Service c5cf8c
                target = strdup(optarg);
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            case 'h':
Packit Service c5cf8c
                set_hints(&info;;
Packit Service c5cf8c
                break;
Packit Service c5cf8c
            default:
Packit Service c5cf8c
                Usage(__LINE__);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (!target) {
Packit Service c5cf8c
        Usage(__LINE__);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    write_file(target, rank, &info;;
Packit Service c5cf8c
    read_file(target, rank, &info, &corrupt_blocks);
Packit Service c5cf8c
Packit Service c5cf8c
    corrupt_blocks = reduce_corruptions(corrupt_blocks);
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        if (corrupt_blocks == 0) {
Packit Service c5cf8c
            fprintf(stdout, " No Errors\n");
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            fprintf(stdout, "%d/%d blocks corrupt\n", corrupt_blocks, nproc * NUM_OBJS);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MPI_Info_free(&info;;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Finalize();
Packit Service c5cf8c
    free(prog);
Packit Service c5cf8c
    exit(0);
Packit Service c5cf8c
}