00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef CH_HDF5_H
00031 #define CH_HDF5_H
00032
00033 #ifdef HDF5 // if you don't have HDF5, then this file is useless
00034
00035 #include <iostream>
00036 using std::cout;
00037 using std::endl;
00038
00039 #ifdef MPI
00040 #include <mpi.h>
00041 #endif
00042
00043 #include "LevelData.H"
00044 #include "HDF5Portable.H"
00045
00046 #undef inline
00047 #include <string>
00048 #include <map>
00049 #include "RealVect.H"
00050
00051
00052
00053 using std::map;
00054
00055 class HDF5Handle;
00056
00057
00058
00059
00060
00062
00073 template <class T>
00074 int writeLevel(HDF5Handle& a_handle,
00075 const int& a_level,
00076 const LevelData<T>& a_data,
00077 const Real& a_dx,
00078 const Real& a_dt,
00079 const Real& a_time,
00080 const Box& a_domain,
00081 const int& a_refRatio,
00082 const IntVect& outputGhost = IntVect::Zero,
00083 const Interval& comps = Interval());
00084
00085 template <class T>
00086 int readLevel(HDF5Handle& a_handle,
00087 const int& a_level,
00088 LevelData<T>& a_data,
00089 Real& a_dx,
00090 Real& a_dt,
00091 Real& a_time,
00092 Box& a_domain,
00093 int& a_refRatio,
00094 const Interval& a_comps = Interval(),
00095 const IntVect& ghost = IntVect::Zero,
00096 bool setGhost = false);
00097
00098
00099
00100
00101
00102
00104
00111 int write(HDF5Handle& a_handle,
00112 const BoxLayout& a_layout);
00113
00115
00120 template <class T>
00121 int write(HDF5Handle& a_handle,
00122 const BoxLayoutData<T>& a_data,
00123 const std::string& a_name,
00124 const IntVect& outputGhost = IntVect::Zero,
00125 const Interval& comps = Interval());
00126
00128
00135 template <class T>
00136 int write(HDF5Handle& a_handle,
00137 const LevelData<T>& a_data,
00138 const std::string& a_name,
00139 const IntVect& outputGhost = IntVect::Zero,
00140 const Interval& comps = Interval());
00141
00143
00150 int read(HDF5Handle& a_handle,
00151 Vector<Box>& boxes);
00152
00154
00161 int readBoxes(HDF5Handle& a_handle,
00162 Vector<Vector<Box> >& boxes);
00163
00164
00166
00174 int readFArrayBox(HDF5Handle& a_handle,
00175 FArrayBox& a_fab,
00176 int a_level,
00177 int a_boxNumber,
00178 const Interval& a_components,
00179 const std::string& a_dataName = "data" );
00180
00182
00188 template <class T>
00189 int read(HDF5Handle& a_handle,
00190 BoxLayoutData<T>& a_data,
00191 const std::string& a_name,
00192 const BoxLayout& a_layout,
00193 const Interval& a_comps = Interval(),
00194 bool redefineData = true);
00195
00197
00203 template <class T>
00204 int read(HDF5Handle& a_handle,
00205 LevelData<T>& a_data,
00206 const std::string& a_name,
00207 const DisjointBoxLayout& a_layout,
00208 const Interval& a_comps = Interval(),
00209 bool redefineData = true);
00210
00212
00222 class HDF5Handle
00223 {
00224 public:
00226
00240 enum mode {CREATE, OPEN_RDONLY, OPEN_RDWR};
00241
00243
00245
00250 HDF5Handle();
00251
00253
00261 HDF5Handle(const std::string& a_filename, mode a_mode);
00262
00264
00266
00286 int open(const std::string& a_filename, mode a_mode);
00287
00289
00292 bool isOpen() const;
00293
00295
00300 void close();
00301
00303
00305
00308 void setGroupToLevel(int a_level);
00309
00311
00318 int setGroup(const std::string& groupAbsPath);
00319
00321
00327 const std::string& getGroup() const;
00328
00329 const hid_t& fileID() const;
00330 const hid_t& groupID() const;
00331 static hid_t box_id;
00332 static hid_t intvect_id;
00333 static hid_t realvect_id;
00334
00335 private:
00336
00337 HDF5Handle(const HDF5Handle&);
00338 HDF5Handle& operator=(const HDF5Handle&);
00339
00340 hid_t m_fileID;
00341 hid_t m_currentGroupID;
00342 bool m_isOpen;
00343 std::string m_filename;
00344 std::string m_group;
00345 int m_level;
00346
00347
00348 static bool initialized;
00349 static void initialize();
00350
00351 };
00352
00354
00396 class HDF5HeaderData
00397 {
00398 public:
00399
00401
00407 int writeToFile(HDF5Handle& file) const;
00408
00410
00418 int readFromFile(HDF5Handle& file);
00419
00421 void clear();
00422
00424 map<std::string, Real> m_real;
00425
00427 map<std::string, int> m_int;
00428
00430 map<std::string, std::string> m_string;
00431
00433 map<std::string, IntVect> m_intvect;
00434
00436 map<std::string, Box> m_box;
00437
00439 map<std::string, RealVect> m_realvect;
00440
00441
00442
00443 int writeToLocation(hid_t loc_id) const;
00444 int readFromLocation(hid_t loc_id);
00445
00446 private:
00447 static herr_t attributeScan(hid_t loc_id, const char *name, void *opdata);
00448 };
00449
00450 extern "C"{
00451 herr_t HDF5HeaderDataattributeScan(hid_t loc_id, const char *name, void *opdata);
00452 }
00453
00454 std::ostream& operator<<(std::ostream& os, const HDF5HeaderData& data);
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 #include "LoadBalance.H"
00493 #include "LayoutIterator.H"
00494 #include "Vector.H"
00495 #include "memtrack.H"
00496
00497
00498
00499
00500 struct OffsetBuffer
00501 {
00502 Vector<int> index;
00503 Vector<Vector<int> > offsets;
00504 void operator=(const OffsetBuffer& rhs);
00505 };
00506
00507 ostream& operator<<(ostream& os, const OffsetBuffer& ob);
00508
00509
00510 template < >
00511 int linearSize(const OffsetBuffer& a_input);
00512
00513
00514 template < >
00515 void linearIn(OffsetBuffer& a_outputT, const void* const a_inBuf);
00516
00517
00518 template < >
00519 void linearOut(void* const a_outBuf, const OffsetBuffer& a_inputT);
00520
00521 template < > int linearSize(const Vector<OffsetBuffer>& a_input);
00522 template < > void linearIn(Vector<OffsetBuffer>& a_outputT, const void* const inBuf);
00523 template < > void linearOut(void* const a_outBuf, const Vector<OffsetBuffer>& a_inputT);
00524
00525
00526
00527 template <>
00528 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<int>& dummy)
00529 {
00530 a_types.resize(1);
00531 a_types[0] = H5T_NATIVE_INT;
00532 }
00533
00534
00535
00536
00537 template <>
00538 inline void dataTypes(Vector<hid_t>& a_types, const FArrayBox& dummy)
00539 { a_types.resize(1); a_types[0] = H5T_NATIVE_REAL;}
00540
00541
00542
00543 template <>
00544 inline void dataSize(const BaseFab<int>& item, Vector<int>& a_sizes,
00545 const Box& box, const Interval& comps)
00546 {
00547 a_sizes[0] = box.numPts() * comps.size();
00548 }
00549
00550 template <>
00551 inline void dataSize(const FArrayBox& item, Vector<int>& a_sizes,
00552 const Box& box, const Interval& comps)
00553 {
00554 a_sizes[0] = box.numPts() * comps.size();
00555 }
00556
00557
00558
00559 template <>
00560 inline const char* name(const FArrayBox& a_dummySpecializationArg)
00561 {
00562
00563
00564 const char* name = "FArrayBox";
00565 return name;
00566 }
00567
00568
00569
00570 template <>
00571 inline const char* name(const BaseFab<int>& a_dummySpecializationArg)
00572 {
00573
00574
00575 const char* name = "BaseFab<int>";
00576 return name;
00577 }
00578
00579
00580
00581
00582
00583 template <class T>
00584 inline void dataTypes(Vector<hid_t>& a_types, const T& dummy)
00585 { a_types.resize(1); a_types[0] = H5T_NATIVE_CHAR;}
00586
00587 template <class T>
00588 inline void dataSize(const T& item, Vector<int>& a_sizes,
00589 const Box& box, const Interval& comps)
00590 {
00591 a_sizes[0] = item.size(box, comps);
00592 }
00593
00594
00595 template <class T>
00596 inline void write(const T& item, Vector<void*>& a_allocatedBuffers,
00597 const Box& box, const Interval& comps)
00598 {
00599 item.linearOut(a_allocatedBuffers[0], box, comps);
00600 }
00601
00602 template <class T>
00603 inline void read(T& item, Vector<void*>& a_allocatedBuffers,
00604 const Box& box, const Interval& comps)
00605 {
00606 item.linearIn(a_allocatedBuffers[0], box, comps);
00607 }
00608
00609 template <class T>
00610 inline const char* name(const T& a_dummySpecializationArg)
00611 {
00612 static const char* name = "unknown";
00613 return name;
00614 }
00615
00616 template <class T>
00617 void getOffsets(Vector<Vector<long long> >& offsets, const BoxLayoutData<T>& a_data,
00618 int types, const Interval& comps, const IntVect& outputGhost)
00619 {
00620
00621
00622 const BoxLayout& layout = a_data.boxLayout();
00623 offsets.resize(types, Vector<long long>(layout.size()+1));
00624
00625 for(int t=0; t<types; t++) offsets[t][0] = 0;
00626 Vector<int> thisSize(types);
00627 if(T::preAllocatable()==0)
00628 {
00629 T dummy;
00630 unsigned int index = 1;
00631 for(LayoutIterator it(layout.layoutIterator()); it.ok(); ++it)
00632 {
00633 Box region = layout[it()];
00634 region.grow(outputGhost);
00635 dataSize(dummy, thisSize, region, comps);
00636 for(unsigned int i=0; i<thisSize.size(); ++i)
00637 {
00638
00639 offsets[i][index] = offsets[i][index-1] + thisSize[i];
00640 }
00641 ++index;
00642 }
00643 }
00644 else
00645 {
00646 OffsetBuffer buff;
00647
00648 for(DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit)
00649 {
00650 int index = a_data.boxLayout().index(dit());
00651
00652 buff.index.push_back(index);
00653 Box region = layout[dit()];
00654 region.grow(outputGhost);
00655 dataSize(a_data[dit()], thisSize, region, comps);
00656 buff.offsets.push_back(thisSize);
00657 }
00658 Vector<OffsetBuffer> gathering(numProc());
00659 gather(gathering, buff, uniqueProc(SerialTask::compute));
00660 broadcast(gathering, uniqueProc(SerialTask::compute));
00661
00662 for(int i=0; i<numProc(); ++i)
00663 {
00664 OffsetBuffer& offbuf = gathering[i];
00665 for(int num=0; num<offbuf.index.size(); num++)
00666 {
00667 int index = offbuf.index[num];
00668 for(unsigned int j=0; j<types; ++j)
00669 {
00670
00671 offsets[j][index+1] = offbuf.offsets[num][j];
00672 }
00673 }
00674 }
00675 for(int i=0; i<layout.size(); i++)
00676 {
00677 for(unsigned int j=0; j<types; ++j)
00678 {
00679
00680 offsets[j][i+1] += offsets[j][i];
00681 }
00682 }
00683 }
00684
00685
00686 }
00687
00688
00689
00690
00691
00692
00693
00694 template <class T>
00695 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data,
00696 const std::string& a_name, const IntVect& outputGhost, const Interval& in_comps)
00697 {
00698 int ret = 0;
00699
00700 Interval comps(in_comps);
00701 if( comps.size() == 0) comps = a_data.interval();
00702 T dummy;
00703 Vector<hid_t> types;
00704 dataTypes(types, dummy);
00705
00706 Vector<Vector<long long> > offsets;
00707 Vector<long long> bufferCapacity(types.size(), 1);
00708 Vector<void*> buffers(types.size(), NULL);
00709
00710 getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00711
00712
00713 hsize_t flatdims[1];
00714 char dataname[100];
00715 Vector<hid_t> dataspace(types.size());
00716 Vector<hid_t> dataset(types.size());
00717
00718
00719
00720 herr_t err;
00721 hsize_t count[1];
00722 hssize_t offset[1];
00723
00724 for(unsigned int i=0; i<types.size(); ++i)
00725 {
00726 flatdims[0] = offsets[i][offsets[i].size()-1];
00727 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00728 dataspace[i] = H5Screate_simple(1, flatdims, NULL);
00729 assert(dataspace[i] >=0);
00730 dataset[i] = H5Dcreate(a_handle.groupID(), dataname,
00731 types[i],
00732 dataspace[i], H5P_DEFAULT);
00733 assert(dataset[i] >= 0);
00734 }
00735
00736 hid_t offsetspace, offsetData;
00737 for(unsigned int i=0; i<types.size(); ++i)
00738 {
00739 flatdims[0] = offsets[i].size();
00740 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00741 offsetspace = H5Screate_simple(1, flatdims, NULL);
00742 assert(offsetspace >= 0);
00743 offsetData = H5Dcreate(a_handle.groupID(), dataname,
00744 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00745 assert(offsetData >= 0);
00746 if(procID() == 0)
00747 {
00748 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00749 assert(memdataspace >= 0);
00750 err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00751 H5P_DEFAULT, &(offsets[i][0]));
00752 assert(err >= 0);
00753 H5Sclose(memdataspace);
00754 }
00755 H5Sclose(offsetspace);
00756 H5Dclose(offsetData);
00757 }
00758
00759
00760 HDF5HeaderData info;
00761 info.m_int["comps"] = comps.size();
00762 info.m_string["objectType"] = name(dummy);
00763 std::string group = a_handle.getGroup();
00764 a_handle.setGroup(group+"/"+a_name+"_attributes");
00765 info.writeToFile(a_handle);
00766 a_handle.setGroup(group);
00767
00768
00769
00770
00771 Vector<size_t> type_size(types.size());
00772 for(unsigned int i=0; i<types.size(); ++i)
00773 {
00774 type_size[i] = H5Tget_size(types[i]);
00775 }
00776
00777 Vector<int> thisSize(types.size());
00778
00779
00780
00781
00782
00783 for(int i=0; i<offsets[0].size(); i++)
00784 {
00785
00786 }
00787
00788 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00789 {
00790 unsigned int index = a_data.boxLayout().index(it());
00791 for(unsigned int i=0; i<types.size(); ++i)
00792 {
00793 long long size = (offsets[i][index+1] - offsets[i][index])
00794 * type_size[i];
00795
00796 assert(size >= 0);
00797 if(size > bufferCapacity[i])
00798 {
00799 bufferCapacity[i] = size;
00800 }
00801 }
00802 }
00803
00804 for(unsigned int i=0; i<types.size(); ++i)
00805 {
00806 buffers[i] = malloc(bufferCapacity[i]);
00807 if(buffers[i] == NULL) {
00808 pout() << " i=" << i
00809 << " types.size() = " << types.size()
00810 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00811 << endl;
00812 MayDay::Error("memory error in buffer allocation write");
00813 }
00814 }
00815
00816
00817
00818
00819 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00820 {
00821 const T& data = a_data[it()];
00822 unsigned int index = a_data.boxLayout().index(it());
00823 Box box = a_data.box(it());
00824 box.grow(outputGhost);
00825 write(data, buffers, box, comps);
00826 for(unsigned int i=0; i<types.size(); ++i)
00827 {
00828 offset[0] = offsets[i][index];
00829 count[0] = offsets[i][index+1] - offset[0];
00830 if(count[0] > 0){
00831 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
00832 offset, NULL,
00833 count, NULL);
00834 assert(err >= 0);
00835 hid_t memdataspace = H5Screate_simple(1, count, NULL);
00836 assert(memdataspace >= 0);
00837 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
00838 H5P_DEFAULT, buffers[i]);
00839 assert(err >= 0);
00840 H5Sclose(memdataspace);
00841 if(err < 0) { ret = err; goto cleanup;}
00842 }
00843 }
00844 }
00845
00846
00847
00848 cleanup:
00849 for(unsigned int i=0; i<types.size(); ++i)
00850 {
00851 free(buffers[i]);
00852 H5Sclose(dataspace[i]);
00853 H5Dclose(dataset[i]);
00854 }
00855 return ret;
00856
00857 }
00858
00859 template <class T>
00860 int write(HDF5Handle& a_handle, const LevelData<T>& a_data,
00861 const std::string& a_name, const IntVect& outputGhost, const Interval& in_comps)
00862 {
00863 HDF5HeaderData info;
00864 info.m_intvect["ghost"] = a_data.ghostVect();
00865 IntVect og(outputGhost);
00866 og.min(a_data.ghostVect());
00867 info.m_intvect["outputGhost"] = og;
00868 std::string group = a_handle.getGroup();
00869 a_handle.setGroup(group+"/"+a_name+"_attributes");
00870 info.writeToFile(a_handle);
00871 a_handle.setGroup(group);
00872 return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og, in_comps);
00873 }
00874
00875 template <class T>
00876 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
00877 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00878 {
00879 if(a_redefineData)
00880 {
00881 HDF5HeaderData info;
00882 std::string group = a_handle.getGroup();
00883 if(a_handle.setGroup(group+"/"+a_name+"_attributes"))
00884 {
00885 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00886 MayDay::Warning(message.c_str());
00887 return 1;
00888 }
00889 info.readFromFile(a_handle);
00890 a_handle.setGroup(group);
00891 int ncomp = info.m_int["comps"];
00892 IntVect ghost = info.m_intvect["ghost"];
00893 if(a_comps.end() > 0 && ncomp < a_comps.end())
00894 {
00895 MayDay::Error("attempt to read component interval that is not available");
00896 }
00897 if(a_comps.size() == 0)
00898 a_data.define(a_layout, ncomp, ghost);
00899 else
00900 a_data.define(a_layout, a_comps.size(), ghost);
00901 }
00902 return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
00903
00904 }
00905 template <class T>
00906 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
00907 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00908 {
00909 int ret = 0;
00910
00911 herr_t err;
00912
00913 char dataname[100];
00914 hsize_t count[1];
00915 hssize_t offset[1];
00916 Vector<Vector<long long> > offsets;
00917
00918 T dummy;
00919 Vector<hid_t> types;
00920 dataTypes(types, dummy);
00921 Vector<hid_t> dataspace(types.size());
00922 Vector<hid_t> dataset(types.size());
00923 offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
00924
00925 Vector<int> bufferCapacity(types.size(), 500);
00926 Vector<void*> buffers(types.size(), NULL);
00927
00928 for(unsigned int i=0; i<types.size(); ++i)
00929 {
00930 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00931 dataset[i] = H5Dopen(a_handle.groupID(), dataname);
00932 if(dataset[i] < 0) {MayDay::Warning("dataset open failure"); return dataset[i];}
00933 dataspace[i] = H5Dget_space(dataset[i]);
00934 if(dataspace[i] < 0) {MayDay::Warning("dataspace open failure"); return dataspace[i];}
00935 }
00936
00937 hid_t offsetspace, offsetData;
00938 hsize_t flatdims[1];
00939 for(unsigned int i=0; i<types.size(); ++i)
00940 {
00941 flatdims[0] = offsets[i].size();
00942 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00943 offsetspace = H5Screate_simple(1, flatdims, NULL);
00944 assert(offsetspace >= 0);
00945 offsetData = H5Dopen(a_handle.groupID(), dataname);
00946 assert(offsetData >= 0);
00947 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00948 assert(memdataspace >= 0);
00949 err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00950 H5P_DEFAULT, &(offsets[i][0]));
00951 assert(err >=0);
00952 H5Sclose(memdataspace);
00953 H5Sclose(offsetspace);
00954 H5Dclose(offsetData);
00955 }
00956
00957 HDF5HeaderData info;
00958 std::string group = a_handle.getGroup();
00959 if(a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
00960 {
00961 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00962 MayDay::Warning(message.c_str());
00963 return 1;
00964 }
00965
00966 info.readFromFile(a_handle);
00967 a_handle.setGroup(group);
00968 int ncomps = info.m_int["comps"];
00969 IntVect outputGhost(IntVect::Zero);
00970 if(info.m_intvect.find("outputGhost") != info.m_intvect.end())
00971 {
00972 outputGhost = info.m_intvect["outputGhost"];
00973 }
00974 if(ncomps <= 0){
00975 MayDay::Warning("ncomps <= 0 in read");
00976 return ncomps;
00977 }
00978
00979 if(a_redefineData){
00980 if(a_comps.size() != 0){
00981 a_data.define(a_layout, a_comps.size());
00982 } else {
00983 a_data.define(a_layout, ncomps);
00984 }
00985 }
00986
00987 Interval comps(0, ncomps-1);
00988
00989
00990
00991
00992
00993 Vector<size_t> type_size(types.size());
00994 for(unsigned int i=0; i<types.size(); ++i)
00995 {
00996 type_size[i] = H5Tget_size(types[i]);
00997 buffers[i] = malloc(bufferCapacity[i]);
00998 if(buffers[i] == NULL) {
00999 pout() << " i= " << i
01000 << " types.size()=" << types.size()
01001 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
01002 << endl;
01003 MayDay::Error("memory error in buffer allocation read");
01004 }
01005 }
01006
01007 Vector<int> thisSize(types.size());
01008 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
01009 {
01010 T& data = a_data[it()];
01011 unsigned int index = a_data.boxLayout().index(it());
01012 Box box = a_data.box(it());
01013
01014 for(unsigned int i=0; i<types.size(); ++i)
01015 {
01016 if(a_comps.size() == 0){
01017 offset[0] = offsets[i][index];
01018 count[0] = offsets[i][index+1] - offset[0];
01019 } else {
01020 offset[0] = offsets[i][index] + box.numPts()*a_comps.begin();
01021 count[0] = a_comps.size() * box.numPts();
01022 }
01023 if(count[0] > 0)
01024 {
01025 int size = count[0] * type_size[i];
01026 if(size > bufferCapacity[i])
01027 {
01028 free(buffers[i]);
01029 bufferCapacity[i] = Max(2*bufferCapacity[i], size);
01030 buffers[i] = malloc(bufferCapacity[i]);
01031 if(buffers[i] == NULL) {
01032 MayDay::Error("memory error in buffer allocation read");
01033 }
01034 }
01035
01036 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01037 offset, NULL,
01038 count, NULL);
01039 assert(err >= 0);
01040 hid_t memdataspace = H5Screate_simple(1, count, NULL);
01041 assert(memdataspace >= 0);
01042 err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01043 H5P_DEFAULT, buffers[i]);
01044 assert(err >= 0);
01045 H5Sclose(memdataspace);
01046 if(err < 0) { ret = err; goto cleanup;}
01047 }
01048 }
01049 box.grow(outputGhost);
01050 read(data, buffers, box, comps);
01051 }
01052
01053 cleanup:
01054 for(unsigned int i=0; i<types.size(); ++i)
01055 {
01056 free(buffers[i]);
01057 H5Sclose(dataspace[i]);
01058 H5Dclose(dataset[i]);
01059 }
01060 return ret;
01061 }
01062
01063
01064 template <class T>
01065 int writeLevel(HDF5Handle& a_handle,
01066 const int& a_level,
01067 const LevelData<T>& a_data,
01068 const Real& a_dx,
01069 const Real& a_dt,
01070 const Real& a_time,
01071 const Box& a_domain,
01072 const int& a_refRatio,
01073 const IntVect& outputGhost,
01074 const Interval& comps)
01075 {
01076 int error;
01077 char levelName[10];
01078 std::string currentGroup = a_handle.getGroup();
01079 sprintf(levelName, "/level_%i",a_level);
01080 error = a_handle.setGroup(currentGroup + levelName);
01081 if(error != 0) return 1;
01082
01083 HDF5HeaderData meta;
01084 meta.m_real["dx"] = a_dx;
01085 meta.m_real["dt"] = a_dt;
01086 meta.m_real["time"] = a_time;
01087 meta.m_box["prob_domain"] = a_domain;
01088 meta.m_int["ref_ratio"] = a_refRatio;
01089
01090 error = meta.writeToFile(a_handle);
01091 if(error != 0) return 2;
01092
01093 error = write(a_handle, a_data.boxLayout());
01094 if(error != 0) return 3;
01095
01096 error = write(a_handle, a_data, "data", outputGhost, comps);
01097 if(error != 0) return 4;
01098
01099 a_handle.setGroup(currentGroup);
01100
01101 return 0;
01102 }
01103
01104
01105 template <class T>
01106 int readLevel(HDF5Handle& a_handle,
01107 const int& a_level,
01108 LevelData<T>& a_data,
01109 Real& a_dx,
01110 Real& a_dt,
01111 Real& a_time,
01112 Box& a_domain,
01113 int& a_refRatio,
01114 const Interval& a_comps,
01115 const IntVect& ghost,
01116 bool setGhost)
01117 {
01118 HDF5HeaderData header;
01119 header.readFromFile(a_handle);
01120 int nComp = header.m_int["num_components"];
01121
01122 int error;
01123 char levelName[10];
01124 std::string currentGroup = a_handle.getGroup();
01125 sprintf(levelName, "/level_%i",a_level);
01126 error = a_handle.setGroup(currentGroup + levelName);
01127 if(error != 0) return 1;
01128
01129 HDF5HeaderData meta;
01130 error = meta.readFromFile(a_handle);
01131 if(error != 0) return 2;
01132 a_dx = meta.m_real["dx"];
01133 a_dt = meta.m_real["dt"];
01134 a_time = meta.m_real["time"];
01135 a_domain = meta.m_box["prob_domain"];
01136 a_refRatio = meta.m_int["ref_ratio"];
01137
01138 Vector<Box> boxes;
01139 error = read(a_handle, boxes);
01140 Vector<int> procIDs;
01141 LoadBalance(procIDs, boxes);
01142
01143 DisjointBoxLayout layout(boxes, procIDs);
01144
01145 layout.close();
01146 if(error != 0) return 3;
01147
01148 if(!setGhost)
01149 error = read(a_handle, a_data, "data", layout, a_comps);
01150 else
01151 {
01152 if(a_comps.size() != 0)
01153 a_data.define(layout, a_comps.size(), ghost);
01154 else
01155 a_data.define(layout, nComp, ghost);
01156
01157 error = read(a_handle, a_data, "data", layout, a_comps, false);
01158
01159 }
01160 if(error != 0) return 4;
01161
01162 a_handle.setGroup(currentGroup);
01163
01164 return 0;
01165 }
01166
01167 #else // HDF5
01168
01169
01170 #define HOFFSET(S,M) (offsetof(S,M))
01171
01172 #endif // HDF5
01173
01174 #endif // CH_HDF5_H