/*@ MPI_Type_create_darray - Creates a datatype corresponding to a distributed, multidimensional array Input Parameters: . size - size of process group (positive integer) . rank - rank in process group (nonnegative integer) . ndims - number of array dimensions as well as process grid dimensions (positive integer) . array_of_gsizes - number of elements of type oldtype in each dimension of global array (array of positive integers) . array_of_distribs - distribution of array in each dimension (array of state) . array_of_dargs - distribution argument in each dimension (array of positive integers) . array_of_psizes - size of process grid in each dimension (array of positive integers) . order - array storage order flag (state) . oldtype - old datatype (handle) Output Parameters: . newtype - new datatype (handle) .N fortran @*/ int MPI_Type_create_darray(int size, int rank, int ndims, int *array_of_gsizes, int *array_of_distribs, int *array_of_dargs, int *array_of_psizes, int order, MPI_Datatype oldtype, MPI_Datatype *newtype) { int err, error_code; int i; MPI_Aint orig_extent, size_with_aint; MPI_Offset size_with_offset; static char myname[] = "MPI_TYPE_CREATE_DARRAY"; /* --BEGIN ERROR HANDLING-- */ if (size <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid size argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (rank < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid rank argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (ndims <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid ndoms argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_gsizes <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_gsizes argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_distribs <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_distribs argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_dargs <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_dargs argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_psizes <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_psizes argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } for (i=0; i<ndims; i++) { if (array_of_gsizes[i] <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS,MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid gsize argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } /* array_of_distribs checked below */ if ((array_of_dargs[i] != MPI_DISTRIBUTE_DFLT_DARG) && (array_of_dargs[i] <= 0)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid darg argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_psizes[i] <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid psize argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_distribs[i] != MPI_DISTRIBUTE_BLOCK && array_of_distribs[i] != MPI_DISTRIBUTE_CYCLIC && array_of_distribs[i] != MPI_DISTRIBUTE_NONE) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid distrib argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_distribs[i] == MPI_DISTRIBUTE_NONE && array_of_psizes[i] != 1) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "For MPI_DISTRIBUTE_NONE, the number of processes in that dimension of the grid must be 1", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } } /* order argument checked below */ if (oldtype == MPI_DATATYPE_NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid type argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } MPI_Type_extent(oldtype, &orig_extent); /* check if MPI_Aint is large enough for size of global array. if not, complain. */ size_with_aint = orig_extent; for (i=0; i<ndims; i++) size_with_aint *= array_of_gsizes[i]; size_with_offset = orig_extent; for (i=0; i<ndims; i++) size_with_offset *= array_of_gsizes[i]; if (size_with_aint != size_with_offset) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array size", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (order != MPI_ORDER_FORTRAN && order != MPI_ORDER_C) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid order argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } /* --END ERROR HANDLING-- */ err = ADIO_Type_create_darray(size, rank, ndims, array_of_gsizes, array_of_distribs, array_of_dargs, array_of_psizes, order, oldtype, newtype); /* --BEGIN ERROR HANDLING-- */ if (err != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, err, "Internal error", 0); } /* --END ERROR HANDLING-- */ return MPI_SUCCESS; }
/*@ MPI_Type_create_subarray - Creates a datatype describing a subarray of a multidimensional array Input Parameters: . ndims - number of array dimensions (positive integer) . array_of_sizes - number of elements of type oldtype in each dimension of the full array (array of positive integers) . array_of_subsizes - number of elements of type oldtype in each dimension of the subarray (array of positive integers) . array_of_starts - starting coordinates of the subarray in each dimension (array of nonnegative integers) . order - array storage order flag (state) . oldtype - old datatype (handle) Output Parameters: . newtype - new datatype (handle) .N fortran @*/ int MPI_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) { MPI_Aint extent, size_with_aint; int i, err, error_code; MPI_Offset size_with_offset; /* --BEGIN ERROR HANDLING-- */ if (ndims <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid ndims argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_sizes <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_sizes argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_subsizes <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_subsizes argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_starts <= (int *) 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid array_of_starts argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } for (i = 0; i < ndims; i++) { if (array_of_sizes[i] <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid size argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_subsizes[i] <= 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid subsize argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_starts[i] < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid start argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_subsizes[i] > array_of_sizes[i]) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid subsize argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (array_of_starts[i] > (array_of_sizes[i] - array_of_subsizes[i])) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid start argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } } /* order argument checked below */ if (oldtype == MPI_DATATYPE_NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid type argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } MPI_Type_extent(oldtype, &extent); /* check if MPI_Aint is large enough for size of global array. if not, complain. */ size_with_aint = extent; for (i = 0; i < ndims; i++) size_with_aint *= array_of_sizes[i]; size_with_offset = extent; for (i = 0; i < ndims; i++) size_with_offset *= array_of_sizes[i]; if (size_with_aint != size_with_offset) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid size argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } if (order != MPI_ORDER_FORTRAN && order != MPI_ORDER_C) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "Invalid order argument", 0); return MPIO_Err_return_comm(MPI_COMM_SELF, error_code); } /* --END ERROR HANDLING-- */ err = ADIO_Type_create_subarray(ndims, array_of_sizes, array_of_subsizes, array_of_starts, order, oldtype, newtype); /* --BEGIN ERROR HANDLING-- */ if (err != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, err, "Internal error", 0); } /* --END ERROR HANDLING-- */ return MPI_SUCCESS; }