* fixed bug in h5bl_defin3dchunkdims call that was using variables addresses ins
* added new MultiBlock module that is used for efficiently loading regular rectilinear grid blocks (using chunking) and handling ghost zones in a distributed-memory environment ** still need to add the "halo exchange" routine for reshuffling ghost regions ** performed some basic testing of read/write functionality ~Mark
This commit is contained in:
@@ -33,6 +33,13 @@ src/H5BlockReadWrite.h -text
|
||||
src/H5BlockReadWriteF.c -text
|
||||
src/H5BlockReadWriteF90.inc -text
|
||||
src/H5BlockTypes.h -text
|
||||
src/H5MultiBlock.c -text
|
||||
src/H5MultiBlock.h -text
|
||||
src/H5MultiBlockErrors.h -text
|
||||
src/H5MultiBlockPrivate.h -text
|
||||
src/H5MultiBlockReadWrite.c -text
|
||||
src/H5MultiBlockReadWrite.h -text
|
||||
src/H5MultiBlockTypes.h -text
|
||||
src/H5Part.c -text
|
||||
src/H5Part.h -text
|
||||
src/H5PartErrors.h -text
|
||||
@@ -44,6 +51,7 @@ src/Makefile.am -text
|
||||
src/TestUnderscore.f -text
|
||||
src/TestUnderscoreC.c -text
|
||||
src/generate-h5bl-readwrite.py -text
|
||||
src/generate-h5multi-readwrite.py -text
|
||||
test/Bench.c -text
|
||||
test/BlockTestSpecs.txt -text
|
||||
test/H5BlockDissolveGhosts.c -text
|
||||
|
||||
+37
-36
@@ -182,6 +182,11 @@ _H5Block_close (
|
||||
if ( herr < 0 ) return HANDLE_H5S_CLOSE_ERR;
|
||||
b->memshape = -1;
|
||||
}
|
||||
if ( b->create_prop != H5P_DEFAULT ) {
|
||||
herr = H5Pclose ( b->create_prop );
|
||||
if ( herr < 0 ) return HANDLE_H5P_CLOSE_ERR ("create_prop");
|
||||
b->create_prop = H5P_DEFAULT;
|
||||
}
|
||||
free ( f->block );
|
||||
f->block = NULL;
|
||||
f->close_block = NULL;
|
||||
@@ -674,7 +679,7 @@ _dissolve_ghostzones (
|
||||
\internal
|
||||
|
||||
*/
|
||||
h5part_int64_t
|
||||
static h5part_int64_t
|
||||
_release_hyperslab (
|
||||
H5PartFile *f /*!< IN: file handle */
|
||||
) {
|
||||
@@ -720,7 +725,7 @@ H5BlockDefine3DFieldLayout(
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockDefine3DFieldLayout" );
|
||||
INIT( f );
|
||||
BLOCK_INIT( f );
|
||||
|
||||
struct H5BlockStruct *b = f->block;
|
||||
struct H5BlockPartition *p = &b->user_layout[f->myproc];
|
||||
@@ -731,7 +736,7 @@ H5BlockDefine3DFieldLayout(
|
||||
p->k_start = k_start;
|
||||
p->k_end = k_end;
|
||||
|
||||
_normalize_partition( p );
|
||||
_normalize_partition ( p );
|
||||
|
||||
h5part_int64_t herr = _allgather ( f );
|
||||
if ( herr < 0 ) return HANDLE_MPI_ALLGATHER_ERR;
|
||||
@@ -760,13 +765,13 @@ H5BlockDefine3DFieldLayout(
|
||||
h5part_int64_t
|
||||
H5BlockDefine3DChunkDims(
|
||||
H5PartFile *f, /*!< IN: File handle */
|
||||
const h5part_int64_t i, /*!< IN: size of \c i */
|
||||
const h5part_int64_t j, /*!< IN: size of \c j */
|
||||
const h5part_int64_t k /*!< IN: size of \c k */
|
||||
const h5part_int64_t i, /*!< IN: size of \c i */
|
||||
const h5part_int64_t j, /*!< IN: size of \c j */
|
||||
const h5part_int64_t k /*!< IN: size of \c k */
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockDefine3DChunkDims" );
|
||||
INIT( f );
|
||||
BLOCK_INIT( f );
|
||||
|
||||
struct H5BlockStruct *b = f->block;
|
||||
|
||||
@@ -782,6 +787,8 @@ H5BlockDefine3DChunkDims(
|
||||
(long long)b->chunk[0] );
|
||||
|
||||
b->create_prop = H5Pcreate (H5P_DATASET_CREATE);
|
||||
if (b->create_prop < 0) return HANDLE_H5P_CREATE_ERR;
|
||||
|
||||
herr_t herr = H5Pset_chunk ( b->create_prop, 3, b->chunk );
|
||||
if ( herr < 0 ) return HANDLE_H5P_SET_CHUNK_ERR;
|
||||
|
||||
@@ -804,7 +811,7 @@ H5BlockGet3DChunkDims(
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGet3DChunkDims" );
|
||||
INIT( f );
|
||||
BLOCK_INIT( f );
|
||||
|
||||
struct H5BlockStruct *b = f->block;
|
||||
|
||||
@@ -869,7 +876,7 @@ H5Block3dGetPartitionOfProc (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dGetProcOf" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
if ( ( proc < 0 ) || ( proc >= f->nprocs ) )
|
||||
@@ -909,7 +916,7 @@ H5Block3dGetReducedPartitionOfProc (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dGetProcOf" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
if ( ( proc < 0 ) || ( proc >= f->nprocs ) )
|
||||
@@ -945,7 +952,7 @@ H5Block3dGetProcOf (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dGetProcOf" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
struct H5BlockPartition *layout = f->block->write_layout;
|
||||
@@ -1060,8 +1067,8 @@ _H5Block_close_field_group (
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_select_hyperslab_for_reading (
|
||||
h5part_int64_t
|
||||
_H5Block_select_hyperslab_for_reading (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
hid_t dataset
|
||||
) {
|
||||
@@ -1155,6 +1162,7 @@ _H5Block_read_data (
|
||||
hid_t type /*!< IN: data type */
|
||||
) {
|
||||
|
||||
h5part_int64_t herr;
|
||||
struct H5BlockStruct *b = f->block;
|
||||
|
||||
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8
|
||||
@@ -1164,7 +1172,7 @@ _H5Block_read_data (
|
||||
#endif
|
||||
if ( dataset_id < 0 ) return HANDLE_H5D_OPEN_ERR ( name );
|
||||
|
||||
h5part_int64_t herr = _select_hyperslab_for_reading ( f, dataset_id );
|
||||
herr = _H5Block_select_hyperslab_for_reading ( f, dataset_id );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
herr = H5Dread (
|
||||
@@ -1172,7 +1180,7 @@ _H5Block_read_data (
|
||||
type,
|
||||
f->block->memshape,
|
||||
f->block->diskshape,
|
||||
H5P_DEFAULT,
|
||||
f->xfer_prop,
|
||||
data );
|
||||
if ( herr < 0 ) return HANDLE_H5D_READ_ERR ( name, f->timestep );
|
||||
|
||||
@@ -1400,7 +1408,6 @@ _H5Block_write_data (
|
||||
|
||||
herr_t herr;
|
||||
hid_t dataset;
|
||||
hid_t create_prop = H5P_DEFAULT;
|
||||
struct H5BlockStruct *b = f->block;
|
||||
|
||||
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8
|
||||
@@ -1420,7 +1427,6 @@ _H5Block_write_data (
|
||||
b->shape,
|
||||
b->create_prop );
|
||||
#endif
|
||||
|
||||
if ( dataset < 0 ) return HANDLE_H5D_CREATE_ERR ( name, f->timestep );
|
||||
|
||||
herr = H5Dwrite (
|
||||
@@ -1435,11 +1441,6 @@ _H5Block_write_data (
|
||||
herr = H5Dclose ( dataset );
|
||||
if ( herr < 0 ) return HANDLE_H5D_CLOSE_ERR;
|
||||
|
||||
if ( create_prop != H5P_DEFAULT ) {
|
||||
herr = H5Pclose ( create_prop );
|
||||
if ( herr < 0 ) return HANDLE_H5P_CLOSE_ERR ( "create_prop" );
|
||||
}
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1458,7 +1459,7 @@ H5BlockGetNumFields (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetNumFields" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
if ( ! _H5Part_have_group ( f->timegroup, H5BLOCK_GROUPNAME_BLOCK ) )
|
||||
@@ -1558,7 +1559,7 @@ H5BlockGetFieldInfo (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetFieldInfo" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
h5part_int64_t herr = _H5Part_get_object_name (
|
||||
@@ -1591,7 +1592,7 @@ H5BlockGetFieldInfoByName (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetFieldInfo" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
return _get_field_info (
|
||||
@@ -1620,7 +1621,7 @@ _write_field_attrib (
|
||||
h5part_int64_t herr = _H5Block_open_field_group ( f, field_name );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
_H5Part_write_attrib (
|
||||
herr = _H5Part_write_attrib (
|
||||
f->block->field_group_id,
|
||||
attrib_name,
|
||||
attrib_type,
|
||||
@@ -1653,7 +1654,7 @@ H5BlockWriteFieldAttrib (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockWriteFieldAttrib" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
@@ -1681,7 +1682,7 @@ H5BlockWriteFieldAttribString (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockWriteFieldAttribString" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
@@ -1706,7 +1707,7 @@ H5BlockGetNumFieldAttribs (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetNumFieldAttribs" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
h5part_int64_t herr = _H5Block_open_field_group ( f, field_name );
|
||||
@@ -1744,7 +1745,7 @@ H5BlockGetFieldAttribInfo (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetFieldAttribInfo" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
h5part_int64_t herr = _H5Block_open_field_group ( f, field_name );
|
||||
@@ -1815,7 +1816,7 @@ H5BlockReadFieldAttrib (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5PartReadFieldAttrib" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
return _read_field_attrib (
|
||||
@@ -1840,7 +1841,7 @@ H5Block3dGetFieldOrigin (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockSetFieldOrigin" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
h5part_float64_t origin[3];
|
||||
@@ -1874,7 +1875,7 @@ H5Block3dSetFieldOrigin (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockSetFieldOrigin" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
@@ -1906,7 +1907,7 @@ H5Block3dGetFieldSpacing (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockGetFieldSpacing" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
h5part_float64_t spacing[3];
|
||||
@@ -1940,7 +1941,7 @@ H5Block3dSetFieldSpacing (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockSetFieldSpacing" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
@@ -1970,7 +1971,7 @@ H5BlockHasFieldData (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5BlockHasFieldData" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
|
||||
if ( ! _H5Part_have_group ( f->timegroup, H5BLOCK_GROUPNAME_BLOCK ) ) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
_H5Part_get_funcname(), \
|
||||
H5PART_ERR_INVAL, \
|
||||
"Group \"%s\" already exists", name )
|
||||
|
||||
#define HANDLE_H5S_CREATE_SIMPLE_3D_ERR( dims ) \
|
||||
(*_err_handler) ( \
|
||||
_H5Part_get_funcname(), \
|
||||
|
||||
+4
-4
@@ -99,14 +99,14 @@ h5bl_define3dlayout (
|
||||
h5part_int64_t
|
||||
h5bl_define3dchunkdims (
|
||||
h5part_int64_t *f,
|
||||
const h5part_int64_t i,
|
||||
const h5part_int64_t j,
|
||||
const h5part_int64_t k
|
||||
const h5part_int64_t *i,
|
||||
const h5part_int64_t *j,
|
||||
const h5part_int64_t *k
|
||||
) {
|
||||
|
||||
H5PartFile *filehandle = (H5PartFile*)(size_t)*f;
|
||||
|
||||
return H5BlockDefine3DChunkDims ( filehandle, i, j, k );
|
||||
return H5BlockDefine3DChunkDims ( filehandle, *i, *j, *k );
|
||||
}
|
||||
|
||||
h5part_int64_t
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define H5BLOCK_GROUPNAME_BLOCK "Block"
|
||||
|
||||
#define INIT( f ) { \
|
||||
#define BLOCK_INIT( f ) { \
|
||||
h5part_int64_t herr = _H5Block_init ( f ); \
|
||||
if ( herr < 0 ) return herr; \
|
||||
}
|
||||
@@ -34,6 +34,12 @@ _H5Block_create_field_group (
|
||||
H5PartFile *f,
|
||||
const char *name
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
_H5Block_select_hyperslab_for_reading (
|
||||
H5PartFile *f,
|
||||
hid_t dataset
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
_H5Block_write_data (
|
||||
|
||||
+16
-16
@@ -31,7 +31,7 @@ H5Block3dWriteScalarFieldFloat64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWriteScalarFieldFloat64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -67,7 +67,7 @@ H5Block3dReadScalarFieldFloat64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dReadScalarFieldFloat64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -106,7 +106,7 @@ H5Block3dWrite3dVectorFieldFloat64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWrite3dVectorFieldFloat64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -150,7 +150,7 @@ H5Block3dRead3dVectorFieldFloat64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dRead3dVectorFieldFloat64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -189,7 +189,7 @@ H5Block3dWriteScalarFieldFloat32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWriteScalarFieldFloat32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -225,7 +225,7 @@ H5Block3dReadScalarFieldFloat32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dReadScalarFieldFloat32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -264,7 +264,7 @@ H5Block3dWrite3dVectorFieldFloat32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWrite3dVectorFieldFloat32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -308,7 +308,7 @@ H5Block3dRead3dVectorFieldFloat32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dRead3dVectorFieldFloat32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -347,7 +347,7 @@ H5Block3dWriteScalarFieldInt64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWriteScalarFieldInt64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -383,7 +383,7 @@ H5Block3dReadScalarFieldInt64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dReadScalarFieldInt64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -422,7 +422,7 @@ H5Block3dWrite3dVectorFieldInt64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWrite3dVectorFieldInt64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -466,7 +466,7 @@ H5Block3dRead3dVectorFieldInt64 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dRead3dVectorFieldInt64" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -505,7 +505,7 @@ H5Block3dWriteScalarFieldInt32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWriteScalarFieldInt32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -541,7 +541,7 @@ H5Block3dReadScalarFieldInt32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dReadScalarFieldInt32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -580,7 +580,7 @@ H5Block3dWrite3dVectorFieldInt32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dWrite3dVectorFieldInt32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -624,7 +624,7 @@ H5Block3dRead3dVectorFieldInt32 (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block3dRead3dVectorFieldInt32" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
|
||||
@@ -0,0 +1,779 @@
|
||||
/*!
|
||||
\defgroup h5multiblock_c_api H5MultiBlock C API
|
||||
|
||||
This package includes C code for writing and reading 3D datasets intended
|
||||
for distributed memory applications. The underlying file format is H5Part,
|
||||
a simple data storage schema and API derived from HDF5. In particular, we
|
||||
use the H5Block subset of H5Part for managing 3D field data. To achieve large
|
||||
contiguous reads and writes, the datasets use HDF5's chunking mechanism to
|
||||
reorder the layout on disk such that local subfields (or "blocks") of the
|
||||
3D field are stored contiguously (as opposed to storing an entire column
|
||||
contiguously, as in the Fortran column-major layout for an array). We refer
|
||||
to this chunked layout as "multiblock" and the column-major layout as
|
||||
"uniblock." Multiblocked datasets exhibit the following constraints:
|
||||
|
||||
* All blocks must be the same size (a requirement of the HDF5 chunking
|
||||
mechanism).
|
||||
* The block dimensions must divide the field dimensions, to prevent fringe
|
||||
data that will lower performance by interfering with contiguous I/O
|
||||
operations.
|
||||
* For load-balancing purposes, the total number of blocks that the field
|
||||
is decomposed into must be a multiple of the number of nodes in the
|
||||
distributed system. (For ease of implementation, we require that the
|
||||
number of blocks equal the number of nodes.)
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
\defgroup h5multiblock_static H5MultiBlock Static
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
\defgroup h5multiblock_private H5MultiBlock Private
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <hdf5.h>
|
||||
#include "H5Part.h"
|
||||
#include "H5PartErrors.h"
|
||||
#include "H5PartPrivate.h"
|
||||
|
||||
#include "H5Block.h"
|
||||
#include "H5BlockTypes.h"
|
||||
#include "H5BlockErrors.h"
|
||||
#include "H5BlockPrivate.h"
|
||||
|
||||
#include "H5MultiBlock.h"
|
||||
#include "H5MultiBlockTypes.h"
|
||||
#include "H5MultiBlockErrors.h"
|
||||
#include "H5MultiBlockPrivate.h"
|
||||
|
||||
#ifdef PARALLEL_IO
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static functions
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Check whether \c f points to a valid file handle.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_file_is_valid (
|
||||
const H5PartFile *f /*!< IN: file handle */
|
||||
) {
|
||||
|
||||
if ( f == NULL )
|
||||
return H5PART_ERR_BADFD;
|
||||
if ( f->file == 0 )
|
||||
return H5PART_ERR_BADFD;
|
||||
if ( f->block == NULL )
|
||||
return H5PART_ERR_BADFD;
|
||||
if ( f->multiblock == NULL )
|
||||
return H5PART_ERR_BADFD;
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Gets the block decomposition and offsets.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_get_decomp_and_offsets (
|
||||
const H5PartFile *f /*!< IN: file handle */
|
||||
) {
|
||||
|
||||
h5part_int64_t i, j, k;
|
||||
h5part_int64_t nblocks;
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
mb->decomp[0] = mb->field_dims[0] / mb->block_dims[0];
|
||||
mb->decomp[1] = mb->field_dims[1] / mb->block_dims[1];
|
||||
mb->decomp[2] = mb->field_dims[2] / mb->block_dims[2];
|
||||
|
||||
_H5Part_print_debug ("PROC[%d]: Block decomposition: (%ld,%ld,%ld)",
|
||||
f->myproc,
|
||||
mb->decomp[0],
|
||||
mb->decomp[1],
|
||||
mb->decomp[2] );
|
||||
|
||||
i = f->myproc % mb->decomp[0];
|
||||
j = (f->myproc / mb->decomp[0]) % mb->decomp[1];
|
||||
k = f->myproc / (mb->decomp[0] * mb->decomp[1]);
|
||||
|
||||
/* keep track of blocks that border the edges of the field */
|
||||
if (i == 0) mb->field_edges | H5MB_EDGE_X0;
|
||||
if (i == mb->decomp[0] - 1) mb->field_edges | H5MB_EDGE_X1;
|
||||
if (j == 0) mb->field_edges | H5MB_EDGE_Y0;
|
||||
if (j == mb->decomp[1] - 1) mb->field_edges | H5MB_EDGE_Y1;
|
||||
if (j == 0) mb->field_edges | H5MB_EDGE_Z0;
|
||||
if (j == mb->decomp[2] - 1) mb->field_edges | H5MB_EDGE_Z1;
|
||||
|
||||
mb->offsets[0] = i * mb->block_dims[0];
|
||||
mb->offsets[1] = j * mb->block_dims[1];
|
||||
mb->offsets[2] = k * mb->block_dims[2];
|
||||
|
||||
_H5Part_print_debug ("PROC[%d]: Block offsets: (%ld,%ld,%ld)",
|
||||
f->myproc,
|
||||
mb->offsets[0],
|
||||
mb->offsets[1],
|
||||
mb->offsets[0] );
|
||||
|
||||
nblocks = mb->decomp[0] * mb->decomp[1] * mb->decomp[2];
|
||||
|
||||
if (f->myproc == 0) {
|
||||
_H5Part_print_info ("Number of blocks: %ld", nblocks);
|
||||
}
|
||||
|
||||
if (nblocks != f->nprocs) {
|
||||
return HANDLE_H5PART_BLOCK_DECOMP_ERR;
|
||||
}
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Calculates an integer \c divisor of \c m that is >= the \c n root of \c m.
|
||||
|
||||
Used for finding block decompositions for an arbitrary number of processors.
|
||||
|
||||
\return \c divisor
|
||||
*/
|
||||
static int
|
||||
_nth_root_int_divisor (const int m, const int n)
|
||||
{
|
||||
int i, root;
|
||||
double p;
|
||||
|
||||
p = 1.0 / (double) n;
|
||||
root = (int) ceil ( pow ((double) m, p) );
|
||||
for (i=root; i<=m; i++)
|
||||
{
|
||||
if (m % i == 0) return i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Allocates a block using the dimensions read from the file and the halo
|
||||
radii specified by the user.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_alloc_block (
|
||||
const H5PartFile *f, /*!< IN: file handle */
|
||||
char **data, /*!< IN/OUT: buffer to alloc */
|
||||
hid_t type /*!< IN: HDF5 datatype of buffer */
|
||||
) {
|
||||
|
||||
char *buffer;
|
||||
size_t datasize;
|
||||
size_t nelems;
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
/* size of datatype */
|
||||
datasize = H5Tget_size ( type );
|
||||
|
||||
/* number of elements */
|
||||
nelems = mb->block_dims[0] + 2*mb->halo_radii[0];
|
||||
nelems *= mb->block_dims[1] + 2*mb->halo_radii[1];
|
||||
nelems *= mb->block_dims[2] + 2*mb->halo_radii[2];
|
||||
|
||||
buffer = (char*) malloc ( nelems * datasize );
|
||||
if ( ! buffer ) return HANDLE_H5PART_NOMEM_ERR;
|
||||
|
||||
*data = buffer;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Takes a contiguous buffer of data and rearranges it in place to add padding
|
||||
with \c radius layers. Assumes that \c buffer is already large enough to
|
||||
perform this operation.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_pad_block (
|
||||
const H5PartFile *f, /*!< IN: file handle */
|
||||
char *data, /*!< IN/OUT: buffer to pad */
|
||||
hid_t type /*!< IN: HDF5 datatype of buffer */
|
||||
) {
|
||||
|
||||
size_t datasize;
|
||||
h5part_int64_t j, k;
|
||||
h5part_int64_t iDst, iSrc;
|
||||
h5part_int64_t xSize, xySize;
|
||||
h5part_int64_t hxSize, hxySize;
|
||||
h5part_int64_t hxInset;
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
/* size of datatype */
|
||||
datasize = H5Tget_size ( type );
|
||||
|
||||
/* size of row in original block */
|
||||
xSize = mb->block_dims[0] * datasize;
|
||||
|
||||
/* size of slab in original block */
|
||||
xySize = xSize * mb->block_dims[1];
|
||||
|
||||
/* size of row/slab with halo regions */
|
||||
hxSize = (mb->block_dims[0] + 2*mb->halo_radii[0]) * datasize;
|
||||
hxySize = hxSize * (mb->block_dims[1] + 2*mb->halo_radii[1]);
|
||||
|
||||
/* inset of row in halo region */
|
||||
hxInset = mb->halo_radii[0] * datasize;
|
||||
|
||||
for (k=(mb->block_dims[2]-1);k>=0;k--)
|
||||
{
|
||||
for (j=(mb->block_dims[1]-1);j>=0;j--)
|
||||
{
|
||||
iSrc = k*xySize + j*xSize;
|
||||
|
||||
iDst = (k + mb->halo_radii[2]) * hxySize +
|
||||
(j + mb->halo_radii[1]) * hxSize +
|
||||
hxInset;
|
||||
|
||||
memcpy ( data + iDst, data + iSrc, xSize );
|
||||
}
|
||||
}
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_static
|
||||
|
||||
\internal
|
||||
|
||||
Exchanges halo regions among neighboring blocks using MPI.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
static h5part_int64_t
|
||||
_halo_exchange (
|
||||
const H5PartFile *f, /*!< IN: file handle */
|
||||
char *data, /*!< IN/OUT: local buffer */
|
||||
hid_t type /*!< IN: HDF5 datatype of buffer */
|
||||
) {
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Private functions
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_private
|
||||
|
||||
\internal
|
||||
|
||||
Initialize H5MultiBlock internal structure.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_init (
|
||||
H5PartFile *f /*!< IN: file handle */
|
||||
) {
|
||||
|
||||
struct H5MultiBlockStruct *mb;
|
||||
|
||||
BLOCK_INIT( f );
|
||||
|
||||
if (f->multiblock != NULL) return H5PART_SUCCESS;
|
||||
|
||||
f->multiblock =
|
||||
(struct H5MultiBlockStruct*) malloc( sizeof (*f->multiblock) );
|
||||
if ( f->multiblock == NULL ) {
|
||||
return HANDLE_H5PART_NOMEM_ERR;
|
||||
}
|
||||
mb = f->multiblock;
|
||||
|
||||
mb->field_edges = 0;
|
||||
mb->halo = 0;
|
||||
mb->read = 0;
|
||||
mb->have_decomp = 0;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_private
|
||||
|
||||
\internal
|
||||
|
||||
Free H5MultiBlock internal struct;
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_close (
|
||||
H5PartFile *f /*!< IN: file handle */
|
||||
) {
|
||||
|
||||
free ( f->multiblock );
|
||||
f->multiblock = NULL;
|
||||
f->close_multiblock = NULL;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_private
|
||||
|
||||
\internal
|
||||
|
||||
Read a multiblock field \c name into the buffer starting at \c data
|
||||
using the current time-step and the block decomposition and dimensions
|
||||
defined in the file.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_read_data (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *field_name, /*!< IN: Name of field */
|
||||
char **data, /*!< OUT: ptr to read buffer ptr*/
|
||||
hid_t type /*!< IN: HDF5 datatype of buffer */
|
||||
) {
|
||||
|
||||
MULTIBLOCK_INIT( f );
|
||||
|
||||
hid_t dataset_id;
|
||||
hid_t dataspace_id;
|
||||
int rank;
|
||||
h5part_int64_t herr;
|
||||
|
||||
struct H5BlockStruct *b = f->block;
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
char * const fname = _H5Part_get_funcname();
|
||||
|
||||
herr = _H5Block_open_field_group ( f, field_name );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8
|
||||
dataset_id = H5Dopen2 ( b->field_group_id, "0", H5P_DEFAULT );
|
||||
#else
|
||||
dataset_id = H5Dopen ( b->field_group_id, "0" );
|
||||
#endif
|
||||
if ( dataset_id < 0 ) return HANDLE_H5D_OPEN_ERR ( "0" );
|
||||
|
||||
/* read block dimensions from field attribute */
|
||||
herr = _H5Part_read_attrib (
|
||||
b->field_group_id,
|
||||
H5MULTIBLOCK_ATTR_NAME,
|
||||
mb->block_dims );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
_H5Part_print_debug ("PROC[%d]: Block dimensions: (%ld,%ld,%ld)",
|
||||
f->myproc,
|
||||
mb->block_dims[0],
|
||||
mb->block_dims[1],
|
||||
mb->block_dims[2] );
|
||||
|
||||
dataspace_id = H5Dget_space ( dataset_id );
|
||||
if ( dataspace_id < 0 ) return HANDLE_H5D_GET_SPACE_ERR;
|
||||
|
||||
rank = H5Sget_simple_extent_dims (
|
||||
dataspace_id,
|
||||
(hsize_t*)mb->field_dims,
|
||||
NULL );
|
||||
if ( rank < 0 ) return HANDLE_H5S_GET_SIMPLE_EXTENT_DIMS_ERR;
|
||||
if ( rank != 3 ) return HANDLE_H5PART_DATASET_RANK_ERR ( rank, 3 );
|
||||
|
||||
herr = _alloc_block ( f, data, type );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
herr = _get_decomp_and_offsets ( f );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
mb->have_decomp = 1;
|
||||
|
||||
herr = H5BlockDefine3DFieldLayout ( f,
|
||||
mb->offsets[0], mb->offsets[0] + mb->block_dims[0] - 1,
|
||||
mb->offsets[1], mb->offsets[1] + mb->block_dims[1] - 1,
|
||||
mb->offsets[2], mb->offsets[2] + mb->block_dims[2] - 1);
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
_H5Part_set_funcname ( fname );
|
||||
|
||||
herr = _H5Block_select_hyperslab_for_reading ( f, dataset_id );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
herr = H5Dread (
|
||||
dataset_id,
|
||||
type,
|
||||
f->block->memshape,
|
||||
f->block->diskshape,
|
||||
f->xfer_prop,
|
||||
*data );
|
||||
if ( herr < 0 ) return HANDLE_H5D_READ_ERR ( field_name, f->timestep );
|
||||
|
||||
herr = H5Dclose ( dataset_id );
|
||||
if ( herr < 0 ) return HANDLE_H5D_CLOSE_ERR;
|
||||
|
||||
herr = _H5Block_close_field_group ( f );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
if ( mb->halo ) {
|
||||
_pad_block ( f, *data, type );
|
||||
_halo_exchange ( f, *data, type );
|
||||
}
|
||||
|
||||
mb->read = 1;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_private
|
||||
|
||||
\internal
|
||||
|
||||
Write a multiblock field \c name from the buffer starting at \c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
|
||||
\return H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_write_data (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const void* data, /*!< IN: data buffer */
|
||||
hid_t type /*!< IN: HDF5 datatype */
|
||||
) {
|
||||
|
||||
MULTIBLOCK_INIT( f );
|
||||
CHECK_WRITABLE_MODE( f );
|
||||
CHECK_TIMEGROUP( f );
|
||||
CHECK_DECOMP ( f );
|
||||
|
||||
hid_t dataset;
|
||||
h5part_int64_t herr;
|
||||
|
||||
struct H5BlockStruct *b = f->block;
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
char * const fname = _H5Part_get_funcname();
|
||||
|
||||
herr = H5BlockDefine3DFieldLayout ( f,
|
||||
mb->offsets[0], mb->offsets[0] + mb->block_dims[0] - 1,
|
||||
mb->offsets[1], mb->offsets[1] + mb->block_dims[1] - 1,
|
||||
mb->offsets[2], mb->offsets[2] + mb->block_dims[2] - 1);
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
herr = H5BlockDefine3DChunkDims( f,
|
||||
mb->block_dims[0],
|
||||
mb->block_dims[1],
|
||||
mb->block_dims[2]);
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
_H5Part_set_funcname ( fname );
|
||||
|
||||
herr = _H5Block_create_field_group ( f, name );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8
|
||||
dataset = H5Dcreate2 (
|
||||
b->field_group_id,
|
||||
"0",
|
||||
type,
|
||||
b->shape,
|
||||
H5P_DEFAULT,
|
||||
b->create_prop,
|
||||
H5P_DEFAULT );
|
||||
#else
|
||||
dataset = H5Dcreate (
|
||||
b->field_group_id,
|
||||
"0",
|
||||
type,
|
||||
b->shape,
|
||||
b->create_prop );
|
||||
#endif
|
||||
if ( dataset < 0 ) return HANDLE_H5D_CREATE_ERR ( name, f->timestep );
|
||||
|
||||
herr = H5Dwrite (
|
||||
dataset,
|
||||
type,
|
||||
b->memshape,
|
||||
b->diskshape,
|
||||
f->xfer_prop,
|
||||
data );
|
||||
if ( herr < 0 ) return HANDLE_H5D_WRITE_ERR ( name, f->timestep );
|
||||
|
||||
herr = H5Dclose ( dataset );
|
||||
if ( herr < 0 ) return HANDLE_H5D_CLOSE_ERR;
|
||||
|
||||
/* write out the block dimensions to a special field attribute */
|
||||
herr = _H5Part_write_attrib (
|
||||
f->block->field_group_id,
|
||||
H5MULTIBLOCK_ATTR_NAME,
|
||||
H5T_NATIVE_INT64,
|
||||
mb->block_dims,
|
||||
3 );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
herr = _H5Block_close_field_group ( f );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Public API
|
||||
*******************************************************************************/
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Define the radius for halo exchanges between the blocks. Blocks on the edges
|
||||
of the field will be padded with zero values out to the radius.
|
||||
|
||||
\return \c H5PART_SUCCESS on success
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineRadius (
|
||||
H5PartFile *f, /* IN: file handle */
|
||||
const h5part_int64_t r /* IN: radius for i, j and k directions*/
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dDefineRadius" );
|
||||
MULTIBLOCK_INIT( f );
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
mb->halo_radii[0] =
|
||||
mb->halo_radii[1] =
|
||||
mb->halo_radii[2] = r;
|
||||
|
||||
mb->halo = 1;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Define the radii for halo exchanges between the blocks. Blocks on the edges
|
||||
of the field will be padded with zero values out to the radius.
|
||||
|
||||
Different radii can be set for each direction.
|
||||
|
||||
\return \c H5PART_SUCCESS on success
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineRadii (
|
||||
H5PartFile *f, /* IN: file handle */
|
||||
const h5part_int64_t ri, /* IN: radius for i direction */
|
||||
const h5part_int64_t rj, /* IN: radius for j direction */
|
||||
const h5part_int64_t rk /* IN: radius for k direction */
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dDefineRadii" );
|
||||
MULTIBLOCK_INIT( f );
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
mb->halo_radii[0] = rk;
|
||||
mb->halo_radii[1] = rj;
|
||||
mb->halo_radii[2] = ri;
|
||||
|
||||
mb->halo = 1;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Define the field and block dimensions for writing.
|
||||
|
||||
\return \c H5PART_SUCCESS on success
|
||||
\c H5PART_ERR_INVAL if block dims do not divide field dims
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineDims (
|
||||
H5PartFile *f, /* IN: file handle */
|
||||
const h5part_int64_t *field_dims, /* IN: field dimensions */
|
||||
const h5part_int64_t *block_dims /* IN: block dimensions */
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dDefineDims" );
|
||||
MULTIBLOCK_INIT ( f );
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
mb->field_dims[0] = field_dims[0];
|
||||
mb->field_dims[1] = field_dims[1];
|
||||
mb->field_dims[2] = field_dims[2];
|
||||
|
||||
mb->block_dims[0] = block_dims[0];
|
||||
mb->block_dims[1] = block_dims[1];
|
||||
mb->block_dims[2] = block_dims[2];
|
||||
|
||||
h5part_int64_t herr = _get_decomp_and_offsets ( f );
|
||||
if ( herr < 0 ) return H5PART_ERR_INVAL;
|
||||
|
||||
mb->have_decomp = 1;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Returns the field dimensions of the last field that was read.
|
||||
|
||||
\return \c H5PART_SUCCESS on success<br>
|
||||
\c H5PART_ERR_INVAL if no field has been read yet
|
||||
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetFieldDims(
|
||||
H5PartFile *f,
|
||||
h5part_int64_t *dims
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dGetFieldDims" );
|
||||
MULTIBLOCK_INIT ( f );
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
if ( ! mb->read ) return H5PART_ERR_INVAL;
|
||||
|
||||
dims[0] = mb->field_dims[0];
|
||||
dims[1] = mb->field_dims[1];
|
||||
dims[2] = mb->field_dims[2];
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Returns the block dimensions of the last field that was read.
|
||||
|
||||
\return \c H5PART_SUCCESS on success<br>
|
||||
\c H5PART_ERR_INVAL if no field has been read yet
|
||||
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetBlockDims(
|
||||
H5PartFile *f, /* IN: file handle */
|
||||
const char *field_name, /* IN: field name */
|
||||
h5part_int64_t *dims /* OUT: block dimensions */
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dGetBlockDims" );
|
||||
MULTIBLOCK_INIT ( f );
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
if ( ! mb->read ) return H5PART_ERR_INVAL;
|
||||
|
||||
dims[0] = mb->block_dims[0];
|
||||
dims[1] = mb->block_dims[1];
|
||||
dims[2] = mb->block_dims[2];
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Return the offsets for the block belonging to processor \c proc.
|
||||
|
||||
\return \c H5PART_SUCCESS on success<br>
|
||||
\c H5PART_ERR_INVAL if proc is invalid
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetOffsetsOfProc (
|
||||
H5PartFile *f, /* IN: file handle */
|
||||
const h5part_int64_t proc, /* IN: processor number */
|
||||
h5part_int64_t *offsets /* OUT: 3d array of offsets */
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5MultiBlock3dGetOffsetsOfProc" );
|
||||
MULTIBLOCK_INIT ( f );
|
||||
|
||||
if ( ( proc < 0 ) || ( proc >= f->nprocs ) )
|
||||
return H5PART_ERR_INVAL;
|
||||
|
||||
struct H5MultiBlockStruct *mb = f->multiblock;
|
||||
|
||||
offsets[0] = mb->offsets[0];
|
||||
offsets[1] = mb->offsets[1];
|
||||
offsets[2] = mb->offsets[2];
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Finds a 3D block decomposition for an arbitrary number of processors
|
||||
\c nprocs.
|
||||
|
||||
\return \c H5PART_SUCCESS on success<br>
|
||||
\c H5PART_ERR_INVAL if the decomp doesn't have \c nprocs blocks
|
||||
*/
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dCalculateDecomp (
|
||||
const int nprocs, /*!< IN: number of processors/blocks */
|
||||
h5part_int64_t *decomp /*!< OUT: 3D block decomposition */
|
||||
) {
|
||||
|
||||
decomp[0] = _nth_root_int_divisor (nprocs, 3);
|
||||
decomp[1] = _nth_root_int_divisor (nprocs / decomp[0], 2);
|
||||
decomp[2] = nprocs / decomp[0] / decomp[1];
|
||||
|
||||
if (decomp[0] * decomp[1] * decomp[2] != nprocs) {
|
||||
return H5PART_ERR_INVAL;
|
||||
}
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef __H5MULTIBLOCK_H
|
||||
#define __H5MULTIBLOCK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Include read/write call variants for different data types and
|
||||
field dimensions.
|
||||
*/
|
||||
#include "H5MultiBlockReadWrite.h"
|
||||
|
||||
#define H5MULTIBLOCK_ATTR_NAME "__BlockDims__"
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineRadius (
|
||||
H5PartFile *f,
|
||||
const h5part_int64_t r
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineRadii (
|
||||
H5PartFile *f,
|
||||
const h5part_int64_t ri,
|
||||
const h5part_int64_t rj,
|
||||
const h5part_int64_t rk
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dDefineDims (
|
||||
H5PartFile *f,
|
||||
const h5part_int64_t *field_dims,
|
||||
const h5part_int64_t *block_dims
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetFieldDims(
|
||||
H5PartFile *f,
|
||||
h5part_int64_t *dims
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetBlockDims(
|
||||
H5PartFile *f,
|
||||
const char *field_name,
|
||||
h5part_int64_t *dims
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dGetOffsetsOfProc (
|
||||
H5PartFile *f,
|
||||
const h5part_int64_t proc,
|
||||
h5part_int64_t *offsets
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dCalculateDecomp (
|
||||
const int nprocs,
|
||||
h5part_int64_t *decomp
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef __H5MULTIBLOCKERRORS_H
|
||||
#define __H5MULTIBLOCKERRORS_H
|
||||
|
||||
#define _err_handler H5PartGetErrorHandler()
|
||||
|
||||
#define CHECK_DECOMP( f ) \
|
||||
if ( ! f->multiblock->have_decomp ) \
|
||||
return (*_err_handler) ( \
|
||||
_H5Part_get_funcname(), \
|
||||
H5PART_ERR_DECOMP, \
|
||||
"No dimensions defined." )
|
||||
|
||||
#define HANDLE_H5PART_BLOCK_DECOMP_ERR \
|
||||
(*_err_handler) ( \
|
||||
_H5Part_get_funcname(), \
|
||||
H5PART_ERR_DECOMP, \
|
||||
"Number of blocks does not equal number of procs" );
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef __H5MULTIBLOCKPRIVATE_H
|
||||
#define __H5MULTIBLOCKPRIVATE_H
|
||||
|
||||
#define MULTIBLOCK_INIT( f ) { \
|
||||
h5part_int64_t herr = _H5MultiBlock_init ( f ); \
|
||||
if ( herr < 0 ) return herr; \
|
||||
}
|
||||
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_init (
|
||||
H5PartFile *f
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_close (
|
||||
H5PartFile *f
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_write_data (
|
||||
H5PartFile *f,
|
||||
const char *field_name,
|
||||
const void *data,
|
||||
const hid_t type
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
_H5MultiBlock_read_data (
|
||||
H5PartFile *f,
|
||||
const char *field_name,
|
||||
char **data,
|
||||
hid_t type
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,239 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <hdf5.h>
|
||||
#include "H5Part.h"
|
||||
#include "H5PartErrors.h"
|
||||
#include "H5PartPrivate.h"
|
||||
|
||||
#include "H5MultiBlockErrors.h"
|
||||
#include "H5MultiBlockPrivate.h"
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Write a multiblock field \c name from the buffer starting at \c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
Values are floating points (64-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldFloat64 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const h5part_float64_t *data /*!< IN: data to write */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dWriteFieldFloat64" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_write_data ( f, name, data, H5T_NATIVE_DOUBLE );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Allocate a buffer to hold a block from a multiblock field and place the
|
||||
pointer in \c data, then read the block into the buffer. Uses the block
|
||||
decomposition specified in the file and the defined halo radius.
|
||||
Values are floating points (64-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldFloat64 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to read */
|
||||
h5part_float64_t **data /*!< OUT: ptr to read buffer */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dReadFieldFloat64" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_read_data ( f, name, (char**) data, H5T_NATIVE_DOUBLE );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Write a multiblock field \c name from the buffer starting at \c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
Values are floating points (32-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldFloat32 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const h5part_float32_t *data /*!< IN: data to write */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dWriteFieldFloat32" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_write_data ( f, name, data, H5T_NATIVE_FLOAT );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Allocate a buffer to hold a block from a multiblock field and place the
|
||||
pointer in \c data, then read the block into the buffer. Uses the block
|
||||
decomposition specified in the file and the defined halo radius.
|
||||
Values are floating points (32-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldFloat32 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to read */
|
||||
h5part_float32_t **data /*!< OUT: ptr to read buffer */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dReadFieldFloat32" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_read_data ( f, name, (char**) data, H5T_NATIVE_FLOAT );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Write a multiblock field \c name from the buffer starting at \c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
Values are integers (64-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldInt64 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const h5part_int64_t *data /*!< IN: data to write */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dWriteFieldInt64" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_write_data ( f, name, data, H5T_NATIVE_INT64 );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Allocate a buffer to hold a block from a multiblock field and place the
|
||||
pointer in \c data, then read the block into the buffer. Uses the block
|
||||
decomposition specified in the file and the defined halo radius.
|
||||
Values are integers (64-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldInt64 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to read */
|
||||
h5part_int64_t **data /*!< OUT: ptr to read buffer */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dReadFieldInt64" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_read_data ( f, name, (char**) data, H5T_NATIVE_INT64 );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Write a multiblock field \c name from the buffer starting at \c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
Values are integers (32-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldInt32 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const h5part_int32_t *data /*!< IN: data to write */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dWriteFieldInt32" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_write_data ( f, name, data, H5T_NATIVE_INT32 );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\ingroup h5multiblock_c_api
|
||||
|
||||
Allocate a buffer to hold a block from a multiblock field and place the
|
||||
pointer in \c data, then read the block into the buffer. Uses the block
|
||||
decomposition specified in the file and the defined halo radius.
|
||||
Values are integers (32-bit).
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \c data.
|
||||
|
||||
\return \c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldInt32 (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to read */
|
||||
h5part_int32_t **data /*!< OUT: ptr to read buffer */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock3dReadFieldInt32" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_read_data ( f, name, (char**) data, H5T_NATIVE_INT32 );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
#ifndef __H5MULTIBLOCKREADWRITE_H
|
||||
#define __H5MULTIBLOCKREADWRITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldFloat64 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
const h5part_float64_t *data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldFloat64 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
h5part_float64_t **data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldFloat32 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
const h5part_float32_t *data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldFloat32 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
h5part_float32_t **data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldInt64 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
const h5part_int64_t *data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldInt64 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
h5part_int64_t **data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dWriteFieldInt32 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
const h5part_int32_t *data
|
||||
);
|
||||
|
||||
h5part_int64_t
|
||||
H5MultiBlock3dReadFieldInt32 (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
h5part_int32_t **data
|
||||
);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef __H5MULTIBLOCKTYPES_H
|
||||
#define __H5MULTIBLOCKTYPES_H
|
||||
|
||||
struct H5MultiBlockStruct {
|
||||
h5part_int64_t halo_radii[3];
|
||||
h5part_int64_t block_dims[3];
|
||||
h5part_int64_t field_dims[3];
|
||||
h5part_int64_t decomp[3];
|
||||
h5part_int64_t offsets[3];
|
||||
char field_edges;
|
||||
int read;
|
||||
int halo;
|
||||
int have_decomp;
|
||||
};
|
||||
|
||||
#define H5PART_ERR_DECOMP -102
|
||||
|
||||
#define H5MB_EDGE_X0 0x01
|
||||
#define H5MB_EDGE_X1 0x02
|
||||
#define H5MB_EDGE_Y0 0x04
|
||||
#define H5MB_EDGE_Y1 0x08
|
||||
#define H5MB_EDGE_Z0 0x10
|
||||
#define H5MB_EDGE_Z1 0x20
|
||||
|
||||
#endif
|
||||
+13
-3
@@ -100,7 +100,7 @@ Last modified on April 19, 2007.
|
||||
static unsigned _debug = 0;
|
||||
static h5part_int64_t _h5part_errno = H5PART_SUCCESS;
|
||||
static h5part_error_handler _err_handler = H5PartReportErrorHandler;
|
||||
static char *__funcname = "NONE";
|
||||
static char *__funcname;
|
||||
|
||||
/********** Declaration of private functions ******/
|
||||
|
||||
@@ -512,6 +512,14 @@ H5PartCloseFile (
|
||||
f->close_block = NULL;
|
||||
}
|
||||
|
||||
#ifdef PARALLEL_IO
|
||||
if ( f->multiblock && f->close_multiblock ) {
|
||||
(*f->close_multiblock) ( f );
|
||||
f->multiblock = NULL;
|
||||
f->close_multiblock = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( f->shape > 0 ) {
|
||||
r = H5Sclose( f->shape );
|
||||
if ( r < 0 ) HANDLE_H5S_CLOSE_ERR;
|
||||
@@ -2878,6 +2886,7 @@ _init ( void ) {
|
||||
|
||||
herr_t r5;
|
||||
if ( ! __init ) {
|
||||
_H5Part_set_funcname ( "NONE" );
|
||||
#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8
|
||||
r5 = H5Eset_auto2 ( H5E_DEFAULT, _h5_error_handler, NULL );
|
||||
#else
|
||||
@@ -3033,14 +3042,15 @@ _H5Part_print_debug_detail (
|
||||
|
||||
void
|
||||
_H5Part_set_funcname (
|
||||
char * const fname
|
||||
char * const fname
|
||||
) {
|
||||
__funcname = fname;
|
||||
}
|
||||
|
||||
const char *
|
||||
char * const
|
||||
_H5Part_get_funcname (
|
||||
void
|
||||
) {
|
||||
return __funcname;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,11 @@ extern "C" {
|
||||
|
||||
#include "H5PartTypes.h"
|
||||
|
||||
#include "H5Block.h"
|
||||
#ifdef PARALLEL_IO
|
||||
#include "H5MultiBlock.h"
|
||||
#endif
|
||||
|
||||
/* error values */
|
||||
#define H5PART_SUCCESS 0
|
||||
#define H5PART_ERR_NOMEM -12
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ _H5Part_set_funcname (
|
||||
char * const fname
|
||||
);
|
||||
|
||||
const char *
|
||||
char * const
|
||||
_H5Part_get_funcname (
|
||||
void
|
||||
);
|
||||
|
||||
+5
-2
@@ -81,6 +81,11 @@ struct H5PartFile {
|
||||
|
||||
struct H5BlockStruct *block;
|
||||
h5part_int64_t (*close_block)(struct H5PartFile *f);
|
||||
|
||||
#ifdef PARALLEL_IO
|
||||
struct H5MultiBlockStruct *multiblock;
|
||||
h5part_int64_t (*close_multiblock)(struct H5PartFile *f);
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct H5PartFile H5PartFile;
|
||||
@@ -89,6 +94,4 @@ typedef struct H5PartFile H5PartFile;
|
||||
# define SEEK_END 2
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+13
-4
@@ -40,13 +40,18 @@ lib_LIBRARIES = @MTARGET@
|
||||
EXTRA_LIBRARIES = libH5Part.a libH5PartF.a
|
||||
|
||||
# Header files that I wish to install in $(prefix)/include
|
||||
include_HEADERS = H5Part.h H5PartTypes.h H5PartErrors.h H5Block.h H5BlockReadWrite.h H5BlockTypes.h H5BlockErrors.h H5Part.inc H5PartF90.inc H5BlockF90.inc H5BlockReadWriteF90.inc @UNDERSCORE_H@
|
||||
include_HEADERS = H5Part.h H5PartTypes.h H5PartErrors.h \
|
||||
H5Block.h H5BlockReadWrite.h H5BlockTypes.h H5BlockErrors.h \
|
||||
H5MultiBlock.h H5MultiBlockReadWrite.h H5MultiBlockTypes.h H5MultiBlockErrors.h \
|
||||
H5Part.inc H5PartF90.inc \
|
||||
H5BlockF90.inc H5BlockReadWriteF90.inc \
|
||||
@UNDERSCORE_H@
|
||||
|
||||
# Listing of all possible headers that I may include
|
||||
EXTRA_HEADERS = H5PartPrivate.h H5BlockPrivate.h
|
||||
EXTRA_HEADERS = H5PartPrivate.h H5BlockPrivate.h H5MultiBlockPrivate.h
|
||||
|
||||
# Listing of sources
|
||||
libH5Part_a_SOURCES = H5Part.c H5Block.c H5BlockReadWrite.c
|
||||
libH5Part_a_SOURCES = H5Part.c H5Block.c H5BlockReadWrite.c H5MultiBlock.c H5MultiBlockReadWrite.c
|
||||
libH5PartF_a_SOURCES = H5PartF.c H5BlockF.c H5BlockReadWriteF.c
|
||||
|
||||
|
||||
@@ -55,7 +60,7 @@ H5Part.inc: H5PartF90.inc
|
||||
|
||||
# Specific building instruction (What compilers to use...)
|
||||
# ------------ Serial Lib build commands ------------
|
||||
libH5Part.a: H5Part.o H5Block.o H5BlockReadWrite.o
|
||||
libH5Part.a: H5Part.o H5Block.o H5BlockReadWrite.o H5MultiBlock.o H5MultiBlockReadWrite.o
|
||||
${AR} rucs $@ $^
|
||||
|
||||
libH5PartF.a: H5Part.o H5PartF.o H5Block.o H5BlockF.o H5BlockReadWrite.o H5BlockReadWriteF.o
|
||||
@@ -70,6 +75,10 @@ H5Block.o: H5Block.c H5Part.h H5PartPrivate.h H5PartTypes.h H5Block.h H5BlockTyp
|
||||
H5BlockF.o: H5BlockF.c Underscore.h H5Block.h
|
||||
H5BlockReadWrite.o: H5BlockReadWrite.c H5Part.h H5PartPrivate.h H5PartTypes.h H5Block.h H5BlockPrivate.h H5BlockReadWrite.h H5BlockTypes.h
|
||||
H5BlockReadWriteF.o: H5BlockF.c Underscore.h H5Block.h H5BlockReadWrite.h
|
||||
H5MultiBlock.o: H5MultiBlock.c
|
||||
H5MultiBlockF.o: H5MultiBlockF.c
|
||||
H5MultiBlockReadWrite.o: H5MultiBlockReadWrite.c
|
||||
H5MultiBlockReadWriteF.o: H5MultiBlockReadWriteF.c
|
||||
|
||||
# ----------- Build Parallel H5Part Stuff ------------
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ H5Block#DIM#dWriteScalarField#TYPE_ABV# (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block#DIM#dWriteScalarField#TYPE_ABV#" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -135,7 +135,7 @@ H5Block#DIM#dReadScalarField#TYPE_ABV# (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block#DIM#dReadScalarField#TYPE_ABV#" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
@@ -268,7 +268,7 @@ H5Block#DIM#dWrite3dVectorField#TYPE_ABV# (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block#DIM#dWrite3dVectorField#TYPE_ABV#" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_WRITABLE_MODE ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
@@ -314,7 +314,7 @@ H5Block#DIM#dRead3dVectorField#TYPE_ABV# (
|
||||
) {
|
||||
|
||||
SET_FNAME ( "H5Block#DIM#dRead3dVectorField#TYPE_ABV#" );
|
||||
INIT ( f );
|
||||
BLOCK_INIT ( f );
|
||||
CHECK_TIMEGROUP ( f );
|
||||
CHECK_LAYOUT ( f );
|
||||
|
||||
|
||||
Executable
+256
@@ -0,0 +1,256 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
c_head = """
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <hdf5.h>
|
||||
#include "H5Part.h"
|
||||
#include "H5PartErrors.h"
|
||||
#include "H5PartPrivate.h"
|
||||
|
||||
#include "H5MultiBlockErrors.h"
|
||||
#include "H5MultiBlockPrivate.h"
|
||||
"""
|
||||
|
||||
h_head = """
|
||||
#ifndef __H5MULTIBLOCKREADWRITE_H
|
||||
#define __H5MULTIBLOCKREADWRITE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
"""
|
||||
|
||||
h_tail = """
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
"""
|
||||
|
||||
fc_head = """
|
||||
#include "H5Part.h"
|
||||
#include "H5PartPrivate.h"
|
||||
#include "H5Block.h"
|
||||
#include "H5BlockReadWrite.h"
|
||||
#include "Underscore.h"
|
||||
|
||||
#if defined(F77_SINGLE_UNDERSCORE)
|
||||
#define F77NAME(a,b) a
|
||||
#elif defined(F77_CRAY_UNDERSCORE)
|
||||
#define F77NAME(a,b) b
|
||||
#elif defined(F77_NO_UNDERSCORE)
|
||||
#else
|
||||
#error Error, no way to determine how to construct fortran bindings
|
||||
#endif
|
||||
"""
|
||||
|
||||
fi_head = """
|
||||
INTERFACE
|
||||
"""
|
||||
|
||||
fi_tail = """
|
||||
END INTERFACE
|
||||
"""
|
||||
|
||||
write_h = """
|
||||
h5part_int64_t
|
||||
H5MultiBlock#DIM#dWriteField#TYPE_ABV# (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
const h5part_#TYPE_H5P#_t *data
|
||||
);
|
||||
"""
|
||||
|
||||
read_h = """
|
||||
h5part_int64_t
|
||||
H5MultiBlock#DIM#dReadField#TYPE_ABV# (
|
||||
H5PartFile *f,
|
||||
const char *name,
|
||||
h5part_#TYPE_H5P#_t **data
|
||||
);
|
||||
"""
|
||||
|
||||
write_c = """
|
||||
/*!
|
||||
\\ingroup h5multiblock_c_api
|
||||
|
||||
Write a multiblock field \\c name from the buffer starting at \\c data
|
||||
to the current time-step using the defined block decomposition and dimensions.
|
||||
Values are #TYPE_FULL#.
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \\c data.
|
||||
|
||||
\\return \\c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock#DIM#dWriteField#TYPE_ABV# (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to write */
|
||||
const h5part_#TYPE_H5P#_t *data /*!< IN: data to write */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock#DIM#dWriteField#TYPE_ABV#" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_write_data ( f, name, data, #TYPE_HDF5# );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
"""
|
||||
|
||||
read_c = """
|
||||
/*!
|
||||
\\ingroup h5multiblock_c_api
|
||||
|
||||
Allocate a buffer to hold a block from a multiblock field and place the
|
||||
pointer in \\c data, then read the block into the buffer. Uses the block
|
||||
decomposition specified in the file and the defined halo radius.
|
||||
Values are #TYPE_FULL#.
|
||||
|
||||
You must use the Fortran indexing scheme to access items in \\c data.
|
||||
|
||||
\\return \\c H5PART_SUCCESS or error code
|
||||
*/
|
||||
h5part_int64_t
|
||||
H5MultiBlock#DIM#dReadField#TYPE_ABV# (
|
||||
H5PartFile *f, /*!< IN: file handle */
|
||||
const char *name, /*!< IN: name of dataset to read */
|
||||
h5part_#TYPE_H5P#_t **data /*!< OUT: ptr to read buffer */
|
||||
) {
|
||||
|
||||
SET_FNAME( "H5MultiBlock#DIM#dReadField#TYPE_ABV#" );
|
||||
|
||||
h5part_int64_t herr;
|
||||
|
||||
herr = _H5MultiBlock_read_data ( f, name, (char**) data, #TYPE_HDF5# );
|
||||
if ( herr < 0 ) return herr;
|
||||
|
||||
return H5PART_SUCCESS;
|
||||
}
|
||||
"""
|
||||
|
||||
write_fi = """
|
||||
INTEGER*8 FUNCTION h5multi_#DIM#d_write_field_#TYPE_F90_ABV# ( filehandle, name, data )
|
||||
INTEGER*8, INTENT(IN) :: filehandle
|
||||
CHARACTER(LEN=*), INTENT(IN) :: name
|
||||
#TYPE_F90#, INTENT(IN) :: data(*)
|
||||
END FUNCTION
|
||||
"""
|
||||
|
||||
read_fi = """
|
||||
INTEGER*8 FUNCTION h5multi_#DIM#d_read_field_#TYPE_F90_ABV# ( filehandle, name, data )
|
||||
INTEGER*8, INTENT(IN) :: filehandle
|
||||
CHARACTER(LEN=*), INTENT(IN) :: name
|
||||
#TYPE_F90#, INTENT(OUT) :: data(*)
|
||||
END FUNCTION
|
||||
"""
|
||||
|
||||
write_fc = """
|
||||
#if ! defined(F77_NO_UNDERSCORE)
|
||||
#define h5multi_#DIM#d_write_field_#TYPE_F90_ABV# F77NAME ( \\
|
||||
h5multi_#DIM#d_write_field_#TYPE_F90_ABV#_, \\
|
||||
H5MULTI_#DIM#D_WRITE_FIELD_#TYPE_F90_ABVC# )
|
||||
#endif
|
||||
|
||||
h5part_int64_t
|
||||
h5multi_#DIM#d_write_field_#TYPE_F90_ABV# (
|
||||
h5part_int64_t *f,
|
||||
const char *field_name,
|
||||
const h5part_#TYPE_H5P#_t *data,
|
||||
const int l_field_name
|
||||
) {
|
||||
|
||||
H5PartFile *filehandle = (H5PartFile*)(size_t)*f;
|
||||
|
||||
char *field_name2 = _H5Part_strdupfor2c ( field_name, l_field_name );
|
||||
|
||||
h5part_int64_t herr = H5MultiBlock#DIM#dWriteField#TYPE_ABV# (
|
||||
filehandle, field_name2, data );
|
||||
|
||||
free ( field_name2 );
|
||||
return herr;
|
||||
}
|
||||
"""
|
||||
|
||||
read_fc = """
|
||||
#if ! defined(F77_NO_UNDERSCORE)
|
||||
#define h5multi_#DIM#d_read_field_#TYPE_F90_ABV# F77NAME ( \\
|
||||
h5multi_#DIM#d_read_field_#TYPE_F90_ABV#_, \\
|
||||
H5MULTI_#DIM#D_READ_FIELD_#TYPE_F90_ABVC# )
|
||||
#endif
|
||||
|
||||
h5part_int64_t
|
||||
h5multi_#DIM#d_read_field_#TYPE_F90_ABV# (
|
||||
h5part_int64_t *f,
|
||||
const char *field_name,
|
||||
h5part_#TYPE_H5P#_t **data,
|
||||
const int l_field_name
|
||||
) {
|
||||
|
||||
H5PartFile *filehandle = (H5PartFile*)(size_t)*f;
|
||||
|
||||
char *field_name2 = _H5Part_strdupfor2c ( field_name, l_field_name );
|
||||
|
||||
h5part_int64_t herr = H5MultiBlock#DIM#dReadField#TYPE_ABV# (
|
||||
filehandle, field_name2, (char**) data );
|
||||
|
||||
free ( field_name2 );
|
||||
return herr;
|
||||
}
|
||||
"""
|
||||
|
||||
dims = [ "3" ]
|
||||
types = [
|
||||
["floating points (64-bit)", "Float64", "float64", "H5T_NATIVE_DOUBLE", "REAL*8", "r8", "R8"],
|
||||
["floating points (32-bit)", "Float32", "float32", "H5T_NATIVE_FLOAT", "REAL*4", "r4", "R4"],
|
||||
["integers (64-bit)", "Int64", "int64", "H5T_NATIVE_INT64", "INTEGER*8", "i8", "I8"],
|
||||
["integers (32-bit)", "Int32", "int32", "H5T_NATIVE_INT32", "INTEGER*4", "i4", "I4"]
|
||||
]
|
||||
|
||||
def create_call(template, type, dim):
|
||||
fcn = template
|
||||
fcn = fcn.replace('#DIM#',dim)\
|
||||
.replace('#TYPE_FULL#',type[0])\
|
||||
.replace('#TYPE_ABV#',type[1])\
|
||||
.replace('#TYPE_H5P#',type[2])\
|
||||
.replace('#TYPE_HDF5#',type[3])\
|
||||
.replace('#TYPE_F90#',type[4])\
|
||||
.replace('#TYPE_F90_ABV#',type[5])\
|
||||
.replace('#TYPE_F90_ABVC#',type[6])
|
||||
return fcn
|
||||
|
||||
def write_calls():
|
||||
cfile = file('H5MultiBlockReadWrite.c','w')
|
||||
cfile.write(c_head)
|
||||
hfile = file('H5MultiBlockReadWrite.h','w')
|
||||
hfile.write(h_head)
|
||||
# fcfile = file('H5MultiBlockReadWriteF.c','w')
|
||||
# fcfile.write(fc_head)
|
||||
# fifile = file('H5MultiBlockReadWriteF90.inc','w')
|
||||
# fifile.write(fi_head)
|
||||
for dim in dims:
|
||||
for type in types:
|
||||
cfile.write(create_call(write_c,type,dim));
|
||||
cfile.write(create_call(read_c,type,dim));
|
||||
hfile.write(create_call(write_h,type,dim));
|
||||
hfile.write(create_call(read_h,type,dim));
|
||||
# fcfile.write(create_call(write_fc,type,dim));
|
||||
# fcfile.write(create_call(read_fc,type,dim));
|
||||
# fifile.write(create_call(write_fi,type,dim));
|
||||
# fifile.write(create_call(read_fi,type,dim));
|
||||
cfile.close()
|
||||
hfile.write(h_tail)
|
||||
hfile.close()
|
||||
# fcfile.close()
|
||||
# fifile.write(fi_tail)
|
||||
# fifile.close()
|
||||
|
||||
write_calls()
|
||||
|
||||
Reference in New Issue
Block a user