diff --git a/plugins/HDF_IO.hh b/plugins/HDF_IO.hh index f0cee50..a0e7353 100755 --- a/plugins/HDF_IO.hh +++ b/plugins/HDF_IO.hh @@ -44,8 +44,15 @@ hid_t GetDataType( void ) if( typeid(T) == typeid(double) ) return H5T_NATIVE_DOUBLE; - //if( typeid(T) == typeid(long long) ) - // return H5T_NATIVE_LLONG; + if( typeid(T) == typeid(long long) ) + return H5T_NATIVE_LLONG; + + if( typeid(T) == typeid(unsigned long long) ) + return H5T_NATIVE_ULLONG; + + if( typeid(T) == typeid(size_t) ) + return H5T_NATIVE_ULLONG; + std::cerr << " - Error: [HDF_IO] trying to evaluate unsupported type in GetDataType\n\n"; return -1; @@ -90,6 +97,8 @@ inline void HDFReadVector( const std::string Filename, const std::string ObjName } + + inline void HDFGetDatasetExtent( const std::string Filename, const std::string ObjName, std::vector &Extent ) { hid_t HDF_FileID, HDF_DatasetID, HDF_DataspaceID; @@ -751,6 +760,51 @@ inline void HDFWriteDataset3D( const std::string Filename, const std::string Obj H5Fclose( HDF_FileID ); } + +template< typename T > +struct HDFHyperslabWriter3Ds +{ + hid_t dset_id_, type_id_, file_id_; + + HDFHyperslabWriter3Ds( const std::string Filename, const std::string ObjName, size_t nd[3] ) + { + hid_t filespace; + + hsize_t sizes[4] = { 1, nd[0], nd[1], nd[2] }; + + type_id_ = GetDataType(); + file_id_ = H5Fopen( Filename.c_str(), H5F_ACC_RDWR, H5P_DEFAULT ); + filespace = H5Screate_simple( 4, sizes, NULL ); + dset_id_ = H5Dcreate( file_id_, ObjName.c_str(), type_id_, filespace, H5P_DEFAULT ); + + H5Sclose(filespace); + } + + ~HDFHyperslabWriter3Ds() + { + H5Dclose( dset_id_ ); + H5Fclose( file_id_ ); + } + + void write_slab( T* data, size_t* count, size_t* offset ) + { + + hsize_t counts[4] = { 1, count[0], count[1], count[2] }; + hsize_t offsets[4] = { 0, offset[0], offset[1], offset[2] }; + + hid_t filespace = H5Dget_space(dset_id_); + hid_t memspace = H5Screate_simple(4, counts, NULL); + H5Sselect_hyperslab( filespace, H5S_SELECT_SET, offsets, NULL, counts, NULL ); + + herr_t status; + status = H5Dwrite(dset_id_, type_id_, memspace, filespace, H5P_DEFAULT, reinterpret_cast(data)); + H5Sclose(filespace); + H5Sclose(memspace); + } + +}; + + template< typename T > inline void HDFWriteDataset3Ds( const std::string Filename, const std::string ObjName, unsigned nd[3], const std::vector< T > &Data ) { diff --git a/plugins/output_enzo.cc b/plugins/output_enzo.cc index 98bd75a..bd716b5 100644 --- a/plugins/output_enzo.cc +++ b/plugins/output_enzo.cc @@ -17,13 +17,19 @@ #include "HDF_IO.hh" +//#define MAX_SLAB_SIZE 134217728 // = 128 MBytes + //#define MAX_SLAB_SIZE 33554432 // = 32 Mbytes + +#define MAX_SLAB_SIZE 1048576 + + class enzo_output_plugin : public output_plugin { protected: struct patch_header{ int component_rank; - int component_size; + size_t component_size; std::vector dimensions; int rank; std::vector top_grid_dims; @@ -88,26 +94,65 @@ protected: //... need to copy data because we need to get rid of the ghost zones - std::vector data; - data.reserve( ng[0]*ng[1]*ng[2] ); + //... write in slabs if data is more than MAX_SLAB_SIZE (default 128 MB) - for( int k=0; k(&ng_fortran[0]), data ); + HDFHyperslabWriter3Ds *slab_writer = new HDFHyperslabWriter3Ds( filename, enzoname, nsz ); + + double *data_buf = new double[ slices_in_slab * (size_t)ng[0] * (size_t)ng[1] ]; + + size_t slices_written = 0; + while( slices_written < (size_t)ng[2] ) + { + slices_in_slab = std::min( (size_t)ng[2]-slices_written, slices_in_slab ); + + #pragma omp parallel for + for( int k=0; k<(int)slices_in_slab; ++k ) + for( int j=0; jwrite_slab( data_buf, count, offset ); + slices_written += slices_in_slab; + + } + + delete[] data_buf; + + delete slab_writer; + + //... header data for the patch patch_header ph; ph.component_rank = 1; - ph.component_size = ng[0]*ng[1]*ng[2]; + ph.component_size = (size_t)ng[0]*(size_t)ng[1]*(size_t)ng[2]; ph.dimensions = ng; ph.rank = 3; @@ -120,7 +165,7 @@ protected: ph.top_grid_start.push_back( (int)(gh.offset_abs(ilevel, 0)*rfac) ); ph.top_grid_start.push_back( (int)(gh.offset_abs(ilevel, 1)*rfac) ); ph.top_grid_start.push_back( (int)(gh.offset_abs(ilevel, 2)*rfac) ); - + ph.top_grid_end.push_back( ph.top_grid_start[0] + (int)(ng[0]*rfac) ); ph.top_grid_end.push_back( ph.top_grid_start[1] + (int)(ng[1]*rfac) ); ph.top_grid_end.push_back( ph.top_grid_start[2] + (int)(ng[2]*rfac) ); @@ -185,7 +230,7 @@ public: sprintf( filename, "%s/parameter_file.txt", fname_.c_str() ); - std::ofstream ofs( filename, std::ios::trunc ); + std::ofstream ofs( filename, std::ios::trunc ); ofs << "#\n"