19 int *array_of_subsizes,
int *array_of_starts,
20 int order, MPI_Datatype oldtype,
21 MPI_Datatype *newtype)
44 MPI_Aint extent, disps[
AL_MAX_DIM], size, size_with_aint;
47 MPI_Offset size_with_offset;
50 printf(
"MPI_Type_create_subarray: Invalid ndims argument\n");
51 MPI_Abort(MPI_COMM_WORLD, 1);
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);
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);
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);
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);
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);
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);
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);
88 MPI_Type_extent(oldtype, (MPI_Aint *) &extent);
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);
105 MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
107 MPI_Type_vector(array_of_subsizes[1], array_of_subsizes[0],
108 array_of_sizes[0], oldtype, &tmp1);
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);
121 disps[1] = array_of_starts[0];
123 for (i=1; i<ndims; i++) {
124 size *= array_of_sizes[i-1];
125 disps[1] += size*array_of_starts[
i];
133 MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
135 MPI_Type_vector(array_of_subsizes[ndims-2],
136 array_of_subsizes[ndims-1],
137 array_of_sizes[ndims-1], oldtype, &tmp1);
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);
150 disps[1] = array_of_starts[ndims-1];
152 for (i=ndims-2; i>=0; i--) {
153 size *= array_of_sizes[i+1];
154 disps[1] += size*array_of_starts[
i];
158 printf(
"MPI_Type_create_subarray: Invalid order argument\n");
159 MPI_Abort(MPI_COMM_WORLD, 1);
165 for (i=0; i<ndims; i++) disps[2] *= array_of_sizes[i];
168 blklens[0] = blklens[1] = blklens[2] = 1;
173 MPI_Type_struct(3, blklens, disps, types, newtype);
175 MPI_Type_free(&tmp1);
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)
Internal include file for the ArrayLib.