root/ompi/mca/io/romio321/romio/test/large_array.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /*  
   3  *  (C) 2001 by Argonne National Laboratory.
   4  *      See COPYRIGHT in top-level directory.
   5  */
   6 #include "mpi.h"
   7 #include <stdio.h>
   8 #include <string.h>
   9 #include <stdlib.h>
  10 
  11 /* Writes a 4-Gbyte distributed array, reads it back, and then deletes the 
  12    file. Uses collective I/O. */
  13 /* The file name is taken as a command-line argument. */
  14 /* Run it only on a machine with sufficient memory and a file system
  15    on which ROMIO supports large files, i.e., PIOFS, XFS, SFS, and HFS */
  16 
  17 /* This program will work only if the MPI implementation defines MPI_Aint 
  18    as a 64-bit integer. */
  19    
  20 int main(int argc, char **argv)
  21 {
  22     MPI_Datatype newtype;
  23     int i, ndims, array_of_gsizes[3], array_of_distribs[3];
  24     int order, nprocs, len, flag, err;
  25     int array_of_dargs[3], array_of_psizes[3];
  26     int *readbuf, *writebuf, mynod;
  27     MPI_Count bufcount;
  28     char filename[1024];
  29     MPI_File fh;
  30     MPI_Status status;
  31     MPI_Aint size_with_aint;
  32     MPI_Offset size_with_offset;
  33 
  34     MPI_Init(&argc,&argv);
  35     MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
  36     MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  37 
  38 /* process 0 takes the file name as a command-line argument and 
  39    broadcasts it to other processes */
  40     if (!mynod) {
  41         i = 1;
  42         while ((i < argc) && strcmp("-fname", *argv)) {
  43             i++;
  44             argv++;
  45         }
  46         if (i >= argc) {
  47             fprintf(stderr, "\n*#  Usage: large_array -fname filename\n\n");
  48             MPI_Abort(MPI_COMM_WORLD, 1);
  49         }
  50         argv++;
  51         len = strlen(*argv);
  52         strcpy(filename, *argv);
  53         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
  54         MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
  55         fprintf(stderr, "This program creates a 4 Gbyte file. Don't run it if you don't have that much disk space!\n");
  56     }
  57     else {
  58         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
  59         MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
  60     }
  61 
  62 /* create the distributed array filetype */
  63     ndims = 3;
  64     order = MPI_ORDER_C;
  65 
  66     array_of_gsizes[0] = 1024;
  67     array_of_gsizes[1] = 1024;
  68     array_of_gsizes[2] = 4*1024/sizeof(int);
  69 
  70     array_of_distribs[0] = MPI_DISTRIBUTE_BLOCK;
  71     array_of_distribs[1] = MPI_DISTRIBUTE_BLOCK;
  72     array_of_distribs[2] = MPI_DISTRIBUTE_BLOCK;
  73 
  74     array_of_dargs[0] = MPI_DISTRIBUTE_DFLT_DARG;
  75     array_of_dargs[1] = MPI_DISTRIBUTE_DFLT_DARG;
  76     array_of_dargs[2] = MPI_DISTRIBUTE_DFLT_DARG;
  77 
  78     for (i=0; i<ndims; i++) array_of_psizes[i] = 0;
  79     MPI_Dims_create(nprocs, ndims, array_of_psizes);
  80 
  81 /* check if MPI_Aint is large enough for size of global array. 
  82    if not, complain. */
  83 
  84     size_with_aint = sizeof(int);
  85     for (i=0; i<ndims; i++) size_with_aint *= array_of_gsizes[i];
  86     size_with_offset = sizeof(int);
  87     for (i=0; i<ndims; i++) size_with_offset *= array_of_gsizes[i];
  88     if (size_with_aint != size_with_offset) {
  89         fprintf(stderr, "Can't use an array of this size unless the MPI implementation defines a 64-bit MPI_Aint\n");
  90         MPI_Abort(MPI_COMM_WORLD, 1);
  91     }
  92 
  93     MPI_Type_create_darray(nprocs, mynod, ndims, array_of_gsizes, 
  94                            array_of_distribs, array_of_dargs,
  95                            array_of_psizes, order, MPI_INT, &newtype);
  96     MPI_Type_commit(&newtype);
  97 
  98 /* initialize writebuf */
  99 
 100     MPI_Type_size_x(newtype, &bufcount);
 101     bufcount = bufcount/sizeof(int);
 102     writebuf = (int *) malloc(bufcount * sizeof(int));
 103     if (!writebuf) fprintf(stderr, "Process %d, not enough memory for writebuf\n", mynod);
 104     for (i=0; i<bufcount; i++) writebuf[i] = mynod*1024 + i;
 105 
 106     /* write the array to the file */
 107     MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, 
 108                   MPI_INFO_NULL, &fh);
 109     MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL);
 110     MPI_File_write_all(fh, writebuf, bufcount, MPI_INT, &status);
 111     MPI_File_close(&fh);
 112 
 113     free(writebuf);
 114 
 115     /* now read it back */
 116     readbuf = (int *) calloc(bufcount, sizeof(int));
 117     if (!readbuf) fprintf(stderr, "Process %d, not enough memory for readbuf\n", mynod);
 118 
 119     MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, 
 120                   MPI_INFO_NULL, &fh);
 121     MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL);
 122     MPI_File_read_all(fh, readbuf, bufcount, MPI_INT, &status);
 123     MPI_File_close(&fh);
 124 
 125     /* check the data read */
 126     flag = 0;
 127     for (i=0; i<bufcount; i++) 
 128         if (readbuf[i] != mynod*1024 + i) {
 129             fprintf(stderr, "Process %d, readbuf=%d, writebuf=%d\n", mynod, readbuf[i], mynod*1024 + i);
 130             flag = 1;
 131         }
 132     if (!flag) fprintf(stderr, "Process %d: data read back is correct\n", mynod);
 133 
 134     MPI_Type_free(&newtype);
 135     free(readbuf);
 136 
 137     MPI_Barrier(MPI_COMM_WORLD);
 138     if (!mynod) {
 139         err = MPI_File_delete(filename, MPI_INFO_NULL);
 140         if (err == MPI_SUCCESS) fprintf(stderr, "file deleted\n");
 141     }
 142 
 143     MPI_Finalize();
 144     return 0;
 145 }

/* [<][>][^][v][top][bottom][index][help] */