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

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2008 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
/* Wei-keng Liao (wkliao@ece.northwestern.edu) September 8, 2008 */
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#include <mpi.h>
Packit Service c5cf8c
Packit Service c5cf8c
static void handle_error(int errcode, const char *str)
Packit Service c5cf8c
{
Packit Service c5cf8c
    char msg[MPI_MAX_ERROR_STRING];
Packit Service c5cf8c
    int resultlen;
Packit Service c5cf8c
    MPI_Error_string(errcode, msg, &resultlen);
Packit Service c5cf8c
    fprintf(stderr, "%s: %s\n", str, msg);
Packit Service c5cf8c
    MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#define MPI_CHECK(fn) { int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, #fn); }
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#define YLEN 5
Packit Service c5cf8c
#define XLEN 10
Packit Service c5cf8c
#define SUB_XLEN 3
Packit Service c5cf8c
Packit Service c5cf8c
/* rjl: I was just too lazy to compute this at run-time */
Packit Service c5cf8c
char compare_buf[XLEN * 4][YLEN * 4] = {
Packit Service c5cf8c
    {'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
Packit Service c5cf8c
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/* set this if you want a dump of the global array
Packit Service c5cf8c
#define VERBOSE 1
Packit Service c5cf8c
*/
Packit Service c5cf8c
Packit Service c5cf8c
/*----< main() >------------------------------------------------------------*/
Packit Service c5cf8c
int main(int argc, char **argv)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, j, err, rank, np, num_io;
Packit Service c5cf8c
    char *buf, *filename;
Packit Service c5cf8c
    int rank_dim[2], array_of_sizes[2];
Packit Service c5cf8c
    int array_of_subsizes[2];
Packit Service c5cf8c
    int count, *blocklengths, global_array_size;
Packit Service c5cf8c
    MPI_Count ftype_size;
Packit Service c5cf8c
    MPI_Aint *displacements;
Packit Service c5cf8c
    MPI_File fh;
Packit Service c5cf8c
    MPI_Datatype ftype;
Packit Service c5cf8c
    MPI_Status status;
Packit Service c5cf8c
    MPI_Offset offset = 0;
Packit Service c5cf8c
    int nr_errors = 0;
Packit Service c5cf8c
#ifdef VERBOSE
Packit Service c5cf8c
    int k;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Init(&argc, &argv);
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &np);
Packit Service c5cf8c
Packit Service c5cf8c
    if (np != 4) {
Packit Service c5cf8c
        if (!rank)
Packit Service c5cf8c
            printf("Please run with 4 processes. Exiting ...\n\n");
Packit Service c5cf8c
        MPI_Finalize();
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    filename = argv[1];
Packit Service c5cf8c
Packit Service c5cf8c
    num_io = 2;
Packit Service c5cf8c
Packit Service c5cf8c
    /*-----------------------------------------------------------------------*/
Packit Service c5cf8c
    /* process rank in each dimension */
Packit Service c5cf8c
    rank_dim[0] = rank / 2;
Packit Service c5cf8c
    rank_dim[1] = rank % 2;
Packit Service c5cf8c
Packit Service c5cf8c
    /* global 2D array size */
Packit Service c5cf8c
    array_of_sizes[0] = YLEN * 2;
Packit Service c5cf8c
    array_of_sizes[1] = XLEN * 2;
Packit Service c5cf8c
Packit Service c5cf8c
    global_array_size = array_of_sizes[0] * array_of_sizes[1];
Packit Service c5cf8c
Packit Service c5cf8c
    array_of_subsizes[0] = YLEN / 2;
Packit Service c5cf8c
    array_of_subsizes[1] = XLEN * SUB_XLEN / 5;
Packit Service c5cf8c
Packit Service c5cf8c
    offset = rank_dim[0] * YLEN * array_of_sizes[1] + rank_dim[1] * XLEN;
Packit Service c5cf8c
Packit Service c5cf8c
    /* define data type for file view */
Packit Service c5cf8c
    count = array_of_subsizes[0] * 2;   /* 2 is the no. blocks along X */
Packit Service c5cf8c
    blocklengths = (int *) malloc(count * sizeof(int));
Packit Service c5cf8c
    displacements = (MPI_Aint *) malloc(count * sizeof(MPI_Aint));
Packit Service c5cf8c
    for (i = 0; i < count; i++)
Packit Service c5cf8c
        blocklengths[i] = array_of_subsizes[1] / 2;
Packit Service c5cf8c
    for (i = 0; i < array_of_subsizes[0]; i++)
Packit Service c5cf8c
        for (j = 0; j < 2; j++)
Packit Service c5cf8c
            displacements[i * 2 + j] = offset + i * 2 * array_of_sizes[1] + j * XLEN / 2;
Packit Service c5cf8c
    MPI_Type_create_hindexed(count, blocklengths, displacements, MPI_CHAR, &ftype);
Packit Service c5cf8c
    MPI_Type_commit(&ftype);
Packit Service c5cf8c
    MPI_Type_size_x(ftype, &ftype_size);
Packit Service c5cf8c
Packit Service c5cf8c
/* subarray's layout in the global array
Packit Service c5cf8c
Packit Service c5cf8c
   P0's 's layout                               P1's layout
Packit Service c5cf8c
   [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
Packit Service c5cf8c
[ 0] 0 1 2     3 4 5                          |                       D E F     G H I
Packit Service c5cf8c
[ 1]                                          |
Packit Service c5cf8c
[ 2] 6 7 8     9 : ;                          |                       J K L     M N O
Packit Service c5cf8c
[ 3]                                          |
Packit Service c5cf8c
[ 4]                                          |
Packit Service c5cf8c
[ 5]                                          |
Packit Service c5cf8c
[ 6]                                          |
Packit Service c5cf8c
[ 7]                                          |
Packit Service c5cf8c
[ 8]                                          |
Packit Service c5cf8c
[ 9]                                          |
Packit Service c5cf8c
Packit Service c5cf8c
   P2's 's layout                               P3's layout
Packit Service c5cf8c
   [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
Packit Service c5cf8c
[ 0]                                          |
Packit Service c5cf8c
[ 1]                                          |
Packit Service c5cf8c
[ 2]                                          |
Packit Service c5cf8c
[ 3]                                          |
Packit Service c5cf8c
[ 4]                                          |
Packit Service c5cf8c
[ 5] X Y Z     [ \ ]                          |                       l m n     o p q
Packit Service c5cf8c
[ 6]                                          |
Packit Service c5cf8c
[ 7] ^ _ `     a b c                          |                       r s t     u v w
Packit Service c5cf8c
[ 8]                                          |
Packit Service c5cf8c
[ 9]                                          |
Packit Service c5cf8c
*/
Packit Service c5cf8c
Packit Service c5cf8c
    /* initialize the write buffer */
Packit Service c5cf8c
    buf = (char *) malloc(array_of_subsizes[0] * array_of_subsizes[1]);
Packit Service c5cf8c
    for (i = 0; i < array_of_subsizes[0] * array_of_subsizes[1]; i++)
Packit Service c5cf8c
        buf[i] = '0' + rank * 20 + i % 79;
Packit Service c5cf8c
Packit Service c5cf8c
    /* zero file contents --------------------------------------------------- */
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        char *wr_buf = (char *) calloc(num_io * global_array_size, 1);
Packit Service c5cf8c
        MPI_CHECK(MPI_File_open(MPI_COMM_SELF, filename,
Packit Service c5cf8c
                                MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh));
Packit Service c5cf8c
        MPI_CHECK(MPI_File_write(fh, wr_buf, num_io * global_array_size, MPI_CHAR, &status));
Packit Service c5cf8c
        MPI_CHECK(MPI_File_close(&fh));
Packit Service c5cf8c
        free(wr_buf);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    /* open the file -------------------------------------------------------- */
Packit Service c5cf8c
    err = MPI_File_open(MPI_COMM_WORLD, filename,
Packit Service c5cf8c
                        MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh;;
Packit Service c5cf8c
    if (err != MPI_SUCCESS) {
Packit Service c5cf8c
        printf("Error: MPI_File_open() filename %s\n", filename);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, -1);
Packit Service c5cf8c
        exit(1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* MPI collective write */
Packit Service c5cf8c
    for (i = 0; i < num_io; i++) {
Packit Service c5cf8c
        offset = i * global_array_size;
Packit Service c5cf8c
        /* set the file view */
Packit Service c5cf8c
        MPI_CHECK(MPI_File_set_view(fh, offset, MPI_BYTE, ftype, "native", MPI_INFO_NULL));
Packit Service c5cf8c
        MPI_CHECK(MPI_File_write_all(fh, buf, ftype_size, MPI_CHAR, &status));
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MPI_CHECK(MPI_File_close(&fh));
Packit Service c5cf8c
Packit Service c5cf8c
    /* read and print file contents ----------------------------------------- */
Packit Service c5cf8c
    if (rank == 0) {
Packit Service c5cf8c
        char *ptr;
Packit Service c5cf8c
        char *rd_buf = (char *) calloc(num_io * global_array_size, 1);
Packit Service c5cf8c
        MPI_CHECK(MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh));
Packit Service c5cf8c
        MPI_CHECK(MPI_File_read(fh, rd_buf, num_io * global_array_size, MPI_CHAR, &status));
Packit Service c5cf8c
        MPI_CHECK(MPI_File_close(&fh));
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef VERBOSE
Packit Service c5cf8c
        printf("-------------------------------------------------------\n");
Packit Service c5cf8c
        printf("   [");
Packit Service c5cf8c
        for (i = 0; i < 2; i++) {
Packit Service c5cf8c
            for (j = 0; j < XLEN; j++)
Packit Service c5cf8c
                printf(" %d", j);
Packit Service c5cf8c
            printf(" ");
Packit Service c5cf8c
        }
Packit Service c5cf8c
        printf("]\n\n");
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
        ptr = rd_buf;
Packit Service c5cf8c
        for (k = 0; k < num_io; k++) {
Packit Service c5cf8c
            for (i = 0; i < 2 * YLEN; i++) {
Packit Service c5cf8c
                printf("[%2d]", k * 2 * YLEN + i);
Packit Service c5cf8c
                for (j = 0; j < 2 * XLEN; j++) {
Packit Service c5cf8c
                    if (j > 0 && j % XLEN == 0)
Packit Service c5cf8c
                        printf(" ");
Packit Service c5cf8c
                    if (*ptr != 0)
Packit Service c5cf8c
                        printf(" %c", *ptr);
Packit Service c5cf8c
                    else
Packit Service c5cf8c
                        printf("  ");
Packit Service c5cf8c
                    ptr++;
Packit Service c5cf8c
                }
Packit Service c5cf8c
                printf("\n");
Packit Service c5cf8c
            }
Packit Service c5cf8c
            printf("\n");
Packit Service c5cf8c
        }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
        ptr = rd_buf;
Packit Service c5cf8c
        for (i = 0; i < 2 * YLEN * num_io; i++) {
Packit Service c5cf8c
            for (j = 0; j < 2 * XLEN; j++) {
Packit Service c5cf8c
                if (*ptr != compare_buf[i][j]) {
Packit Service c5cf8c
                    fprintf(stderr, "expected %c got %c at [%d][%d]\n",
Packit Service c5cf8c
                            *ptr, compare_buf[i][j], i, j);
Packit Service c5cf8c
                    nr_errors++;
Packit Service c5cf8c
                }
Packit Service c5cf8c
                ptr++;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
        free(rd_buf);
Packit Service c5cf8c
Packit Service c5cf8c
        if (nr_errors == 0)
Packit Service c5cf8c
            fprintf(stdout, " No Errors\n");
Packit Service c5cf8c
        else
Packit Service c5cf8c
            fprintf(stderr, "Found %d errors\n", nr_errors);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    free(blocklengths);
Packit Service c5cf8c
    free(displacements);
Packit Service c5cf8c
    free(buf);
Packit Service c5cf8c
    MPI_Type_free(&ftype);
Packit Service c5cf8c
    MPI_Finalize();
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* command-line outputs are: (the global array is written twice)
Packit Service c5cf8c
Packit Service c5cf8c
% mpiexec -n 4 wkl_subarray
Packit Service c5cf8c
-------------------------------------------------------
Packit Service c5cf8c
   [ 0 1 2 3 4 5 6 7 8 9  0 1 2 3 4 5 6 7 8 9 ]
Packit Service c5cf8c
Packit Service c5cf8c
[ 0] 0 1 2     3 4 5      D E F     G H I
Packit Service c5cf8c
[ 1]
Packit Service c5cf8c
[ 2] 6 7 8     9 : ;      J K L     M N O
Packit Service c5cf8c
[ 3]
Packit Service c5cf8c
[ 4]
Packit Service c5cf8c
[ 5] X Y Z     [ \ ]      l m n     o p q
Packit Service c5cf8c
[ 6]
Packit Service c5cf8c
[ 7] ^ _ `     a b c      r s t     u v w
Packit Service c5cf8c
[ 8]
Packit Service c5cf8c
[ 9]
Packit Service c5cf8c
Packit Service c5cf8c
[10] 0 1 2     3 4 5      D E F     G H I
Packit Service c5cf8c
[11]
Packit Service c5cf8c
[12] 6 7 8     9 : ;      J K L     M N O
Packit Service c5cf8c
[13]
Packit Service c5cf8c
[14]
Packit Service c5cf8c
[15] X Y Z     [ \ ]      l m n     o p q
Packit Service c5cf8c
[16]
Packit Service c5cf8c
[17] ^ _ `     a b c      r s t     u v w
Packit Service c5cf8c
[18]
Packit Service c5cf8c
[19]
Packit Service c5cf8c
Packit Service c5cf8c
*/