This source file includes following definitions.
- ADIO_Type_create_darray
- MPIOI_Type_block
- MPIOI_Type_cyclic
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 #include "adio.h"
   9 #include "adio_extern.h"
  10 
  11 static int MPIOI_Type_block(int *array_of_gsizes, int dim, int ndims, int nprocs,
  12                      int rank, int darg, int order, MPI_Aint orig_extent,
  13                      MPI_Datatype type_old, MPI_Datatype *type_new,
  14                      MPI_Aint *st_offset);
  15 static int MPIOI_Type_cyclic(int *array_of_gsizes, int dim, int ndims, int nprocs,
  16                       int rank, int darg, int order, MPI_Aint orig_extent,
  17                       MPI_Datatype type_old, MPI_Datatype *type_new,
  18                       MPI_Aint *st_offset);
  19 
  20 
  21 int ADIO_Type_create_darray(int size, int rank, int ndims, 
  22                             int *array_of_gsizes, int *array_of_distribs, 
  23                             int *array_of_dargs, int *array_of_psizes, 
  24                             int order, MPI_Datatype oldtype, 
  25                             MPI_Datatype *newtype) 
  26 {
  27     MPI_Datatype type_old, type_new=MPI_DATATYPE_NULL, inttype;
  28     int procs, tmp_rank, i, tmp_size, blklen, *coords;
  29     MPI_Aint *st_offsets, orig_extent, disp, ub, lb;
  30 
  31     MPI_Type_get_extent(oldtype, &lb, &orig_extent);
  32 
  33 
  34 
  35     coords = (int *) ADIOI_Malloc(ndims*sizeof(int));
  36     procs = size;
  37     tmp_rank = rank;
  38     for (i=0; i<ndims; i++) {
  39         procs = procs/array_of_psizes[i];
  40         coords[i] = tmp_rank/procs;
  41         tmp_rank = tmp_rank % procs;
  42     }
  43 
  44     st_offsets = (MPI_Aint *) ADIOI_Malloc(ndims*sizeof(MPI_Aint));
  45     type_old = oldtype;
  46 
  47     if (order == MPI_ORDER_FORTRAN) {
  48       
  49         for (i=0; i<ndims; i++) {
  50             switch(array_of_distribs[i]) {
  51             case MPI_DISTRIBUTE_BLOCK:
  52                 MPIOI_Type_block(array_of_gsizes, i, ndims,
  53                                  array_of_psizes[i],
  54                                  coords[i], array_of_dargs[i],
  55                                  order, orig_extent, 
  56                                  type_old, &type_new,
  57                                  st_offsets+i); 
  58                 break;
  59             case MPI_DISTRIBUTE_CYCLIC:
  60                 MPIOI_Type_cyclic(array_of_gsizes, i, ndims, 
  61                                   array_of_psizes[i], coords[i],
  62                                   array_of_dargs[i], order,
  63                                   orig_extent, type_old,
  64                                   &type_new, st_offsets+i);
  65                 break;
  66             case MPI_DISTRIBUTE_NONE:
  67                 
  68                 MPIOI_Type_block(array_of_gsizes, i, ndims, 1, 0, 
  69                                  MPI_DISTRIBUTE_DFLT_DARG, order,
  70                                  orig_extent, 
  71                                  type_old, &type_new,
  72                                  st_offsets+i); 
  73                 break;
  74             }
  75             if (i) MPI_Type_free(&type_old);
  76             type_old = type_new;
  77         }
  78 
  79         
  80         disp = st_offsets[0];
  81         tmp_size = 1;
  82         for (i=1; i<ndims; i++) {
  83             tmp_size *= array_of_gsizes[i-1];
  84             disp += (MPI_Aint)tmp_size*st_offsets[i];
  85         }
  86         
  87     }
  88 
  89     else  {
  90         
  91         for (i=ndims-1; i>=0; i--) {
  92             switch(array_of_distribs[i]) {
  93             case MPI_DISTRIBUTE_BLOCK:
  94                 MPIOI_Type_block(array_of_gsizes, i, ndims, array_of_psizes[i],
  95                                  coords[i], array_of_dargs[i], order,
  96                                  orig_extent, type_old, &type_new,
  97                                  st_offsets+i); 
  98                 break;
  99             case MPI_DISTRIBUTE_CYCLIC:
 100                 MPIOI_Type_cyclic(array_of_gsizes, i, ndims, 
 101                                   array_of_psizes[i], coords[i],
 102                                   array_of_dargs[i], order, 
 103                                   orig_extent, type_old, &type_new,
 104                                   st_offsets+i);
 105                 break;
 106             case MPI_DISTRIBUTE_NONE:
 107                 
 108                 MPIOI_Type_block(array_of_gsizes, i, ndims, array_of_psizes[i],
 109                       coords[i], MPI_DISTRIBUTE_DFLT_DARG, order, orig_extent, 
 110                            type_old, &type_new, st_offsets+i); 
 111                 break;
 112             }
 113             if (i != ndims-1) MPI_Type_free(&type_old);
 114             type_old = type_new;
 115         }
 116 
 117         
 118         disp = st_offsets[ndims-1];
 119         tmp_size = 1;
 120         for (i=ndims-2; i>=0; i--) {
 121             tmp_size *= array_of_gsizes[i+1];
 122             disp += (MPI_Aint)tmp_size*st_offsets[i];
 123         }
 124     }
 125 
 126     disp *= orig_extent;
 127 
 128     ub = orig_extent;
 129     for (i=0; i<ndims; i++) ub *= (MPI_Aint)array_of_gsizes[i];
 130         
 131     blklen = 1;
 132     
 133     MPI_Type_create_struct(1, &blklen, &disp, &type_new, &inttype);
 134     MPI_Type_create_resized (inttype, 0, ub, newtype);
 135     MPI_Type_free (&inttype);
 136 
 137     MPI_Type_free(&type_new);
 138     ADIOI_Free(st_offsets);
 139     ADIOI_Free(coords);
 140     return MPI_SUCCESS;
 141 }
 142 
 143 
 144 
 145 
 146 
 147 static int MPIOI_Type_block(int *array_of_gsizes, int dim, int ndims, int nprocs,
 148                      int rank, int darg, int order, MPI_Aint orig_extent,
 149                      MPI_Datatype type_old, MPI_Datatype *type_new,
 150                      MPI_Aint *st_offset) 
 151 {
 152 
 153 
 154     int blksize, global_size, mysize, i, j;
 155     MPI_Aint stride;
 156     
 157     global_size = array_of_gsizes[dim];
 158 
 159     if (darg == MPI_DISTRIBUTE_DFLT_DARG)
 160         blksize = (global_size + nprocs - 1)/nprocs;
 161     else {
 162         blksize = darg;
 163 
 164         
 165         if (blksize <= 0) {
 166             return MPI_ERR_ARG;
 167         }
 168 
 169         if (blksize * nprocs < global_size) {
 170             return MPI_ERR_ARG;
 171         }
 172         
 173     }
 174 
 175     j = global_size - blksize*rank;
 176     mysize = ADIOI_MIN(blksize, j);
 177     if (mysize < 0) mysize = 0;
 178 
 179     stride = orig_extent;
 180     if (order == MPI_ORDER_FORTRAN) {
 181         if (dim == 0) 
 182             MPI_Type_contiguous(mysize, type_old, type_new);
 183         else {
 184             for (i=0; i<dim; i++) stride *= (MPI_Aint)array_of_gsizes[i];
 185             MPI_Type_create_hvector(mysize, 1, stride, type_old, type_new);
 186         }
 187     }
 188     else {
 189         if (dim == ndims-1) 
 190             MPI_Type_contiguous(mysize, type_old, type_new);
 191         else {
 192             for (i=ndims-1; i>dim; i--) stride *= (MPI_Aint)array_of_gsizes[i];
 193             MPI_Type_create_hvector(mysize, 1, stride, type_old, type_new);
 194         }
 195 
 196     }
 197 
 198     *st_offset = (MPI_Aint)blksize * (MPI_Aint)rank;
 199      
 200     if (mysize == 0) *st_offset = 0;
 201 
 202     return MPI_SUCCESS;
 203 }
 204 
 205 
 206 
 207 
 208 
 209 static int MPIOI_Type_cyclic(int *array_of_gsizes, int dim, int ndims, int nprocs,
 210                       int rank, int darg, int order, MPI_Aint orig_extent,
 211                       MPI_Datatype type_old, MPI_Datatype *type_new,
 212                       MPI_Aint *st_offset) 
 213 {
 214 
 215 
 216     int blksize, i, blklens[3], st_index, end_index, local_size, rem, count;
 217     MPI_Aint stride, disps[3];
 218     MPI_Datatype type_tmp, type_tmp1, types[3];
 219 
 220     if (darg == MPI_DISTRIBUTE_DFLT_DARG) blksize = 1;
 221     else blksize = darg;
 222 
 223     
 224     if (blksize <= 0) {
 225         return MPI_ERR_ARG;
 226     }
 227     
 228     
 229     st_index = rank*blksize;
 230     end_index = array_of_gsizes[dim] - 1;
 231 
 232     if (end_index < st_index) local_size = 0;
 233     else {
 234         local_size = ((end_index - st_index + 1)/(nprocs*blksize))*blksize;
 235         rem = (end_index - st_index + 1) % (nprocs*blksize);
 236         local_size += ADIOI_MIN(rem, blksize);
 237     }
 238 
 239     count = local_size/blksize;
 240     rem = local_size % blksize;
 241     
 242     stride = (MPI_Aint)nprocs*(MPI_Aint)blksize*orig_extent;
 243     if (order == MPI_ORDER_FORTRAN)
 244         for (i=0; i<dim; i++) stride *= (MPI_Aint)array_of_gsizes[i];
 245     else for (i=ndims-1; i>dim; i--) stride *= (MPI_Aint)array_of_gsizes[i];
 246 
 247     MPI_Type_create_hvector(count, blksize, stride, type_old, type_new);
 248 
 249     if (rem) {
 250         
 251 
 252 
 253         types[0] = *type_new;
 254         types[1] = type_old;
 255         disps[0] = 0;
 256         disps[1] = (MPI_Aint)count*stride;
 257         blklens[0] = 1;
 258         blklens[1] = rem;
 259 
 260         MPI_Type_create_struct(2, blklens, disps, types, &type_tmp);
 261 
 262         MPI_Type_free(type_new);
 263         *type_new = type_tmp;
 264     }
 265 
 266     
 267  
 268     if ( ((order == MPI_ORDER_FORTRAN) && (dim == 0)) ||
 269          ((order == MPI_ORDER_C) && (dim == ndims-1)) ) {
 270         types[0] = *type_new;
 271         disps[0] = (MPI_Aint)rank * (MPI_Aint)blksize * orig_extent;
 272         blklens[0] = 1;
 273         MPI_Type_create_struct(1, blklens, disps, types, &type_tmp1);
 274         MPI_Type_create_resized (type_tmp1, 0, orig_extent * (MPI_Aint)array_of_gsizes[dim], &type_tmp);
 275         MPI_Type_free(&type_tmp1);
 276         MPI_Type_free(type_new);
 277         *type_new = type_tmp;
 278 
 279         *st_offset = 0;  
 280 
 281     }
 282     else {
 283         *st_offset = (MPI_Aint)rank * (MPI_Aint)blksize; 
 284         
 285  
 286     }
 287 
 288     if (local_size == 0) *st_offset = 0;
 289 
 290     return MPI_SUCCESS;
 291 }