PLUTO
al_subarray_.c File Reference

Creates a datatype describing a subarray of a multidimensional array. More...

#include "al_hidden.h"
Include dependency graph for al_subarray_.c:

Go to the source code of this file.

Functions

int AL_Type_create_subarray (int ndims, int *array_of_sizes, int *array_of_subsizes, int *array_of_starts, int order, MPI_Datatype oldtype, MPI_Datatype *newtype)
 

Detailed Description

Creates a datatype describing a subarray of a multidimensional array.

Creates a datatype describing a subarray of a multidimensional array

Authors
A. Malagoli (University of Chicago)
Date
Jul 17, 1999

Definition in file al_subarray_.c.

Function Documentation

int AL_Type_create_subarray ( int  ndims,
int *  array_of_sizes,
int *  array_of_subsizes,
int *  array_of_starts,
int  order,
MPI_Datatype  oldtype,
MPI_Datatype *  newtype 
)

Creates a datatype describing a subarray of a multidimensional array NOTE: This routine has been modified from R. Thakur's ROMIO implementation of MPI_Type_create_subarry. The reason for keeping a local copy is mainly to reduce this package's dependence on ROMIO. It only affects the non I/O components of the library (e.g. AL_Allgather).

Parameters
[in]ndimsnumber of array dimensions
[in]array_of_sizesnumber of elements of type oldtype in each dimension of the full array
[in]array_of_subsizesnumber of elements of type oldtype in each dimension of the subarray
[in]array_of_startsstarting coordinates of the subarray in each dimension
[in]orderarray storage order flag
[in]oldtypeold datatype (handle)
[out]newtypenew datatype (handle)

Definition at line 18 of file al_subarray_.c.

43 {
44  MPI_Aint extent, disps[AL_MAX_DIM], size, size_with_aint;
45  int i, blklens[AL_MAX_DIM];
46  MPI_Datatype tmp1, tmp2, types[AL_MAX_DIM];
47  MPI_Offset size_with_offset;
48 
49  if (ndims <= 0) {
50  printf("MPI_Type_create_subarray: Invalid ndims argument\n");
51  MPI_Abort(MPI_COMM_WORLD, 1);
52  }
53  if (array_of_sizes <= (int *) 0) {
54  printf("MPI_Type_create_subarray: array_of_sizes is an invalid address\n");
55  MPI_Abort(MPI_COMM_WORLD, 1);
56  }
57  if (array_of_subsizes <= (int *) 0) {
58  printf("MPI_Type_create_subarray: array_of_subsizes is an invalid address\n");
59  MPI_Abort(MPI_COMM_WORLD, 1);
60  }
61  if (array_of_starts <= (int *) 0) {
62  printf("MPI_Type_create_subarray: array_of_starts is an invalid address\n");
63  MPI_Abort(MPI_COMM_WORLD, 1);
64  }
65 
66  for (i=0; i<ndims; i++) {
67  if (array_of_sizes[i] <= 0) {
68  printf("MPI_Type_create_subarray: Invalid value in array_of_sizes\n");
69  MPI_Abort(MPI_COMM_WORLD, 1);
70  }
71  if (array_of_subsizes[i] <= 0) {
72  printf("MPI_Type_create_subarray: Invalid value in array_of_subsizes\n");
73  MPI_Abort(MPI_COMM_WORLD, 1);
74  }
75  if (array_of_starts[i] < 0) {
76  printf("MPI_Type_create_subarray: Invalid value in array_of_starts\n");
77  MPI_Abort(MPI_COMM_WORLD, 1);
78  }
79  }
80 
81  /* order argument checked below */
82 
83  if (oldtype == MPI_DATATYPE_NULL) {
84  printf("MPI_Type_create_subarray: oldtype is an invalid datatype\n");
85  MPI_Abort(MPI_COMM_WORLD, 1);
86  }
87 
88  MPI_Type_extent(oldtype, (MPI_Aint *) &extent);
89 
90 /* check if MPI_Aint is large enough for size of global array.
91  if not, complain. */
92 
93  size_with_aint = extent;
94  for (i=0; i<ndims; i++) size_with_aint *= array_of_sizes[i];
95  size_with_offset = extent;
96  for (i=0; i<ndims; i++) size_with_offset *= array_of_sizes[i];
97  if (size_with_aint != size_with_offset) {
98  printf("MPI_Type_create_subarray: Can't use an array of this size unless the MPI implementation defines a 64-bit MPI_Aint\n");
99  MPI_Abort(MPI_COMM_WORLD, 1);
100  }
101 
102  if (order == AL_ORDER_FORTRAN) {
103  /* dimension 0 changes fastest */
104  if (ndims == 1)
105  MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
106  else {
107  MPI_Type_vector(array_of_subsizes[1], array_of_subsizes[0],
108  array_of_sizes[0], oldtype, &tmp1);
109 
110  size = array_of_sizes[0]*extent;
111  for (i=2; i<ndims; i++) {
112  size *= array_of_sizes[i-1];
113  MPI_Type_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
114  MPI_Type_free(&tmp1);
115  tmp1 = tmp2;
116  }
117  }
118 
119  /* add displacement and UB */
120 
121  disps[1] = array_of_starts[0];
122  size = 1;
123  for (i=1; i<ndims; i++) {
124  size *= array_of_sizes[i-1];
125  disps[1] += size*array_of_starts[i];
126  }
127  /* rest done below for both Fortran and C order */
128  }
129 
130  else if (order == AL_ORDER_C) {
131  /* dimension ndims-1 changes fastest */
132  if (ndims == 1)
133  MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
134  else {
135  MPI_Type_vector(array_of_subsizes[ndims-2],
136  array_of_subsizes[ndims-1],
137  array_of_sizes[ndims-1], oldtype, &tmp1);
138 
139  size = array_of_sizes[ndims-1]*extent;
140  for (i=ndims-3; i>=0; i--) {
141  size *= array_of_sizes[i+1];
142  MPI_Type_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
143  MPI_Type_free(&tmp1);
144  tmp1 = tmp2;
145  }
146  }
147 
148  /* add displacement and UB */
149 
150  disps[1] = array_of_starts[ndims-1];
151  size = 1;
152  for (i=ndims-2; i>=0; i--) {
153  size *= array_of_sizes[i+1];
154  disps[1] += size*array_of_starts[i];
155  }
156  }
157  else {
158  printf("MPI_Type_create_subarray: Invalid order argument\n");
159  MPI_Abort(MPI_COMM_WORLD, 1);
160  }
161 
162  disps[1] *= extent;
163 
164  disps[2] = extent;
165  for (i=0; i<ndims; i++) disps[2] *= array_of_sizes[i];
166 
167  disps[0] = 0;
168  blklens[0] = blklens[1] = blklens[2] = 1;
169  types[0] = MPI_LB;
170  types[1] = tmp1;
171  types[2] = MPI_UB;
172 
173  MPI_Type_struct(3, blklens, disps, types, newtype);
174 
175  MPI_Type_free(&tmp1);
176 
177  return MPI_SUCCESS;
178 }
#define AL_MAX_DIM
Definition: al_codes.h:18
#define AL_ORDER_C
Definition: al_codes.h:45
#define AL_ORDER_FORTRAN
Definition: al_codes.h:46
int i
Definition: analysis.c:2

Here is the caller graph for this function: