00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mpioimpl.h"
00010
00011 #ifdef HAVE_WEAK_SYMBOLS
00012
00013 #if defined(HAVE_PRAGMA_WEAK)
00014 #pragma weak MPI_Type_create_subarray = PMPI_Type_create_subarray
00015 #elif defined(HAVE_PRAGMA_HP_SEC_DEF)
00016 #pragma _HP_SECONDARY_DEF PMPI_Type_create_subarray MPI_Type_create_subarray
00017 #elif defined(HAVE_PRAGMA_CRI_DUP)
00018 #pragma _CRI duplicate MPI_Type_create_subarray as PMPI_Type_create_subarray
00019
00020 #endif
00021
00022
00023 #define MPIO_BUILD_PROFILING
00024 #include "mpioprof.h"
00025 #endif
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 int MPI_Type_create_subarray(int ndims, int *array_of_sizes,
00044 int *array_of_subsizes, int *array_of_starts,
00045 int order, MPI_Datatype oldtype,
00046 MPI_Datatype *newtype)
00047 {
00048 MPI_Aint extent, disps[3], size, size_with_aint;
00049 int i, blklens[3];
00050 MPI_Datatype tmp1, tmp2, types[3];
00051 MPI_Offset size_with_offset;
00052
00053 if (ndims <= 0) {
00054 FPRINTF(stderr, "MPI_Type_create_subarray: Invalid ndims argument\n");
00055 MPI_Abort(MPI_COMM_WORLD, 1);
00056 }
00057 if (array_of_sizes <= (int *) 0) {
00058 FPRINTF(stderr, "MPI_Type_create_subarray: array_of_sizes is an invalid address\n");
00059 MPI_Abort(MPI_COMM_WORLD, 1);
00060 }
00061 if (array_of_subsizes <= (int *) 0) {
00062 FPRINTF(stderr, "MPI_Type_create_subarray: array_of_subsizes is an invalid address\n");
00063 MPI_Abort(MPI_COMM_WORLD, 1);
00064 }
00065 if (array_of_starts <= (int *) 0) {
00066 FPRINTF(stderr, "MPI_Type_create_subarray: array_of_starts is an invalid address\n");
00067 MPI_Abort(MPI_COMM_WORLD, 1);
00068 }
00069
00070 for (i=0; i<ndims; i++) {
00071 if (array_of_sizes[i] <= 0) {
00072 FPRINTF(stderr, "MPI_Type_create_subarray: Invalid value in array_of_sizes\n");
00073 MPI_Abort(MPI_COMM_WORLD, 1);
00074 }
00075 if (array_of_subsizes[i] <= 0) {
00076 FPRINTF(stderr, "MPI_Type_create_subarray: Invalid value in array_of_subsizes\n");
00077 MPI_Abort(MPI_COMM_WORLD, 1);
00078 }
00079 if (array_of_starts[i] < 0) {
00080 FPRINTF(stderr, "MPI_Type_create_subarray: Invalid value in array_of_starts\n");
00081 MPI_Abort(MPI_COMM_WORLD, 1);
00082 }
00083 if (array_of_subsizes[i] > array_of_sizes[i]) {
00084 FPRINTF(stderr, "MPI_Type_create_subarray: Error! array_of_subsizes[%d] > array_of_sizes[%d]\n", i, i);
00085 MPI_Abort(MPI_COMM_WORLD, 1);
00086 }
00087 if (array_of_starts[i] > (array_of_sizes[i] - array_of_subsizes[i])) {
00088 FPRINTF(stderr, "MPI_Type_create_subarray: Error! array_of_starts[%d] > (array_of_sizes[%d] - array_of_subsizes[%d])\n", i, i, i);
00089 MPI_Abort(MPI_COMM_WORLD, 1);
00090 }
00091 }
00092
00093
00094
00095 if (oldtype == MPI_DATATYPE_NULL) {
00096 FPRINTF(stderr, "MPI_Type_create_subarray: oldtype is an invalid datatype\n");
00097 MPI_Abort(MPI_COMM_WORLD, 1);
00098 }
00099
00100 MPI_Type_extent(oldtype, &extent);
00101
00102
00103
00104
00105 size_with_aint = extent;
00106 for (i=0; i<ndims; i++) size_with_aint *= array_of_sizes[i];
00107 size_with_offset = extent;
00108 for (i=0; i<ndims; i++) size_with_offset *= array_of_sizes[i];
00109 if (size_with_aint != size_with_offset) {
00110 FPRINTF(stderr, "MPI_Type_create_subarray: Can't use an array of this size unless the MPI implementation defines a 64-bit MPI_Aint\n");
00111 MPI_Abort(MPI_COMM_WORLD, 1);
00112 }
00113
00114 if (order == MPI_ORDER_FORTRAN) {
00115
00116 if (ndims == 1)
00117 MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
00118 else {
00119 MPI_Type_vector(array_of_subsizes[1], array_of_subsizes[0],
00120 array_of_sizes[0], oldtype, &tmp1);
00121
00122 size = array_of_sizes[0]*extent;
00123 for (i=2; i<ndims; i++) {
00124 size *= array_of_sizes[i-1];
00125 MPI_Type_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
00126 MPI_Type_free(&tmp1);
00127 tmp1 = tmp2;
00128 }
00129 }
00130
00131
00132
00133 disps[1] = array_of_starts[0];
00134 size = 1;
00135 for (i=1; i<ndims; i++) {
00136 size *= array_of_sizes[i-1];
00137 disps[1] += size*array_of_starts[i];
00138 }
00139
00140 }
00141
00142 else if (order == MPI_ORDER_C) {
00143
00144 if (ndims == 1)
00145 MPI_Type_contiguous(array_of_subsizes[0], oldtype, &tmp1);
00146 else {
00147 MPI_Type_vector(array_of_subsizes[ndims-2],
00148 array_of_subsizes[ndims-1],
00149 array_of_sizes[ndims-1], oldtype, &tmp1);
00150
00151 size = array_of_sizes[ndims-1]*extent;
00152 for (i=ndims-3; i>=0; i--) {
00153 size *= array_of_sizes[i+1];
00154 MPI_Type_hvector(array_of_subsizes[i], 1, size, tmp1, &tmp2);
00155 MPI_Type_free(&tmp1);
00156 tmp1 = tmp2;
00157 }
00158 }
00159
00160
00161
00162 disps[1] = array_of_starts[ndims-1];
00163 size = 1;
00164 for (i=ndims-2; i>=0; i--) {
00165 size *= array_of_sizes[i+1];
00166 disps[1] += size*array_of_starts[i];
00167 }
00168 }
00169 else {
00170 FPRINTF(stderr, "MPI_Type_create_subarray: Invalid order argument\n");
00171 MPI_Abort(MPI_COMM_WORLD, 1);
00172 }
00173
00174 disps[1] *= extent;
00175
00176 disps[2] = extent;
00177 for (i=0; i<ndims; i++) disps[2] *= array_of_sizes[i];
00178
00179 disps[0] = 0;
00180 blklens[0] = blklens[1] = blklens[2] = 1;
00181 types[0] = MPI_LB;
00182 types[1] = tmp1;
00183 types[2] = MPI_UB;
00184
00185 MPI_Type_struct(3, blklens, disps, types, newtype);
00186
00187 MPI_Type_free(&tmp1);
00188
00189 return MPI_SUCCESS;
00190 }