void MPICH_DEFAULT_MINF(void *invec, void *inoutvec, int *Len, MPI_Datatype *type) { int i, len = *Len; switch (*type) { case MPIR_INT:{ int *a = (int *) inoutvec; int *b = (int *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_UINT:{ unsigned *a = (unsigned *) inoutvec; unsigned *b = (unsigned *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_LONG:{ long *a = (long *) inoutvec; long *b = (long *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } #if defined(HAVE_LONG_LONG_INT) case MPIR_LONGLONGINT:{ long long *a = (long long *) inoutvec; long long *b = (long long *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } #endif case MPIR_ULONG:{ unsigned long *a = (unsigned long *) inoutvec; unsigned long *b = (unsigned long *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_SHORT:{ short *a = (short *) inoutvec; short *b = (short *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_USHORT:{ unsigned short *a = (unsigned short *) inoutvec; unsigned short *b = (unsigned short *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_CHAR:{ char *a = (char *) inoutvec; char *b = (char *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_UCHAR: case MPI_BYTE:{ unsigned char *a = (unsigned char *) inoutvec; unsigned char *b = (unsigned char *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_FLOAT:{ float *a = (float *) inoutvec; float *b = (float *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } case MPIR_DOUBLE:{ double *a = (double *) inoutvec; double *b = (double *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } #if defined(HAVE_LONG_DOUBLE) case MPIR_LONGDOUBLE:{ long double *a = (long double *) inoutvec; long double *b = (long double *) invec; for (i = 0; i < len; i++) a[i] = MPIR_MIN(a[i], b[i]); break; } #endif default: MPIR_Op_errno = MPIR_ERR_OP_NOT_DEFINED; MPIR_ERROR(MPIR_COMM_WORLD, MPIR_ERR_OP_NOT_DEFINED, "MPI_MIN"); break; } }
PMPI_LOCAL int MPIR_Type_block(const int *array_of_gsizes, int dim, int ndims, int nprocs, int rank, int darg, int order, MPI_Aint orig_extent, MPI_Datatype type_old, MPI_Datatype *type_new, MPI_Aint *st_offset) { /* nprocs = no. of processes in dimension dim of grid rank = coordinate of this process in dimension dim */ static const char FCNAME[] = "MPIR_Type_block"; int mpi_errno, blksize, global_size, mysize, i, j; MPI_Aint stride; global_size = array_of_gsizes[dim]; if (darg == MPI_DISTRIBUTE_DFLT_DARG) blksize = (global_size + nprocs - 1)/nprocs; else { blksize = darg; #ifdef HAVE_ERROR_CHECKING if (blksize <= 0) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_ARG, "**darrayblock", "**darrayblock %d", blksize); return mpi_errno; } if (blksize * nprocs < global_size) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_ARG, "**darrayblock2", "**darrayblock2 %d %d", blksize*nprocs, global_size); return mpi_errno; } #endif } j = global_size - blksize*rank; mysize = MPIR_MIN(blksize, j); if (mysize < 0) mysize = 0; stride = orig_extent; if (order == MPI_ORDER_FORTRAN) { if (dim == 0) { mpi_errno = MPID_Type_contiguous(mysize, type_old, type_new); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ } else { for (i=0; i<dim; i++) stride *= (MPI_Aint)(array_of_gsizes[i]); mpi_errno = MPID_Type_vector(mysize, 1, stride, 1, /* stride in bytes */ type_old, type_new); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ } } else { if (dim == ndims-1) { mpi_errno = MPID_Type_contiguous(mysize, type_old, type_new); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ } else { for (i=ndims-1; i>dim; i--) stride *= (MPI_Aint)(array_of_gsizes[i]); mpi_errno = MPID_Type_vector(mysize, 1, stride, 1, /* stride in bytes */ type_old, type_new); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ } } *st_offset = (MPI_Aint) blksize * (MPI_Aint) rank; /* in terms of no. of elements of type oldtype in this dimension */ if (mysize == 0) *st_offset = 0; return MPI_SUCCESS; }
void MPIR_MINLOC( void *invec, void *inoutvec, int *Len, MPI_Datatype *type ) { int i, len = *Len; struct MPIR_DATATYPE *dtype = MPIR_GET_DTYPE_PTR(*type); if ((dtype)->dte_type == MPIR_STRUCT) { /* Perform the operation based on the type of the first type in */ /* struct */ switch ((dtype)->old_types[0]->dte_type) { case MPIR_INT: { MPIR_2int_loctype *a = (MPIR_2int_loctype *)inoutvec; MPIR_2int_loctype *b = (MPIR_2int_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } case MPIR_FLOAT: { MPIR_floatint_loctype *a = (MPIR_floatint_loctype *)inoutvec; MPIR_floatint_loctype *b = (MPIR_floatint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } case MPIR_LONG: { MPIR_longint_loctype *a = (MPIR_longint_loctype *)inoutvec; MPIR_longint_loctype *b = (MPIR_longint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } #if defined(HAVE_LONG_LONG_INT) case MPIR_LONGLONGINT: { MPIR_longlongint_loctype *a = (MPIR_longlongint_loctype *)inoutvec; MPIR_longlongint_loctype *b = (MPIR_longlongint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } #endif case MPIR_SHORT: { MPIR_shortint_loctype *a = (MPIR_shortint_loctype *)inoutvec; MPIR_shortint_loctype *b = (MPIR_shortint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } case MPIR_DOUBLE: { MPIR_doubleint_loctype *a = (MPIR_doubleint_loctype *)inoutvec; MPIR_doubleint_loctype *b = (MPIR_doubleint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } #if defined(HAVE_LONG_DOUBLE) case MPIR_LONGDOUBLE: { MPIR_longdoubleint_loctype *a = (MPIR_longdoubleint_loctype *)inoutvec; MPIR_longdoubleint_loctype *b = (MPIR_longdoubleint_loctype *)invec; for (i=0; i<len; i++) { if (a[i].value == b[i].value) a[i].loc = MPIR_MIN(a[i].loc,b[i].loc); else if (a[i].value > b[i].value) { a[i].value = b[i].value; a[i].loc = b[i].loc; } } break; } #endif default: MPIR_Op_errno = MPIR_ERR_OP_NOT_DEFINED; MPIR_ERROR(MPIR_COMM_WORLD, MPIR_ERR_OP_NOT_DEFINED, "MPI_MINLOC" ); } } else if ((dtype)->dte_type == MPIR_CONTIG && ((dtype)->count == 2)) { struct MPIR_DATATYPE *oldtype = (dtype)->old_type; /* Set the actual length */ len = len * (dtype)->count; /* Perform the operation */ switch (oldtype->dte_type) { case MPIR_INT: { int *a = (int *)inoutvec; int *b = (int *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } case MPIR_LONG: { long *a = (long *)inoutvec; long *b = (long *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } #if defined(HAVE_LONG_LONG_INT) case MPIR_LONGLONGINT: { long long *a = (long long *)inoutvec; long long *b = (long long *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } #endif case MPIR_SHORT: { short *a = (short *)inoutvec; short *b = (short *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } case MPIR_CHAR: { char *a = (char *)inoutvec; char *b = (char *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } case MPIR_FLOAT: { float *a = (float *)inoutvec; float *b = (float *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } case MPIR_DOUBLE: { double *a = (double *)inoutvec; double *b = (double *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } #ifdef HAVE_LONG_DOUBLE case MPIR_LONGDOUBLE: { long double *a = (long double *)inoutvec; long double *b = (long double *)invec; for ( i=0; i<len; i+=2 ) { if (a[i] == b[i]) a[i+1] = MPIR_MIN(a[i+1],b[i+1]); else if (a[i] > b[i]) { a[i] = b[i]; a[i+1] = b[i+1]; } } break; } #endif default: MPIR_Op_errno = MPIR_ERR_OP_NOT_DEFINED; MPIR_ERROR(MPIR_COMM_WORLD, MPIR_ERR_OP_NOT_DEFINED, "MPI_MINLOC" ); break; } } else { MPIR_Op_errno = MPIR_ERR_OP_NOT_DEFINED; MPIR_ERROR(MPIR_COMM_WORLD, MPIR_ERR_OP_NOT_DEFINED, "MPI_MINLOC" ); } }
PMPI_LOCAL int MPIR_Type_cyclic(const int *array_of_gsizes, int dim, int ndims, int nprocs, int rank, int darg, int order, MPI_Aint orig_extent, MPI_Datatype type_old, MPI_Datatype *type_new, MPI_Aint *st_offset) { /* nprocs = no. of processes in dimension dim of grid rank = coordinate of this process in dimension dim */ static const char FCNAME[] = "MPIR_Type_cyclic"; int mpi_errno,blksize, i, blklens[3], st_index, end_index, local_size, rem, count; MPI_Aint stride, disps[3]; MPI_Datatype type_tmp, types[3]; if (darg == MPI_DISTRIBUTE_DFLT_DARG) blksize = 1; else blksize = darg; #ifdef HAVE_ERROR_CHECKING if (blksize <= 0) { mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_ARG, "**darraycyclic", "**darraycyclic %d", blksize); return mpi_errno; } #endif st_index = rank*blksize; end_index = array_of_gsizes[dim] - 1; if (end_index < st_index) local_size = 0; else { local_size = ((end_index - st_index + 1)/(nprocs*blksize))*blksize; rem = (end_index - st_index + 1) % (nprocs*blksize); local_size += MPIR_MIN(rem, blksize); } count = local_size/blksize; rem = local_size % blksize; stride = (MPI_Aint) nprocs * (MPI_Aint) blksize * orig_extent; if (order == MPI_ORDER_FORTRAN) for (i=0; i<dim; i++) stride *= (MPI_Aint)(array_of_gsizes[i]); else for (i=ndims-1; i>dim; i--) stride *= (MPI_Aint)(array_of_gsizes[i]); mpi_errno = MPID_Type_vector(count, blksize, stride, 1, /* stride in bytes */ type_old, type_new); /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ if (rem) { /* if the last block is of size less than blksize, include it separately using MPI_Type_struct */ types[0] = *type_new; types[1] = type_old; disps[0] = 0; disps[1] = (MPI_Aint) count * stride; blklens[0] = 1; blklens[1] = rem; mpi_errno = MPID_Type_struct(2, blklens, disps, types, &type_tmp); MPIR_Type_free_impl(type_new); *type_new = type_tmp; /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ } /* In the first iteration, we need to set the displacement in that dimension correctly. */ if (((order == MPI_ORDER_FORTRAN) && (dim == 0)) || ((order == MPI_ORDER_C) && (dim == ndims-1))) { types[0] = MPI_LB; disps[0] = 0; types[1] = *type_new; disps[1] = (MPI_Aint) rank * (MPI_Aint) blksize * orig_extent; types[2] = MPI_UB; disps[2] = orig_extent * (MPI_Aint)(array_of_gsizes[dim]); blklens[0] = blklens[1] = blklens[2] = 1; mpi_errno = MPID_Type_struct(3, blklens, disps, types, &type_tmp); MPIR_Type_free_impl(type_new); *type_new = type_tmp; /* --BEGIN ERROR HANDLING-- */ if (mpi_errno != MPI_SUCCESS) { mpi_errno = MPIR_Err_create_code(mpi_errno, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER, "**fail", 0); return mpi_errno; } /* --END ERROR HANDLING-- */ *st_offset = 0; /* set it to 0 because it is taken care of in the struct above */ } else { *st_offset = (MPI_Aint) rank * (MPI_Aint) blksize; /* st_offset is in terms of no. of elements of type oldtype in * this dimension */ } if (local_size == 0) *st_offset = 0; return MPI_SUCCESS; }