opal_datatype_t* create_strange_dt( void ) { sdata_intern v[2]; OPAL_PTRDIFF_TYPE displ[3]; sstrange t[2]; int pBlock[3] = {1, 10, 1}, dispi[3]; opal_datatype_t *pdt, *pdt1, *pdt2, *pdtTemp; opal_datatype_create_contiguous(0, &opal_datatype_empty, &pdt1); opal_datatype_add( pdt1, &opal_datatype_float8, 1, 0, -1 ); opal_datatype_add( pdt1, &opal_datatype_int1, 1, 8, -1 ); #ifdef USE_RESIZED /* optional */ displ[0] = 0; displ[1] = (char*)&(v[1]) - (char*)&(v[0]); opal_datatype_resize( pdt1, displ[0], displ[1]); #endif /* USE_RESIZED */ opal_datatype_create_contiguous( SSTRANGE_CNT, pdt1, &pdt ); OBJ_RELEASE( pdt1 ); printf( "\nStrange datatype BEFORE COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { opal_datatype_dump( pdt ); } opal_datatype_commit( pdt ); printf( "\nStrange datatype AFTER COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { opal_datatype_dump( pdt ); } return pdt; }
static int cyclic(const int *gsize_array, int dim, int ndims, int nprocs, int rank, int darg, int order, ptrdiff_t orig_extent, ompi_datatype_t* type_old, ompi_datatype_t **type_new, ptrdiff_t *st_offset) { int blksize, i, blklens[2], st_index, end_index, local_size, rem, count, rc; ptrdiff_t stride, disps[2]; ompi_datatype_t *type_tmp, *types[2]; if (darg == MPI_DISTRIBUTE_DFLT_DARG) { blksize = 1; } else { blksize = darg; } st_index = rank * blksize; end_index = gsize_array[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 += rem < blksize ? rem : blksize; } count = local_size / blksize; rem = local_size % blksize; stride = nprocs*blksize*orig_extent; if (order == MPI_ORDER_FORTRAN) { for (i=0; i<dim; i++) { stride *= gsize_array[i]; } } else { for (i=ndims-1; i>dim; i--) { stride *= gsize_array[i]; } } rc = ompi_datatype_create_hvector(count, blksize, stride, type_old, type_new); if (OMPI_SUCCESS != rc) return rc; 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] = count*stride; blklens[0] = 1; blklens[1] = rem; rc = ompi_datatype_create_struct(2, blklens, disps, types, &type_tmp); ompi_datatype_destroy(type_new); /* even in error condition, need to destroy type_new, so check for error after destroy. */ if (OMPI_SUCCESS != rc) return rc; *type_new = type_tmp; } /* need to set the UB for block-cyclic to work */ disps[0] = 0; disps[1] = orig_extent; if (order == MPI_ORDER_FORTRAN) { for(i=0; i<=dim; i++) { disps[1] *= gsize_array[i]; } } else { for(i=ndims-1; i>=dim; i--) { disps[1] *= gsize_array[i]; } } rc = opal_datatype_resize( &(*type_new)->super, disps[0], disps[1] ); if (OMPI_SUCCESS != rc) return rc; *st_offset = rank * blksize; /* in terms of no. of elements of type oldtype in this dimension */ if (local_size == 0) *st_offset = 0; return OMPI_SUCCESS; }