root/ompi/mca/io/romio321/romio/adio/common/utils.c

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

DEFINITIONS

This source file includes following definitions.
  1. type_create_contiguous_x
  2. ADIOI_Type_create_hindexed_x
  3. pread
  4. pwrite

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
   2 /*
   3  *
   4  *   Copyright (C) 2014 UChicgo/Argonne, LLC.
   5  *   See COPYRIGHT notice in top-level directory.
   6  */
   7 
   8 #include <adio.h>
   9 #include <limits.h>
  10 
  11 
  12 /* utility function for creating large contiguous types: algorithim from BigMPI
  13  * https://github.com/jeffhammond/BigMPI */
  14 
  15 static int type_create_contiguous_x(MPI_Count count,
  16         MPI_Datatype oldtype, MPI_Datatype *newtype)
  17 {
  18     /* to make 'count' fit MPI-3 type processing routines (which take integer
  19      * counts), we construct a type consisting of N INT_MAX chunks followed by
  20      * a remainder.  e.g for a count of 4000000000 bytes you would end up with
  21      * one 2147483647-byte chunk followed immediately by a 1852516353-byte
  22      * chunk */
  23     MPI_Datatype chunks, remainder;
  24     MPI_Aint lb, extent, disps[2];
  25     int blocklens[2];
  26     MPI_Datatype types[2];
  27 
  28     /* truly stupendously large counts will overflow an integer with this math,
  29      * but that is a problem for a few decades from now.  Sorry, few decades
  30      * from now! */
  31     ADIOI_Assert(count/INT_MAX == (int)(count/INT_MAX));
  32     int c = (int)(count/INT_MAX); /* OK to cast until 'count' is 256 bits */
  33     int r = count%INT_MAX;
  34 
  35     MPI_Type_vector(c, INT_MAX, INT_MAX, oldtype, &chunks);
  36     MPI_Type_contiguous(r, oldtype, &remainder);
  37 
  38     MPI_Type_get_extent(oldtype, &lb, &extent);
  39 
  40     blocklens[0] = 1;      blocklens[1] = 1;
  41     disps[0]     = 0;      disps[1]     = c*extent*INT_MAX;
  42     types[0]     = chunks; types[1]     = remainder;
  43 
  44     MPI_Type_create_struct(2, blocklens, disps, types, newtype);
  45 
  46     MPI_Type_free(&chunks);
  47     MPI_Type_free(&remainder);
  48 
  49     return MPI_SUCCESS;
  50 }
  51 /* like MPI_Type_create_hindexed, except array_of_lengths can be a larger datatype.
  52  *
  53  * Hindexed provides 'count' pairs of (displacement, length), but what if
  54  * length is longer than an integer?  We will create 'count' types, using
  55  * contig if length is small enough, or something more complex if not */
  56 
  57 int ADIOI_Type_create_hindexed_x(int count,
  58                 const MPI_Count array_of_blocklengths[],
  59                 const MPI_Aint array_of_displacements[],
  60                 MPI_Datatype oldtype,
  61                 MPI_Datatype *newtype)
  62 {
  63     int i, ret;
  64     MPI_Datatype *types;
  65     int *blocklens;
  66     int is_big=0;
  67 
  68     types = ADIOI_Malloc(count*sizeof(MPI_Datatype));
  69     blocklens = ADIOI_Malloc(count*sizeof(int));
  70 
  71     /* squashing two loops into one.
  72      * - Look in the array_of_blocklengths for any large values
  73      * - convert MPI_Count items (if they are not too big) into int-sized items
  74      * after this loop we will know if we can use MPI_type_hindexed or if we
  75      * need a more complicated BigMPI-style struct-of-chunks.
  76      *
  77      * Why not use the struct-of-chunks in all cases?  HDF5 reported a bug,
  78      * which I have not yet precicesly nailed down, but appears to have
  79      * something to do with struct-of-chunks when the chunks are small */
  80 
  81     for(i=0; i<count; i++) {
  82         if (array_of_blocklengths[i] > INT_MAX) {
  83             blocklens[i] = 1;
  84             is_big=1;
  85             type_create_contiguous_x(array_of_blocklengths[i], oldtype,  &(types[i]));
  86         } else {
  87             /* OK to cast: checked for "bigness" above */
  88             blocklens[i] = (int)array_of_blocklengths[i];
  89             MPI_Type_contiguous(blocklens[i], oldtype, &(types[i]));
  90         }
  91     }
  92 
  93     if (is_big) {
  94         ret = MPI_Type_create_struct(count, blocklens, array_of_displacements,
  95                 types, newtype);
  96     } else {
  97         ret = MPI_Type_create_hindexed(count, blocklens,
  98                 array_of_displacements, oldtype, newtype);
  99     }
 100     for (i=0; i< count; i++)
 101         MPI_Type_free(&(types[i]));
 102     ADIOI_Free(types);
 103     ADIOI_Free(blocklens);
 104 
 105     return ret;
 106 }
 107 
 108 /* some systems do not have pread/pwrite, or requrie XOPEN_SOURCE set higher
 109  * than we would like.  see #1973 */
 110 #if (HAVE_DECL_PWRITE == 0)
 111 
 112 #include <sys/types.h>
 113 #include <unistd.h>
 114 
 115 ssize_t pread(int fd, void *buf, size_t count, off_t offset);
 116 ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
 117 
 118 ssize_t pread(int fd, void *buf, size_t count, off_t offset) {
 119     off_t lseek_ret;
 120     off_t old_offset;
 121     ssize_t read_ret;
 122 
 123     old_offset = lseek(fd, 0, SEEK_CUR);
 124     lseek_ret = lseek(fd, offset, SEEK_SET);
 125     if (lseek_ret == -1)
 126         return lseek_ret;
 127     read_ret = read(fd, buf, count);
 128     if (read_ret < 0)
 129         return read_ret;
 130     /* man page says "file offset is not changed" */
 131     if ( (lseek_ret = lseek(fd, old_offset, SEEK_SET)) < 0)
 132         return lseek_ret;
 133 
 134     return read_ret;
 135 }
 136 
 137 ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) {
 138     off_t lseek_ret;
 139     off_t old_offset;
 140     ssize_t write_ret;
 141 
 142     old_offset = lseek(fd, 0, SEEK_CUR);
 143     lseek_ret = lseek(fd, offset, SEEK_SET);
 144     if (lseek_ret == -1)
 145         return lseek_ret;
 146     write_ret = write(fd, buf, count);
 147     if (write_ret < 0)
 148         return write_ret;
 149     /* man page says "file offset is not changed" */
 150     if ( (lseek_ret = lseek(fd, old_offset, SEEK_SET)) < 0)
 151         return lseek_ret;
 152 
 153     return write_ret;
 154 }
 155 #endif
 156 
 157 /*
 158  * vim: ts=8 sts=4 sw=4 noexpandtab
 159  */

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