summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-19 05:05:45 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-19 05:05:45 (GMT)
commitf82774c0d5a59c8ff48c91bd1339eb13605b2b87 (patch)
tree68289ae6df66d56f69371c6c540de2050abaa431 /src
parent075f618e23fdfefb104e6df289a010a884aa5a02 (diff)
downloadhdf5-f82774c0d5a59c8ff48c91bd1339eb13605b2b87.zip
hdf5-f82774c0d5a59c8ff48c91bd1339eb13605b2b87.tar.gz
hdf5-f82774c0d5a59c8ff48c91bd1339eb13605b2b87.tar.bz2
[svn-r19092] Description:
Bring "shape same" changes from LBL branch to trunk. These changes allow shapes that are the same, but projected into dataspaces with different ranks to be detected correctly, and also contains code to project a dataspace into greater/lesser number of dimensions, so the I/O can proceed in a faster way. These changes also contain several bug fixes and _lots_ of code cleanups to the MPI datatype creation code. Many other misc. code cleanup are included as well... Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.3 (amazon) in debug mode Mac OS X/32 10.6.3 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src')
-rw-r--r--src/H5Dchunk.c3
-rw-r--r--src/H5Dio.c98
-rw-r--r--src/H5Dmpio.c124
-rw-r--r--src/H5Sall.c99
-rw-r--r--src/H5Shyper.c828
-rw-r--r--src/H5Smpio.c627
-rw-r--r--src/H5Snone.c254
-rw-r--r--src/H5Spkg.h6
-rw-r--r--src/H5Spoint.c181
-rw-r--r--src/H5Sprivate.h21
-rw-r--r--src/H5Sselect.c740
11 files changed, 2058 insertions, 923 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index a28bce9..88c4ab9 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -2665,7 +2665,6 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache*/
H5D_rdcc_ent_t *ent = NULL; /*cache entry */
- hbool_t found = FALSE; /*already in cache? */
haddr_t chunk_addr = HADDR_UNDEF; /* Address of chunk on disk */
size_t chunk_size; /*size of a chunk */
void *chunk = NULL; /*the file chunk */
@@ -2797,7 +2796,7 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
rdcc->stats.ninits++;
} /* end else */
} /* end else */
- HDassert(found || chunk_size > 0);
+ HDassert(chunk_size > 0);
if(ent) {
/*
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 285451e..b7c2ecb 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -291,6 +291,19 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_type_info_t type_info; /* Datatype info for operation */
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
+ H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
+ /* projection of the supplied mem_space to a new */
+ /* data space with rank equal to that of */
+ /* file_space. */
+ /* */
+ /* This field is only used if */
+ /* H5S_select_shape_same() returns TRUE when */
+ /* comparing the mem_space and the data_space, */
+ /* and the mem_space have different rank. */
+ /* */
+ /* Note that if this variable is used, the */
+ /* projected mem space must be discarded at the */
+ /* end of the function to avoid a memory leak. */
H5D_storage_t store; /*union of EFL and chunk pointer in file space */
hssize_t snelmts; /*total number of elmts (signed) */
hsize_t nelmts; /*total number of elmts */
@@ -340,6 +353,37 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
if(!(H5S_has_extent(mem_space)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
+ /* H5S_select_shape_same() has been modified to accept topologically identical
+ * selections with different rank as having the same shape (if the most
+ * rapidly changing coordinates match up), but the I/O code still has
+ * difficulties with the notion.
+ *
+ * To solve this, we check to see if H5S_select_shape_same() returns true,
+ * and if the ranks of the mem and file spaces are different. If the are,
+ * construct a new mem space that is equivalent to the old mem space, and
+ * use that instead.
+ *
+ * Note that in general, this requires us to touch up the memory buffer as
+ * well.
+ */
+ if(TRUE == H5S_select_shape_same(mem_space, file_space) &&
+ H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) {
+ void *adj_buf = NULL; /* Pointer to the location in buf corresponding */
+ /* to the beginning of the projected mem space. */
+
+ /* Attempt to construct projected dataspace for memory dataspace */
+ if(H5S_select_construct_projection(mem_space, &projected_mem_space,
+ (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.dst_type_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
+ HDassert(projected_mem_space);
+ HDassert(adj_buf);
+
+ /* Switch to using projected memory dataspace & adjusted buffer */
+ mem_space = projected_mem_space;
+ buf = adj_buf;
+ } /* end if */
+
+
/* Retrieve dataset properties */
/* <none needed in the general case> */
@@ -417,6 +461,11 @@ done:
if(type_info_init && H5D_typeinfo_term(&type_info) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info")
+ /* discard projected mem space if it was created */
+ if(NULL != projected_mem_space)
+ if(H5S_close(projected_mem_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace")
+
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5D_read() */
@@ -442,6 +491,19 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
H5D_io_info_t io_info; /* Dataset I/O info */
H5D_type_info_t type_info; /* Datatype info for operation */
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
+ H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
+ /* projection of the supplied mem_space to a new */
+ /* data space with rank equal to that of */
+ /* file_space. */
+ /* */
+ /* This field is only used if */
+ /* H5S_select_shape_same() returns TRUE when */
+ /* comparing the mem_space and the data_space, */
+ /* and the mem_space have different rank. */
+ /* */
+ /* Note that if this variable is used, the */
+ /* projected mem space must be discarded at the */
+ /* end of the function to avoid a memory leak. */
H5D_storage_t store; /*union of EFL and chunk pointer in file space */
hssize_t snelmts; /*total number of elmts (signed) */
hsize_t nelmts; /*total number of elmts */
@@ -515,6 +577,37 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
file_space = dataset->shared->space;
if(!mem_space)
mem_space = file_space;
+
+ /* H5S_select_shape_same() has been modified to accept topologically
+ * identical selections with different rank as having the same shape
+ * (if the most rapidly changing coordinates match up), but the I/O
+ * code still has difficulties with the notion.
+ *
+ * To solve this, we check to see if H5S_select_shape_same() returns
+ * true, and if the ranks of the mem and file spaces are different.
+ * If the are, construct a new mem space that is equivalent to the
+ * old mem space, and use that instead.
+ *
+ * Note that in general, this requires us to touch up the memory buffer
+ * as well.
+ */
+ if(TRUE == H5S_select_shape_same(mem_space, file_space) &&
+ H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) {
+ void *adj_buf = NULL; /* Pointer to the location in buf corresponding */
+ /* to the beginning of the projected mem space. */
+
+ /* Attempt to construct projected dataspace for memory dataspace */
+ if(H5S_select_construct_projection(mem_space, &projected_mem_space,
+ (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, &adj_buf, type_info.src_type_size) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
+ HDassert(projected_mem_space);
+ HDassert(adj_buf);
+
+ /* Switch to using projected memory dataspace & adjusted buffer */
+ mem_space = projected_mem_space;
+ buf = adj_buf;
+ } /* end if */
+
if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t);
@@ -608,6 +701,11 @@ done:
if(type_info_init && H5D_typeinfo_term(&type_info) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info")
+ /* discard projected mem space if it was created */
+ if(NULL != projected_mem_space)
+ if(H5S_close(projected_mem_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace")
+
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5D_write() */
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index ad9b737..e646a7b 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -115,7 +115,7 @@ static herr_t H5D_inter_collective_io(H5D_io_info_t *io_info,
const H5D_type_info_t *type_info, const H5S_t *file_space,
const H5S_t *mem_space);
static herr_t H5D_final_collective_io(H5D_io_info_t *io_info,
- const H5D_type_info_t *type_info, size_t nelmts, MPI_Datatype *mpi_file_type,
+ const H5D_type_info_t *type_info, hsize_t nelmts, MPI_Datatype *mpi_file_type,
MPI_Datatype *mpi_buf_type);
#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
static herr_t H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
@@ -819,10 +819,10 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
H5D_chunk_map_t *fm, int sum_chunk)
{
H5D_chunk_addr_info_t *chunk_addr_info_array = NULL;
- hbool_t mbt_is_derived = FALSE;
- hbool_t mft_is_derived = FALSE;
MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with seletion */
+ hbool_t chunk_final_mtype_is_derived = FALSE;
MPI_Datatype chunk_final_ftype; /* Final file MPI datatype for all chunks with seletion */
+ hbool_t chunk_final_ftype_is_derived = FALSE;
H5D_storage_t ctg_store; /* Storage info for "fake" contiguous dataset */
size_t total_chunks;
haddr_t *total_chunk_addr_array = NULL;
@@ -830,7 +830,10 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
MPI_Datatype *chunk_ftype = NULL;
MPI_Aint *chunk_disp_array = NULL;
MPI_Aint *chunk_mem_disp_array = NULL;
- int *blocklen = NULL;
+ hbool_t *chunk_mft_is_derived_array = NULL; /* Flags to indicate each chunk's MPI file datatype is derived */
+ hbool_t *chunk_mbt_is_derived_array = NULL; /* Flags to indicate each chunk's MPI memory datatype is derived */
+ int *chunk_mpi_file_counts = NULL; /* Count of MPI file datatype for each chunk */
+ int *chunk_mpi_mem_counts = NULL; /* Count of MPI memory datatype for each chunk */
int mpi_code; /* MPI return code */
herr_t ret_value = SUCCEED;
@@ -897,7 +900,7 @@ if(H5DEBUG(D))
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
} /* end if */
else {
- size_t mpi_buf_count; /* Number of MPI types */
+ hsize_t mpi_buf_count; /* Number of MPI types */
size_t num_chunk; /* Number of chunks for this process */
size_t u; /* Local index variable */
@@ -912,21 +915,25 @@ if(H5DEBUG(D))
/* Set up MPI datatype for chunks selected */
if(num_chunk) {
- hsize_t mpi_mem_extra_offset; /* Extra offset for memory MPI datatype */
- hsize_t mpi_file_extra_offset; /* Extra offset for file MPI datatype */
- size_t mpi_mem_count; /* Memory MPI datatype count */
- size_t mpi_file_count; /* File MPI datatype count */
- hbool_t locl_mbt_is_derived = FALSE, /* Whether the buffer (memory) type is derived and needs to be free'd */
- local_mft_is_derived = FALSE; /* Whether the file type is derived and needs to be free'd */
- int blocklen_value; /* Placeholder for array fill */
-
/* Allocate chunking information */
- chunk_addr_info_array= H5MM_malloc(num_chunk * sizeof(H5D_chunk_addr_info_t));
- chunk_mtype = H5MM_malloc(num_chunk * sizeof(MPI_Datatype));
- chunk_ftype = H5MM_malloc(num_chunk * sizeof(MPI_Datatype));
- chunk_disp_array = H5MM_malloc(num_chunk * sizeof(MPI_Aint));
- chunk_mem_disp_array = H5MM_calloc(num_chunk * sizeof(MPI_Aint));
- blocklen = H5MM_malloc(num_chunk * sizeof(int));
+ if(NULL == (chunk_addr_info_array = (H5D_chunk_addr_info_t *)H5MM_malloc(num_chunk * sizeof(H5D_chunk_addr_info_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk array buffer")
+ if(NULL == (chunk_mtype = (MPI_Datatype *)H5MM_malloc(num_chunk * sizeof(MPI_Datatype))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk memory datatype buffer")
+ if(NULL == (chunk_ftype = (MPI_Datatype *)H5MM_malloc(num_chunk * sizeof(MPI_Datatype))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file datatype buffer")
+ if(NULL == (chunk_disp_array = (MPI_Aint *)H5MM_malloc(num_chunk * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file displacement buffer")
+ if(NULL == (chunk_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_chunk * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk memory displacement buffer")
+ if(NULL == (chunk_mpi_mem_counts = (int *)H5MM_calloc(num_chunk * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk memory counts buffer")
+ if(NULL == (chunk_mpi_file_counts = (int *)H5MM_calloc(num_chunk * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file counts buffer")
+ if(NULL == (chunk_mbt_is_derived_array = (hbool_t *)H5MM_calloc(num_chunk * sizeof(hbool_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk memory is derived datatype flags buffer")
+ if(NULL == (chunk_mft_is_derived_array = (hbool_t *)H5MM_calloc(num_chunk * sizeof(hbool_t))))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file is derived datatype flags buffer")
#ifdef H5D_DEBUG
if(H5DEBUG(D))
@@ -945,14 +952,12 @@ if(H5DEBUG(D))
for(u = 0; u < num_chunk; u++) {
/* Disk MPI derived datatype */
if(H5S_mpio_space_type(chunk_addr_info_array[u].chunk_info.fspace,
- type_info->src_type_size, &chunk_ftype[u], &mpi_file_count,
- &mpi_file_extra_offset, &local_mft_is_derived) < 0)
+ type_info->src_type_size, &chunk_ftype[u], &chunk_mpi_file_counts[u], &(chunk_mft_is_derived_array[u])) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type")
/* Buffer MPI derived datatype */
if(H5S_mpio_space_type(chunk_addr_info_array[u].chunk_info.mspace,
- type_info->dst_type_size, &chunk_mtype[u], &mpi_mem_count,
- &mpi_mem_extra_offset, &locl_mbt_is_derived) < 0)
+ type_info->dst_type_size, &chunk_mtype[u], &chunk_mpi_mem_counts[u], &(chunk_mbt_is_derived_array[u])) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type")
/* Chunk address relative to the first chunk */
@@ -963,39 +968,38 @@ if(H5DEBUG(D))
chunk_disp_array[u] = (MPI_Aint)chunk_addr_info_array[u].chunk_addr;
} /* end for */
- /* Initialize the buffer with the constant value 1 */
- blocklen_value = 1;
- H5V_array_fill(blocklen, &blocklen_value, sizeof(int), num_chunk);
-
/* Create final MPI derived datatype for the file */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_struct((int)num_chunk, blocklen, chunk_disp_array, chunk_ftype, &chunk_final_ftype)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_struct((int)num_chunk, chunk_mpi_file_counts, chunk_disp_array, chunk_ftype, &chunk_final_ftype)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code)
if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&chunk_final_ftype)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ chunk_final_ftype_is_derived = TRUE;
/* Create final MPI derived datatype for memory */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_struct(num_chunk, blocklen, chunk_mem_disp_array, chunk_mtype, &chunk_final_mtype)))
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_struct((int)num_chunk, chunk_mpi_mem_counts, chunk_mem_disp_array, chunk_mtype, &chunk_final_mtype)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code)
if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&chunk_final_mtype)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ chunk_final_mtype_is_derived = TRUE;
/* Free the file & memory MPI datatypes for each chunk */
for(u = 0; u < num_chunk; u++) {
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_mtype + u)))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if(chunk_mbt_is_derived_array[u])
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_mtype + u)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_ftype + u)))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ if(chunk_mft_is_derived_array[u])
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_ftype + u)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
} /* end for */
- /* buffer, file derived datatypes should be true */
- mbt_is_derived = TRUE;
- mft_is_derived = TRUE;
- mpi_buf_count = (size_t)1;
+ /* We have a single, complicated MPI datatype for both memory & file */
+ mpi_buf_count = (hsize_t)1;
} /* end if */
else { /* no selection at all for this process */
/* Allocate chunking information */
- total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * total_chunks);
+ if(NULL == (total_chunk_addr_array = (haddr_t *)H5MM_malloc(sizeof(haddr_t) * total_chunks)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate total chunk address arraybuffer")
/* Retrieve chunk address map */
if(H5D_chunk_addrmap(io_info, total_chunk_addr_array) < 0)
@@ -1012,8 +1016,8 @@ if(H5DEBUG(D))
chunk_final_ftype = MPI_BYTE;
chunk_final_mtype = MPI_BYTE;
- /* buffer, file derived datatypes should be true */
- mpi_buf_count = (size_t)0;
+ /* No chunks selected for this process */
+ mpi_buf_count = (hsize_t)0;
} /* end else */
#ifdef H5D_DEBUG
if(H5DEBUG(D))
@@ -1033,6 +1037,7 @@ done:
if(H5DEBUG(D))
HDfprintf(H5DEBUG(D),"before freeing memory inside H5D_link_collective_io ret_value = %d\n", ret_value);
#endif
+ /* Release resources */
if(total_chunk_addr_array)
H5MM_xfree(total_chunk_addr_array);
if(chunk_addr_info_array)
@@ -1045,13 +1050,19 @@ if(H5DEBUG(D))
H5MM_xfree(chunk_disp_array);
if(chunk_mem_disp_array)
H5MM_xfree(chunk_mem_disp_array);
- if(blocklen)
- H5MM_xfree(blocklen);
+ if(chunk_mpi_mem_counts)
+ H5MM_xfree(chunk_mpi_mem_counts);
+ if(chunk_mpi_file_counts)
+ H5MM_xfree(chunk_mpi_file_counts);
+ if(chunk_mbt_is_derived_array)
+ H5MM_xfree(chunk_mbt_is_derived_array);
+ if(chunk_mft_is_derived_array)
+ H5MM_xfree(chunk_mft_is_derived_array);
/* Free the MPI buf and file types, if they were derived */
- if(mbt_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_final_mtype)))
+ if(chunk_final_mtype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_final_mtype)))
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- if(mft_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_final_ftype)))
+ if(chunk_final_ftype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&chunk_final_ftype)))
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
FUNC_LEAVE_NOAPI(ret_value)
@@ -1547,32 +1558,29 @@ static herr_t
H5D_inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
const H5S_t *file_space, const H5S_t *mem_space)
{
- size_t mpi_buf_count; /* # of MPI types */
+ int mpi_buf_count; /* # of MPI types */
hbool_t mbt_is_derived = FALSE;
hbool_t mft_is_derived = FALSE;
MPI_Datatype mpi_file_type, mpi_buf_type;
- int mpi_code; /* MPI return code */
- herr_t ret_value = SUCCEED; /* return value */
+ int mpi_code; /* MPI return code */
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_inter_collective_io)
if((file_space != NULL) && (mem_space != NULL)) {
- hsize_t mpi_buf_offset, mpi_file_offset; /* Offset within dataset where selection (ie. MPI type) begins */
- size_t mpi_file_count; /* Number of file "objects" to transfer */
+ int mpi_file_count; /* Number of file "objects" to transfer */
/* Obtain disk and memory MPI derived datatype */
- if(H5S_mpio_space_type(file_space, type_info->src_type_size,
- &mpi_file_type, &mpi_file_count, &mpi_file_offset, &mft_is_derived) < 0)
+ if(H5S_mpio_space_type(file_space, type_info->src_type_size, &mpi_file_type, &mpi_file_count, &mft_is_derived) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type")
- if(H5S_mpio_space_type(mem_space, type_info->src_type_size,
- &mpi_buf_type, &mpi_buf_count, &mpi_buf_offset, &mbt_is_derived) < 0)
+ if(H5S_mpio_space_type(mem_space, type_info->src_type_size, &mpi_buf_type, &mpi_buf_count, &mbt_is_derived) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buffer type")
} /* end if */
else {
/* For non-selection, participate with a none MPI derived datatype, the count is 0. */
mpi_buf_type = MPI_BYTE;
mpi_file_type = MPI_BYTE;
- mpi_buf_count = (size_t)0;
+ mpi_buf_count = 0;
mbt_is_derived = FALSE;
mft_is_derived = FALSE;
} /* end else */
@@ -1583,7 +1591,7 @@ if(H5DEBUG(D))
#endif
/* Perform final collective I/O operation */
- if(H5D_final_collective_io(io_info, type_info, mpi_buf_count, &mpi_file_type, &mpi_buf_type) < 0)
+ if(H5D_final_collective_io(io_info, type_info, (hsize_t)mpi_buf_count, &mpi_file_type, &mpi_buf_type) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish collective MPI-IO")
done:
@@ -1616,7 +1624,7 @@ if(H5DEBUG(D))
*/
static herr_t
H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- size_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type)
+ hsize_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type)
{
hbool_t plist_is_setup = FALSE; /* Whether the dxpl has been customized */
herr_t ret_value = SUCCEED;
@@ -1629,11 +1637,11 @@ H5D_final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info
plist_is_setup = TRUE;
if(io_info->op_type == H5D_IO_OP_WRITE) {
- if((io_info->io_ops.single_write)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_write)(io_info, type_info, mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed")
} /* end if */
else {
- if((io_info->io_ops.single_read)(io_info, type_info, (hsize_t)mpi_buf_count, NULL, NULL) < 0)
+ if((io_info->io_ops.single_read)(io_info, type_info, mpi_buf_count, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed")
} /* end else */
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 115d5d35..c98781a 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -47,6 +47,8 @@ static htri_t H5S_all_is_contiguous(const H5S_t *space);
static htri_t H5S_all_is_single(const H5S_t *space);
static htri_t H5S_all_is_regular(const H5S_t *space);
static herr_t H5S_all_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S_all_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S_all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S_all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
/* Selection iteration callbacks */
@@ -76,6 +78,8 @@ const H5S_select_class_t H5S_sel_all[1] = {{
H5S_all_is_single,
H5S_all_is_regular,
H5S_all_adjust_u,
+ H5S_all_project_scalar,
+ H5S_all_project_simple,
H5S_all_iter_init,
}};
@@ -372,18 +376,18 @@ H5S_all_iter_release (H5S_sel_iter_t UNUSED * iter)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t
-H5S_all_release (H5S_t UNUSED * space)
+static herr_t
+H5S_all_release(H5S_t *space)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5S_all_release);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_all_release)
/* Check args */
- assert (space);
+ HDassert(space);
/* Reset the number of elements in the selection */
- space->select.num_elem=0;
+ space->select.num_elem = 0;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_all_release() */
@@ -406,18 +410,18 @@ H5S_all_release (H5S_t UNUSED * space)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t
+static herr_t
H5S_all_copy(H5S_t *dst, const H5S_t UNUSED *src, hbool_t UNUSED share_selection)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5S_all_copy);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_all_copy)
- assert(src);
- assert(dst);
+ HDassert(src);
+ HDassert(dst);
/* Set number of elements in selection */
- dst->select.num_elem=(hsize_t)H5S_GET_EXTENT_NPOINTS(dst);
+ dst->select.num_elem = (hsize_t)H5S_GET_EXTENT_NPOINTS(dst);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S_all_copy() */
@@ -542,20 +546,20 @@ H5S_all_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_all_deserialize (H5S_t *space, const uint8_t UNUSED *buf)
+H5S_all_deserialize(H5S_t *space, const uint8_t UNUSED *buf)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI(H5S_all_deserialize, FAIL);
+ FUNC_ENTER_NOAPI(H5S_all_deserialize, FAIL)
- assert(space);
+ HDassert(space);
/* Change to "all" selection */
if((ret_value = H5S_select_all(space, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_all_deserialize() */
@@ -764,6 +768,69 @@ H5S_all_adjust_u(H5S_t UNUSED *space, const hsize_t UNUSED *offset)
} /* H5S_all_adjust_u() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_project_scalar
+ *
+ * Purpose: Projects a single element 'all' selection into a scalar
+ * dataspace
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_all_project_scalar(const H5S_t UNUSED *space, hsize_t *offset)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_all_project_scalar)
+
+ /* Check args */
+ HDassert(space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space));
+ HDassert(offset);
+
+ /* Set offset of selection in projected buffer */
+ *offset = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_all_project_scalar() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_all_project_simple
+ *
+ * Purpose: Projects an 'all' selection onto/into a simple dataspace
+ * of a different rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_all_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_all_project_simple)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(offset);
+
+ /* Select the entire new space */
+ if(H5S_select_all(new_space, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to set all selection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_all_project_simple() */
+
+
/*--------------------------------------------------------------------------
NAME
H5S_select_all
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 74402b1..df81275 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -33,12 +33,12 @@
/* Local datatypes */
/* Static function prototypes */
-static herr_t H5S_hyper_free_span_info (H5S_hyper_span_info_t *span_info);
-static herr_t H5S_hyper_free_span (H5S_hyper_span_t *span);
-static H5S_hyper_span_info_t *H5S_hyper_copy_span (H5S_hyper_span_info_t *spans);
-static herr_t H5S_hyper_span_scratch (H5S_hyper_span_info_t *spans, void *scr_value);
-static herr_t H5S_hyper_span_precompute (H5S_hyper_span_info_t *spans, size_t elmt_size);
-static herr_t H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op,
+static herr_t H5S_hyper_free_span_info(H5S_hyper_span_info_t *span_info);
+static herr_t H5S_hyper_free_span(H5S_hyper_span_t *span);
+static H5S_hyper_span_info_t *H5S_hyper_copy_span(H5S_hyper_span_info_t *spans);
+static void H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value);
+static herr_t H5S_hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size);
+static herr_t H5S_generate_hyperslab(H5S_t *space, H5S_seloper_t op,
const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]);
static herr_t H5S_hyper_generate_spans(H5S_t *space);
/* Needed for use in hyperslab code (H5Shyper.c) */
@@ -62,6 +62,8 @@ static htri_t H5S_hyper_is_contiguous(const H5S_t *space);
static htri_t H5S_hyper_is_single(const H5S_t *space);
static htri_t H5S_hyper_is_regular(const H5S_t *space);
static herr_t H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S_hyper_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S_hyper_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
/* Selection iteration callbacks */
@@ -96,6 +98,8 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S_hyper_is_single,
H5S_hyper_is_regular,
H5S_hyper_adjust_u,
+ H5S_hyper_project_scalar,
+ H5S_hyper_project_simple,
H5S_hyper_iter_init,
}};
@@ -292,15 +296,15 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
/* Check if the regular selection can be "flattened" */
if(cont_dim>0) {
- unsigned last_dim_flattened=1; /* Flag to indicate that the last dimension was flattened */
- unsigned flat_rank=rank-cont_dim; /* Number of dimensions after flattening */
+ unsigned last_dim_flattened = 1; /* Flag to indicate that the last dimension was flattened */
+ unsigned flat_rank = rank-cont_dim; /* Number of dimensions after flattening */
unsigned curr_dim; /* Current dimension */
/* Set the iterator's rank to the contiguous dimensions */
- iter->u.hyp.iter_rank=flat_rank;
+ iter->u.hyp.iter_rank = flat_rank;
/* "Flatten" dataspace extent and selection information */
- curr_dim=flat_rank-1;
+ curr_dim = flat_rank - 1;
for(i = (int)rank - 1, acc = 1; i >= 0; i--) {
if(tdiminfo[i].block == mem_size[i] && i > 0) {
/* "Flatten" this dimension */
@@ -308,24 +312,25 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
acc *= mem_size[i];
/* Indicate that the dimension was flattened */
- last_dim_flattened=1;
+ last_dim_flattened = 1;
} /* end if */
else {
if(last_dim_flattened) {
/* First dimension after flattened dimensions */
- iter->u.hyp.diminfo[curr_dim].start = tdiminfo[i].start*acc;
+ iter->u.hyp.diminfo[curr_dim].start = tdiminfo[i].start * acc;
+
/* Special case for single block regular selections */
if(tdiminfo[i].count==1)
iter->u.hyp.diminfo[curr_dim].stride = 1;
else
- iter->u.hyp.diminfo[curr_dim].stride = tdiminfo[i].stride*acc;
+ iter->u.hyp.diminfo[curr_dim].stride = tdiminfo[i].stride * acc;
iter->u.hyp.diminfo[curr_dim].count = tdiminfo[i].count;
- iter->u.hyp.diminfo[curr_dim].block = tdiminfo[i].block*acc;
- iter->u.hyp.size[curr_dim] = mem_size[i]*acc;
+ iter->u.hyp.diminfo[curr_dim].block = tdiminfo[i].block * acc;
+ iter->u.hyp.size[curr_dim] = mem_size[i] * acc;
iter->u.hyp.sel_off[curr_dim] = space->select.offset[i] * acc;
/* Reset the "last dim flattened" flag to avoid flattened any further dimensions */
- last_dim_flattened=0;
+ last_dim_flattened = 0;
/* Reset the "accumulator" for possible further dimension flattening */
acc=1;
@@ -596,12 +601,12 @@ static htri_t
H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *iter)
{
unsigned u; /* Local index variable */
- herr_t ret_value=FALSE; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_iter_has_next_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_iter_has_next_block)
/* Check args */
- assert (iter);
+ HDassert(iter);
/* Check for a single "regular" hyperslab */
if(iter->u.hyp.diminfo_valid) {
@@ -609,25 +614,25 @@ H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *iter)
const hsize_t *toff; /* Temporary offset in selection */
/* Check if the offset of the iterator is at the last location in all dimensions */
- tdiminfo=iter->u.hyp.diminfo;
- toff=iter->u.hyp.off;
- for(u=0; u<iter->rank; u++) {
+ tdiminfo = iter->u.hyp.diminfo;
+ toff = iter->u.hyp.off;
+ for(u = 0; u < iter->rank; u++) {
/* If there is only one block, continue */
- if(tdiminfo[u].count==1)
+ if(tdiminfo[u].count == 1)
continue;
- if(toff[u]!=(tdiminfo[u].start+((tdiminfo[u].count-1)*tdiminfo[u].stride)))
+ if(toff[u] != (tdiminfo[u].start + ((tdiminfo[u].count - 1) * tdiminfo[u].stride)))
HGOTO_DONE(TRUE);
} /* end for */
} /* end if */
else {
/* Check for any levels of the tree with more sequences in them */
- for(u=0; u<iter->rank; u++)
- if(iter->u.hyp.span[u]->next!=NULL)
+ for(u = 0; u < iter->rank; u++)
+ if(iter->u.hyp.span[u]->next != NULL)
HGOTO_DONE(TRUE);
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_iter_has_next_block() */
@@ -1089,30 +1094,30 @@ H5S_hyper_iter_release (H5S_sel_iter_t *iter)
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_hyper_span_t *
-H5S_hyper_new_span (hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next)
+H5S_hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next)
{
H5S_hyper_span_t *ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_new_span);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_new_span)
/* Allocate a new span node */
- if((ret_value = H5FL_MALLOC(H5S_hyper_span_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+ if(NULL == (ret_value = H5FL_MALLOC(H5S_hyper_span_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span")
/* Copy the span's basic information */
- ret_value->low=low;
- ret_value->high=high;
- ret_value->nelem=(high-low)+1;
- ret_value->pstride=0;
- ret_value->down=down;
- ret_value->next=next;
+ ret_value->low = low;
+ ret_value->high = high;
+ ret_value->nelem = (high - low) + 1;
+ ret_value->pstride = 0;
+ ret_value->down = down;
+ ret_value->next = next;
/* Increment the reference count of the 'down span' if there is one */
- if(ret_value->down!=NULL)
+ if(ret_value->down)
ret_value->down->count++;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_new_span() */
@@ -1195,24 +1200,23 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_span_precompute (H5S_hyper_span_info_t *spans, size_t elmt_size)
+H5S_hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_span_precompute);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_span_precompute)
- assert(spans);
+ HDassert(spans);
/* Call the helper routine to actually do the work */
- if(H5S_hyper_span_precompute_helper(spans,elmt_size)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't precompute span info");
+ if(H5S_hyper_span_precompute_helper(spans, elmt_size) < 0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't precompute span info")
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(spans,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ H5S_hyper_span_scratch(spans, NULL);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_span_precompute() */
@@ -1222,10 +1226,10 @@ done:
PURPOSE
Set the scratch pointers on hyperslab span trees
USAGE
- herr_t H5S_hyper_span_scratch(span_info)
+ void H5S_hyper_span_scratch(span_info)
H5S_hyper_span_info_t *span_info; IN: Span tree to reset
RETURNS
- Non-negative on success, negative on failure
+ <none>
DESCRIPTION
Set the scratch pointers on a hyperslab span tree.
GLOBAL VARIABLES
@@ -1233,37 +1237,33 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static herr_t
-H5S_hyper_span_scratch (H5S_hyper_span_info_t *spans, void *scr_value)
+static void
+H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value)
{
- H5S_hyper_span_t *span; /* Hyperslab span */
- herr_t ret_value=SUCCEED; /* Return value */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_span_scratch)
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_span_scratch);
-
- assert(spans);
+ HDassert(spans);
/* Check if we've already set this down span tree */
- if(spans->scratch!=scr_value) {
+ if(spans->scratch != scr_value) {
+ H5S_hyper_span_t *span; /* Hyperslab span */
+
/* Set the tree's scratch pointer */
spans->scratch = (H5S_hyper_span_info_t *)scr_value;
/* Set the scratch pointers in all the nodes */
- span=spans->head;
- while(span!=NULL) {
+ span = spans->head;
+ while(span != NULL) {
/* If there are down spans, set their scratch value also */
- if(span->down!=NULL) {
- if(H5S_hyper_span_scratch(span->down,scr_value)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
- } /* end if */
+ if(span->down != NULL)
+ H5S_hyper_span_scratch(span->down, scr_value);
/* Advance to next span */
- span=span->next;
+ span = span->next;
} /* end while */
} /* end if */
-done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI_VOID
} /* H5S_hyper_span_scratch() */
@@ -1293,65 +1293,65 @@ H5S_hyper_copy_span_helper (H5S_hyper_span_info_t *spans)
H5S_hyper_span_info_t *new_down; /* New down span tree */
H5S_hyper_span_info_t *ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_copy_span_helper);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_copy_span_helper)
- assert(spans);
+ HDassert(spans);
/* Check if the span tree was already copied */
- if(spans->scratch!=NULL && spans->scratch!=(H5S_hyper_span_info_t *)~((size_t)NULL)) {
+ if(spans->scratch != NULL && spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) {
/* Just return the value of the already copied span tree */
- ret_value=spans->scratch;
+ ret_value = spans->scratch;
/* Increment the reference count of the span tree */
ret_value->count++;
} /* end if */
else {
/* Allocate a new span_info node */
- if((ret_value = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+ if(NULL == (ret_value = H5FL_MALLOC(H5S_hyper_span_info_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info")
/* Copy the span_info information */
- ret_value->count=1;
- ret_value->scratch=NULL;
- ret_value->head=NULL;
+ ret_value->count = 1;
+ ret_value->scratch = NULL;
+ ret_value->head = NULL;
/* Set the scratch pointer in the node being copied to the newly allocated node */
- spans->scratch=ret_value;
+ spans->scratch = ret_value;
/* Copy over the nodes in the span list */
- span=spans->head;
- prev_span=NULL;
- while(span!=NULL) {
+ span = spans->head;
+ prev_span = NULL;
+ while(span != NULL) {
/* Allocate a new node */
- if((new_span = H5S_hyper_new_span(span->low,span->high,NULL,NULL))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+ if(NULL == (new_span = H5S_hyper_new_span(span->low, span->high, NULL, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span")
/* Append to list of spans */
- if(prev_span==NULL)
- ret_value->head=new_span;
+ if(NULL == prev_span)
+ ret_value->head = new_span;
else
- prev_span->next=new_span;
+ prev_span->next = new_span;
/* Copy the pstride */
- new_span->pstride=span->pstride;
+ new_span->pstride = span->pstride;
/* Recurse to copy the 'down' spans, if there are any */
- if(span->down!=NULL) {
- if((new_down = H5S_hyper_copy_span_helper(span->down))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
- new_span->down=new_down;
+ if(span->down != NULL) {
+ if(NULL == (new_down = H5S_hyper_copy_span_helper(span->down)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy hyperslab spans")
+ new_span->down = new_down;
} /* end if */
/* Update the previous (new) span */
- prev_span=new_span;
+ prev_span = new_span;
/* Advance to next span */
- span=span->next;
+ span = span->next;
} /* end while */
} /* end else */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_copy_span_helper() */
@@ -1375,23 +1375,23 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_hyper_span_info_t *
-H5S_hyper_copy_span (H5S_hyper_span_info_t *spans)
+H5S_hyper_copy_span(H5S_hyper_span_info_t *spans)
{
H5S_hyper_span_info_t *ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_copy_span);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_copy_span)
- assert(spans);
+ HDassert(spans);
/* Copy the hyperslab span tree */
- ret_value=H5S_hyper_copy_span_helper(spans);
+ if(NULL == (ret_value = H5S_hyper_copy_span_helper(spans)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(spans,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "can't reset span tree scratch pointers");
+ H5S_hyper_span_scratch(spans, NULL);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_copy_span() */
@@ -1630,7 +1630,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
assert(dst);
/* Allocate space for the hyperslab selection information */
- if((dst->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL)
+ if(NULL == (dst->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info");
/* Set temporary pointers */
@@ -1658,7 +1658,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
} /* end if */
else
/* Copy the hyperslab span information */
- dst->select.sel_info.hslab->span_lst=H5S_hyper_copy_span(src->select.sel_info.hslab->span_lst);
+ dst->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(src->select.sel_info.hslab->span_lst);
} /* end if */
done:
@@ -2331,44 +2331,44 @@ H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
hsize_t u; /* Index variable */
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_span_blocklist);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_span_blocklist)
/* Sanity checks */
- assert(spans);
- assert(rank<H5O_LAYOUT_NDIMS);
- assert(start);
- assert(end);
- assert(startblock);
- assert(numblocks && *numblocks>0);
- assert(buf && *buf);
+ HDassert(spans);
+ HDassert(rank < H5O_LAYOUT_NDIMS);
+ HDassert(start);
+ HDassert(end);
+ HDassert(startblock);
+ HDassert(numblocks && *numblocks > 0);
+ HDassert(buf && *buf);
/* Walk through the list of spans, recursing or outputing them */
- curr=spans->head;
- while(curr!=NULL && *numblocks>0) {
+ curr = spans->head;
+ while(curr != NULL && *numblocks > 0) {
/* Recurse if this node has down spans */
- if(curr->down!=NULL) {
+ if(curr->down != NULL) {
/* Add the starting and ending points for this span to the list */
- start[rank]=curr->low;
- end[rank]=curr->high;
+ start[rank] = curr->low;
+ end[rank] = curr->high;
/* Recurse down to the next dimension */
- if(H5S_hyper_span_blocklist(curr->down,start,end,rank+1,startblock,numblocks,buf)<0)
+ if(H5S_hyper_span_blocklist(curr->down, start, end, (rank + 1), startblock, numblocks, buf) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans");
} /* end if */
else {
/* Skip this block if we haven't skipped all the startblocks yet */
- if(*startblock>0) {
+ if(*startblock > 0) {
/* Decrement the starting block */
(*startblock)--;
- }
+ } /* end if */
/* Process this block */
else {
/* Encode all the previous dimensions starting & ending points */
/* Copy previous starting points */
- for(u=0; u<rank; u++, (*buf)++)
+ for(u = 0; u < rank; u++, (*buf)++)
HDmemcpy(*buf, &start[u], sizeof(hsize_t));
/* Copy starting point for this span */
@@ -2376,7 +2376,7 @@ H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t
(*buf)++;
/* Copy previous ending points */
- for(u=0; u<rank; u++, (*buf)++)
+ for(u = 0; u < rank; u++, (*buf)++)
HDmemcpy(*buf, &end[u], sizeof(hsize_t));
/* Copy starting point for this span */
@@ -2389,11 +2389,11 @@ H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t
} /* end else */
/* Advance to next node */
- curr=curr->next;
+ curr = curr->next;
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_span_blocklist() */
@@ -2430,29 +2430,26 @@ done:
static herr_t
H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
{
- H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
- hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
- hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */
- hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */
- hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */
- hsize_t temp_off; /* Offset in a given dimension */
- int i; /* Counter */
- int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
- int temp_dim; /* Temporary rank holder */
- int ndims; /* Rank of the dataspace */
- int done; /* Whether we are done with the iteration */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_hyper_blocklist);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_get_select_hyper_blocklist)
- assert(space);
- assert(buf);
+ HDassert(space);
+ HDassert(buf);
/* Check for a "regular" hyperslab selection */
if(space->select.sel_info.hslab->diminfo_valid) {
+ const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
+ hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */
+ unsigned fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ unsigned ndims; /* Rank of the dataspace */
+ hbool_t done; /* Whether we are done with the iteration */
+ unsigned u; /* Counter */
+
/* Set some convienence values */
- ndims=space->extent.rank;
- fast_dim=ndims-1;
+ ndims = space->extent.rank;
+ fast_dim = ndims - 1;
/* Check which set of dimension information to use */
if(internal)
@@ -2460,39 +2457,41 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
* Use the "optimized dimension information" to pass back information
* on the blocks set, not the "application information".
*/
- diminfo=space->select.sel_info.hslab->opt_diminfo;
+ diminfo = space->select.sel_info.hslab->opt_diminfo;
else
/*
* Use the "application dimension information" to pass back to the user
* the blocks they set, not the optimized, internal information.
*/
- diminfo=space->select.sel_info.hslab->app_diminfo;
+ diminfo = space->select.sel_info.hslab->app_diminfo;
/* Build the tables of count sizes as well as the initial offset */
- for(i=0; i<ndims; i++) {
- tmp_count[i]=diminfo[i].count;
- offset[i]=diminfo[i].start;
+ for(u = 0; u < ndims; u++) {
+ tmp_count[u] = diminfo[u].count;
+ offset[u] = diminfo[u].start;
} /* end for */
/* We're not done with the iteration */
- done=0;
+ done = FALSE;
/* Go iterate over the hyperslabs */
- while(done==0 && numblocks>0) {
+ while(!done && numblocks > 0) {
+ hsize_t temp_off; /* Offset in a given dimension */
+
/* Iterate over the blocks in the fastest dimension */
- while(tmp_count[fast_dim]>0 && numblocks>0) {
+ while(tmp_count[fast_dim] > 0 && numblocks > 0) {
/* Check if we should copy this block information */
- if(startblock==0) {
+ if(startblock == 0) {
/* Copy the starting location */
- HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
- buf+=ndims;
+ HDmemcpy(buf, offset, sizeof(hsize_t) * ndims);
+ buf += ndims;
/* Compute the ending location */
- HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
- for(i=0; i<ndims; i++)
- buf[i]+=(diminfo[i].block-1);
- buf+=ndims;
+ HDmemcpy(buf, offset, sizeof(hsize_t) * ndims);
+ for(u = 0; u < ndims; u++)
+ buf[u] += (diminfo[u].block - 1);
+ buf += ndims;
/* Decrement the number of blocks to retrieve */
numblocks--;
@@ -2501,33 +2500,35 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
startblock--;
/* Move the offset to the next sequence to start */
- offset[fast_dim]+=diminfo[fast_dim].stride;
+ offset[fast_dim] += diminfo[fast_dim].stride;
/* Decrement the block count */
tmp_count[fast_dim]--;
} /* end while */
/* Work on other dimensions if necessary */
- if(fast_dim>0 && numblocks>0) {
+ if(fast_dim > 0 && numblocks > 0) {
+ int temp_dim; /* Temporary rank holder */
+
/* Reset the block counts */
- tmp_count[fast_dim]=diminfo[fast_dim].count;
+ tmp_count[fast_dim] = diminfo[fast_dim].count;
/* Bubble up the decrement to the slower changing dimensions */
- temp_dim=fast_dim-1;
- while(temp_dim>=0 && done==0) {
+ temp_dim = (int)(fast_dim - 1);
+ while(temp_dim >= 0 && !done) {
/* Decrement the block count */
tmp_count[temp_dim]--;
/* Check if we have more blocks left */
- if(tmp_count[temp_dim]>0)
+ if(tmp_count[temp_dim] > 0)
break;
/* Check for getting out of iterator */
- if(temp_dim==0)
- done=1;
+ if(temp_dim == 0)
+ done = TRUE;
/* Reset the block count in this dimension */
- tmp_count[temp_dim]=diminfo[temp_dim].count;
+ tmp_count[temp_dim] = diminfo[temp_dim].count;
/* Wrapped a dimension, go up to next dimension */
temp_dim--;
@@ -2535,16 +2536,20 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
} /* end if */
/* Re-compute offset array */
- for(i=0; i<ndims; i++) {
- temp_off=diminfo[i].start+diminfo[i].stride*(diminfo[i].count-tmp_count[i]);
- offset[i]=temp_off;
+ for(u = 0; u < ndims; u++) {
+ temp_off = diminfo[u].start + diminfo[u].stride * (diminfo[u].count - tmp_count[u]);
+ offset[u] = temp_off;
} /* end for */
} /* end while */
} /* end if */
- else
- ret_value=H5S_hyper_span_blocklist(space->select.sel_info.hslab->span_lst,start,end,(hsize_t)0,&startblock,&numblocks,&buf);
+ else {
+ hsize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */
+ hsize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */
- FUNC_LEAVE_NOAPI(ret_value);
+ ret_value = H5S_hyper_span_blocklist(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &startblock, &numblocks, &buf);
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_get_select_hyper_blocklist() */
@@ -2636,40 +2641,40 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end)
+H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end)
{
- H5S_hyper_span_t *curr; /* Hyperslab information nodes */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5S_hyper_span_t *curr; /* Hyperslab information nodes */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_bounds_helper)
- assert(spans);
- assert(offset);
- assert(rank<H5O_LAYOUT_NDIMS);
- assert(start);
- assert(end);
+ HDassert(spans);
+ HDassert(offset);
+ HDassert(rank < H5O_LAYOUT_NDIMS);
+ HDassert(start);
+ HDassert(end);
/* Check each point to determine whether selection+offset is within extent */
curr=spans->head;
while(curr!=NULL) {
/* Check for offset moving selection negative */
- if(((hssize_t)curr->low+offset[rank])<0)
+ if(((hssize_t)curr->low + offset[rank]) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
/* Check if the current span extends the bounding box */
- if((curr->low+offset[rank])<start[rank])
- start[rank]=curr->low+offset[rank];
- if((curr->high+offset[rank])>end[rank])
- end[rank]=curr->high+offset[rank];
+ if((curr->low + offset[rank]) < start[rank])
+ start[rank] = curr->low + offset[rank];
+ if((curr->high + offset[rank]) > end[rank])
+ end[rank] = curr->high + offset[rank];
/* Recurse if this node has down spans */
- if(curr->down!=NULL) {
- if(H5S_hyper_bounds_helper(curr->down,offset,rank+1,start,end)<0)
+ if(curr->down != NULL) {
+ if(H5S_hyper_bounds_helper(curr->down, offset, (rank + 1), start, end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "failure in lower dimension")
} /* end if */
/* Advance to next node */
- curr=curr->next;
+ curr = curr->next;
} /* end while */
done:
@@ -3609,20 +3614,16 @@ done:
herr_t
H5S_hyper_reset_scratch(H5S_t *space)
{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_reset_scratch);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_reset_scratch)
- assert(space);
+ HDassert(space);
/* Check if there are spans in the span tree */
- if(space->select.sel_info.hslab->span_lst!=NULL)
+ if(space->select.sel_info.hslab->span_lst != NULL)
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset span tree scratch pointers");
+ H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
-done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_hyper_reset_scratch() */
@@ -3685,6 +3686,8 @@ H5S_hyper_convert(H5S_t *space)
case H5S_SEL_NONE: /* No elements selected in dataspace */
case H5S_SEL_POINTS: /* Point selection */
+ case H5S_SEL_ERROR: /* Selection error */
+ case H5S_SEL_N: /* Selection count */
default:
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "can't convert to span tree selection");
} /* end switch */
@@ -4033,8 +4036,7 @@ H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset adjustment");
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
} /* end if */
done:
@@ -4042,6 +4044,357 @@ done:
} /* H5S_hyper_adjust_u() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_project_scalar
+ *
+ * Purpose: Projects a single element hyperslab selection into a scalar
+ * dataspace
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_project_scalar(const H5S_t *space, hsize_t *offset)
+{
+ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_project_scalar)
+
+ /* Check args */
+ HDassert(space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(space));
+ HDassert(offset);
+
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab->diminfo_valid) {
+ const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */
+ unsigned u; /* Counter */
+
+ /* Build the table of the initial offset */
+ for(u = 0; u < space->extent.rank; u++) {
+ block[u] = diminfo[u].start;
+
+ /* Check for more than one hyperslab */
+ if(diminfo[u].count > 1 || diminfo[u].block > 1)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "hyperslab selection of one element has more than one node!")
+ } /* end for */
+ } /* end if */
+ else {
+ const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
+ unsigned curr_dim; /* Current dimension being operated on */
+
+ /* Advance down selected spans */
+ curr = space->select.sel_info.hslab->span_lst->head;
+ curr_dim = 0;
+ while(curr) {
+ /* Check for more than one span */
+ if(curr->next || curr->low != curr->high)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "hyperslab selection of one element has more than one node!")
+
+ /* Save the location of the selection in current dimension */
+ block[curr_dim] = curr->low;
+
+ /* Advance down to next dimension */
+ curr = curr->down->head;
+ curr_dim++;
+ } /* end while */
+ } /* end else */
+
+ /* Calculate offset of selection in projected buffer */
+ *offset = H5V_array_offset(space->extent.rank, space->extent.size, block);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_project_scalar() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_project_simple_lower
+ *
+ * Purpose: Projects a hyperslab selection onto/into a simple dataspace
+ * of a lower rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space)
+{
+ H5S_hyper_span_info_t *down; /* Pointer to list of spans */
+ unsigned curr_dim; /* Current dimension being operated on */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_project_simple_lower)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(new_space->extent.rank < base_space->extent.rank);
+
+ /* Walk down the span tree until we reach the selection to project */
+ down = base_space->select.sel_info.hslab->span_lst;
+ curr_dim = 0;
+ while(down && curr_dim < (base_space->extent.rank - new_space->extent.rank)) {
+ /* Sanity check */
+ HDassert(NULL == down->head->next);
+
+ /* Advance down to next dimension */
+ down = down->head->down;
+ curr_dim++;
+ } /* end while */
+ HDassert(down);
+
+ /* Share the underlying hyperslab span information */
+ new_space->select.sel_info.hslab->span_lst = down;
+ new_space->select.sel_info.hslab->span_lst->count++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_hyper_project_simple_lower() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_project_simple_higher
+ *
+ * Purpose: Projects a hyperslab selection onto/into a simple dataspace
+ * of a higher rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
+{
+ H5S_hyper_span_t *prev_span = NULL; /* Pointer to previous list of spans */
+ unsigned curr_dim; /* Current dimension being operated on */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_project_simple_higher)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(new_space->extent.rank > base_space->extent.rank);
+
+ /* Create nodes until reaching the correct # of dimensions */
+ new_space->select.sel_info.hslab->span_lst = NULL;
+ curr_dim = 0;
+ while(curr_dim < (new_space->extent.rank - base_space->extent.rank)) {
+ H5S_hyper_span_info_t *new_span_info; /* Pointer to list of spans */
+ H5S_hyper_span_t *new_span; /* Temporary hyperslab span */
+
+ /* Allocate a new span_info node */
+ if(NULL == (new_span_info = H5FL_MALLOC(H5S_hyper_span_info_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span info")
+
+ /* Check for linking into higher span */
+ if(prev_span)
+ prev_span->down = new_span_info;
+
+ /* Allocate a new node */
+ if(NULL == (new_span = H5S_hyper_new_span(0, 0, NULL, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate hyperslab span")
+
+ /* Set the span_info information */
+ new_span_info->count = 1;
+ new_span_info->scratch = NULL;
+ new_span_info->head = new_span;
+
+ /* Attach to new space, if top span info */
+ if(NULL == new_space->select.sel_info.hslab->span_lst)
+ new_space->select.sel_info.hslab->span_lst = new_span_info;
+
+ /* Remember previous span info */
+ prev_span = new_span;
+
+ /* Advance to next dimension */
+ curr_dim++;
+ } /* end while */
+ HDassert(new_space->select.sel_info.hslab->span_lst);
+ HDassert(prev_span);
+
+ /* Share the underlying hyperslab span information */
+ prev_span->down = base_space->select.sel_info.hslab->span_lst;
+ prev_span->down->count++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_project_simple_higher() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_project_simple
+ *
+ * Purpose: Projects a hyperslab selection onto/into a simple dataspace
+ * of a different rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_project_simple)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_HYPERSLABS == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(offset);
+
+ /* We are setting a new selection, remove any current selection in new dataspace */
+ if(H5S_SELECT_RELEASE(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+
+ /* Allocate space for the hyperslab selection information */
+ if(NULL == (new_space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
+
+ /* Check for a "regular" hyperslab selection */
+ if(base_space->select.sel_info.hslab->diminfo_valid) {
+ unsigned base_space_dim; /* Current dimension in the base dataspace */
+ unsigned new_space_dim; /* Current dimension in the new dataspace */
+
+ /* Check if the new space's rank is < or > base space's rank */
+ if(new_space->extent.rank < base_space->extent.rank) {
+ const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+ unsigned u; /* Local index variable */
+
+ /* Compute the offset for the down-projection */
+ HDmemset(block, 0, sizeof(block));
+ for(u = 0; u < (base_space->extent.rank - new_space->extent.rank); u++)
+ block[u] = opt_diminfo[u].start;
+ *offset = H5V_array_offset(base_space->extent.rank, base_space->extent.size, block);
+
+ /* Set the correct dimensions for the base & new spaces */
+ base_space_dim = base_space->extent.rank - new_space->extent.rank;
+ new_space_dim = 0;
+ } /* end if */
+ else {
+ HDassert(new_space->extent.rank > base_space->extent.rank);
+
+ /* The offset is zero when projected into higher dimensions */
+ *offset = 0;
+
+ /* Set the diminfo information for the higher dimensions */
+ for(new_space_dim = 0; new_space_dim < (new_space->extent.rank - base_space->extent.rank); new_space_dim++) {
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start = 0;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride = 1;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count = 1;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block = 1;
+
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start = 0;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride = 1;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count = 1;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block = 1;
+ } /* end for */
+
+ /* Start at beginning of base space's dimension info */
+ base_space_dim = 0;
+ } /* end else */
+
+ /* Copy the diminfo */
+ while(base_space_dim < base_space->extent.rank) {
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start =
+ base_space->select.sel_info.hslab->app_diminfo[base_space_dim].start;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride =
+ base_space->select.sel_info.hslab->app_diminfo[base_space_dim].stride;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count =
+ base_space->select.sel_info.hslab->app_diminfo[base_space_dim].count;
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block =
+ base_space->select.sel_info.hslab->app_diminfo[base_space_dim].block;
+
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start =
+ base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].start;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride =
+ base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].stride;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count =
+ base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].count;
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block =
+ base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].block;
+
+ /* Advance to next dimensions */
+ base_space_dim++;
+ new_space_dim++;
+ } /* end for */
+
+ /* Indicate that the dimension information is valid */
+ new_space->select.sel_info.hslab->diminfo_valid = TRUE;
+
+ /* Indicate that there's no slab information */
+ new_space->select.sel_info.hslab->span_lst = NULL;
+ } /* end if */
+ else {
+ /* Check if the new space's rank is < or > base space's rank */
+ if(new_space->extent.rank < base_space->extent.rank) {
+ const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
+ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+ unsigned curr_dim; /* Current dimension being operated on */
+
+ /* Clear the block buffer */
+ HDmemset(block, 0, sizeof(block));
+
+ /* Advance down selected spans */
+ curr = base_space->select.sel_info.hslab->span_lst->head;
+ curr_dim = 0;
+ while(curr && curr_dim < (base_space->extent.rank - new_space->extent.rank)) {
+ /* Save the location of the selection in current dimension */
+ block[curr_dim] = curr->low;
+
+ /* Advance down to next dimension */
+ curr = curr->down->head;
+ curr_dim++;
+ } /* end while */
+
+ /* Compute the offset for the down-projection */
+ *offset = H5V_array_offset(base_space->extent.rank, base_space->extent.size, block);
+
+ /* Project the base space's selection down in less dimensions */
+ if(H5S_hyper_project_simple_lower(base_space, new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions")
+ } /* end if */
+ else {
+ HDassert(new_space->extent.rank > base_space->extent.rank);
+
+ /* The offset is zero when projected into higher dimensions */
+ *offset = 0;
+
+ /* Project the base space's selection down in less dimensions */
+ if(H5S_hyper_project_simple_higher(base_space, new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions")
+ } /* end else */
+
+ /* Indicate that the dimension information is not valid */
+ new_space->select.sel_info.hslab->diminfo_valid = FALSE;
+ } /* end else */
+
+ /* Number of elements selected will be the same */
+ new_space->select.num_elem = base_space->select.num_elem;
+
+ /* Set selection type */
+ new_space->select.type = H5S_sel_hyper;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_project_simple() */
+
+
/*--------------------------------------------------------------------------
NAME
H5S_hyper_adjust_helper_s
@@ -4061,41 +4414,41 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_adjust_helper_s (H5S_hyper_span_info_t *spans, const hssize_t *offset)
+H5S_hyper_adjust_helper_s(H5S_hyper_span_info_t *spans, const hssize_t *offset)
{
H5S_hyper_span_t *span; /* Pointer to current span in span tree */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_adjust_helper_s);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_adjust_helper_s)
/* Sanity check */
- assert(spans);
- assert(offset);
+ HDassert(spans);
+ HDassert(offset);
/* Check if we've already set this down span tree */
- if(spans->scratch!=(H5S_hyper_span_info_t *)~((size_t)NULL)) {
+ if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) {
/* Set the tree's scratch pointer */
- spans->scratch=(H5S_hyper_span_info_t *)~((size_t)NULL);
+ spans->scratch = (H5S_hyper_span_info_t *)~((size_t)NULL);
/* Get the span lists for each span in this tree */
- span=spans->head;
+ span = spans->head;
/* Iterate over the spans in tree */
- while(span!=NULL) {
+ while(span != NULL) {
/* Adjust span offset */
- assert((hssize_t)span->low>=*offset);
- span->low-=*offset;
- span->high-=*offset;
+ HDassert((hssize_t)span->low >= *offset);
+ span->low -= *offset;
+ span->high -= *offset;
/* Recursively adjust spans in next dimension down */
- if(span->down!=NULL)
- H5S_hyper_adjust_helper_s(span->down,offset+1);
+ if(span->down != NULL)
+ H5S_hyper_adjust_helper_s(span->down, offset + 1);
/* Advance to next span in this dimension */
- span=span->next;
+ span = span->next;
} /* end while */
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_hyper_adjust_helper_s() */
@@ -4142,8 +4495,7 @@ H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset adjustment");
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
} /* end if */
done:
@@ -4252,8 +4604,7 @@ H5S_hyper_move(H5S_t *space, const hssize_t *offset)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset movement");
/* Reset the scratch pointers for the next routine which needs them */
- if(H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst,NULL)==FAIL)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset hyperslab scratch pointer");
+ H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
} /* end if */
done:
@@ -6035,8 +6386,6 @@ done:
* Programmer: Quincey Koziol
* Wednesday, January 10, 2001
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -6220,18 +6569,18 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
} /* end switch */
- if(op==H5S_SELECT_SET) {
+ if(op == H5S_SELECT_SET) {
/* If we are setting a new selection, remove current selection first */
- if(H5S_SELECT_RELEASE(space)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
+ if(H5S_SELECT_RELEASE(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
/* Allocate space for the hyperslab selection information */
- if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info");
+ if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
/* Save the diminfo */
- space->select.num_elem=1;
- for(u=0; u<space->extent.rank; u++) {
+ space->select.num_elem = 1;
+ for(u = 0; u < space->extent.rank; u++) {
space->select.sel_info.hslab->app_diminfo[u].start = start[u];
space->select.sel_info.hslab->app_diminfo[u].stride = stride[u];
space->select.sel_info.hslab->app_diminfo[u].count = count[u];
@@ -6241,39 +6590,40 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u];
space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u];
space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u];
- space->select.num_elem*=(opt_count[u]*opt_block[u]);
+
+ space->select.num_elem *= (opt_count[u] * opt_block[u]);
} /* end for */
/* Indicate that the dimension information is valid */
- space->select.sel_info.hslab->diminfo_valid=TRUE;
+ space->select.sel_info.hslab->diminfo_valid = TRUE;
/* Indicate that there's no slab information */
- space->select.sel_info.hslab->span_lst=NULL;
+ space->select.sel_info.hslab->span_lst = NULL;
} /* end if */
- else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) {
+ else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) {
/* Sanity check */
- assert(H5S_GET_SELECT_TYPE(space)==H5S_SEL_HYPERSLABS);
+ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
/* Check if there's no hyperslab span information currently */
- if(space->select.sel_info.hslab->span_lst==NULL)
- if(H5S_hyper_generate_spans(space)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree");
+ if(NULL == space->select.sel_info.hslab->span_lst)
+ if(H5S_hyper_generate_spans(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
/* Indicate that the regular dimensions are no longer valid */
- space->select.sel_info.hslab->diminfo_valid=FALSE;
+ space->select.sel_info.hslab->diminfo_valid = FALSE;
/* Add in the new hyperslab information */
- if(H5S_generate_hyperslab (space, op, start, opt_stride, opt_count, opt_block)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs");
+ if(H5S_generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs")
} /* end if */
else
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation");
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
/* Set selection type */
- space->select.type=H5S_sel_hyper;
+ space->select.type = H5S_sel_hyper;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_hyperslab() */
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index f535122..e9d0541 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -31,45 +31,25 @@
#include "H5Fprivate.h" /* File access */
#include "H5FDprivate.h" /* File drivers */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
#include "H5Spkg.h" /* Dataspaces */
#ifdef H5_HAVE_PARALLEL
-static herr_t
-H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type );
-static herr_t
-H5S_mpio_none_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type );
-static herr_t
-H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type );
-
-static herr_t
-H5S_mpio_span_hyper_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type );
+static herr_t H5S_mpio_all_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type);
+static herr_t H5S_mpio_none_type(MPI_Datatype *new_type, int *count,
+ hbool_t *is_derived_type);
+static herr_t H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type);
+static herr_t H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type);
+static herr_t H5S_obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span,
+ const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size);
-static herr_t H5S_obtain_datatype(const hsize_t size[],
- H5S_hyper_span_t* span,MPI_Datatype *span_type,
- size_t elmt_size,int dimindex);
+#define H5S_MPIO_INITIAL_ALLOC_COUNT 256
/*-------------------------------------------------------------------------
@@ -82,30 +62,20 @@ static herr_t H5S_obtain_datatype(const hsize_t size[],
* Outputs: *new_type the MPI type corresponding to the selection
* *count how many objects of the new_type in selection
* (useful if this is the buffer type for xfer)
- * *extra_offset Number of bytes of offset within dataset
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: rky 980813
*
- * Modifications:
- *
- * Quincey Koziol, June 18, 2002
- * Added 'extra_offset' parameter
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type )
+H5S_mpio_all_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type)
{
hsize_t total_bytes;
- hssize_t snelmts; /*total number of elmts (signed) */
- hsize_t nelmts; /*total number of elmts */
- herr_t ret_value = SUCCEED;
+ hssize_t snelmts; /* Total number of elmts (signed) */
+ hsize_t nelmts; /* Total number of elmts */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_all_type)
@@ -121,8 +91,7 @@ H5S_mpio_all_type( const H5S_t *space, size_t elmt_size,
/* fill in the return values */
*new_type = MPI_BYTE;
- H5_ASSIGN_OVERFLOW(*count, total_bytes, hsize_t, size_t);
- *extra_offset = 0;
+ H5_ASSIGN_OVERFLOW(*count, total_bytes, hsize_t, int);
*is_derived_type = FALSE;
done:
@@ -140,32 +109,23 @@ done:
* Outputs: *new_type the MPI type corresponding to the selection
* *count how many objects of the new_type in selection
* (useful if this is the buffer type for xfer)
- * *extra_offset Number of bytes of offset within dataset
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: Quincey Koziol, October 29, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_mpio_none_type( const H5S_t UNUSED *space, size_t UNUSED elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type )
+H5S_mpio_none_type(MPI_Datatype *new_type, int *count, hbool_t *is_derived_type)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_mpio_none_type);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_mpio_none_type)
/* fill in the return values */
*new_type = MPI_BYTE;
*count = 0;
- *extra_offset = 0;
*is_derived_type = FALSE;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_mpio_none_type() */
@@ -179,35 +139,15 @@ H5S_mpio_none_type( const H5S_t UNUSED *space, size_t UNUSED elmt_size,
* Outputs: *new_type the MPI type corresponding to the selection
* *count how many objects of the new_type in selection
* (useful if this is the buffer type for xfer)
- * *extra_offset Number of bytes of offset within dataset
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: rky 980813
*
- * Modifications: ppw 990401
- * rky, ppw 2000-09-26 Freed old type after creating struct type.
- * rky 2000-10-05 Changed displacements to be MPI_Aint.
- * rky 2000-10-06 Added code for cases of empty hyperslab.
- * akc, rky 2000-11-16 Replaced hard coded dimension size with
- * H5S_MAX_RANK.
- *
- * Quincey Koziol, June 18, 2002
- * Added 'extra_offset' parameter. Also accomodate selection
- * offset in MPI type built.
- *
- * Albert Cheng, August 4, 2004
- * Reimplemented the algorithm of forming the outer_type by
- * defining it as (start, vector, extent) in one call.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type )
+H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type)
{
H5S_sel_iter_t sel_iter; /* Selection iteration info */
hbool_t sel_iter_init = FALSE; /* Selection iteration info has been initialized */
@@ -231,18 +171,16 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
int mpi_code; /* MPI return code */
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_hyper_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_hyper_type)
/* Check args */
HDassert(space);
HDassert(sizeof(MPI_Aint) >= sizeof(elmt_size));
- if(0 == elmt_size)
- goto empty;
/* Initialize selection iterator */
if(H5S_select_iter_init(&sel_iter, space, elmt_size) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
- sel_iter_init = 1; /* Selection iteration info has been initialized */
+ sel_iter_init = TRUE; /* Selection iteration info has been initialized */
/* Abbreviate args */
diminfo = sel_iter.u.hyp.diminfo;
@@ -251,18 +189,16 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
/* make a local copy of the dimension info so we can operate with them */
/* Check if this is a "flattened" regular hyperslab selection */
- if(sel_iter.u.hyp.iter_rank!=0 && sel_iter.u.hyp.iter_rank<space->extent.rank) {
+ if(sel_iter.u.hyp.iter_rank != 0 && sel_iter.u.hyp.iter_rank < space->extent.rank) {
/* Flattened selection */
rank = sel_iter.u.hyp.iter_rank;
HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */
- if (0==rank)
- goto empty;
#ifdef H5S_DEBUG
if(H5DEBUG(S))
HDfprintf(H5DEBUG(S), "%s: Flattened selection\n",FUNC);
#endif
- for ( i=0; i<rank; ++i) {
- d[i].start = diminfo[i].start+sel_iter.u.hyp.sel_off[i];
+ for(i = 0; i < rank; ++i) {
+ d[i].start = diminfo[i].start + sel_iter.u.hyp.sel_off[i];
d[i].strid = diminfo[i].stride;
d[i].block = diminfo[i].block;
d[i].count = diminfo[i].count;
@@ -277,26 +213,26 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
HDfprintf(H5DEBUG(S), "\n" );
}
#endif
- if (0==d[i].block)
+ if(0 == d[i].block)
goto empty;
- if (0==d[i].count)
+ if(0 == d[i].count)
goto empty;
- if (0==d[i].xtent)
+ if(0 == d[i].xtent)
goto empty;
- }
+ } /* end for */
} /* end if */
else {
/* Non-flattened selection */
rank = space->extent.rank;
- HDassert(rank >= 0 && rank<=H5S_MAX_RANK); /* within array bounds */
- if (0==rank)
+ HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */
+ if(0 == rank)
goto empty;
#ifdef H5S_DEBUG
if(H5DEBUG(S))
HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC);
#endif
- for ( i=0; i<rank; ++i) {
- d[i].start = diminfo[i].start+space->select.offset[i];
+ for(i = 0; i < rank; ++i) {
+ d[i].start = diminfo[i].start + space->select.offset[i];
d[i].strid = diminfo[i].stride;
d[i].block = diminfo[i].block;
d[i].count = diminfo[i].count;
@@ -311,40 +247,37 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
HDfprintf(H5DEBUG(S), "\n" );
}
#endif
- if (0==d[i].block)
+ if(0 == d[i].block)
goto empty;
- if (0==d[i].count)
+ if(0 == d[i].count)
goto empty;
- if (0==d[i].xtent)
+ if(0 == d[i].xtent)
goto empty;
- }
+ } /* end for */
} /* end else */
/**********************************************************************
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 */ /* leave the old way */
+ offset[rank - 1] = 1;
+ max_xtent[rank - 1] = d[rank - 1].xtent;
#ifdef H5S_DEBUG
- if(H5DEBUG(S)){
+ if(H5DEBUG(S)) {
i=rank-1;
- HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n",
+ HDfprintf(H5DEBUG(S), " 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;
+ 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 H5S_DEBUG
- if(H5DEBUG(S)){
+ if(H5DEBUG(S))
HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n",
i, offset[i], i, max_xtent[i]);
- }
#endif
-
- }
+ } /* end for */
/* Create a type covering the selected hyperslab.
* Multidimensional dataspaces are stored in row-major order.
@@ -356,59 +289,58 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
*******************************************************/
#ifdef H5S_DEBUG
if(H5DEBUG(S)) {
- HDfprintf(H5DEBUG(S), "%s: Making contig type %d MPI_BYTEs\n", FUNC,elmt_size );
+ HDfprintf(H5DEBUG(S), "%s: Making contig type %Zu MPI_BYTEs\n", FUNC, elmt_size);
for (i=rank-1; i>=0; --i)
HDfprintf(H5DEBUG(S), "d[%d].xtent=%Hu \n", i, d[i].xtent);
}
#endif
- if (MPI_SUCCESS != (mpi_code= MPI_Type_contiguous( (int)elmt_size, MPI_BYTE, &inner_type )))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &inner_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
/*******************************************************
* Construct the type by walking the hyperslab dims
* from the inside out:
*******************************************************/
- for ( i=rank-1; i>=0; --i) {
+ for(i = rank - 1; i >= 0; --i) {
#ifdef H5S_DEBUG
- if(H5DEBUG(S)) {
- HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n"
+ if(H5DEBUG(S))
+ HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n"
"start=%Hd count=%Hu block=%Hu stride=%Hu, xtent=%Hu max_xtent=%d\n",
FUNC, i, d[i].start, d[i].count, d[i].block, d[i].strid, d[i].xtent, max_xtent[i]);
- }
#endif
#ifdef H5S_DEBUG
if(H5DEBUG(S))
- HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i);
+ HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i);
#endif
/****************************************
* Build vector type of the selection.
****************************************/
- mpi_code =MPI_Type_vector((int)(d[i].count), /* count */
- (int)(d[i].block), /* blocklength */
- (int)(d[i].strid), /* stride */
- inner_type, /* old type */
- &outer_type); /* new type */
-
- MPI_Type_free( &inner_type );
- if (mpi_code!=MPI_SUCCESS)
- HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code);
-
- /****************************************
- * Then build the dimension type as (start, vector type, xtent).
- ****************************************/
- /* calculate start and extent values of this dimension */
+ mpi_code = MPI_Type_vector((int)(d[i].count), /* count */
+ (int)(d[i].block), /* blocklength */
+ (int)(d[i].strid), /* stride */
+ inner_type, /* old type */
+ &outer_type); /* new type */
+
+ MPI_Type_free(&inner_type);
+ if(mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code)
+
+ /****************************************
+ * Then build the dimension type as (start, vector type, xtent).
+ ****************************************/
+ /* calculate start and extent values of this dimension */
displacement[1] = d[i].start * offset[i] * elmt_size;
displacement[2] = (MPI_Aint)elmt_size * max_xtent[i];
if(MPI_SUCCESS != (mpi_code = MPI_Type_extent(outer_type, &extent_len)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_extent failed", mpi_code);
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_extent failed", mpi_code)
- /*************************************************
- * Restructure this datatype ("outer_type")
- * so that it still starts at 0, but its extent
- * is the full extent in this dimension.
- *************************************************/
- if (displacement[1] > 0 || (int)extent_len < displacement[2]) {
+ /*************************************************
+ * Restructure this datatype ("outer_type")
+ * so that it still starts at 0, but its extent
+ * is the full extent in this dimension.
+ *************************************************/
+ if(displacement[1] > 0 || (int)extent_len < displacement[2]) {
block_length[0] = 1;
block_length[1] = 1;
@@ -420,42 +352,37 @@ H5S_mpio_hyper_type( const H5S_t *space, size_t elmt_size,
old_types[1] = outer_type;
old_types[2] = MPI_UB;
#ifdef H5S_DEBUG
- if(H5DEBUG(S)){
- HDfprintf(H5DEBUG(S), "%s: i=%d Extending struct type\n"
- "***displacements: %d, %d, %d\n",
- FUNC, i, displacement[0], displacement[1], displacement[2]);
- }
+ if(H5DEBUG(S))
+ HDfprintf(H5DEBUG(S), "%s: i=%d Extending struct type\n"
+ "***displacements: %ld, %ld, %ld\n",
+ FUNC, i, (long)displacement[0], (long)displacement[1], (long)displacement[2]);
#endif
- mpi_code = MPI_Type_struct ( 3, /* count */
- block_length, /* blocklengths */
- displacement, /* displacements */
- old_types, /* old types */
- &inner_type); /* new type */
-
- MPI_Type_free (&outer_type);
- if (mpi_code!=MPI_SUCCESS)
- HMPI_GOTO_ERROR(FAIL, "couldn't resize MPI vector type", mpi_code);
- }
- else {
+ mpi_code = MPI_Type_struct(3, /* count */
+ block_length, /* blocklengths */
+ displacement, /* displacements */
+ old_types, /* old types */
+ &inner_type); /* new type */
+
+ MPI_Type_free(&outer_type);
+ if(mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "couldn't resize MPI vector type", mpi_code)
+ } /* end if */
+ 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 */
-
*new_type = inner_type;
- if (MPI_SUCCESS != (mpi_code= MPI_Type_commit( new_type )))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
/* fill in the remaining return values */
*count = 1; /* only have to move one of these suckers! */
- *extra_offset = 0;
*is_derived_type = TRUE;
HGOTO_DONE(SUCCEED);
@@ -463,24 +390,21 @@ empty:
/* special case: empty hyperslab */
*new_type = MPI_BYTE;
*count = 0;
- *extra_offset = 0;
*is_derived_type = FALSE;
done:
/* Release selection iterator */
- if(sel_iter_init) {
- if (H5S_SELECT_ITER_RELEASE(&sel_iter)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
- } /* end if */
+ if(sel_iter_init)
+ if(H5S_SELECT_ITER_RELEASE(&sel_iter) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
#ifdef H5S_DEBUG
- if(H5DEBUG(S)){
+ if(H5DEBUG(S))
HDfprintf(H5DEBUG(S), "Leave %s, count=%ld is_derived_type=%t\n",
FUNC, *count, *is_derived_type );
- }
#endif
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_mpio_hyper_type() */
/*-------------------------------------------------------------------------
@@ -494,68 +418,57 @@ done:
* Outputs: *new_type the MPI type corresponding to the selection
* *count how many objects of the new_type in selection
* (useful if this is the buffer type for xfer)
- * *extra_offset Number of bytes of offset within dataset
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: kyang
*
+ *-------------------------------------------------------------------------
*/
static herr_t
-H5S_mpio_span_hyper_type( const H5S_t *space,
- size_t elmt_size,
- MPI_Datatype *new_type,/* out: */
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type )
+H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type)
{
- MPI_Datatype span_type;
- H5S_hyper_span_t *ospan;
- H5S_hyper_span_info_t *odown;
- hsize_t *size;
- int mpi_code;
- herr_t ret_value = SUCCEED;
+ MPI_Datatype elmt_type; /* MPI datatype for an element */
+ hbool_t elmt_type_is_derived = FALSE; /* Whether the element type has been created */
+ MPI_Datatype span_type; /* MPI datatype for overall span tree */
+ hsize_t down[H5S_MAX_RANK]; /* 'down' sizes for each dimension */
+ int mpi_code; /* MPI return code */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_span_hyper_type)
/* Check args */
HDassert(space);
-
- if(0 == elmt_size)
- goto empty;
- size = space->extent.size;
- if(0 == size)
- goto empty;
-
- odown = space->select.sel_info.hslab->span_lst;
- if(NULL == odown)
- goto empty;
- ospan = odown->head;
- if(NULL == ospan)
- goto empty;
-
- /* obtain derived data type */
- if(FAIL == H5S_obtain_datatype(space->extent.size, ospan, &span_type, elmt_size, space->extent.rank))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
-
+ HDassert(space->extent.size);
+ HDassert(space->select.sel_info.hslab->span_lst);
+ HDassert(space->select.sel_info.hslab->span_lst->head);
+
+ /* Create the base type for an element */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ elmt_type_is_derived = TRUE;
+
+ /* Compute 'down' sizes for each dimension */
+ if(H5V_array_down(space->extent.rank, space->extent.size, down) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGETSIZE, FAIL, "couldn't compute 'down' dimension sizes")
+
+ /* Obtain derived data type */
+ if(H5S_obtain_datatype(down, space->select.sel_info.hslab->span_lst->head, &elmt_type, &span_type, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type")
if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
-
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
*new_type = span_type;
+
/* fill in the remaining return values */
*count = 1;
- *extra_offset = 0;
*is_derived_type = TRUE;
- HGOTO_DONE(SUCCEED)
-
-empty:
- /* special case: empty hyperslab */
- *new_type = MPI_BYTE;
- *count = 0;
- *extra_offset = 0;
- *is_derived_type = FALSE;
-
done:
+ /* Release resources */
+ if(elmt_type_is_derived)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&elmt_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_mpio_span_hyper_type() */
@@ -564,7 +477,7 @@ done:
* Function: H5S_obtain datatype
*
* Purpose: Obtain an MPI derived datatype based on span-tree
- implementation
+ * implementation
*
* Return: non-negative on success, negative on failure.
*
@@ -572,165 +485,169 @@ done:
*
* Programmer: kyang
*
+ *-------------------------------------------------------------------------
*/
static herr_t
-H5S_obtain_datatype(const hsize_t size[],
- H5S_hyper_span_t* span,
- MPI_Datatype *span_type,
- size_t elmt_size,
- int dimindex)
+H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span,
+ const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size)
{
- int innercount, outercount;
- MPI_Datatype bas_type;
- MPI_Datatype temp_type;
- MPI_Datatype tempinner_type;
+ size_t alloc_count; /* Number of span tree nodes allocated at this level */
+ size_t outercount; /* Number of span tree nodes at this level */
MPI_Datatype *inner_type = NULL;
+ hbool_t inner_types_freed = FALSE; /* Whether the inner_type MPI datatypes have been freed */
+ hbool_t span_type_valid = FALSE; /* Whether the span_type MPI datatypes is valid */
int *blocklen = NULL;
MPI_Aint *disp = NULL;
- MPI_Aint stride;
- H5S_hyper_span_info_t *down;
- H5S_hyper_span_t *tspan;
-#ifdef H5_HAVE_MPI2
- MPI_Aint sizeaint, sizedtype;
-#endif /* H5_HAVE_MPI2 */
- hsize_t total_lowd, total_lowd1;
- int i;
- int mpi_code;
- herr_t ret_value = SUCCEED;
+ H5S_hyper_span_t *tspan; /* Temporary pointer to span tree node */
+ int mpi_code; /* MPI return status code */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5S_obtain_datatype)
+ /* Sanity check */
HDassert(span);
- inner_type = NULL;
- down = NULL;
- tspan = NULL;
- down = span->down;
- tspan = span;
-
- /* Obtain the number of span tree nodes for this dimension */
- outercount = 0;
- while(tspan) {
- tspan = tspan->next;
- outercount++;
- } /* end while */
- if(outercount == 0)
- HGOTO_DONE(SUCCEED)
-
-/* MPI2 hasn't been widely acccepted, adding H5_HAVE_MPI2 for the future use */
-#ifdef H5_HAVE_MPI2
- MPI_Type_extent(MPI_Aint, &sizeaint);
- MPI_Type_extent(MPI_Datatype, &sizedtype);
-
- blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeaint);
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizedtype);
-#else
- blocklen = (int *)HDcalloc((size_t)outercount, sizeof(int));
- disp = (MPI_Aint *)HDcalloc((size_t)outercount, sizeof(MPI_Aint));
- inner_type = (MPI_Datatype *)HDcalloc((size_t)outercount, sizeof(MPI_Datatype));
-#endif
-
- tspan = span;
- outercount = 0;
+ /* Allocate the initial displacement & block length buffers */
+ alloc_count = H5S_MPIO_INITIAL_ALLOC_COUNT;
+ if(NULL == (disp = (MPI_Aint *)H5MM_malloc(alloc_count * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements")
+ if(NULL == (blocklen = (int *)H5MM_malloc(alloc_count * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths")
/* if this is the fastest changing dimension, it is the base case for derived datatype. */
- if(down == NULL) {
-
- HDassert(dimindex <= 1);
-
- if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code);
-
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&bas_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
-
+ if(NULL == span->down) {
+ tspan = span;
+ outercount = 0;
while(tspan) {
+ /* Check if we need to increase the size of the buffers */
+ if(outercount >= alloc_count) {
+ MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */
+ int *tmp_blocklen; /* Temporary pointer to new block length buffer */
+
+ /* Double the allocation count */
+ alloc_count *= 2;
+
+ /* Re-allocate the buffers */
+ if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements")
+ disp = tmp_disp;
+ if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths")
+ blocklen = tmp_blocklen;
+ } /* end if */
+
+ /* Store displacement & block length */
disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
blocklen[outercount] = tspan->nelem;
+
tspan = tspan->next;
outercount++;
} /* end while */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed(outercount, blocklen, disp, bas_type, span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code);
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hindexed((int)outercount, blocklen, disp, *elmt_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hindexed failed", mpi_code)
+ span_type_valid = TRUE;
} /* end if */
- else { /* dimindex is the rank of the dimension */
-
- HDassert(dimindex > 1);
-
- /* Calculate the total bytes of the lower dimensions */
- total_lowd = 1; /* one dimension down */
- total_lowd1 = 1; /* two dimensions down */
-
- for(i = dimindex - 1; i > 0; i--)
- total_lowd = total_lowd * size[i];
+ else {
+ size_t u; /* Local index variable */
- for(i = dimindex - 1; i > 1; i--)
- total_lowd1 = total_lowd1 * size[i];
+ if(NULL == (inner_type = (MPI_Datatype *)H5MM_malloc(alloc_count * sizeof(MPI_Datatype))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes")
+ tspan = span;
+ outercount = 0;
while(tspan) {
+ MPI_Datatype down_type; /* Temporary MPI datatype for a span tree node's children */
+ MPI_Aint stride; /* Distance between inner MPI datatypes */
+
+ /* Check if we need to increase the size of the buffers */
+ if(outercount >= alloc_count) {
+ MPI_Aint *tmp_disp; /* Temporary pointer to new displacement buffer */
+ int *tmp_blocklen; /* Temporary pointer to new block length buffer */
+ MPI_Datatype *tmp_inner_type; /* Temporary pointer to inner MPI datatype buffer */
+
+ /* Double the allocation count */
+ alloc_count *= 2;
+
+ /* Re-allocate the buffers */
+ if(NULL == (tmp_disp = (MPI_Aint *)H5MM_realloc(disp, alloc_count * sizeof(MPI_Aint))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of displacements")
+ disp = tmp_disp;
+ if(NULL == (tmp_blocklen = (int *)H5MM_realloc(blocklen, alloc_count * sizeof(int))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of block lengths")
+ blocklen = tmp_blocklen;
+ if(NULL == (tmp_inner_type = (MPI_Datatype *)H5MM_realloc(inner_type, alloc_count * sizeof(MPI_Datatype))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of inner MPI datatypes")
+ } /* end if */
/* Displacement should be in byte and should have dimension information */
/* First using MPI Type vector to build derived data type for this span only */
/* Need to calculate the disp in byte for this dimension. */
/* Calculate the total bytes of the lower dimension */
-
- disp[outercount] = tspan->low * total_lowd * elmt_size;
+ disp[outercount] = tspan->low * (*down) * elmt_size;
blocklen[outercount] = 1;
- /* generating inner derived datatype by using MPI_Type_hvector */
- if(FAIL == H5S_obtain_datatype(size, tspan->down->head, &temp_type, elmt_size, dimindex - 1))
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't obtain MPI derived data type")
-
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
-
- /* building the inner vector datatype */
- stride = total_lowd * elmt_size;
- innercount = tspan->nelem;
+ /* Generate MPI datatype for next dimension down */
+ if(H5S_obtain_datatype(down + 1, tspan->down->head, elmt_type, &down_type, elmt_size) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't obtain MPI derived data type")
- if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector(innercount, 1, stride, temp_type, &tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code);
+ /* Build the MPI datatype for this node */
+ stride = (*down) * elmt_size;
+ H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_hvector((int)tspan->nelem, 1, stride, down_type, &inner_type[outercount]))) {
+ MPI_Type_free(&down_type);
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_hvector failed", mpi_code)
+ } /* end if */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(&tempinner_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code);
+ /* Release MPI datatype for next dimension down */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&down_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&temp_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
-
- inner_type[outercount] = tempinner_type;
- outercount ++;
tspan = tspan->next;
+ outercount++;
} /* end while */
/* building the whole vector datatype */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_struct(outercount, blocklen, disp, inner_type, span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code);
+ H5_CHECK_OVERFLOW(outercount, size_t, int)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_struct((int)outercount, blocklen, disp, inner_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_struct failed", mpi_code)
+ span_type_valid = TRUE;
+
+ /* Release inner node types */
+ for(u = 0; u < outercount; u++)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[u])))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ inner_types_freed = TRUE;
} /* end else */
- if(inner_type != NULL && down != NULL) {
- } /* end if */
-
done:
+ /* General cleanup */
if(inner_type != NULL) {
- if(down != NULL) {
- for(i = 0; i < outercount; i++)
- if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[i])))
- HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code);
+ if(!inner_types_freed) {
+ size_t u; /* Local index variable */
+
+ for(u = 0; u < outercount; u++)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(&inner_type[u])))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
} /* end if */
- HDfree(inner_type);
+ H5MM_free(inner_type);
} /* end if */
if(blocklen != NULL)
- HDfree(blocklen);
+ H5MM_free(blocklen);
if(disp != NULL)
- HDfree(disp);
+ H5MM_free(disp);
+
+ /* Error cleanup */
+ if(ret_value < 0) {
+ if(span_type_valid)
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_free(span_type)))
+ HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_obtain_datatype() */
-
/*-------------------------------------------------------------------------
* Function: H5S_mpio_space_type
@@ -743,49 +660,38 @@ done:
* Outputs: *new_type the MPI type corresponding to the selection
* *count how many objects of the new_type in selection
* (useful if this is the buffer type for xfer)
- * *extra_offset Number of bytes of offset within dataset
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: rky 980813
*
- * Modifications:
- *
- * Quincey Koziol, June 18, 2002
- * Added 'extra_offset' parameter
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type )
+H5S_mpio_space_type(const H5S_t *space, size_t elmt_size,
+ MPI_Datatype *new_type, int *count, hbool_t *is_derived_type)
{
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_space_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_mpio_space_type)
/* Check args */
HDassert(space);
+ HDassert(elmt_size);
/* Creat MPI type based on the kind of selection */
- switch (H5S_GET_EXTENT_TYPE(space)) {
+ switch(H5S_GET_EXTENT_TYPE(space)) {
case H5S_NULL:
case H5S_SCALAR:
case H5S_SIMPLE:
switch(H5S_GET_SELECT_TYPE(space)) {
case H5S_SEL_NONE:
- if ( H5S_mpio_none_type( space, elmt_size,
- /* out: */ new_type, count, extra_offset, is_derived_type ) <0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type");
+ if(H5S_mpio_none_type(new_type, count, is_derived_type) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert 'none' selection to MPI type")
break;
case H5S_SEL_ALL:
- if ( H5S_mpio_all_type( space, elmt_size,
- /* out: */ new_type, count, extra_offset, is_derived_type ) <0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type");
+ if(H5S_mpio_all_type(space, elmt_size, new_type, count, is_derived_type) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert 'all' selection to MPI type")
break;
case H5S_SEL_POINTS:
@@ -794,16 +700,14 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
break;
case H5S_SEL_HYPERSLABS:
- if((H5S_SELECT_IS_REGULAR(space) == TRUE)) {
- if(H5S_mpio_hyper_type( space, elmt_size,
- /* out: */ new_type, count, extra_offset, is_derived_type )<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type");
- }
- else {
- if(H5S_mpio_span_hyper_type( space, elmt_size,
- /* out: */ new_type, count, extra_offset, is_derived_type )<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert \"all\" selection to MPI type");
- }
+ if((H5S_SELECT_IS_REGULAR(space) == TRUE)) {
+ if(H5S_mpio_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert regular 'hyperslab' selection to MPI type")
+ } /* end if */
+ else {
+ if(H5S_mpio_span_hyper_type(space, elmt_size, new_type, count, is_derived_type) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't convert irregular 'hyperslab' selection to MPI type")
+ } /* end else */
break;
default:
@@ -815,11 +719,10 @@ H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
default:
HDassert("unknown data space type" && 0);
break;
- }
+ } /* end switch */
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
-
+} /* end H5S_mpio_space_type() */
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5Snone.c b/src/H5Snone.c
index c6e8a6a..1948f13 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -48,6 +48,8 @@ static htri_t H5S_none_is_contiguous(const H5S_t *space);
static htri_t H5S_none_is_single(const H5S_t *space);
static htri_t H5S_none_is_regular(const H5S_t *space);
static herr_t H5S_none_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S_none_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S_none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
/* Selection iteration callbacks */
@@ -77,6 +79,8 @@ const H5S_select_class_t H5S_sel_none[1] = {{
H5S_none_is_single,
H5S_none_is_regular,
H5S_none_adjust_u,
+ H5S_none_project_scalar,
+ H5S_none_project_simple,
H5S_none_iter_init,
}};
@@ -110,18 +114,18 @@ static const H5S_sel_iter_class_t H5S_sel_iter_none[1] = {{
*-------------------------------------------------------------------------
*/
herr_t
-H5S_none_iter_init (H5S_sel_iter_t *iter, const H5S_t UNUSED *space)
+H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5S_none_iter_init);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_none_iter_init)
/* Check args */
- assert (space && H5S_SEL_NONE==H5S_GET_SELECT_TYPE(space));
- assert (iter);
+ HDassert(space && H5S_SEL_NONE==H5S_GET_SELECT_TYPE(space));
+ HDassert(iter);
/* Initialize type of selection iterator */
- iter->type=H5S_sel_iter_none;
+ iter->type = H5S_sel_iter_none;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_iter_init() */
@@ -141,15 +145,15 @@ H5S_none_iter_init (H5S_sel_iter_t *iter, const H5S_t UNUSED *space)
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_none_iter_coords (const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *coords)
+H5S_none_iter_coords(const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *coords)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_coords);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_coords)
/* Check args */
- assert (iter);
- assert (coords);
+ HDassert(iter);
+ HDassert(coords);
- FUNC_LEAVE_NOAPI(FAIL);
+ FUNC_LEAVE_NOAPI(FAIL)
} /* H5S_none_iter_coords() */
@@ -169,16 +173,16 @@ H5S_none_iter_coords (const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *coords)
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_none_iter_block (const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *start, hsize_t UNUSED *end)
+H5S_none_iter_block(const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *start, hsize_t UNUSED *end)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_block)
/* Check args */
- assert (iter);
- assert (start);
- assert (end);
+ HDassert(iter);
+ HDassert(start);
+ HDassert(end);
- FUNC_LEAVE_NOAPI(FAIL);
+ FUNC_LEAVE_NOAPI(FAIL)
} /* H5S_none_iter_block() */
@@ -197,14 +201,14 @@ H5S_none_iter_block (const H5S_sel_iter_t UNUSED *iter, hsize_t UNUSED *start, h
*-------------------------------------------------------------------------
*/
static hsize_t
-H5S_none_iter_nelmts (const H5S_sel_iter_t UNUSED *iter)
+H5S_none_iter_nelmts(const H5S_sel_iter_t UNUSED *iter)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_nelmts);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_nelmts)
/* Check args */
- assert (iter);
+ HDassert(iter);
- FUNC_LEAVE_NOAPI(0);
+ FUNC_LEAVE_NOAPI(0)
} /* H5S_none_iter_nelmts() */
@@ -228,12 +232,12 @@ H5S_none_iter_nelmts (const H5S_sel_iter_t UNUSED *iter)
static htri_t
H5S_none_iter_has_next_block(const H5S_sel_iter_t UNUSED *iter)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_has_next_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_has_next_block)
/* Check args */
- assert (iter);
+ HDassert(iter);
- FUNC_LEAVE_NOAPI(FAIL);
+ FUNC_LEAVE_NOAPI(FAIL)
} /* H5S_none_iter_has_next_block() */
@@ -258,13 +262,13 @@ H5S_none_iter_has_next_block(const H5S_sel_iter_t UNUSED *iter)
static herr_t
H5S_none_iter_next(H5S_sel_iter_t UNUSED *iter, size_t UNUSED nelem)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_next);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_next)
/* Check args */
- assert (iter);
- assert (nelem>0);
+ HDassert(iter);
+ HDassert(nelem>0);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_iter_next() */
@@ -315,14 +319,14 @@ H5S_none_iter_next_block(H5S_sel_iter_t UNUSED *iter)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_iter_release (H5S_sel_iter_t UNUSED * iter)
+H5S_none_iter_release(H5S_sel_iter_t UNUSED * iter)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_release);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_iter_release)
/* Check args */
- assert (iter);
+ HDassert(iter);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_iter_release() */
@@ -344,14 +348,14 @@ H5S_none_iter_release (H5S_sel_iter_t UNUSED * iter)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_release (H5S_t UNUSED * space)
+H5S_none_release(H5S_t UNUSED * space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_release);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_release)
/* Check args */
- assert (space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_release() */
@@ -377,15 +381,15 @@ H5S_none_release (H5S_t UNUSED * space)
static herr_t
H5S_none_copy(H5S_t *dst, const H5S_t UNUSED *src, hbool_t UNUSED share_selection)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_copy);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_copy)
- assert(src);
- assert(dst);
+ HDassert(src);
+ HDassert(dst);
/* Set number of elements in selection */
- dst->select.num_elem=0;
+ dst->select.num_elem = 0;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S_none_copy() */
@@ -410,13 +414,13 @@ H5S_none_copy(H5S_t *dst, const H5S_t UNUSED *src, hbool_t UNUSED share_selectio
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_none_is_valid (const H5S_t UNUSED *space)
+H5S_none_is_valid(const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_valid);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_valid)
- assert(space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(TRUE);
+ FUNC_LEAVE_NOAPI(TRUE)
} /* end H5S_none_is_valid() */
@@ -440,17 +444,17 @@ H5S_none_is_valid (const H5S_t UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static hssize_t
-H5S_none_serial_size (const H5S_t UNUSED *space)
+H5S_none_serial_size(const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_serial_size);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_serial_size)
- assert(space);
+ HDassert(space);
/* Basic number of bytes required to serialize point selection:
* <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
* <length (4 bytes)> = 16 bytes
*/
- FUNC_LEAVE_NOAPI(16);
+ FUNC_LEAVE_NOAPI(16)
} /* end H5S_none_serial_size() */
@@ -474,11 +478,11 @@ H5S_none_serial_size (const H5S_t UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_serialize (const H5S_t *space, uint8_t *buf)
+H5S_none_serialize(const H5S_t *space, uint8_t *buf)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_serialize);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_serialize)
- assert(space);
+ HDassert(space);
/* Store the preamble information */
UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
@@ -486,7 +490,7 @@ H5S_none_serialize (const H5S_t *space, uint8_t *buf)
UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
UINT32ENCODE(buf, (uint32_t)0); /* Store the additional information length */
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_serialize() */
@@ -510,20 +514,20 @@ H5S_none_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_deserialize (H5S_t *space, const uint8_t UNUSED *buf)
+H5S_none_deserialize(H5S_t *space, const uint8_t UNUSED *buf)
{
- herr_t ret_value; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_none_deserialize);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_none_deserialize)
- assert(space);
+ HDassert(space);
/* Change to "none" selection */
- if((ret_value=H5S_select_none(space))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
+ if(H5S_select_none(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_none_deserialize() */
@@ -555,13 +559,13 @@ done:
static herr_t
H5S_none_bounds(const H5S_t UNUSED *space, hsize_t UNUSED *start, hsize_t UNUSED *end)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_bounds);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_bounds)
- assert(space);
- assert(start);
- assert(end);
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
- FUNC_LEAVE_NOAPI(FAIL);
+ FUNC_LEAVE_NOAPI(FAIL)
} /* H5Sget_none_bounds() */
@@ -618,11 +622,11 @@ H5S_none_offset(const H5S_t UNUSED *space, hsize_t UNUSED *offset)
static htri_t
H5S_none_is_contiguous(const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_contiguous);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_contiguous)
- assert(space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(FALSE);
+ FUNC_LEAVE_NOAPI(FALSE)
} /* H5S_none_is_contiguous() */
@@ -647,11 +651,11 @@ H5S_none_is_contiguous(const H5S_t UNUSED *space)
static htri_t
H5S_none_is_single(const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_single);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_single)
- assert(space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(FALSE);
+ FUNC_LEAVE_NOAPI(FALSE)
} /* H5S_none_is_single() */
@@ -677,12 +681,12 @@ H5S_none_is_single(const H5S_t UNUSED *space)
static htri_t
H5S_none_is_regular(const H5S_t UNUSED *space)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_regular);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_is_regular)
/* Check args */
- assert(space);
+ HDassert(space);
- FUNC_LEAVE_NOAPI(TRUE);
+ FUNC_LEAVE_NOAPI(TRUE)
} /* H5S_none_is_regular() */
@@ -717,6 +721,65 @@ H5S_none_adjust_u(H5S_t UNUSED *space, const hsize_t UNUSED *offset)
} /* H5S_none_adjust_u() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_none_project_scalar
+ *
+ * Purpose: Projects a 'none' selection into a scalar dataspace
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_none_project_scalar(const H5S_t UNUSED *space, hsize_t UNUSED *offset)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_project_scalar)
+
+ /* Check args */
+ HDassert(space && H5S_SEL_NONE == H5S_GET_SELECT_TYPE(space));
+ HDassert(offset);
+
+ FUNC_LEAVE_NOAPI(FAIL)
+} /* H5S_none_project_scalar() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_none_project_simple
+ *
+ * Purpose: Projects an 'none' selection onto/into a simple dataspace
+ * of a different rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_none_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_none_project_simple)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_NONE == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(offset);
+
+ /* Select the entire new space */
+ if(H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to set none selection")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_none_project_simple() */
+
+
/*--------------------------------------------------------------------------
NAME
H5S_select_none
@@ -734,27 +797,28 @@ H5S_none_adjust_u(H5S_t UNUSED *space, const hsize_t UNUSED *offset)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t H5S_select_none (H5S_t *space)
+herr_t
+H5S_select_none(H5S_t *space)
{
- herr_t ret_value=SUCCEED; /* return value */
+ herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI(H5S_select_none, FAIL);
+ FUNC_ENTER_NOAPI(H5S_select_none, FAIL)
/* Check args */
- assert(space);
+ HDassert(space);
/* Remove current selection first */
- if(H5S_SELECT_RELEASE(space)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
+ if(H5S_SELECT_RELEASE(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab")
/* Set number of elements in selection */
- space->select.num_elem=0;
+ space->select.num_elem = 0;
/* Set selection type */
- space->select.type=H5S_sel_none;
+ space->select.type = H5S_sel_none;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_none() */
@@ -833,24 +897,24 @@ H5S_none_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_
size_t UNUSED maxseq, size_t UNUSED maxelem, size_t *nseq, size_t *nelem,
hsize_t UNUSED *off, size_t UNUSED *len)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_get_seq_list);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_none_get_seq_list)
/* Check args */
- assert(space);
- assert(iter);
- assert(maxseq>0);
- assert(maxelem>0);
- assert(nseq);
- assert(nelem);
- assert(off);
- assert(len);
+ HDassert(space);
+ HDassert(iter);
+ HDassert(maxseq > 0);
+ HDassert(maxelem > 0);
+ HDassert(nseq);
+ HDassert(nelem);
+ HDassert(off);
+ HDassert(len);
/* "none" selections don't generate sequences of bytes */
- *nseq=0;
+ *nseq = 0;
/* They don't use any elements, either */
- *nelem=0;
+ *nelem = 0;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S_none_get_seq_list() */
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index b7818a2..0a9df69 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -145,6 +145,10 @@ typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space);
typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space);
/* Method to adjust a selection by an offset */
typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset);
+/* Method to construct single element projection onto scalar dataspace */
+typedef herr_t (*H5S_sel_project_scalar)(const H5S_t *space, hsize_t *offset);
+/* Method to construct selection projection onto/into simple dataspace */
+typedef herr_t (*H5S_sel_project_simple)(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
/* Method to initialize iterator for current selection */
typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_sel_iter_t *sel_iter, const H5S_t *space);
@@ -166,6 +170,8 @@ typedef struct {
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */
+ H5S_sel_project_scalar project_scalar; /* Method to construct scalar dataspace projection */
+ H5S_sel_project_simple project_simple; /* Method to construct simple dataspace projection */
H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */
} H5S_select_class_t;
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 24dfe2a..cb7e98f 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -49,6 +49,8 @@ static htri_t H5S_point_is_contiguous(const H5S_t *space);
static htri_t H5S_point_is_single(const H5S_t *space);
static htri_t H5S_point_is_regular(const H5S_t *space);
static herr_t H5S_point_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S_point_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S_point_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
/* Selection iteration callbacks */
@@ -78,6 +80,8 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S_point_is_single,
H5S_point_is_regular,
H5S_point_adjust_u,
+ H5S_point_project_scalar,
+ H5S_point_project_simple,
H5S_point_iter_init,
}};
@@ -610,18 +614,18 @@ H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t UNUSED share_selection)
/* Allocate room for the head of the point list */
if(NULL == (dst->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node")
curr = src->select.sel_info.pnt_lst->head;
new_tail = NULL;
while(curr) {
/* Create new point */
if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank*sizeof(hsize_t)))) {
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank * sizeof(hsize_t)))) {
new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
} /* end if */
/* Copy over the point's coordinates */
@@ -976,7 +980,7 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint
node = node->next;
} /* end while */
- /* Iterate through the node, copying each hyperslab's information */
+ /* Iterate through the node, copying each point's information */
while(node != NULL && numpoints > 0) {
HDmemcpy(buf, node->pnt, sizeof(hsize_t) * rank);
buf += rank;
@@ -1346,6 +1350,173 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset)
} /* H5S_point_adjust_u() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_project_scalar
+ *
+ * Purpose: Projects a single element point selection into a scalar
+ * dataspace
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_point_project_scalar(const H5S_t *space, hsize_t *offset)
+{
+ const H5S_pnt_node_t *node; /* Point node */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_project_scalar)
+
+ /* Check args */
+ HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space));
+ HDassert(offset);
+
+ /* Get the head of the point list */
+ node = space->select.sel_info.pnt_lst->head;
+
+ /* Check for more than one point selected */
+ if(node->next)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "point selection of one element has more than one node!")
+
+ /* Calculate offset of selection in projected buffer */
+ *offset = H5V_array_offset(space->extent.rank, space->extent.size, node->pnt);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_project_scalar() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_project_simple
+ *
+ * Purpose: Projects a point selection onto/into a simple dataspace
+ * of a different rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset)
+{
+ const H5S_pnt_node_t *base_node; /* Point node in base space */
+ H5S_pnt_node_t *new_node; /* Point node in new space */
+ H5S_pnt_node_t *prev_node; /* Previous point node in new space */
+ unsigned rank_diff; /* Difference in ranks between spaces */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_project_simple)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(offset);
+
+ /* We are setting a new selection, remove any current selection in new dataspace */
+ if(H5S_SELECT_RELEASE(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+
+ /* Allocate room for the head of the point list */
+ if(NULL == (new_space->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node")
+
+ /* Check if the new space's rank is < or > base space's rank */
+ if(new_space->extent.rank < base_space->extent.rank) {
+ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+
+ /* Compute the difference in ranks */
+ rank_diff = base_space->extent.rank - new_space->extent.rank;
+
+ /* Calculate offset of selection in projected buffer */
+ HDmemset(block, 0, sizeof(block));
+ HDmemcpy(block, base_space->select.sel_info.pnt_lst->head->pnt, sizeof(hsize_t) * rank_diff);
+ *offset = H5V_array_offset(base_space->extent.rank, base_space->extent.size, block);
+
+ /* Iterate through base space's point nodes, copying the point information */
+ base_node = base_space->select.sel_info.pnt_lst->head;
+ prev_node = NULL;
+ while(base_node) {
+ /* Create new point */
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
+ new_node->next = NULL;
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
+ new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
+ } /* end if */
+
+ /* Copy over the point's coordinates */
+ HDmemcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t)));
+
+ /* Keep the order the same when copying */
+ if(NULL == prev_node)
+ prev_node = new_space->select.sel_info.pnt_lst->head = new_node;
+ else {
+ prev_node->next = new_node;
+ prev_node = new_node;
+ } /* end else */
+
+ /* Advance to next node */
+ base_node = base_node->next;
+ } /* end while */
+ } /* end if */
+ else {
+ HDassert(new_space->extent.rank > base_space->extent.rank);
+
+ /* Compute the difference in ranks */
+ rank_diff = new_space->extent.rank - base_space->extent.rank;
+
+ /* The offset is zero when projected into higher dimensions */
+ *offset = 0;
+
+ /* Iterate through base space's point nodes, copying the point information */
+ base_node = base_space->select.sel_info.pnt_lst->head;
+ prev_node = NULL;
+ while(base_node) {
+ /* Create new point */
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
+ new_node->next = NULL;
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
+ new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
+ } /* end if */
+
+ /* Copy over the point's coordinates */
+ HDmemset(new_node->pnt, 0, sizeof(hsize_t) * rank_diff);
+ HDmemcpy(&new_node->pnt[rank_diff], base_node->pnt, (new_space->extent.rank * sizeof(hsize_t)));
+
+ /* Keep the order the same when copying */
+ if(NULL == prev_node)
+ prev_node = new_space->select.sel_info.pnt_lst->head = new_node;
+ else {
+ prev_node->next = new_node;
+ prev_node = new_node;
+ } /* end else */
+
+ /* Advance to next node */
+ base_node = base_node->next;
+ } /* end while */
+ } /* end else */
+
+ /* Number of elements selected will be the same */
+ new_space->select.num_elem = base_space->select.num_elem;
+
+ /* Set selection type */
+ new_space->select.type = H5S_sel_point;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_project_simple() */
+
+
/*--------------------------------------------------------------------------
NAME
H5Sselect_elements
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 2858ddb..2faf977 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -133,6 +133,8 @@ typedef struct H5S_sel_iter_t {
#define H5S_SELECT_IS_SINGLE(S) ((*(S)->select.type->is_single)(S))
#define H5S_SELECT_IS_REGULAR(S) ((*(S)->select.type->is_regular)(S))
#define H5S_SELECT_ADJUST_U(S,O) ((*(S)->select.type->adjust_u)(S, O))
+#define H5S_SELECT_PROJECT_SCALAR(S,O) ((*(S)->select.type->project_scalar)(S, O))
+#define H5S_SELECT_PROJECT_SIMPLE(S,NS, O) ((*(S)->select.type->project_simple)(S, NS, O))
#define H5S_SELECT_ITER_COORDS(ITER,COORDS) ((*(ITER)->type->iter_coords)(ITER,COORDS))
#define H5S_SELECT_ITER_BLOCK(ITER,START,END) ((*(ITER)->type->iter_block)(ITER,START,END))
#define H5S_SELECT_ITER_NELMTS(ITER) ((*(ITER)->type->iter_nelmts)(ITER))
@@ -157,6 +159,8 @@ typedef struct H5S_sel_iter_t {
#define H5S_SELECT_IS_SINGLE(S) (H5S_select_is_single(S))
#define H5S_SELECT_IS_REGULAR(S) (H5S_select_is_regular(S))
#define H5S_SELECT_ADJUST_U(S,O) (H5S_select_adjust_u(S, O))
+#define H5S_SELECT_PROJECT_SCALAR(S,O) (H5S_select_project_scalar)(S, O))
+#define H5S_SELECT_PROJECT_SIMPLE(S,NS,O) (H5S_select_project_simple)(S, NS, O))
#define H5S_SELECT_ITER_COORDS(ITER,COORDS) (H5S_select_iter_coords(ITER,COORDS))
#define H5S_SELECT_ITER_BLOCK(ITER,START,END) (H5S_select_iter_block(ITER,START,END))
#define H5S_SELECT_ITER_NELMTS(ITER) (H5S_select_iter_nelmts(ITER))
@@ -215,6 +219,9 @@ H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset);
H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
+H5_DLL herr_t H5S_select_construct_projection(const H5S_t *base_space,
+ H5S_t **new_space_ptr, unsigned new_space_rank, const void *buf,
+ void **adj_buf_ptr, hsize_t element_size);
H5_DLL herr_t H5S_select_release(H5S_t *ds);
H5_DLL herr_t H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
@@ -225,6 +232,8 @@ H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space);
H5_DLL htri_t H5S_select_is_single(const H5S_t *space);
H5_DLL htri_t H5S_select_is_regular(const H5S_t *space);
H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset);
+H5_DLL herr_t H5S_select_project_scalar(const H5S_t *space, hsize_t *offset);
+H5_DLL herr_t H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
/* Operations on all selections */
H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev);
@@ -268,18 +277,8 @@ H5_DLL herr_t
H5S_mpio_space_type( const H5S_t *space, size_t elmt_size,
/* out: */
MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
+ int *count,
hbool_t *is_derived_type );
-
-H5_DLL herr_t
-H5S_mpio_space_span_type( const H5S_t *space, size_t elmt_size,
- /* out: */
- MPI_Datatype *new_type,
- size_t *count,
- hsize_t *extra_offset,
- hbool_t *is_derived_type );
-
#endif /* H5_HAVE_PARALLEL */
#endif /* _H5Sprivate_H */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index a419131..af3c9f9 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -27,6 +27,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Spkg.h" /* Dataspaces */
#include "H5Vprivate.h" /* Vector and array functions */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -108,7 +109,7 @@ H5S_select_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI(H5S_select_copy, FAIL);
+ FUNC_ENTER_NOAPI(H5S_select_copy, FAIL)
/* Check args */
assert(dst);
@@ -119,10 +120,10 @@ H5S_select_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
/* Perform correct type of copy based on the type of selection */
if((ret_value=(*src->select.type->copy)(dst,src,share_selection))<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information");
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_copy() */
@@ -149,14 +150,14 @@ H5S_select_release(H5S_t *ds)
{
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_release);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_release)
assert(ds);
/* Call the selection type's release function */
ret_value=(*ds->select.type->release)(ds);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_release() */
@@ -186,14 +187,14 @@ H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
{
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_get_seq_list);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_get_seq_list)
assert(space);
/* Call the selection type's get_seq_list function */
ret_value=(*space->select.type->get_seq_list)(space,flags,iter,maxseq,maxbytes,nseq,nbytes,off,len);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_get_seq_list() */
@@ -221,14 +222,14 @@ H5S_select_serial_size(const H5S_t *space)
{
hssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serial_size);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serial_size)
assert(space);
/* Call the selection type's serial_size function */
ret_value=(*space->select.type->serial_size)(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_serial_size() */
@@ -259,7 +260,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf)
{
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serialize);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_serialize)
assert(space);
assert(buf);
@@ -267,7 +268,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf)
/* Call the selection type's serialize function */
ret_value=(*space->select.type->serialize)(space,buf);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_serialize() */
@@ -410,13 +411,13 @@ H5S_select_valid(const H5S_t *space)
{
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_valid);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_valid)
assert(space);
ret_value = (*space->select.type->is_valid)(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_valid() */
@@ -449,7 +450,7 @@ H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
uint32_t sel_type; /* Pointer to the selection type */
herr_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI(H5S_select_deserialize, FAIL);
+ FUNC_ENTER_NOAPI(H5S_select_deserialize, FAIL)
assert(space);
@@ -476,10 +477,10 @@ H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
break;
}
if(ret_value<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection");
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_deserialize() */
@@ -567,7 +568,7 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_bounds);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_bounds)
/* Check args */
assert(space);
@@ -576,7 +577,7 @@ H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
ret_value = (*space->select.type->bounds)(space,start,end);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_get_select_bounds() */
@@ -646,14 +647,14 @@ H5S_select_is_contiguous(const H5S_t *space)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_contiguous);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_contiguous)
/* Check args */
assert(space);
ret_value = (*space->select.type->is_contiguous)(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_is_contiguous() */
@@ -683,14 +684,14 @@ H5S_select_is_single(const H5S_t *space)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_single);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_single)
/* Check args */
assert(space);
ret_value = (*space->select.type->is_single)(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_is_single() */
@@ -720,14 +721,14 @@ H5S_select_is_regular(const H5S_t *space)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_regular);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_is_regular)
/* Check args */
assert(space);
ret_value = (*space->select.type->is_regular)(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_is_regular() */
@@ -770,6 +771,86 @@ H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
/*--------------------------------------------------------------------------
NAME
+ H5S_select_project_scalar
+ PURPOSE
+ Project a single element selection for a scalar dataspace
+ USAGE
+ herr_t H5S_select_project_scalar(space, offset)
+ const H5S_t *space; IN: Pointer to dataspace to project
+ hsize_t *offset; IN/OUT: Offset of projected point
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Projects a selection of a single element into a scalar dataspace, computing
+ the offset of the element in the original selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ This routine participates in the "Inlining C function pointers"
+ pattern, don't call it directly, use the appropriate macro
+ defined in H5Sprivate.h.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_project_scalar)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(offset);
+
+ ret_value = (*space->select.type->project_scalar)(space, offset);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_select_project_scalar() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_project_simple
+ PURPOSE
+ Project a selection onto/into a dataspace of different rank
+ USAGE
+ herr_t H5S_select_project_simple(space, new_space, offset)
+ const H5S_t *space; IN: Pointer to dataspace to project
+ H5S_t *new_space; IN/OUT: Pointer to dataspace projected onto
+ hsize_t *offset; IN/OUT: Offset of projected point
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Projects a selection onto/into a simple dataspace, computing
+ the offset of the first element in the original selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ This routine participates in the "Inlining C function pointers"
+ pattern, don't call it directly, use the appropriate macro
+ defined in H5Sprivate.h.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
+{
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_project_simple)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(new_space);
+ HDassert(offset);
+
+ ret_value = (*space->select.type->project_simple)(space, new_space, offset);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_select_project_simple() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_iter_init
PURPOSE
Initializes iteration information for a selection.
@@ -790,7 +871,7 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
{
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_init);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_init)
/* Check args */
assert(sel_iter);
@@ -813,7 +894,7 @@ H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_s
/* Call initialization routine for selection type */
ret_value= (*space->select.type->iter_init)(sel_iter, space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_init() */
@@ -844,7 +925,7 @@ H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hsize_t *coords)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_coords);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_coords)
/* Check args */
assert(sel_iter);
@@ -853,7 +934,7 @@ H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hsize_t *coords)
/* Call iter_coords routine for selection type */
ret_value = (*sel_iter->type->iter_coords)(sel_iter,coords);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_coords() */
#ifdef LATER
@@ -886,7 +967,7 @@ H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_block)
/* Check args */
assert(iter);
@@ -896,7 +977,7 @@ H5S_select_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
/* Call iter_block routine for selection type */
ret_value = (*iter->type->iter_block)(iter,start,end);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_block() */
#endif /* LATER */
@@ -926,7 +1007,7 @@ H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
{
hsize_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_nelmts);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_nelmts)
/* Check args */
assert(sel_iter);
@@ -934,7 +1015,7 @@ H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
/* Call iter_nelmts routine for selection type */
ret_value = (*sel_iter->type->iter_nelmts)(sel_iter);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_nelmts() */
#ifdef LATER
@@ -965,7 +1046,7 @@ H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_has_next_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_has_next_block)
/* Check args */
assert(iter);
@@ -973,7 +1054,7 @@ H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter)
/* Call iter_has_next_block routine for selection type */
ret_value = (*iter->type->iter_has_next_block)(iter);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_has_next_block() */
#endif /* LATER */
@@ -1005,7 +1086,7 @@ H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_next);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_next)
/* Check args */
assert(iter);
@@ -1017,7 +1098,7 @@ H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
/* Decrement the number of elements left in selection */
iter->elmt_left-=nelem;
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_next() */
#ifdef LATER
@@ -1050,7 +1131,7 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_next_block);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_select_iter_next_block)
/* Check args */
assert(iter);
@@ -1058,7 +1139,7 @@ H5S_select_iter_next_block(H5S_sel_iter_t *iter)
/* Call iter_next_block routine for selection type */
ret_value = (*iter->type->iter_next_block)(iter);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_next_block() */
#endif /* LATER */
@@ -1088,7 +1169,7 @@ H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
{
herr_t ret_value; /* return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_release);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_select_iter_release)
/* Check args */
assert(sel_iter);
@@ -1096,7 +1177,7 @@ H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
/* Call selection type-specific release routine */
ret_value = (*sel_iter->type->iter_release)(sel_iter);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_select_iter_release() */
@@ -1154,7 +1235,7 @@ H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t
herr_t user_ret=0; /* User's return value */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5S_select_iterate, FAIL);
+ FUNC_ENTER_NOAPI(H5S_select_iterate, FAIL)
/* Check args */
HDassert(buf);
@@ -1302,7 +1383,7 @@ H5S_get_select_type(const H5S_t *space)
{
H5S_sel_type ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_type);
+ FUNC_ENTER_NOAPI_NOFUNC(H5S_get_select_type)
/* Check args */
assert(space);
@@ -1310,7 +1391,7 @@ H5S_get_select_type(const H5S_t *space)
/* Set return value */
ret_value=H5S_GET_SELECT_TYPE(space);
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_get_select_type() */
@@ -1334,16 +1415,17 @@ H5S_get_select_type(const H5S_t *space)
Assumes that there is only a single "block" for hyperslab selections.
EXAMPLES
REVISION LOG
+ Modified function to view identical shapes with different dimensions
+ as being the same under some circumstances.
--------------------------------------------------------------------------*/
htri_t
H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
{
- H5S_sel_iter_t iter1; /* Selection #1 iteration info */
- H5S_sel_iter_t iter2; /* Selection #2 iteration info */
- hbool_t iter1_init = 0; /* Selection #1 iteration info has been initialized */
- hbool_t iter2_init = 0; /* Selection #2 iteration info has been initialized */
- unsigned u; /* Index variable */
- htri_t ret_value = TRUE; /* Return value */
+ H5S_sel_iter_t iter_a; /* Selection a iteration info */
+ H5S_sel_iter_t iter_b; /* Selection b iteration info */
+ hbool_t iter_a_init = 0; /* Selection a iteration info has been initialized */
+ hbool_t iter_b_init = 0; /* Selection b iteration info has been initialized */
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_shape_same, FAIL)
@@ -1358,139 +1440,527 @@ H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
HGOTO_DONE(FALSE)
} /* end if */
else {
- /* Check for different dimensionality */
- if(space1->extent.rank != space2->extent.rank)
- HGOTO_DONE(FALSE)
+ const H5S_t *space_a; /* Dataspace with larger rank */
+ const H5S_t *space_b; /* Dataspace with smaller rank */
+ unsigned space_a_rank; /* Number of dimensions of dataspace A */
+ unsigned space_b_rank; /* Number of dimensions of dataspace B */
+
+ /* need to be able to handle spaces of different rank:
+ *
+ * To simplify logic, let space_a point to the element of the set
+ * {space1, space2} with the largest rank or space1 if the ranks
+ * are identical.
+ *
+ * Similarly, let space_b point to the element of {space1, space2}
+ * with the smallest rank, or space2 if they are identical.
+ *
+ * Let: space_a_rank be the rank of space_a,
+ * space_b_rank be the rank of space_b,
+ * delta_rank = space_a_rank - space_b_rank.
+ *
+ * Set all this up below.
+ */
+ if(space1->extent.rank >= space2->extent.rank) {
+ space_a = space1;
+ space_a_rank = space_a->extent.rank;
+
+ space_b = space2;
+ space_b_rank = space_b->extent.rank;
+ } /* end if */
+ else {
+ space_a = space2;
+ space_a_rank = space_a->extent.rank;
+
+ space_b = space1;
+ space_b_rank = space_b->extent.rank;
+ } /* end else */
+ HDassert(space_a_rank >= space_b_rank);
+ HDassert(space_b_rank > 0);
/* Check for different number of elements selected */
- if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
+ if(H5S_GET_SELECT_NPOINTS(space_a) != H5S_GET_SELECT_NPOINTS(space_b))
HGOTO_DONE(FALSE)
/* Check for "easy" cases before getting into generalized block iteration code */
- if(H5S_GET_SELECT_TYPE(space1)==H5S_SEL_ALL && H5S_GET_SELECT_TYPE(space2)==H5S_SEL_ALL) {
- hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
- hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
-
- if(H5S_get_simple_extent_dims(space1, dims1, NULL)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
- if(H5S_get_simple_extent_dims(space2, dims2, NULL)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
-
- /* Check that the sizes are the same */
- for (u=0; u<space1->extent.rank; u++)
- if(dims1[u]!=dims2[u])
- HGOTO_DONE(FALSE);
+ if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_ALL) && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_ALL)) {
+ hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
+ hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
+ int space_a_dim; /* Current dimension in dataspace A */
+ int space_b_dim; /* Current dimension in dataspace B */
+
+ if(H5S_get_simple_extent_dims(space_a, dims1, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
+ if(H5S_get_simple_extent_dims(space_b, dims2, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
+
+ space_a_dim = (int)space_a_rank - 1;
+ space_b_dim = (int)space_b_rank - 1;
+
+ /* recall that space_a_rank >= space_b_rank.
+ *
+ * In the following while loop, we test to see if space_a and space_b
+ * have identical size in all dimensions they have in common.
+ */
+ while(space_b_dim >= 0) {
+ if(dims1[space_a_dim] != dims2[space_b_dim])
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ space_b_dim--;
+ } /* end while */
+
+ /* Since we are selecting the entire spaces, we must also verify that space_a
+ * has size 1 in all dimensions that it does not share with space_b.
+ */
+ while(space_a_dim >= 0) {
+ if(dims1[space_a_dim] != 1)
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ } /* end while */
} /* end if */
- else if(H5S_GET_SELECT_TYPE(space1)==H5S_SEL_NONE || H5S_GET_SELECT_TYPE(space2)==H5S_SEL_NONE) {
- HGOTO_DONE(TRUE);
+ else if((H5S_GET_SELECT_TYPE(space1) == H5S_SEL_NONE) || (H5S_GET_SELECT_TYPE(space2) == H5S_SEL_NONE)) {
+ HGOTO_DONE(TRUE)
} /* end if */
- else if((H5S_GET_SELECT_TYPE(space1)==H5S_SEL_HYPERSLABS && space1->select.sel_info.hslab->diminfo_valid)
- && (H5S_GET_SELECT_TYPE(space2)==H5S_SEL_HYPERSLABS && space2->select.sel_info.hslab->diminfo_valid)) {
-
- /* Check that the shapes are the same */
- for (u=0; u<space1->extent.rank; u++) {
- if(space1->select.sel_info.hslab->opt_diminfo[u].stride!=space2->select.sel_info.hslab->opt_diminfo[u].stride)
- HGOTO_DONE(FALSE);
- if(space1->select.sel_info.hslab->opt_diminfo[u].count!=space2->select.sel_info.hslab->opt_diminfo[u].count)
- HGOTO_DONE(FALSE);
- if(space1->select.sel_info.hslab->opt_diminfo[u].block!=space2->select.sel_info.hslab->opt_diminfo[u].block)
- HGOTO_DONE(FALSE);
- } /* end for */
+ else if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_HYPERSLABS && space_a->select.sel_info.hslab->diminfo_valid)
+ && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_HYPERSLABS && space_b->select.sel_info.hslab->diminfo_valid)) {
+ int space_a_dim; /* Current dimension in dataspace A */
+ int space_b_dim; /* Current dimension in dataspace B */
+
+ space_a_dim = (int)space_a_rank - 1;
+ space_b_dim = (int)space_b_rank - 1;
+
+ /* check that the shapes are the same in the common dimensions, and that
+ * block == 1 in all dimensions that appear only in space_a.
+ */
+ while(space_b_dim >= 0) {
+ if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].stride !=
+ space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].stride)
+ HGOTO_DONE(FALSE)
+
+ if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].count !=
+ space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].count)
+ HGOTO_DONE(FALSE)
+
+ if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block !=
+ space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].block)
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ space_b_dim--;
+ } /* end while */
+
+ while(space_a_dim >= 0) {
+ if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != 1)
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ } /* end while */
} /* end if */
/* Iterate through all the blocks in the selection */
else {
- hsize_t start1[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace #1 */
- hsize_t start2[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace #2 */
- hsize_t end1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
- hsize_t end2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
- hsize_t off1[H5O_LAYOUT_NDIMS]; /* Offset of selection #1 blocks */
- hsize_t off2[H5O_LAYOUT_NDIMS]; /* Offset of selection #2 blocks */
- htri_t status1,status2; /* Status from next block checks */
- unsigned first_block=1; /* Flag to indicate the first block */
+ hsize_t start_a[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace a */
+ hsize_t start_b[H5O_LAYOUT_NDIMS]; /* Start point of selection block in dataspace b */
+ hsize_t end_a[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace a */
+ hsize_t end_b[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace b */
+ hsize_t off_a[H5O_LAYOUT_NDIMS]; /* Offset of selection a blocks */
+ hsize_t off_b[H5O_LAYOUT_NDIMS]; /* Offset of selection b blocks */
+ hbool_t first_block = TRUE; /* Flag to indicate the first block */
/* Initialize iterator for each dataspace selection
* Use '0' for element size instead of actual element size to indicate
* that the selection iterator shouldn't be "flattened", since we
* aren't actually going to be doing I/O with the iterators.
*/
- if(H5S_select_iter_init(&iter1, space1, (size_t)0) < 0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- iter1_init = 1;
- if(H5S_select_iter_init(&iter2, space2, (size_t)0) < 0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- iter2_init = 1;
+ if(H5S_select_iter_init(&iter_a, space_a, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a")
+ iter_a_init = 1;
+ if(H5S_select_iter_init(&iter_b, space_b, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b")
+ iter_b_init = 1;
/* Iterate over all the blocks in each selection */
while(1) {
+ int space_a_dim; /* Current dimension in dataspace A */
+ int space_b_dim; /* Current dimension in dataspace B */
+ htri_t status_a, status_b; /* Status from next block checks */
+
/* Get the current block for each selection iterator */
- if(H5S_SELECT_ITER_BLOCK(&iter1,start1,end1)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block");
- if(H5S_SELECT_ITER_BLOCK(&iter2,start2,end2)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block");
+ if(H5S_SELECT_ITER_BLOCK(&iter_a, start_a, end_a) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block a")
+ if(H5S_SELECT_ITER_BLOCK(&iter_b, start_b, end_b) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block b")
- /* The first block only compares the sizes and sets the relative offsets for later blocks */
+ space_a_dim = (int)space_a_rank - 1;
+ space_b_dim = (int)space_b_rank - 1;
+
+ /* The first block only compares the sizes and sets the
+ * relative offsets for later blocks
+ */
if(first_block) {
- /* If the block sizes from each selection doesn't match, get out */
- for (u=0; u<space1->extent.rank; u++) {
- if((end1[u]-start1[u])!=(end2[u]-start2[u]))
- HGOTO_DONE(FALSE);
+ /* If the block sizes in the common dimensions from
+ * each selection don't match, get out
+ */
+ while(space_b_dim >= 0) {
+ if((end_a[space_a_dim] - start_a[space_a_dim]) !=
+ (end_b[space_b_dim] - start_b[space_b_dim]))
+ HGOTO_DONE(FALSE)
+
+ /* Set the relative locations of the selections */
+ off_a[space_a_dim] = start_a[space_a_dim];
+ off_b[space_b_dim] = start_b[space_b_dim];
+
+ space_a_dim--;
+ space_b_dim--;
+ } /* end while */
+
+ /* similarly, if the block size in any dimension that appears only
+ * in space_a is not equal to 1, get out.
+ */
+ while(space_a_dim >= 0) {
+ if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
+ HGOTO_DONE(FALSE)
/* Set the relative locations of the selections */
- off1[u]=start1[u];
- off2[u]=start2[u];
- } /* end for */
+ off_a[space_a_dim] = start_a[space_a_dim];
+
+ space_a_dim--;
+ } /* end while */
/* Reset "first block" flag */
- first_block=0;
+ first_block = FALSE;
} /* end if */
+ /* Check over the blocks for each selection */
else {
- /* Check over the blocks for each selection */
- for (u=0; u<space1->extent.rank; u++) {
+ /* for dimensions that space_a and space_b have in common: */
+ while(space_b_dim >= 0) {
/* Check if the blocks are in the same relative location */
- if((start1[u]-off1[u])!=(start2[u]-off2[u]))
- HGOTO_DONE(FALSE);
+ if((start_a[space_a_dim] - off_a[space_a_dim]) !=
+ (start_b[space_b_dim] - off_b[space_b_dim]))
+ HGOTO_DONE(FALSE)
/* If the block sizes from each selection doesn't match, get out */
- if((end1[u]-start1[u])!=(end2[u]-start2[u]))
- HGOTO_DONE(FALSE);
- } /* end for */
+ if((end_a[space_a_dim] - start_a[space_a_dim]) !=
+ (end_b[space_b_dim] - start_b[space_b_dim]))
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ space_b_dim--;
+ } /* end while */
+
+ /* For dimensions that appear only in space_a: */
+ while(space_a_dim >= 0) {
+ /* If the block size isn't 1, get out */
+ if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
+ HGOTO_DONE(FALSE)
+
+ space_a_dim--;
+ } /* end while */
} /* end else */
/* Check if we are able to advance to the next selection block */
- if((status1=H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter1))<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block");
- if((status2=H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter2))<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block");
+ if((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_a)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block a")
+
+ if((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(&iter_b)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b")
/* Did we run out of blocks at the same time? */
- if(status1==FALSE && status2==FALSE)
+ if((status_a == FALSE) && (status_b == FALSE))
break;
- else if(status1!=status2) {
- HGOTO_DONE(FALSE);
- } /* end if */
+ else if(status_a != status_b)
+ HGOTO_DONE(FALSE)
else {
/* Advance to next block in selection iterators */
- if(H5S_SELECT_ITER_NEXT_BLOCK(&iter1)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block");
- if(H5S_SELECT_ITER_NEXT_BLOCK(&iter2)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block");
+ if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_a) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block a")
+
+ if(H5S_SELECT_ITER_NEXT_BLOCK(&iter_b) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block b")
} /* end else */
} /* end while */
} /* end else */
} /* end else */
done:
- if(iter1_init) {
- if (H5S_SELECT_ITER_RELEASE(&iter1)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
+ if(iter_a_init)
+ if(H5S_SELECT_ITER_RELEASE(&iter_a) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a")
+ if(iter_b_init)
+ if(H5S_SELECT_ITER_RELEASE(&iter_b) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_select_shape_same() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_construct_projection
+
+ PURPOSE
+ Given a dataspace a of rank n with some selection, construct a new
+ dataspace b of rank m (m != n), with the selection in a being
+ topologically identical to that in b (as verified by
+ H5S_select_shape_same().
+
+ This function exists, as some I/O code chokes of topologically
+ identical selections with different ranks. At least to begin
+ with, we will deal with the issue by constructing projections
+ of the memory dataspace with ranks equaling those of the file
+ dataspace.
+
+ Note that if m > n, it is possible that the starting point in the
+ buffer associated with the memory dataspace will have to be
+ adjusted to match the projected dataspace. If the buf parameter
+ is not NULL, the function must return an adjusted buffer base
+ address in *adj_buf_ptr.
+
+ USAGE
+ htri_t H5S_select_construct_projection(base_space,
+ new_space_ptr,
+ new_space_rank,
+ buf,
+ adj_buf_ptr)
+ const H5S_t *base_space; IN: Ptr to Dataspace to project
+ H5S_t ** new_space_ptr; OUT: Ptr to location in which to return
+ the address of the projected space
+ int new_space_rank; IN: Rank of the projected space.
+ const void * buf; IN: Base address of the buffer
+ associated with the base space.
+ May be NULL.
+ void ** adj_buf_ptr; OUT: If buf != NULL, store the base
+ address of the section of buf
+ that is described by *new_space_ptr
+ in *adj_buf_ptr.
+
+ RETURNS
+ Non-negative on success/Negative on failure.
+
+ DESCRIPTION
+ Construct a new dataspace and associated selection which is a
+ projection of the supplied dataspace and associated selection into
+ the specified rank. Return it in *new_space_ptr.
+
+ If buf is supplied, computes the base address of the projected
+ selection in buf, and stores the base address in *adj_buf_ptr.
+
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ The selection in the supplied base_space has thickness 1 in all
+ dimensions greater than new_space_rank. Note that here we count
+ dimensions from the fastest changing coordinate to the slowest
+ changing changing coordinate.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
+ unsigned new_space_rank, const void *buf, void **adj_buf_ptr, hsize_t element_size)
+{
+ H5S_t * new_space = NULL; /* New dataspace constructed */
+ hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */
+ hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */
+ int sbase_space_rank; /* Signed # of dimensions of base dataspace */
+ unsigned base_space_rank; /* # of dimensions of base dataspace */
+ hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_construct_projection, FAIL)
+
+ /* Sanity checks */
+ HDassert(base_space != NULL);
+ HDassert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) || (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE));
+ HDassert(new_space_ptr != NULL);
+ HDassert((new_space_rank != 0) || (H5S_GET_SELECT_NPOINTS(base_space) <= 1));
+ HDassert(new_space_rank <= H5S_MAX_RANK);
+ HDassert((buf == NULL) || (adj_buf_ptr != NULL));
+ HDassert(element_size > 0 );
+
+ /* Get the extent info for the base dataspace */
+ if((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality of base space")
+ base_space_rank = (unsigned)sbase_space_rank;
+ HDassert(base_space_rank != new_space_rank);
+
+ /* Check if projected space is scalar */
+ if(new_space_rank == 0) {
+ hssize_t npoints; /* Number of points selected */
+
+ /* Retreve the number of elements selected */
+ if((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected")
+ HDassert(npoints <= 1);
+
+ /* Create new scalar dataspace */
+ if(NULL == (new_space = H5S_create(H5S_SCALAR)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace")
+
+ /* No need to register the dataspace(i.e. get an ID) as
+ * we will just be discarding it shortly.
+ */
+
+ /* Selection for the new space will be either all or
+ * none, depending on whether the base space has 0 or
+ * 1 elements selected.
+ *
+ * Observe that the base space can't have more than
+ * one selected element, since its selection has the
+ * same shape as the file dataspace, and that data
+ * space is scalar.
+ */
+ if(1 == npoints) {
+ /* Assuming that the selection in the base dataspace is not
+ * empty, we must compute the offset of the selected item in
+ * the buffer associated with the base dataspace.
+ *
+ * Since the new space rank is zero, we know that the
+ * the base space must have rank at least 1 -- and
+ * hence it is a simple dataspace. However, the
+ * selection, may be either point, hyperspace, or all.
+ *
+ */
+ if(H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection")
+ } /* end if */
+ else {
+ HDassert(0 == npoints);
+
+ if(H5S_select_none(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
+ } /* end else */
+ } /* end if */
+ else { /* projected space must be simple */
+ hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */
+ hsize_t new_space_maxdims[H5S_MAX_RANK];/* Maximum dimensions for new dataspace */
+ unsigned rank_diff; /* Difference in ranks */
+
+ /* Set up the dimensions of the new, projected dataspace.
+ *
+ * How we do this depends on whether we are projecting up into
+ * increased dimensions, or down into a reduced number of
+ * dimensions.
+ *
+ * If we are projecting up (the first half of the following
+ * if statement), we copy the dimensions of the base data
+ * space into the fastest changing dimensions of the new
+ * projected dataspace, and set the remaining dimensions to
+ * one.
+ *
+ * If we are projecting down (the second half of the following
+ * if statement), we just copy the dimensions with the most
+ * quickly changing dimensions into the dims for the projected
+ * data set.
+ *
+ * This works, because H5S_select_shape_same() will return
+ * true on selections of different rank iff:
+ *
+ * 1) the selection in the lower rank dataspace matches that
+ * in the dimensions with the fastest changing indicies in
+ * the larger rank dataspace, and
+ *
+ * 2) the selection has thickness 1 in all ranks that appear
+ * only in the higher rank dataspace (i.e. those with
+ * more slowly changing indicies).
+ */
+ if(new_space_rank > base_space_rank) {
+ hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
+
+ /* we must copy the dimensions of the base space into
+ * the fastest changing dimensions of the new space,
+ * and set the remaining dimensions to 1
+ */
+ rank_diff = new_space_rank - base_space_rank;
+ H5V_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
+ H5V_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
+ HDmemcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank);
+ HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank);
+ } /* end if */
+ else { /* new_space_rank < base_space_rank */
+ /* we must copy the fastest changing dimension of the
+ * base space into the dimensions of the new space.
+ */
+ rank_diff = base_space_rank - new_space_rank;
+ HDmemcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank);
+ HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank);
+ } /* end else */
+
+ /* now have the new space rank and dimensions set up --
+ * so we can create the new simple dataspace.
+ */
+ if(NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
+
+ /* No need to register the dataspace(i.e. get an ID) as
+ * we will just be discarding it shortly.
+ */
+
+ /* If we get this far, we have successfully created the projected
+ * dataspace. We must now project the selection in the base
+ * dataspace into the projected dataspace.
+ */
+ if(H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection")
+
+ /* If we get this far, we have created the new dataspace, and projected
+ * the selection in the base dataspace into the new dataspace.
+ *
+ * If the base dataspace is simple, check to see if the
+ * offset_changed flag on the base selection has been set -- if so,
+ * project the offset into the new dataspace and set the
+ * offset_changed flag.
+ */
+ if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) {
+ if(new_space_rank > base_space_rank) {
+ HDmemset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff);
+ HDmemcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank);
+ } /* end if */
+ else
+ HDmemcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank);
+
+ /* Propagate the offset changed flag into the new dataspace. */
+ new_space->select.offset_changed = TRUE;
+ } /* end if */
+ } /* end else */
+
+ /* If we have done the projection correctly, the following assertion
+ * should hold.
+ */
+ HDassert(TRUE == H5S_select_shape_same(base_space, new_space));
+
+ /* load the address of the new space into *new_space_ptr */
+ *new_space_ptr = new_space;
+
+ /* now adjust the buffer if required */
+ if(buf != NULL) {
+ if(new_space_rank < base_space_rank) {
+ /* a bit of pointer magic here:
+ *
+ * Since we can't do pointer arithmetic on void pointers, we first
+ * cast buf to a pointer to byte -- i.e. uint8_t.
+ *
+ * We then multiply the projected space element offset we
+ * calculated earlier by the supplied element size, add this
+ * value to the type cast buf pointer, cast the result back
+ * to a pointer to void, and assign the result to *adj_buf_ptr.
+ */
+ *adj_buf_ptr = (void *)(((const uint8_t *)buf) +
+ ((size_t)(projected_space_element_offset * element_size)));
+ } /* end if */
+ else
+ /* No adjustment necessary */
+ *adj_buf_ptr = buf;
} /* end if */
- if(iter2_init) {
- if (H5S_SELECT_ITER_RELEASE(&iter2)<0)
- HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
+
+done:
+ /* Cleanup on error */
+ if(ret_value < 0) {
+ if(new_space && H5S_close(new_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5S_select_shape_same() */
+} /* H5S_select_construct_projection() */
/*--------------------------------------------------------------------------
@@ -1536,7 +2006,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b
/* Initialize iterator */
if(H5S_select_iter_init(&iter, space, fill_size) < 0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
iter_init = 1; /* Selection iteration info has been initialized */
/* Get the number of elements in selection */
@@ -1556,7 +2026,7 @@ H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_b
/* Get the sequences of bytes */
if(H5S_SELECT_GET_SEQ_LIST(space, 0, &iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
+ HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
/* Loop over sequences */
for(curr_seq = 0; curr_seq < nseq; curr_seq++) {