root/ompi/mca/io/romio321/romio/test/noncontig.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 /* tests noncontiguous reads/writes using independent I/O */
  12 
  13 #define SIZE 5000
  14 
  15 #define VERBOSE 0
  16 int main(int argc, char **argv)
  17 {
  18     int *buf, i, mynod, nprocs, len, b[3];
  19     int errs=0, toterrs;
  20     MPI_Aint d[3];
  21     MPI_File fh;
  22     MPI_Status status;
  23     char *filename;
  24     MPI_Datatype typevec, newtype, t[3];
  25     MPI_Info info;
  26 
  27     MPI_Init(&argc,&argv);
  28     MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  29     MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
  30 
  31     if (nprocs != 2) {
  32         fprintf(stderr, "Run this program on two processes\n");
  33         MPI_Abort(MPI_COMM_WORLD, 1);
  34     }
  35 
  36 /* process 0 takes the file name as a command-line argument and 
  37    broadcasts it to other processes (length first, then string) */
  38     if (!mynod) {
  39         i = 1;
  40         while ((i < argc) && strcmp("-fname", *argv)) {
  41             i++;
  42             argv++;
  43         }
  44         if (i >= argc) {
  45             fprintf(stderr, "\n*#  Usage: noncontig -fname filename\n\n");
  46             MPI_Abort(MPI_COMM_WORLD, 1);
  47         }
  48         argv++;
  49         len = strlen(*argv);
  50         filename = (char *) malloc(len+1);
  51         strcpy(filename, *argv);
  52         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
  53         MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
  54     }
  55     else {
  56         MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
  57         filename = (char *) malloc(len+1);
  58         MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
  59     }
  60 
  61     buf = (int *) malloc(SIZE*sizeof(int));
  62 
  63     MPI_Type_vector(SIZE/2, 1, 2, MPI_INT, &typevec);
  64 
  65     /* create a struct type with explicitly set LB and UB; displacements
  66      * of typevec are such that the types for the two processes won't
  67      * overlap.
  68      */
  69     b[0] = b[1] = b[2] = 1;
  70     d[0] = 0;
  71     d[1] = mynod*sizeof(int);
  72     d[2] = SIZE*sizeof(int);
  73     t[0] = MPI_LB;
  74     t[1] = typevec;
  75     t[2] = MPI_UB;
  76 
  77     /* keep the struct, ditch the vector */
  78     MPI_Type_struct(3, b, d, t, &newtype);
  79     MPI_Type_commit(&newtype);
  80     MPI_Type_free(&typevec);
  81 
  82     MPI_Info_create(&info);
  83     /* I am setting these info values for testing purposes only. It is
  84        better to use the default values in practice. */
  85     MPI_Info_set(info, "ind_rd_buffer_size", "1209");
  86     MPI_Info_set(info, "ind_wr_buffer_size", "1107");
  87 
  88     if (!mynod) {
  89 #if VERBOSE
  90         fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using independent I/O\n");
  91 #endif
  92         MPI_File_delete(filename, MPI_INFO_NULL);
  93     }
  94     MPI_Barrier(MPI_COMM_WORLD);
  95 
  96     MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
  97                   info, &fh);
  98 
  99     /* set the file view for each process -- now writes go into the non-
 100      * overlapping but interleaved region defined by the struct type up above
 101      */
 102     MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
 103 
 104     /* fill our buffer with a pattern and write, using our type again */
 105     for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
 106     MPI_File_write(fh, buf, 1, newtype, &status);
 107 
 108     MPI_Barrier(MPI_COMM_WORLD);
 109 
 110     /* fill the entire buffer with -1's.  read back with type.
 111      * note that the result of this read should be that every other value
 112      * in the buffer is still -1, as defined by our type.
 113      */
 114     for (i=0; i<SIZE; i++) buf[i] = -1;
 115     MPI_File_read_at(fh, 0, buf, 1, newtype, &status);
 116 
 117     /* check that all the values read are correct and also that we didn't
 118      * overwrite any of the -1 values that we shouldn't have.
 119      */
 120     for (i=0; i<SIZE; i++) {
 121         if (!mynod) {
 122             if ((i%2) && (buf[i] != -1)) {
 123                 errs++;
 124                 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
 125                         mynod, i, buf[i]);
 126             }
 127             if (!(i%2) && (buf[i] != i)) {
 128                 errs++;
 129                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 130                         mynod, i, buf[i], i);
 131             }
 132         }
 133         else {
 134             if ((i%2) && (buf[i] != i + mynod*SIZE)) {
 135                 errs++;
 136                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 137                         mynod, i, buf[i], i + mynod*SIZE);
 138             }
 139             if (!(i%2) && (buf[i] != -1)) {
 140                 errs++;
 141                 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
 142                         mynod, i, buf[i]);
 143             }
 144         }
 145     }
 146 
 147     MPI_File_close(&fh);
 148 
 149     MPI_Barrier(MPI_COMM_WORLD);
 150 
 151     if (!mynod) {
 152 #if VERBOSE
 153         fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using independent I/O\n");
 154 #endif
 155         MPI_File_delete(filename, MPI_INFO_NULL);
 156     }
 157     MPI_Barrier(MPI_COMM_WORLD);
 158 
 159     MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
 160                   info, &fh);
 161 
 162     /* in this case we write to either the first half or the second half
 163      * of the file space, so the regions are not interleaved.  this is done
 164      * by leaving the file view at its default.
 165      */
 166     for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
 167     MPI_File_write_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);
 168 
 169     MPI_Barrier(MPI_COMM_WORLD);
 170 
 171     /* same as before; fill buffer with -1's and then read; every other
 172      * value should still be -1 after the read
 173      */
 174     for (i=0; i<SIZE; i++) buf[i] = -1;
 175     MPI_File_read_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);
 176 
 177     /* verify that the buffer looks like it should */
 178     for (i=0; i<SIZE; i++) {
 179         if (!mynod) {
 180             if ((i%2) && (buf[i] != -1)) {
 181                 errs++;
 182                 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
 183                         mynod, i, buf[i]);
 184             }
 185             if (!(i%2) && (buf[i] != i)) {
 186                 errs++;
 187                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 188                         mynod, i, buf[i], i);
 189             }
 190         }
 191         else {
 192             if ((i%2) && (buf[i] != i + mynod*SIZE)) {
 193                 errs++;
 194                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 195                         mynod, i, buf[i], i + mynod*SIZE);
 196             }
 197             if (!(i%2) && (buf[i] != -1)) {
 198                 errs++;
 199                 fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
 200                         mynod, i, buf[i]);
 201             }
 202         }
 203     }
 204 
 205     MPI_File_close(&fh);
 206 
 207     MPI_Barrier(MPI_COMM_WORLD);
 208 
 209     if (!mynod) {
 210 #if VERBOSE
 211         fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using independent I/O\n");
 212 #endif
 213         MPI_File_delete(filename, MPI_INFO_NULL);
 214     }
 215     MPI_Barrier(MPI_COMM_WORLD);
 216 
 217     MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, 
 218                   info, &fh);
 219 
 220     /* set the file view so that we have interleaved access again */
 221     MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
 222 
 223     /* this time write a contiguous buffer */
 224     for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
 225     MPI_File_write(fh, buf, SIZE, MPI_INT, &status);
 226 
 227     MPI_Barrier(MPI_COMM_WORLD);
 228 
 229     /* fill buffer with -1's; this time they will all be overwritten */
 230     for (i=0; i<SIZE; i++) buf[i] = -1;
 231     MPI_File_read_at(fh, 0, buf, SIZE, MPI_INT, &status);
 232 
 233     for (i=0; i<SIZE; i++) {
 234         if (!mynod) {
 235             if (buf[i] != i) {
 236                 errs++;
 237                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 238                         mynod, i, buf[i], i);
 239             }
 240         }
 241         else {
 242             if (buf[i] != i + mynod*SIZE) {
 243                 errs++;
 244                 fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", 
 245                         mynod, i, buf[i], i + mynod*SIZE);
 246             }
 247         }
 248     }
 249 
 250     MPI_File_close(&fh);
 251 
 252     MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
 253     if (mynod == 0) {
 254         if( toterrs > 0) {
 255             fprintf( stderr, "Found %d errors\n", toterrs );
 256         }
 257         else {
 258             fprintf( stdout, " No Errors\n" );
 259         }
 260     }
 261     MPI_Type_free(&newtype);
 262     MPI_Info_free(&info);
 263     free(buf);
 264     free(filename);
 265     MPI_Finalize();
 266     return 0;
 267 }

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