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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef _CH_HDF5_H_
00053 #define _CH_HDF5_H_
00054
00055 #ifdef HDF5 // if you don't have HDF5, then this file is useless
00056
00057 #include <iostream>
00058 using std::cout;
00059 using std::endl;
00060
00061 #ifdef MPI
00062 #include <mpi.h>
00063 #endif
00064
00065 #include "LevelData.H"
00066 #include "HDF5Portable.H"
00067
00068 #undef inline
00069 #include <string>
00070 #include <map>
00071 #include "RealVect.H"
00072
00073 template <class T>
00074 void read(T& item, Vector<Vector<char> >& a_allocatedBuffers, const Box& box,
00075 const Interval& comps)
00076 {
00077 Vector<void*> b(a_allocatedBuffers.size());
00078 for(int i=0; i<b.size(); ++i) b[i]= &(a_allocatedBuffers[i][0]);
00079 read(item, b, box, comps);
00080 }
00081
00082 using std::map;
00083
00084 class HDF5Handle;
00085
00086
00087
00088
00090
00101 template <class T>
00102 int writeLevel(HDF5Handle& a_handle,
00103 const int& a_level,
00104 const LevelData<T>& a_data,
00105 const Real& a_dx,
00106 const Real& a_dt,
00107 const Real& a_time,
00108 const Box& a_domain,
00109 const int& a_refRatio,
00110 const IntVect& outputGhost = IntVect::Zero,
00111 const Interval& comps = Interval());
00112
00113 template <class T>
00114 int readLevel(HDF5Handle& a_handle,
00115 const int& a_level,
00116 LevelData<T>& a_data,
00117 Real& a_dx,
00118 Real& a_dt,
00119 Real& a_time,
00120 Box& a_domain,
00121 int& a_refRatio,
00122 const Interval& a_comps = Interval(),
00123 bool setGhost = false);
00124
00125
00126
00127
00128
00130
00137 int write(HDF5Handle& a_handle,
00138 const BoxLayout& a_layout,
00139 const std::string& name = "boxes");
00140
00142
00147 template <class T>
00148 int write(HDF5Handle& a_handle,
00149 const BoxLayoutData<T>& a_data,
00150 const std::string& a_name,
00151 IntVect outputGhost = IntVect::Zero,
00152 const Interval& comps = Interval(),
00153 bool newForm = false);
00154
00156
00163 template <class T>
00164 int write(HDF5Handle& a_handle,
00165 const LevelData<T>& a_data,
00166 const std::string& a_name,
00167 const IntVect& outputGhost = IntVect::Zero,
00168 const Interval& comps = Interval());
00169
00171
00178 int read(HDF5Handle& a_handle,
00179 Vector<Box>& boxes,
00180 const std::string& name = "boxes");
00181
00183
00190 int readBoxes(HDF5Handle& a_handle,
00191 Vector<Vector<Box> >& boxes);
00192
00194
00202 int readFArrayBox(HDF5Handle& a_handle,
00203 FArrayBox& a_fab,
00204 int a_level,
00205 int a_boxNumber,
00206 const Interval& a_components,
00207 const std::string& a_dataName = "data" );
00208
00210
00216 template <class T>
00217 int read(HDF5Handle& a_handle,
00218 BoxLayoutData<T>& a_data,
00219 const std::string& a_name,
00220 const BoxLayout& a_layout,
00221 const Interval& a_comps = Interval(),
00222 bool redefineData = true);
00223
00225
00231 template <class T>
00232 int read(HDF5Handle& a_handle,
00233 LevelData<T>& a_data,
00234 const std::string& a_name,
00235 const DisjointBoxLayout& a_layout,
00236 const Interval& a_comps = Interval(),
00237 bool redefineData = true);
00238
00240
00250 class HDF5Handle
00251 {
00252 public:
00254
00268 enum mode {CREATE, OPEN_RDONLY, OPEN_RDWR};
00269
00271
00273
00278 HDF5Handle();
00279
00281
00289 HDF5Handle(const std::string& a_filename, mode a_mode);
00290
00292
00294
00314 int open(const std::string& a_filename, mode a_mode);
00315
00317
00320 bool isOpen() const;
00321
00323
00328 void close();
00329
00331
00333
00336 void setGroupToLevel(int a_level);
00337
00339
00346 int setGroup(const std::string& groupAbsPath);
00347
00349
00355 const std::string& getGroup() const;
00356
00357 const hid_t& fileID() const;
00358 const hid_t& groupID() const;
00359 static hid_t box_id;
00360 static hid_t intvect_id;
00361 static hid_t realvect_id;
00362 static map<std::string, std::string> groups;
00363
00364 private:
00365
00366 HDF5Handle(const HDF5Handle&);
00367 HDF5Handle& operator=(const HDF5Handle&);
00368
00369 hid_t m_fileID;
00370 hid_t m_currentGroupID;
00371 bool m_isOpen;
00372 std::string m_filename;
00373 std::string m_group;
00374 int m_level;
00375
00376
00377 static bool initialized;
00378 static void initialize();
00379
00380 };
00381
00383
00425 class HDF5HeaderData
00426 {
00427 public:
00428
00430
00436 int writeToFile(HDF5Handle& file) const;
00437
00439
00447 int readFromFile(HDF5Handle& file);
00448
00450 void clear();
00451
00453 map<std::string, Real> m_real;
00454
00456 map<std::string, int> m_int;
00457
00459 map<std::string, std::string> m_string;
00460
00462 map<std::string, IntVect> m_intvect;
00463
00465 map<std::string, Box> m_box;
00466
00468 map<std::string, RealVect> m_realvect;
00469
00470
00471
00472 int writeToLocation(hid_t loc_id) const;
00473 int readFromLocation(hid_t loc_id);
00474
00475 private:
00476 static herr_t attributeScan(hid_t loc_id, const char *name, void *opdata);
00477 };
00478
00479 extern "C"{
00480 herr_t HDF5HeaderDataattributeScan(hid_t loc_id, const char *name, void *opdata);
00481 }
00482
00483 std::ostream& operator<<(std::ostream& os, const HDF5HeaderData& data);
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 #include "LoadBalance.H"
00521 #include "LayoutIterator.H"
00522 #include "Vector.H"
00523 #include "memtrack.H"
00524
00525 template<class T>
00526 hid_t H5Type(const T* dummy);
00527
00528 template< >
00529 hid_t H5Type(const int* dummy);
00530
00531 template< >
00532 hid_t H5Type(const long long* dummy);
00533
00534 template< >
00535 hid_t H5Type(const float* dummy);
00536
00537 template< >
00538 hid_t H5Type(const double* dummy);
00539
00540 template< >
00541 hid_t H5Type(const Box* dummy);
00542
00543 template< >
00544 hid_t H5Type(const RealVect* dummy);
00545
00546 template< >
00547 hid_t H5Type(const IntVect* dummy);
00548
00549 template<class T>
00550 hid_t H5Type(const T* dummy)
00551 {
00552
00553 MayDay::Error(" H5Type(const T* dummy)");
00554 return -4;
00555 }
00556
00557 void createData(hid_t& a_dataset,
00558 hid_t& a_dataspace,
00559 HDF5Handle& handle,
00560 const std::string& name,
00561 hid_t type,
00562 hsize_t size);
00563
00564 template <class T>
00565 void createDataset(hid_t& a_dataset,
00566 hid_t& a_dataspace,
00567 HDF5Handle& handle,
00568 const std::string& name,
00569 const T* dummy,
00570 hsize_t size)
00571 {
00572 createData(a_dataset, a_dataspace, handle, name, H5Type(dummy), size);
00573
00574 }
00575
00576 void writeDataset(hid_t a_dataset,
00577 hid_t a_dataspace,
00578 const void* start,
00579 hssize_t off,
00580 hsize_t count);
00581
00582 void readDataset(hid_t a_dataset,
00583 hid_t a_dataspace,
00584 void* start,
00585 hssize_t off,
00586 hsize_t count);
00587
00588
00589
00590 struct OffsetBuffer
00591 {
00592 Vector<int> index;
00593 Vector<Vector<int> > offsets;
00594 void operator=(const OffsetBuffer& rhs);
00595 };
00596
00597 ostream& operator<<(ostream& os, const OffsetBuffer& ob);
00598
00599
00600 template < >
00601 int linearSize(const OffsetBuffer& a_input);
00602
00603
00604 template < >
00605 void linearIn(OffsetBuffer& a_outputT, const void* const a_inBuf);
00606
00607
00608 template < >
00609 void linearOut(void* const a_outBuf, const OffsetBuffer& a_inputT);
00610
00611 template < > int linearSize(const Vector<OffsetBuffer>& a_input);
00612 template < > void linearIn(Vector<OffsetBuffer>& a_outputT, const void* const inBuf);
00613 template < > void linearOut(void* const a_outBuf, const Vector<OffsetBuffer>& a_inputT);
00614
00615
00616
00617 template <>
00618 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<int>& dummy)
00619 {
00620 a_types.resize(1);
00621 a_types[0] = H5T_NATIVE_INT;
00622 }
00623
00624 template <>
00625 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<char>& dummy)
00626 {
00627 a_types.resize(1);
00628 a_types[0] = H5T_NATIVE_CHAR;
00629 }
00630
00631
00632
00633
00634 template <>
00635 inline void dataTypes(Vector<hid_t>& a_types, const FArrayBox& dummy)
00636 { a_types.resize(1); a_types[0] = H5T_NATIVE_REAL;}
00637
00638 template <>
00639 inline void dataSize(const BaseFab<int>& item, Vector<int>& a_sizes,
00640 const Box& box, const Interval& comps)
00641 {
00642 a_sizes[0] = box.numPts() * comps.size();
00643 }
00644
00645 template <>
00646 inline void dataSize(const BaseFab<char>& item, Vector<int>& a_sizes,
00647 const Box& box, const Interval& comps)
00648 {
00649 a_sizes[0] = box.numPts() * comps.size();
00650 }
00651
00652 template <>
00653 inline void dataSize(const FArrayBox& item, Vector<int>& a_sizes,
00654 const Box& box, const Interval& comps)
00655 {
00656 a_sizes[0] = box.numPts() * comps.size();
00657 }
00658
00659 template <>
00660 inline const char* name(const FArrayBox& a_dummySpecializationArg)
00661 {
00662
00663
00664 const char* name = "FArrayBox";
00665 return name;
00666 }
00667
00668 template <>
00669 inline const char* name(const BaseFab<int>& a_dummySpecializationArg)
00670 {
00671
00672
00673 const char* name = "BaseFab<int>";
00674 return name;
00675 }
00676
00677 template <>
00678 inline const char* name(const BaseFab<char>& a_dummySpecializationArg)
00679 {
00680
00681
00682 const char* name = "BaseFab<char>";
00683 return name;
00684 }
00685
00686
00687
00688
00689 template <class T>
00690 inline void dataTypes(Vector<hid_t>& a_types, const T& dummy)
00691 { a_types.resize(1); a_types[0] = H5T_NATIVE_CHAR;}
00692
00693 template <class T>
00694 inline void dataSize(const T& item, Vector<int>& a_sizes,
00695 const Box& box, const Interval& comps)
00696 {
00697 a_sizes[0] = item.size(box, comps);
00698 }
00699
00700 template <class T>
00701 inline void write(const T& item, Vector<void*>& a_allocatedBuffers,
00702 const Box& box, const Interval& comps)
00703 {
00704 item.linearOut(a_allocatedBuffers[0], box, comps);
00705 }
00706
00707 template <class T>
00708 inline void read(T& item, Vector<void*>& a_allocatedBuffers,
00709 const Box& box, const Interval& comps)
00710 {
00711 item.linearIn(a_allocatedBuffers[0], box, comps);
00712 }
00713
00714 template <class T>
00715 inline const char* name(const T& a_dummySpecializationArg)
00716 {
00717 static const char* name = "unknown";
00718 return name;
00719 }
00720
00721 template <class T>
00722 void getOffsets(Vector<Vector<long long> >& offsets, const BoxLayoutData<T>& a_data,
00723 int types, const Interval& comps, const IntVect& outputGhost)
00724 {
00725 const BoxLayout& layout = a_data.boxLayout();
00726 offsets.resize(types, Vector<long long>(layout.size()+1));
00727
00728 for(int t=0; t<types; t++) offsets[t][0] = 0;
00729 Vector<int> thisSize(types);
00730 if(T::preAllocatable()==0)
00731 {
00732 T dummy;
00733 unsigned int index = 1;
00734 for(LayoutIterator it(layout.layoutIterator()); it.ok(); ++it)
00735 {
00736 Box region = layout[it()];
00737 region.grow(outputGhost);
00738 dataSize(dummy, thisSize, region, comps);
00739 for(unsigned int i=0; i<thisSize.size(); ++i)
00740 {
00741
00742 offsets[i][index] = offsets[i][index-1] + thisSize[i];
00743 }
00744 ++index;
00745 }
00746 }
00747 else
00748 {
00749 OffsetBuffer buff;
00750
00751 for(DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit)
00752 {
00753 int index = a_data.boxLayout().index(dit());
00754
00755 buff.index.push_back(index);
00756 Box region = layout[dit()];
00757 region.grow(outputGhost);
00758 dataSize(a_data[dit()], thisSize, region, comps);
00759 buff.offsets.push_back(thisSize);
00760 }
00761 Vector<OffsetBuffer> gathering(numProc());
00762 gather(gathering, buff, uniqueProc(SerialTask::compute));
00763 broadcast(gathering, uniqueProc(SerialTask::compute));
00764
00765 for(int i=0; i<numProc(); ++i)
00766 {
00767 OffsetBuffer& offbuf = gathering[i];
00768 for(int num=0; num<offbuf.index.size(); num++)
00769 {
00770 int index = offbuf.index[num];
00771 for(unsigned int j=0; j<types; ++j)
00772 {
00773
00774 offsets[j][index+1] = offbuf.offsets[num][j];
00775 }
00776 }
00777 }
00778 for(int i=0; i<layout.size(); i++)
00779 {
00780 for(unsigned int j=0; j<types; ++j)
00781 {
00782
00783 offsets[j][i+1] += offsets[j][i];
00784 }
00785 }
00786 }
00787
00788
00789 }
00790
00791
00792
00793
00794
00795 template <class T>
00796 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data,
00797 const std::string& a_name, IntVect outputGhost,
00798 const Interval& in_comps, bool newForm)
00799 {
00800 int ret = 0;
00801
00802 Interval comps(in_comps);
00803 if( comps.size() == 0) comps = a_data.interval();
00804 T dummy;
00805 Vector<hid_t> types;
00806 dataTypes(types, dummy);
00807
00808 if(newForm && memcmp(a_name.c_str(), "M", 1)==0)
00809 {
00810 std::string currentGroup = a_handle.getGroup();
00811 a_handle.setGroup("/");
00812 HDF5HeaderData info;
00813 info.readFromFile(a_handle);
00814 outputGhost = info.m_intvect["Ghost"];
00815 info.clear();
00816 a_handle.setGroup("/" + HDF5Handle::groups[a_name] + "CenteredComponents");
00817 info.readFromFile(a_handle);
00818 int nc = info.m_int["Num"+a_name];
00819 if(nc == 0){
00820 char cname[40];
00821 info.m_int["Num"+a_name] = comps.size();
00822 nc = comps.size();
00823 for(int i=0; i<nc; ++i){
00824 sprintf(cname, "Component%i", i);
00825 info.m_string[cname] = cname;
00826 }
00827 info.writeToFile(a_handle);
00828 }
00829 a_handle.setGroup(currentGroup);
00830 assert(nc == comps.size());
00831 }
00832
00833 Vector<Vector<long long> > offsets;
00834 Vector<long long> bufferCapacity(types.size(), 1);
00835 Vector<void*> buffers(types.size(), NULL);
00836
00837 getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00838
00839
00840 hsize_t flatdims[1];
00841 char dataname[100];
00842 Vector<hid_t> dataspace(types.size());
00843 Vector<hid_t> dataset(types.size());
00844
00845 herr_t err;
00846 hsize_t count[1];
00847 hssize_t offset[1];
00848 assert(!(newForm && types.size() != 1));
00849
00850 for(unsigned int i=0; i<types.size(); ++i)
00851 {
00852 flatdims[0] = offsets[i][offsets[i].size()-1];
00853 if(newForm){
00854 if(memcmp(a_name.c_str(), "M", 1)==0){
00855 sprintf(dataname, "Mask");
00856 }else{
00857 sprintf(dataname, "%sRegular", a_name.c_str());
00858 }
00859 }else {
00860 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00861 }
00862 dataspace[i] = H5Screate_simple(1, flatdims, NULL);
00863 assert(dataspace[i] >=0);
00864 dataset[i] = H5Dcreate(a_handle.groupID(), dataname,
00865 types[i],
00866 dataspace[i], H5P_DEFAULT);
00867 assert(dataset[i] >= 0);
00868 }
00869
00870 hid_t offsetspace, offsetData;
00871 for(unsigned int i=0; i<types.size(); ++i)
00872 {
00873 flatdims[0] = offsets[i].size();
00874 if(newForm){
00875 sprintf(dataname, "%sOffsets",a_name.c_str());
00876 } else {
00877 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00878 }
00879 offsetspace = H5Screate_simple(1, flatdims, NULL);
00880 assert(offsetspace >= 0);
00881 offsetData = H5Dcreate(a_handle.groupID(), dataname,
00882 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00883 assert(offsetData >= 0);
00884 if(procID() == 0)
00885 {
00886 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00887 assert(memdataspace >= 0);
00888 err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00889 H5P_DEFAULT, &(offsets[i][0]));
00890 assert(err >= 0);
00891 H5Sclose(memdataspace);
00892 }
00893 H5Sclose(offsetspace);
00894 H5Dclose(offsetData);
00895 }
00896
00897
00898 if(!newForm){
00899 HDF5HeaderData info;
00900 info.m_int["comps"] = comps.size();
00901 info.m_string["objectType"] = name(dummy);
00902 std::string group = a_handle.getGroup();
00903 a_handle.setGroup(group+"/"+a_name+"_attributes");
00904 info.writeToFile(a_handle);
00905 a_handle.setGroup(group);
00906 }
00907
00908
00909
00910
00911 Vector<size_t> type_size(types.size());
00912 for(unsigned int i=0; i<types.size(); ++i)
00913 {
00914 type_size[i] = H5Tget_size(types[i]);
00915 }
00916
00917 Vector<int> thisSize(types.size());
00918
00919
00920
00921
00922
00923 for(int i=0; i<offsets[0].size(); i++)
00924 {
00925
00926 }
00927
00928 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00929 {
00930 unsigned int index = a_data.boxLayout().index(it());
00931 for(unsigned int i=0; i<types.size(); ++i)
00932 {
00933 long long size = (offsets[i][index+1] - offsets[i][index])
00934 * type_size[i];
00935
00936 assert(size >= 0);
00937 if(size > bufferCapacity[i])
00938 {
00939 bufferCapacity[i] = size;
00940 }
00941 }
00942 }
00943
00944 for(unsigned int i=0; i<types.size(); ++i)
00945 {
00946 buffers[i] = malloc(bufferCapacity[i]);
00947 if(buffers[i] == NULL) {
00948 pout() << " i=" << i
00949 << " types.size() = " << types.size()
00950 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00951 << endl;
00952 MayDay::Error("memory error in buffer allocation write");
00953 }
00954 }
00955
00956
00957
00958
00959 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00960 {
00961 const T& data = a_data[it()];
00962 unsigned int index = a_data.boxLayout().index(it());
00963 Box box = a_data.box(it());
00964 box.grow(outputGhost);
00965 write(data, buffers, box, comps);
00966 for(unsigned int i=0; i<types.size(); ++i)
00967 {
00968 offset[0] = offsets[i][index];
00969 count[0] = offsets[i][index+1] - offset[0];
00970 if(count[0] > 0){
00971 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
00972 offset, NULL,
00973 count, NULL);
00974 assert(err >= 0);
00975 hid_t memdataspace = H5Screate_simple(1, count, NULL);
00976 assert(memdataspace >= 0);
00977 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
00978 H5P_DEFAULT, buffers[i]);
00979 assert(err >= 0);
00980 H5Sclose(memdataspace);
00981 if(err < 0) { ret = err; goto cleanup;}
00982 }
00983 }
00984 }
00985
00986
00987
00988 cleanup:
00989 for(unsigned int i=0; i<types.size(); ++i)
00990 {
00991 free(buffers[i]);
00992 H5Sclose(dataspace[i]);
00993 H5Dclose(dataset[i]);
00994 }
00995 return ret;
00996
00997 }
00998
00999 template <class T>
01000 int write(HDF5Handle& a_handle, const LevelData<T>& a_data,
01001 const std::string& a_name, const IntVect& outputGhost, const Interval& in_comps)
01002 {
01003 HDF5HeaderData info;
01004 info.m_intvect["ghost"] = a_data.ghostVect();
01005 IntVect og(outputGhost);
01006 og.min(a_data.ghostVect());
01007 info.m_intvect["outputGhost"] = og;
01008 std::string group = a_handle.getGroup();
01009 a_handle.setGroup(group+"/"+a_name+"_attributes");
01010 info.writeToFile(a_handle);
01011 a_handle.setGroup(group);
01012 return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og, in_comps);
01013 }
01014
01015 template <class T>
01016 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
01017 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
01018 {
01019 if(a_redefineData)
01020 {
01021 HDF5HeaderData info;
01022 std::string group = a_handle.getGroup();
01023 if(a_handle.setGroup(group+"/"+a_name+"_attributes"))
01024 {
01025 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
01026 MayDay::Warning(message.c_str());
01027 return 1;
01028 }
01029 info.readFromFile(a_handle);
01030 a_handle.setGroup(group);
01031 int ncomp = info.m_int["comps"];
01032 IntVect ghost = info.m_intvect["ghost"];
01033 if(a_comps.end() > 0 && ncomp < a_comps.end())
01034 {
01035 MayDay::Error("attempt to read component interval that is not available");
01036 }
01037 if(a_comps.size() == 0)
01038 a_data.define(a_layout, ncomp, ghost);
01039 else
01040 a_data.define(a_layout, a_comps.size(), ghost);
01041 }
01042 return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
01043
01044 }
01045
01046 template <class T>
01047 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
01048 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
01049 {
01050 int ret = 0;
01051
01052 herr_t err;
01053
01054 char dataname[100];
01055 hsize_t count[1];
01056 hssize_t offset[1];
01057 Vector<Vector<long long> > offsets;
01058
01059 T dummy;
01060 Vector<hid_t> types;
01061 dataTypes(types, dummy);
01062 Vector<hid_t> dataspace(types.size());
01063 Vector<hid_t> dataset(types.size());
01064 offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
01065
01066
01067
01068 Vector<Vector<char> > buffers(types.size(), 500);
01069
01070 for(unsigned int i=0; i<types.size(); ++i)
01071 {
01072 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
01073 dataset[i] = H5Dopen(a_handle.groupID(), dataname);
01074 if(dataset[i] < 0) {MayDay::Warning("dataset open failure"); return dataset[i];}
01075 dataspace[i] = H5Dget_space(dataset[i]);
01076 if(dataspace[i] < 0) {MayDay::Warning("dataspace open failure"); return dataspace[i];}
01077 }
01078
01079 hid_t offsetspace, offsetData;
01080 hsize_t flatdims[1];
01081 for(unsigned int i=0; i<types.size(); ++i)
01082 {
01083 flatdims[0] = offsets[i].size();
01084 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
01085 offsetspace = H5Screate_simple(1, flatdims, NULL);
01086 assert(offsetspace >= 0);
01087 offsetData = H5Dopen(a_handle.groupID(), dataname);
01088 assert(offsetData >= 0);
01089 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
01090 assert(memdataspace >= 0);
01091 err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
01092 H5P_DEFAULT, &(offsets[i][0]));
01093 assert(err >=0);
01094 H5Sclose(memdataspace);
01095 H5Sclose(offsetspace);
01096 H5Dclose(offsetData);
01097 }
01098
01099 HDF5HeaderData info;
01100 std::string group = a_handle.getGroup();
01101 if(a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
01102 {
01103 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
01104 MayDay::Warning(message.c_str());
01105 return 1;
01106 }
01107
01108 info.readFromFile(a_handle);
01109 a_handle.setGroup(group);
01110 int ncomps = info.m_int["comps"];
01111 IntVect outputGhost(IntVect::Zero);
01112 if(info.m_intvect.find("outputGhost") != info.m_intvect.end())
01113 {
01114 outputGhost = info.m_intvect["outputGhost"];
01115 }
01116 if(ncomps <= 0){
01117 MayDay::Warning("ncomps <= 0 in read");
01118 return ncomps;
01119 }
01120
01121 if(a_redefineData){
01122 if(a_comps.size() != 0){
01123 a_data.define(a_layout, a_comps.size());
01124 } else {
01125 a_data.define(a_layout, ncomps);
01126 }
01127 }
01128
01129 Interval comps(0, ncomps-1);
01130
01131
01132
01133
01134
01135 Vector<size_t> type_size(types.size());
01136 for(unsigned int i=0; i<types.size(); ++i)
01137 {
01138 type_size[i] = H5Tget_size(types[i]);
01139
01140 }
01141
01142 Vector<int> thisSize(types.size());
01143 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
01144 {
01145 T& data = a_data[it()];
01146 unsigned int index = a_data.boxLayout().index(it());
01147 Box box = a_data.box(it());
01148
01149 for(unsigned int i=0; i<types.size(); ++i)
01150 {
01151 if(a_comps.size() == 0){
01152 offset[0] = offsets[i][index];
01153 count[0] = offsets[i][index+1] - offset[0];
01154 } else {
01155 offset[0] = offsets[i][index] + box.numPts()*a_comps.begin();
01156 count[0] = a_comps.size() * box.numPts();
01157 }
01158 if(count[0] > 0)
01159 {
01160 int size = count[0] * type_size[i];
01161 while(size > buffers[i].size())
01162 {
01163 buffers[i].resize(2*buffers[i].size());
01164 }
01165
01166 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01167 offset, NULL,
01168 count, NULL);
01169 assert(err >= 0);
01170 hid_t memdataspace = H5Screate_simple(1, count, NULL);
01171 assert(memdataspace >= 0);
01172 err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01173 H5P_DEFAULT, &(buffers[i][0]));
01174 assert(err >= 0);
01175 H5Sclose(memdataspace);
01176 if(err < 0) { ret = err; goto cleanup;}
01177 }
01178 }
01179 box.grow(outputGhost);
01180 read(data, buffers, box, comps);
01181 }
01182
01183 cleanup:
01184 for(unsigned int i=0; i<types.size(); ++i)
01185 {
01186
01187 H5Sclose(dataspace[i]);
01188 H5Dclose(dataset[i]);
01189 }
01190 return ret;
01191 }
01192
01193 template <class T>
01194 int writeLevel(HDF5Handle& a_handle,
01195 const int& a_level,
01196 const LevelData<T>& a_data,
01197 const Real& a_dx,
01198 const Real& a_dt,
01199 const Real& a_time,
01200 const Box& a_domain,
01201 const int& a_refRatio,
01202 const IntVect& outputGhost,
01203 const Interval& comps)
01204 {
01205 int error;
01206 char levelName[10];
01207 std::string currentGroup = a_handle.getGroup();
01208 sprintf(levelName, "/level_%i",a_level);
01209 error = a_handle.setGroup(currentGroup + levelName);
01210 if(error != 0) return 1;
01211
01212 HDF5HeaderData meta;
01213 meta.m_real["dx"] = a_dx;
01214 meta.m_real["dt"] = a_dt;
01215 meta.m_real["time"] = a_time;
01216 meta.m_box["prob_domain"] = a_domain;
01217 meta.m_int["ref_ratio"] = a_refRatio;
01218
01219 error = meta.writeToFile(a_handle);
01220 if(error != 0) return 2;
01221
01222 error = write(a_handle, a_data.boxLayout());
01223 if(error != 0) return 3;
01224
01225 error = write(a_handle, a_data, "data", outputGhost, comps);
01226 if(error != 0) return 4;
01227
01228 a_handle.setGroup(currentGroup);
01229
01230 return 0;
01231 }
01232
01233 template <class T>
01234 int readLevel(HDF5Handle& a_handle,
01235 const int& a_level,
01236 LevelData<T>& a_data,
01237 Real& a_dx,
01238 Real& a_dt,
01239 Real& a_time,
01240 Box& a_domain,
01241 int& a_refRatio,
01242 const Interval& a_comps,
01243 bool setGhost)
01244 {
01245 HDF5HeaderData header;
01246 header.readFromFile(a_handle);
01247
01248
01249
01250 int error;
01251 char levelName[10];
01252 std::string currentGroup = a_handle.getGroup();
01253 sprintf(levelName, "/level_%i",a_level);
01254 error = a_handle.setGroup(currentGroup + levelName);
01255 if(error != 0) return 1;
01256
01257 HDF5HeaderData meta;
01258 error = meta.readFromFile(a_handle);
01259 if(error != 0) return 2;
01260 a_dx = meta.m_real["dx"];
01261 a_dt = meta.m_real["dt"];
01262 a_time = meta.m_real["time"];
01263 a_domain = meta.m_box["prob_domain"];
01264 a_refRatio = meta.m_int["ref_ratio"];
01265
01266 Vector<Box> boxes;
01267 error = read(a_handle, boxes);
01268 Vector<int> procIDs;
01269 LoadBalance(procIDs, boxes);
01270
01271 DisjointBoxLayout layout(boxes, procIDs);
01272
01273 layout.close();
01274 if(error != 0) return 3;
01275
01276 error = read(a_handle, a_data, "data", layout, a_comps);
01277
01278 if(error != 0) return 4;
01279
01280 a_handle.setGroup(currentGroup);
01281
01282 return 0;
01283 }
01284
01285 #else // HDF5
01286
01287
01288 #define HOFFSET(S,M) (offsetof(S,M))
01289
01290 #endif // HDF5
01291
01292 #endif // CH_HDF5_H