00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _CH_HDF5_H_
00012 #define _CH_HDF5_H_
00013
00014 #define CHOFFSET(object, member) (int)((char*)&(object.member) - (char*)&object)
00015
00016 #ifdef CH_USE_HDF5 // if you don't have CH_USE_HDF5, then this file is useless
00017
00018 #include <iostream>
00019 using std::cout;
00020 using std::endl;
00021
00022 #ifdef CH_MPI
00023 #include <mpi.h>
00024 #endif
00025
00026 #include "LevelData.H"
00027 #include "HDF5Portable.H"
00028
00029 #undef inline
00030 #include <string>
00031 #include <map>
00032 #include "RealVect.H"
00033 #include "CH_Timer.H"
00034 #include "LoadBalance.H"
00035 #include "LayoutIterator.H"
00036 #include "Vector.H"
00037 #include "memtrack.H"
00038 #include "FluxBox.H"
00039
00040 #ifdef CH_MULTIDIM
00041 #include "BoxTools_ExternC_Mangler.H"
00042 #endif
00043 #include "NamespaceHeader.H"
00044
00045
00046 template <class T>
00047 void read(T& item, Vector<Vector<char> >& a_allocatedBuffers, const Box& box,
00048 const Interval& comps)
00049 {
00050 Vector<void*> b(a_allocatedBuffers.size());
00051 for (int i=0; i<b.size(); ++i) b[i]= &(a_allocatedBuffers[i][0]);
00052 read(item, b, box, comps);
00053 }
00054
00055 using std::map;
00056
00057 class HDF5Handle;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template <class T>
00075 int writeLevel(HDF5Handle& a_handle,
00076 const int& a_level,
00077 const T& a_data,
00078 const Real& a_dx,
00079 const Real& a_dt,
00080 const Real& a_time,
00081 const Box& a_domain,
00082 const int& a_refRatio,
00083 const IntVect& outputGhost = IntVect::Zero,
00084 const Interval& comps = Interval());
00085
00086 template <class T>
00087 int readLevel(HDF5Handle& a_handle,
00088 const int& a_level,
00089 LevelData<T>& a_data,
00090 Real& a_dx,
00091 Real& a_dt,
00092 Real& a_time,
00093 Box& a_domain,
00094 int& a_refRatio,
00095 const Interval& a_comps = Interval(),
00096 bool setGhost = false);
00097
00098 template <class T>
00099 int readLevel(HDF5Handle& a_handle,
00100 const int& a_level,
00101 LevelData<T>& a_data,
00102 RealVect& a_dx,
00103 Real& a_dt,
00104 Real& a_time,
00105 Box& a_domain,
00106 IntVect& a_refRatio,
00107 const Interval& a_comps = Interval(),
00108 bool setGhost = false);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int write(HDF5Handle& a_handle,
00123 const BoxLayout& a_layout,
00124 const std::string& name = "boxes");
00125
00126
00127
00128
00129
00130
00131
00132 template <class T>
00133 int write(HDF5Handle& a_handle,
00134 const BoxLayoutData<T>& a_data,
00135 const std::string& a_name,
00136 IntVect outputGhost = IntVect::Zero,
00137 const Interval& comps = Interval(),
00138 bool newForm = false);
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 template <class T>
00149 int write(HDF5Handle& a_handle,
00150 const LevelData<T>& a_data,
00151 const std::string& a_name,
00152 const IntVect& outputGhost = IntVect::Zero,
00153 const Interval& comps = Interval());
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 int read(HDF5Handle& a_handle,
00193 Vector<Box>& boxes,
00194 const std::string& name = "boxes");
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 int readBoxes(HDF5Handle& a_handle,
00205 Vector<Vector<Box> >& boxes);
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 int readFArrayBox(HDF5Handle& a_handle,
00217 FArrayBox& a_fab,
00218 int a_level,
00219 int a_boxNumber,
00220 const Interval& a_components,
00221 const std::string& a_dataName = "data" );
00222
00223
00224
00225
00226
00227
00228
00229
00230 template <class T>
00231 int read(HDF5Handle& a_handle,
00232 BoxLayoutData<T>& a_data,
00233 const std::string& a_name,
00234 const BoxLayout& a_layout,
00235 const Interval& a_comps = Interval(),
00236 bool redefineData = true);
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 template <class T>
00261 int read(HDF5Handle& a_handle,
00262 LevelData<T>& a_data,
00263 const std::string& a_name,
00264 const DisjointBoxLayout& a_layout,
00265 const Interval& a_comps = Interval(),
00266 bool redefineData = true);
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 class HDF5Handle
00280 {
00281 public:
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 enum mode
00302 {
00303 CREATE,
00304 CREATE_SERIAL,
00305 OPEN_RDONLY,
00306 OPEN_RDWR
00307 };
00308
00309
00310
00311
00312
00313
00314
00315
00316 HDF5Handle();
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 HDF5Handle(
00332 const std::string& a_filename,
00333 mode a_mode,
00334 const char *a_globalGroupName="Chombo_global");
00335
00336
00337
00338 ~HDF5Handle();
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 int open(
00368 const std::string& a_filename,
00369 mode a_mode,
00370 const char *a_globalGroupName="Chombo_global");
00371
00372
00373
00374
00375
00376
00377
00378 bool isOpen() const;
00379
00380
00381
00382
00383
00384
00385
00386 void close();
00387
00388
00389
00390
00391
00392
00393
00394 void setGroupToLevel(int a_level);
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 int setGroup(const std::string& groupAbsPath);
00405
00406
00407
00408
00409
00410
00411
00412
00413 int pushGroup( const std::string& grp );
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 int popGroup();
00424
00425
00426
00427
00428
00429
00430
00431
00432 const std::string& getGroup() const;
00433
00434 const hid_t& fileID() const;
00435 const hid_t& groupID() const;
00436 static hid_t box_id;
00437 static hid_t intvect_id;
00438 static hid_t realvect_id;
00439 static map<std::string, std::string> groups;
00440
00441 private:
00442
00443 HDF5Handle(const HDF5Handle&);
00444 HDF5Handle& operator=(const HDF5Handle&);
00445
00446 hid_t m_fileID;
00447 hid_t m_currentGroupID;
00448 bool m_isOpen;
00449 std::string m_filename;
00450 std::string m_group;
00451 int m_level;
00452
00453
00454 static bool initialized;
00455 static void initialize();
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
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 class HDF5HeaderData
00503 {
00504 public:
00505
00506
00507
00508
00509
00510
00511
00512
00513 int writeToFile(HDF5Handle& file) const;
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 int readFromFile(HDF5Handle& file);
00525
00526
00527 void clear();
00528
00529
00530 map<std::string, Real> m_real;
00531
00532
00533 map<std::string, int> m_int;
00534
00535
00536 map<std::string, std::string> m_string;
00537
00538
00539 map<std::string, IntVect> m_intvect;
00540
00541
00542 map<std::string, Box> m_box;
00543
00544
00545 map<std::string, RealVect> m_realvect;
00546
00547
00548
00549 int writeToLocation(hid_t loc_id) const;
00550 int readFromLocation(hid_t loc_id);
00551
00552
00553 void dump() const;
00554
00555 private:
00556 static herr_t attributeScan(hid_t loc_id, const char *name, void *opdata);
00557 };
00558
00559 extern "C"
00560 {
00561 herr_t HDF5HeaderDataattributeScan(hid_t loc_id, const char *name, void *opdata);
00562 }
00563
00564 std::ostream& operator<<(std::ostream& os, const HDF5HeaderData& data);
00565
00566
00567
00568
00569
00570
00571
00572 #if ( H5_VERS_MAJOR == 1 && H5_VERS_MINOR > 6 )
00573 typedef hsize_t ch_offset_t;
00574 #else
00575 #if ( H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 && H5_VERS_RELEASE >= 4 )
00576 typedef hsize_t ch_offset_t;
00577 #else
00578 typedef hssize_t ch_offset_t;
00579 #endif
00580 #endif
00581
00582
00583 template<class T>
00584 hid_t H5Type(const T* dummy);
00585
00586 template< >
00587 hid_t H5Type(const int* dummy);
00588
00589 template< >
00590 hid_t H5Type(const long long* dummy);
00591
00592 template< >
00593 hid_t H5Type(const float* dummy);
00594
00595 template< >
00596 hid_t H5Type(const double* dummy);
00597
00598 template< >
00599 hid_t H5Type(const Box* dummy);
00600
00601 template< >
00602 hid_t H5Type(const RealVect* dummy);
00603
00604 template< >
00605 hid_t H5Type(const IntVect* dummy);
00606
00607 template<class T>
00608 hid_t H5Type(const T* dummy)
00609 {
00610
00611 MayDay::Error(" H5Type(const T* dummy)");
00612 return -4;
00613 }
00614
00615
00616 void createData(hid_t& a_dataset,
00617 hid_t& a_dataspace,
00618 HDF5Handle& handle,
00619 const std::string& name,
00620 hid_t type,
00621 hsize_t size);
00622
00623 template <class T>
00624 void createDataset(hid_t& a_dataset,
00625 hid_t& a_dataspace,
00626 HDF5Handle& handle,
00627 const std::string& name,
00628 const T* dummy,
00629 hsize_t size)
00630 {
00631 createData(a_dataset, a_dataspace, handle, name, H5Type(dummy), size);
00632
00633 }
00634
00635 void writeDataset(hid_t a_dataset,
00636 hid_t a_dataspace,
00637 const void* start,
00638 ch_offset_t off,
00639 hsize_t count);
00640
00641 void readDataset(hid_t a_dataset,
00642 hid_t a_dataspace,
00643 void* start,
00644 ch_offset_t off,
00645 hsize_t count);
00646
00647
00648
00649 struct OffsetBuffer
00650 {
00651 Vector<int> index;
00652 Vector<Vector<int> > offsets;
00653 void operator=(const OffsetBuffer& rhs);
00654 };
00655
00656 ostream& operator<<(ostream& os, const OffsetBuffer& ob);
00657
00658
00659 #include "NamespaceFooter.H"
00660
00661 #include "BaseNamespaceHeader.H"
00662
00663 #include "NamespaceVar.H"
00664
00665
00666 template < >
00667 int linearSize(const CH_XDIR::OffsetBuffer& a_input);
00668
00669
00670 template < >
00671 void linearIn(CH_XDIR::OffsetBuffer& a_outputT, const void* const a_inBuf);
00672
00673
00674 template < >
00675 void linearOut(void* const a_outBuf, const CH_XDIR::OffsetBuffer& a_inputT);
00676
00677 template < > int linearSize(const Vector<CH_XDIR::OffsetBuffer>& a_input);
00678 template < > void linearIn(Vector<CH_XDIR::OffsetBuffer>& a_outputT, const void* const inBuf);
00679 template < > void linearOut(void* const a_outBuf, const Vector<CH_XDIR::OffsetBuffer>& a_inputT);
00680
00681
00682 #include "BaseNamespaceFooter.H"
00683 #include "NamespaceHeader.H"
00684
00685
00686
00687 template <>
00688 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<int>& dummy)
00689 {
00690 a_types.resize(1);
00691 a_types[0] = H5T_NATIVE_INT;
00692 }
00693
00694 template <>
00695 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<char>& dummy)
00696 {
00697 a_types.resize(1);
00698 a_types[0] = H5T_NATIVE_CHAR;
00699 }
00700
00701
00702
00703
00704 template <>
00705 inline void dataTypes(Vector<hid_t>& a_types, const FArrayBox& dummy)
00706 {
00707 a_types.resize(1);
00708 a_types[0] = H5T_NATIVE_REAL;
00709 }
00710
00711 template <>
00712 inline void dataTypes(Vector<hid_t>& a_types, const FluxBox& dummy)
00713 {
00714 a_types.resize(1);
00715 a_types[0] = H5T_NATIVE_REAL;
00716 }
00717
00718 template <>
00719 inline void dataSize(const BaseFab<int>& item, Vector<int>& a_sizes,
00720 const Box& box, const Interval& comps)
00721 {
00722 a_sizes[0] = box.numPts() * comps.size();
00723 }
00724
00725 template <>
00726 inline void dataSize(const BaseFab<char>& item, Vector<int>& a_sizes,
00727 const Box& box, const Interval& comps)
00728 {
00729 a_sizes[0] = box.numPts() * comps.size();
00730 }
00731
00732 template <>
00733 inline void dataSize(const FArrayBox& item, Vector<int>& a_sizes,
00734 const Box& box, const Interval& comps)
00735 {
00736 a_sizes[0] = box.numPts() * comps.size();
00737 }
00738
00739 template <>
00740 inline void dataSize(const FluxBox& item, Vector<int>& a_sizes,
00741 const Box& box, const Interval& comps)
00742 {
00743 int& t = a_sizes[0];
00744 t = 0;
00745 for (int dir =0; dir<CH_SPACEDIM; dir++)
00746 {
00747 Box edgeBox(surroundingNodes(box,dir));
00748 t += edgeBox.numPts()*comps.size();
00749 }
00750 }
00751
00752 template <>
00753 inline const char* name(const FArrayBox& a_dummySpecializationArg)
00754 {
00755
00756
00757 const char* name = "FArrayBox";
00758 return name;
00759 }
00760
00761 template <>
00762 inline const char* name(const BaseFab<int>& a_dummySpecializationArg)
00763 {
00764
00765
00766 const char* name = "BaseFab<int>";
00767 return name;
00768 }
00769
00770 template <>
00771 inline const char* name(const BaseFab<char>& a_dummySpecializationArg)
00772 {
00773
00774
00775 const char* name = "BaseFab<char>";
00776 return name;
00777 }
00778
00779
00780
00781
00782 template <class T>
00783 inline void dataTypes(Vector<hid_t>& a_types, const T& dummy)
00784 {
00785 a_types.resize(1);
00786 a_types[0] = H5T_NATIVE_CHAR;
00787 }
00788
00789 template <class T>
00790 inline void dataSize(const T& item, Vector<int>& a_sizes,
00791 const Box& box, const Interval& comps)
00792 {
00793 a_sizes[0] = item.size(box, comps);
00794 }
00795
00796 template <class T>
00797 inline void write(const T& item, Vector<void*>& a_allocatedBuffers,
00798 const Box& box, const Interval& comps)
00799 {
00800 item.linearOut(a_allocatedBuffers[0], box, comps);
00801 }
00802
00803 template <class T>
00804 inline void read(T& item, Vector<void*>& a_allocatedBuffers,
00805 const Box& box, const Interval& comps)
00806 {
00807 item.linearIn(a_allocatedBuffers[0], box, comps);
00808 }
00809
00810 template <class T>
00811 inline const char* name(const T& a_dummySpecializationArg)
00812 {
00813 static const char* name = "unknown";
00814 return name;
00815 }
00816
00817 template <class T>
00818 void getOffsets(Vector<Vector<long long> >& offsets, const BoxLayoutData<T>& a_data,
00819 int types, const Interval& comps, const IntVect& outputGhost)
00820 {
00821 CH_TIME("getOffsets");
00822 const BoxLayout& layout = a_data.boxLayout();
00823 offsets.resize(types, Vector<long long>(layout.size()+1));
00824
00825 for (int t=0; t<types; t++) offsets[t][0] = 0;
00826 Vector<int> thisSize(types);
00827 if (T::preAllocatable()==0)
00828 {
00829 T dummy;
00830 unsigned int index = 1;
00831 for (LayoutIterator it(layout.layoutIterator()); it.ok(); ++it)
00832 {
00833 Box region = layout[it()];
00834 region.grow(outputGhost);
00835 dataSize(dummy, thisSize, region, comps);
00836 for (unsigned int i=0; i<thisSize.size(); ++i)
00837 {
00838
00839 offsets[i][index] = offsets[i][index-1] + thisSize[i];
00840 }
00841 ++index;
00842 }
00843 }
00844 else
00845 {
00846 OffsetBuffer buff;
00847
00848 for (DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit)
00849 {
00850 int index = a_data.boxLayout().index(dit());
00851
00852 buff.index.push_back(index);
00853 Box region = layout[dit()];
00854 region.grow(outputGhost);
00855 dataSize(a_data[dit()], thisSize, region, comps);
00856 buff.offsets.push_back(thisSize);
00857 }
00858 Vector<OffsetBuffer> gathering(numProc());
00859 gather(gathering, buff, uniqueProc(SerialTask::compute));
00860 broadcast(gathering, uniqueProc(SerialTask::compute));
00861
00862 for (int i=0; i<numProc(); ++i)
00863 {
00864 OffsetBuffer& offbuf = gathering[i];
00865 for (int num=0; num<offbuf.index.size(); num++)
00866 {
00867 int index = offbuf.index[num];
00868 for (unsigned int j=0; j<types; ++j)
00869 {
00870
00871 offsets[j][index+1] = offbuf.offsets[num][j];
00872 }
00873 }
00874 }
00875 for (int i=0; i<layout.size(); i++)
00876 {
00877 for (unsigned int j=0; j<types; ++j)
00878 {
00879
00880 offsets[j][i+1] += offsets[j][i];
00881 }
00882 }
00883 }
00884
00885
00886 }
00887
00888
00889
00890
00891
00892 template <class T>
00893 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data,
00894 const std::string& a_name, IntVect outputGhost,
00895 const Interval& in_comps, bool newForm)
00896 {
00897 CH_TIME("write_Level");
00898 int ret = 0;
00899
00900 Interval comps(in_comps);
00901 if ( comps.size() == 0) comps = a_data.interval();
00902 T dummy;
00903 Vector<hid_t> types;
00904 dataTypes(types, dummy);
00905
00906 Vector<Vector<long long> > offsets;
00907 Vector<long long> bufferCapacity(types.size(), 1);
00908 Vector<void*> buffers(types.size(), NULL);
00909
00910 getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00911
00912
00913 hsize_t flatdims[1];
00914 char dataname[100];
00915 Vector<hid_t> dataspace(types.size());
00916 Vector<hid_t> dataset(types.size());
00917
00918 herr_t err;
00919 hsize_t count[1];
00920 ch_offset_t offset[1];
00921 CH_assert(!(newForm && types.size() != 1));
00922
00923 for (unsigned int i=0; i<types.size(); ++i)
00924 {
00925 flatdims[0] = offsets[i][offsets[i].size()-1];
00926 if (newForm)
00927 {
00928 if (a_name == "M")
00929 {
00930 strcpy(dataname, "Mask");
00931 }
00932 else
00933 {
00934 sprintf(dataname, "%sRegular", a_name.c_str());
00935 }
00936 }
00937 else
00938 {
00939 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00940 }
00941 {
00942 CH_TIME("H5Screate");
00943 dataspace[i] = H5Screate_simple(1, flatdims, NULL);
00944 }
00945 CH_assert(dataspace[i] >=0);
00946 {
00947 CH_TIME("H5Dcreate");
00948 dataset[i] = H5Dcreate(a_handle.groupID(), dataname,
00949 types[i],
00950 dataspace[i], H5P_DEFAULT);
00951 }
00952 CH_assert(dataset[i] >= 0);
00953 }
00954
00955 hid_t offsetspace, offsetData;
00956 for (unsigned int i=0; i<types.size(); ++i)
00957 {
00958 flatdims[0] = offsets[i].size();
00959 if (newForm)
00960 {
00961 if (a_name == "M")
00962 {
00963 strcpy(dataname, "MaskOffsets");
00964 }
00965 else
00966 {
00967 sprintf(dataname, "%sOffsets",a_name.c_str());
00968 }
00969 }
00970 else
00971 {
00972 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00973 }
00974 {
00975 CH_TIME("H5S_H5D_offsets_create");
00976 offsetspace = H5Screate_simple(1, flatdims, NULL);
00977 CH_assert(offsetspace >= 0);
00978 offsetData = H5Dcreate(a_handle.groupID(), dataname,
00979 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00980 CH_assert(offsetData >= 0);
00981 }
00982 if (procID() == 0)
00983 {
00984 CH_TIME("WriteOffsets");
00985 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00986 CH_assert(memdataspace >= 0);
00987 err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00988 H5P_DEFAULT, &(offsets[i][0]));
00989 CH_assert(err >= 0);
00990 H5Sclose(memdataspace);
00991 }
00992 {
00993 CH_TIME("H5S_H5D_offsets_close");
00994 H5Sclose(offsetspace);
00995 H5Dclose(offsetData);
00996 }
00997 }
00998
00999
01000 if (!newForm)
01001 {
01002 CH_TIME("WriteAttributes");
01003 HDF5HeaderData info;
01004 info.m_int["comps"] = comps.size();
01005 info.m_string["objectType"] = name(dummy);
01006 std::string group = a_handle.getGroup();
01007 a_handle.setGroup(group+"/"+a_name+"_attributes");
01008 info.writeToFile(a_handle);
01009 a_handle.setGroup(group);
01010 }
01011
01012
01013
01014
01015 Vector<size_t> type_size(types.size());
01016 for (unsigned int i=0; i<types.size(); ++i)
01017 {
01018 type_size[i] = H5Tget_size(types[i]);
01019 }
01020
01021 Vector<int> thisSize(types.size());
01022
01023
01024
01025
01026
01027 for (int i=0; i<offsets[0].size(); i++)
01028 {
01029
01030 }
01031
01032 {
01033 CH_TIME("ComputeBufferCapacity");
01034 for (DataIterator it = a_data.dataIterator(); it.ok(); ++it)
01035 {
01036 unsigned int index = a_data.boxLayout().index(it());
01037 for (unsigned int i=0; i<types.size(); ++i)
01038 {
01039 long long size = (offsets[i][index+1] - offsets[i][index])
01040 * type_size[i];
01041
01042 CH_assert(size >= 0);
01043 if (size > bufferCapacity[i])
01044 {
01045 bufferCapacity[i] = size;
01046 }
01047 }
01048 }
01049 }
01050
01051 for (unsigned int i=0; i<types.size(); ++i)
01052 {
01053 CH_TIME("mallocMT_buffers");
01054 buffers[i] = mallocMT(bufferCapacity[i]);
01055 if (buffers[i] == NULL)
01056 {
01057 pout() << " i=" << i
01058 << " types.size() = " << types.size()
01059 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
01060 << endl;
01061 MayDay::Error("memory error in buffer allocation write");
01062 }
01063 }
01064
01065
01066
01067
01068 #ifdef TRY_MPI_COLLECTIVES_
01069 hid_t DXPL = H5Pcreate(H5P_DATASET_XFER);
01070 H5Pset_dxpl_mpio(DXPL, H5FD_MPIO_COLLECTIVE);
01071 #endif
01072 {
01073 CH_TIME("linearize_H5Dwrite");
01074 for (DataIterator it = a_data.dataIterator(); it.ok(); ++it)
01075 {
01076 const T& data = a_data[it()];
01077 unsigned int index = a_data.boxLayout().index(it());
01078 Box box = a_data.box(it());
01079 box.grow(outputGhost);
01080 {
01081 CH_TIMELEAF("linearize");
01082 write(data, buffers, box, comps);
01083 }
01084 for (unsigned int i=0; i<types.size(); ++i)
01085 {
01086 offset[0] = offsets[i][index];
01087 count[0] = offsets[i][index+1] - offset[0];
01088 hid_t memdataspace;
01089 if (count[0] > 0)
01090 {
01091 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01092 offset, NULL,
01093 count, NULL);
01094 CH_assert(err >= 0);
01095 memdataspace = H5Screate_simple(1, count, NULL);
01096 CH_assert(memdataspace >= 0);
01097 }
01098 else
01099 {
01100 H5Sselect_none(dataspace[i]);
01101 H5Sselect_none(memdataspace);
01102 }
01103 {
01104 CH_TIMELEAF("H5Dwrite");
01105 #ifdef TRY_MPI_COLLECTIVES_
01106 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
01107 DXPL, buffers[i]);
01108 #else
01109 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
01110 H5P_DEFAULT, buffers[i]);
01111 #endif
01112 }
01113 CH_assert(err >= 0);
01114 H5Sclose(memdataspace);
01115 if (err < 0)
01116 {
01117 ret = err;
01118 goto cleanup;
01119 }
01120
01121 }
01122 }
01123 }
01124 #ifdef TRY_MPI_COLLECTIVES_
01125 H5Pclose(DXPL);
01126 #endif
01127
01128
01129
01130 cleanup:
01131 for (unsigned int i=0; i<types.size(); ++i)
01132 {
01133 {
01134 CH_TIME("freeMT");
01135 freeMT(buffers[i]);
01136 }
01137 {
01138 CH_TIME("H5Sclose");
01139 H5Sclose(dataspace[i]);
01140 }
01141 {
01142 CH_TIME("H5Dclose");
01143 H5Dclose(dataset[i]);
01144 }
01145 }
01146 return ret;
01147
01148 }
01149
01150 template <class T>
01151 int write(HDF5Handle& a_handle, const LevelData<T>& a_data,
01152 const std::string& a_name, const IntVect& outputGhost, const Interval& in_comps)
01153 {
01154 HDF5HeaderData info;
01155 info.m_intvect["ghost"] = a_data.ghostVect();
01156 IntVect og(outputGhost);
01157 og.min(a_data.ghostVect());
01158 info.m_intvect["outputGhost"] = og;
01159 std::string group = a_handle.getGroup();
01160 a_handle.setGroup(group+"/"+a_name+"_attributes");
01161 info.writeToFile(a_handle);
01162 a_handle.setGroup(group);
01163 return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og, in_comps);
01164 }
01165
01166 template <class T>
01167 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
01168 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
01169 {
01170 if (a_redefineData)
01171 {
01172 HDF5HeaderData info;
01173 std::string group = a_handle.getGroup();
01174 if (a_handle.setGroup(group+"/"+a_name+"_attributes"))
01175 {
01176 std::string message = "error opening "
01177 +a_handle.getGroup()+"/"+a_name+"_attributes" ;
01178 MayDay::Warning(message.c_str());
01179 return 1;
01180 }
01181 info.readFromFile(a_handle);
01182 a_handle.setGroup(group);
01183 int ncomp = info.m_int["comps"];
01184 IntVect ghost = info.m_intvect["ghost"];
01185 if (a_comps.end() > 0 && ncomp < a_comps.end())
01186 {
01187 MayDay::Error("attempt to read component interval that is not available");
01188 }
01189 if (a_comps.size() == 0)
01190 a_data.define(a_layout, ncomp, ghost);
01191 else
01192 a_data.define(a_layout, a_comps.size(), ghost);
01193 }
01194 return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
01195
01196 }
01197
01198 template <class T>
01199 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
01200 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
01201 {
01202 CH_TIME("read");
01203 int ret = 0;
01204
01205 herr_t err;
01206
01207 char dataname[100];
01208 hsize_t count[1];
01209 ch_offset_t offset[1];
01210 Vector<Vector<long long> > offsets;
01211
01212 T dummy;
01213 Vector<hid_t> types;
01214 dataTypes(types, dummy);
01215 Vector<hid_t> dataspace(types.size());
01216 Vector<hid_t> dataset(types.size());
01217 offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
01218
01219
01220
01221 Vector<Vector<char> > buffers(types.size(), 500);
01222
01223 for (unsigned int i=0; i<types.size(); ++i)
01224 {
01225 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
01226 dataset[i] = H5Dopen(a_handle.groupID(), dataname);
01227 if (dataset[i] < 0)
01228 {
01229 MayDay::Warning("dataset open failure"); return dataset[i];
01230 }
01231 dataspace[i] = H5Dget_space(dataset[i]);
01232 if (dataspace[i] < 0)
01233 {
01234 MayDay::Warning("dataspace open failure"); return dataspace[i];
01235 }
01236 }
01237
01238 hid_t offsetspace, offsetData;
01239 hsize_t flatdims[1];
01240 for (unsigned int i=0; i<types.size(); ++i)
01241 {
01242 flatdims[0] = offsets[i].size();
01243 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
01244 offsetspace = H5Screate_simple(1, flatdims, NULL);
01245 CH_assert(offsetspace >= 0);
01246 offsetData = H5Dopen(a_handle.groupID(), dataname);
01247 CH_assert(offsetData >= 0);
01248 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
01249 CH_assert(memdataspace >= 0);
01250 err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
01251 H5P_DEFAULT, &(offsets[i][0]));
01252 CH_assert(err >=0);
01253 H5Sclose(memdataspace);
01254 H5Sclose(offsetspace);
01255 H5Dclose(offsetData);
01256 }
01257
01258 HDF5HeaderData info;
01259 std::string group = a_handle.getGroup();
01260 if (a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
01261 {
01262 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
01263 MayDay::Warning(message.c_str());
01264 return 1;
01265 }
01266
01267 info.readFromFile(a_handle);
01268 a_handle.setGroup(group);
01269 int ncomps = info.m_int["comps"];
01270 IntVect outputGhost(IntVect::Zero);
01271 if (info.m_intvect.find("outputGhost") != info.m_intvect.end())
01272 {
01273 outputGhost = info.m_intvect["outputGhost"];
01274 }
01275 if (ncomps <= 0)
01276 {
01277 MayDay::Warning("ncomps <= 0 in read");
01278 return ncomps;
01279 }
01280
01281 if (a_redefineData)
01282 {
01283 if (a_comps.size() != 0)
01284 {
01285 a_data.define(a_layout, a_comps.size());
01286 }
01287 else
01288 {
01289 a_data.define(a_layout, ncomps);
01290 }
01291 }
01292
01293 Interval comps(0, ncomps-1);
01294
01295
01296
01297
01298
01299 Vector<size_t> type_size(types.size());
01300 for (unsigned int i=0; i<types.size(); ++i)
01301 {
01302 type_size[i] = H5Tget_size(types[i]);
01303
01304 }
01305
01306 Vector<int> thisSize(types.size());
01307 DataIterator it = a_data.dataIterator();
01308 for( ; it.ok(); ++it)
01309 {
01310 CH_TIMELEAF("H5Dread");
01311 T& data = a_data[it()];
01312 unsigned int index = a_data.boxLayout().index(it());
01313 Box box = a_data.box(it());
01314
01315 for (unsigned int i=0; i<types.size(); ++i)
01316 {
01317
01318 offset[0] = offsets[i][index];
01319 count[0] = offsets[i][index+1] - offset[0];
01320 if (count[0] > 0)
01321 {
01322 int size = count[0] * type_size[i];
01323 while (size > buffers[i].size())
01324 {
01325 buffers[i].resize(2*buffers[i].size());
01326 }
01327
01328 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01329 offset, NULL,
01330 count, NULL);
01331 CH_assert(err >= 0);
01332 hid_t memdataspace = H5Screate_simple(1, count, NULL);
01333 CH_assert(memdataspace >= 0);
01334 err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01335 H5P_DEFAULT, &(buffers[i][0]));
01336 CH_assert(err >= 0);
01337 H5Sclose(memdataspace);
01338 if (err < 0)
01339 {
01340 ret = err;
01341 goto cleanup;
01342 }
01343 }
01344 }
01345 box.grow(outputGhost);
01346 read(data, buffers, box, comps);
01347 }
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 cleanup:
01364 for (unsigned int i=0; i<types.size(); ++i)
01365 {
01366
01367 H5Sclose(dataspace[i]);
01368 H5Dclose(dataset[i]);
01369 }
01370 return ret;
01371 }
01372
01373 template <class T>
01374 int writeLevel(HDF5Handle& a_handle,
01375 const int& a_level,
01376 const T& a_data,
01377 const Real& a_dx,
01378 const Real& a_dt,
01379 const Real& a_time,
01380 const Box& a_domain,
01381 const int& a_refRatio,
01382 const IntVect& outputGhost,
01383 const Interval& comps)
01384 {
01385 int error;
01386 char levelName[10];
01387 std::string currentGroup = a_handle.getGroup();
01388 sprintf(levelName, "/level_%i",a_level);
01389 error = a_handle.setGroup(currentGroup + levelName);
01390 if (error != 0) return 1;
01391
01392 HDF5HeaderData meta;
01393 meta.m_real["dx"] = a_dx;
01394 meta.m_real["dt"] = a_dt;
01395 meta.m_real["time"] = a_time;
01396 meta.m_box["prob_domain"] = a_domain;
01397 meta.m_int["ref_ratio"] = a_refRatio;
01398
01399 error = meta.writeToFile(a_handle);
01400 if (error != 0) return 2;
01401
01402 error = write(a_handle, a_data.boxLayout());
01403 if (error != 0) return 3;
01404
01405 error = write(a_handle, a_data, "data", outputGhost, comps);
01406 if (error != 0) return 4;
01407
01408 a_handle.setGroup(currentGroup);
01409
01410 return 0;
01411 }
01412
01413
01414 template <class T>
01415 int writeLevel(HDF5Handle& a_handle,
01416 const int& a_level,
01417 const T& a_data,
01418 const RealVect& a_dx,
01419 const Real& a_dt,
01420 const Real& a_time,
01421 const Box& a_domain,
01422 const IntVect& a_refRatios,
01423 const IntVect& outputGhost,
01424 const Interval& comps)
01425 {
01426 int error;
01427 char levelName[10];
01428 std::string currentGroup = a_handle.getGroup();
01429 sprintf(levelName, "/level_%i",a_level);
01430 error = a_handle.setGroup(currentGroup + levelName);
01431 if (error != 0) return 1;
01432
01433 HDF5HeaderData meta;
01434 meta.m_realvect["vec_dx"] = a_dx;
01435 meta.m_real["dt"] = a_dt;
01436 meta.m_real["time"] = a_time;
01437 meta.m_box["prob_domain"] = a_domain;
01438 meta.m_intvect["vec_ref_ratio"] = a_refRatios;
01439
01440 error = meta.writeToFile(a_handle);
01441 if (error != 0) return 2;
01442
01443 error = write(a_handle, a_data.boxLayout());
01444 if (error != 0) return 3;
01445
01446 error = write(a_handle, a_data, "data", outputGhost, comps);
01447 if (error != 0) return 4;
01448
01449 a_handle.setGroup(currentGroup);
01450
01451 return 0;
01452 }
01453
01454
01455 template <class T>
01456 int readLevel(HDF5Handle& a_handle,
01457 const int& a_level,
01458 LevelData<T>& a_data,
01459 Real& a_dx,
01460 Real& a_dt,
01461 Real& a_time,
01462 Box& a_domain,
01463 int& a_refRatio,
01464 const Interval& a_comps,
01465 bool setGhost)
01466 {
01467 HDF5HeaderData header;
01468 header.readFromFile(a_handle);
01469
01470
01471
01472 int error;
01473 char levelName[10];
01474 std::string currentGroup = a_handle.getGroup();
01475 sprintf(levelName, "/level_%i",a_level);
01476 error = a_handle.setGroup(currentGroup + levelName);
01477 if (error != 0) return 1;
01478
01479 HDF5HeaderData meta;
01480 error = meta.readFromFile(a_handle);
01481 if (error != 0) return 2;
01482 a_dx = meta.m_real["dx"];
01483 a_dt = meta.m_real["dt"];
01484 a_time = meta.m_real["time"];
01485 a_domain = meta.m_box["prob_domain"];
01486 a_refRatio = meta.m_int["ref_ratio"];
01487 Vector<Box> boxes;
01488 error = read(a_handle, boxes);
01489 Vector<int> procIDs;
01490 LoadBalance(procIDs, boxes);
01491
01492 DisjointBoxLayout layout(boxes, procIDs, a_domain);
01493
01494 layout.close();
01495 if (error != 0) return 3;
01496
01497 error = read(a_handle, a_data, "data", layout, a_comps, true);
01498
01499 if (error != 0) return 4;
01500
01501 a_handle.setGroup(currentGroup);
01502
01503 return 0;
01504 }
01505
01506 template <class T>
01507 int readLevel(HDF5Handle& a_handle,
01508 const int& a_level,
01509 LevelData<T>& a_data,
01510 RealVect& a_dx,
01511 Real& a_dt,
01512 Real& a_time,
01513 Box& a_domain,
01514 IntVect& a_refRatio,
01515 const Interval& a_comps,
01516 bool setGhost)
01517 {
01518 HDF5HeaderData header;
01519 header.readFromFile(a_handle);
01520
01521
01522
01523 int error;
01524 char levelName[10];
01525 std::string currentGroup = a_handle.getGroup();
01526 sprintf(levelName, "/level_%i",a_level);
01527 error = a_handle.setGroup(currentGroup + levelName);
01528 if (error != 0) return 1;
01529
01530 HDF5HeaderData meta;
01531 error = meta.readFromFile(a_handle);
01532 if (error != 0) return 2;
01533 a_dx = meta.m_realvect["vec_dx"];
01534 a_dt = meta.m_real["dt"];
01535 a_time = meta.m_real["time"];
01536 a_domain = meta.m_box["prob_domain"];
01537 a_refRatio = meta.m_intvect["vec_ref_ratio"];
01538 Vector<Box> boxes;
01539 error = read(a_handle, boxes);
01540 Vector<int> procIDs;
01541 LoadBalance(procIDs, boxes);
01542
01543 DisjointBoxLayout layout(boxes, procIDs, a_domain);
01544
01545 layout.close();
01546 if (error != 0) return 3;
01547
01548 error = read(a_handle, a_data, "data", layout, a_comps, true);
01549
01550 if (error != 0) return 4;
01551
01552 a_handle.setGroup(currentGroup);
01553
01554 return 0;
01555 }
01556
01557 #include "NamespaceFooter.H"
01558
01559 #else // CH_USE_HDF5
01560
01561
01562 #define HOFFSET(S,M) (offsetof(S,M))
01563
01564 #endif // CH_USE_HDF5 not defined
01565 #endif // CH_HDF5_H