summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Smpio.c235
1 files changed, 150 insertions, 85 deletions
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index 1f538db..fd18f7c 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -121,7 +121,7 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size,
*
* Programmer: rky 980813
*
- * Modifications:
+ * Modifications: ppw 990401
*
*-------------------------------------------------------------------------
*/
@@ -140,12 +140,12 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
hsize_t count;
} d[32];
- int i, err, new_rank, num_to_collapse;
+ int i, j, err, new_rank, num_to_collapse, stride_bytes;
+ int offset[32], max_xtent[32], block_length[2], displacement[2];
H5S_hyper_dim_t *diminfo; /* [rank] */
intn rank;
- MPI_Datatype inner_type, outer_type;
- MPI_Aint s[2]; /* array of displacements for struct type */
- MPI_Aint extent_len, start_Aint; /* for calculating d[1] */
+ MPI_Datatype inner_type, outer_type, old_type[32];
+ MPI_Aint extent_len;
FUNC_ENTER (H5S_mpio_hyper_type, FAIL);
@@ -165,13 +165,33 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
d[i].count = diminfo[i].count;
d[i].xtent = space->extent.u.simple.size[i];
#ifdef H5Smpi_DEBUG
- fprintf(stdout, "hyper_type: start=%Hd stride=%Hu count=%Hu "
+ HDfprintf(stdout, "hyper_type: start=%Hd stride=%Hu count=%Hu "
"block=%Hu xtent=%Hu",
d[i].start, d[i].strid, d[i].count, d[i].block, d[i].xtent );
if (i==0) fprintf(stdout, " rank=%d\n", rank );
else fprintf(stdout, "\n" );
#endif
}
+
+/**********************************************************************
+ Compute array "offset[rank]" which gives the offsets for a multi-
+ dimensional array with dimensions "d[i].xtent" (i=0,1,...,rank-1).
+**********************************************************************/
+ offset[rank-1] = 1;
+ max_xtent[rank-1] = d[rank-1].xtent;
+#ifdef H5Smpi_DEBUG
+ i=rank-1;
+ fprintf(stdout, " offset[%2d]=%d; max_xtent[%2d]=%d\n",
+ i, offset[i], i, max_xtent[i]);
+#endif
+ for (i=rank-2; i>=0; --i) {
+ offset[i] = offset[i+1]*d[i+1].xtent;
+ max_xtent[i] = max_xtent[i+1]*d[i].xtent;
+#ifdef H5Smpi_DEBUG
+ fprintf(stdout, " offset[%2d]=%d; max_xtent[%2d]=%d\n",
+ i, offset[i], i, max_xtent[i]);
+#endif
+ }
/* Create a type covering the selected hyperslab.
* Multidimensional dataspaces are stored in row-major order.
@@ -207,9 +227,8 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
}
} /* end for */
num_to_collapse = i;
-
- num_to_collapse = 0; /* rky 980827 DEBUG Temporary change to prevent
- collapsing dims until further testing of collapse */
+ if (num_to_collapse == rank) num_to_collapse--;
+ printf ("num_to_collapse=%d\n", num_to_collapse);
assert(0<=num_to_collapse && num_to_collapse<rank);
new_rank = rank - num_to_collapse;
@@ -218,10 +237,11 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
#endif
/* To collapse dims, just transform dimension info (from inner to outer) */
+ /* must multiply r.h.s. by "count" --- ppw 03/11/99 */
for (i=rank-1; i>=new_rank; --i) {
- d[i-1].block *= d[i].strid;
- d[i-1].strid *= d[i].strid;
- d[i-1].xtent *= d[i].strid;
+ d[i-1].block *= d[i].count * d[i].block;
+ d[i-1].strid *= d[i].count * d[i].block;
+ d[i-1].xtent *= d[i].count * d[i].block;
assert( d[i].start == 0 );
/* d[i-1].start stays unchanged */
/* d[i-1].count stays unchanged */
@@ -236,96 +256,140 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
}
}
- /* initialize induction variables */
- s[0] = 0; /* stays constant */
- /* create contig type for inner contig dims */
+/*******************************************************
+* Construct contig type for inner contig dims:
+*******************************************************/
#ifdef H5Smpi_DEBUG
fprintf(stdout, "hyper_type: Making contig type %d MPI_BYTEs\n", elmt_size );
+ for (i=new_rank-1; i>=0; --i) {
+ HDfprintf(stdout, "d[%d].xtent=%Hu \n", i, d[i].xtent);
+ }
#endif
err = MPI_Type_contiguous( (int)elmt_size, MPI_BYTE, &inner_type );
if (err) {
HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't create MPI contiguous type");
}
- /* construct the type by walking the hyperslab dims from the inside out */
+/*******************************************************
+* Construct the type by walking the hyperslab dims
+* from the inside out:
+*******************************************************/
for ( i=new_rank-1; i>=0; --i) {
#ifdef H5Smpi_DEBUG
- fprintf(stdout, "hyper_type: i=%d Making vector type\n"
+ HDfprintf(stdout, "hyper_type: Dimension i=%d \n"
"count=%Hu block=%Hu stride=%Hu\n",
i, d[i].count, d[i].block, d[i].strid );
#endif
- err = MPI_Type_vector( (int)(d[i].count), /* count */
- (int)(d[i].block), /* blocklength */
- (MPI_Aint)(d[i].strid), /* stride */
- inner_type, /* old type */
- &outer_type ); /* new type */
- if (err) {
- MPI_Type_free( &inner_type ); /* free before abort */
- HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't create MPI vector type");
- }
- /* from here to end of loop, inner_type actually will get the value
- * of the outermost type: it will be inner for the next iteration */
- if (0 == d[i].start) {
- /* don't need to compensate for the start displacement */
- MPI_Type_free( &inner_type ); /* old inner no longer needed */
- inner_type = outer_type; /* prepare for next iter */
- } else {
- /* need to compensate for the start displacement */
- int b[2]; /* array of rep counts */
- MPI_Datatype t[2]; /* array of MPI types */
-
- /* fill in the b, d, and t arrays, length is 2 */
- /* b gives rep count for each type in t */
- b[0] = 1;
- b[1] = 1;
-
- /* s gives the byte displacement for each "field" by induction:
- * for 0<=i<rank-1 s[1]_i = start[i]*extent_length[i+1];
- * with base case s[1]_(rank-1) = elmt_size (i decreasing).
- * (Assuming dimension index increases as we go deeper in.)
- * Note that in this loop, extent_length[i+1] is the extent length
- * of the inner type (i.e., the type constructed in previous trip).
- */
- err = MPI_Type_extent( inner_type, &extent_len );
- if (err) {
- MPI_Type_free( &inner_type ); /* free before abort */
- MPI_Type_free( &outer_type ); /* free before abort */
- HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,
- "couldn't get extent of MPI type");
- }
- start_Aint = (MPI_Aint)(d[i].start);
- if (start_Aint != d[i].start) {
- MPI_Type_free( &inner_type ); /* free before abort */
- MPI_Type_free( &outer_type ); /* free before abort */
- HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
- "start value overflows MPI_Aint");
- }
- s[1] = start_Aint * extent_len;
-
- /* t gives the MPI types for the "fields" */
- /* I think we could do without the LB type and just have
- * one "field" consisting of the vector type with displacement,
- * but I guess there's no harm in doing it this way. */
- t[0] = MPI_LB;
- t[1] = outer_type; /* the just-created vector type */
- /* Create new struct type to compensate for start displacement.
- * The struct's first "field" is the displacement,
- * and its second "field" is the just-created vector type */
+
+#ifdef H5Smpi_DEBUG
+ HDfprintf(stdout, "hyper_type: i=%d Making vector-type \n", i);
+#endif
+ /****************************************
+ * Build vector in current dimension:
+ ****************************************/
+ err = MPI_Type_vector ( (int)(d[i].count), /* count */
+ (int)(d[i].block), /* blocklength */
+ (MPI_Aint)(d[i].strid), /* stride */
+ inner_type, /* old type */
+ &outer_type ); /* new type */
+
+ MPI_Type_free( &inner_type );
+ if (err) {
+ HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't create MPI vector type");
+ }
+
+ displacement[1] = elmt_size * max_xtent[i];
+ err = MPI_Type_extent(outer_type, &extent_len);
+
+ /*************************************************
+ * Restructure this datatype ("outer_type")
+ * so that it still starts at 0, but its extent
+ * is the full extent in this dimension.
+ *************************************************/
+ if ((int)extent_len < displacement[1]) {
+
+#ifdef H5Smpi_DEBUG
+ HDfprintf(stdout, "hyper_type: i=%d Extending struct type\n"
+ "***displacements: 0, %d\n", i, displacement[1]);
+#endif
+
+#ifdef HAVE_MPI2 /* have MPI-2 */
+ err = MPI_Type_create_resized
+ ( outer_type, /* old type */
+ 0, /* blocklengths */
+ displacement[1], /* displacements */
+ &inner_type); /* new type */
+#else /* do not have MPI-2 */
+ block_length[0] = 1;
+ block_length[1] = 1;
+
+ displacement[0] = 0;
+
+ old_type[0] = outer_type;
+ old_type[1] = MPI_UB;
#ifdef H5Smpi_DEBUG
- fprintf(stdout, "hyper_type: i=%d Making struct type\n"
- "b[1]=%d d[1]=%Hu\n", i, b[1], (hsize_t)s[1] );
+ HDfprintf(stdout, "hyper_type: i=%d Extending struct type\n"
+ "***displacements: 0, %d\n", i, displacement[1]);
#endif
- err = MPI_Type_struct( 2, b, s, t, &inner_type/*becomes outer*/ );
- MPI_Type_free( &outer_type ); /* no longer needed */
- if (err) {
- HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't create MPI struct type");
- }
- } /* end else */
- /* at this point, inner_type is actually the outermost type */
+ err = MPI_Type_struct ( 2, /* count */
+ block_length, /* blocklengths */
+ displacement, /* displacements */
+ old_type, /* old types */
+ &inner_type); /* new type */
+#endif
+
+ MPI_Type_free (&outer_type);
+ if (err) {
+ HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't resize MPI vector type");
+ }
+ }
+ else {
+ inner_type = outer_type;
+ }
} /* end for */
+/***************************
+* End of loop, walking
+* thru dimensions.
+***************************/
+
+
+ /* At this point inner_type is actually the outermost type, even for 0-trip loop */
+
+/***************************************************************
+* Final task: create a struct which is a "clone" of the
+* current struct, but displaced according to the d[i].start
+* values given in the hyperslab description:
+***************************************************************/
+ displacement[0] = 0;
+ for (i=new_rank-1; i>=0; i--)
+ displacement[0] += d[i].start * offset[i];
+
+ if (displacement[0] > 0) {
+ displacement[0] *= elmt_size;
+ block_length[0] = 1;
+ old_type[0] = inner_type;
+
+#ifdef H5Smpi_DEBUG
+ HDfprintf(stdout, "hyper_type: Making final struct\n"
+ "***count=1:\n");
+ HDfprintf(stdout, "\tblocklength[0]=%d; displacement[0]=%d\n",
+ block_length[0], displacement[0]);
+#endif
+
+ err = MPI_Type_struct( 1, /* count */
+ block_length, /* blocklengths */
+ displacement, /* displacements */
+ old_type, /* old type */
+ new_type ); /* new type */
+
+ if (err) {
+ HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't create MPI struct type");
+ }
+ }
+ else {
+ *new_type = inner_type;
+ }
- /* here inner_type is actually the outermost type, even for 0-trip loop */
- *new_type = inner_type; /* return the just-constructed type */
err = MPI_Type_commit( new_type );
if (err) {
HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't commit MPI vector type");
@@ -340,6 +404,7 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size,
#endif
FUNC_LEAVE (SUCCEED);
} /* H5S_mpio_hyper_type() */
+
/*-------------------------------------------------------------------------
* Function: H5S_mpio_space_type