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).
   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);