Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

HDF5.H

Go to the documentation of this file.
00001 /* _______              __
00002   / ___/ /  ___  __ _  / /  ___
00003  / /__/ _ \/ _ \/  ' \/ _ \/ _ \
00004  \___/_//_/\___/_/_/_/_.__/\___/ 
00005 */
00006 //
00007 // This software is copyright (C) by the Lawrence Berkeley
00008 // National Laboratory.  Permission is granted to reproduce
00009 // this software for non-commercial purposes provided that
00010 // this notice is left intact.
00011 // 
00012 // It is acknowledged that the U.S. Government has rights to
00013 // this software under Contract DE-AC03-765F00098 between
00014 // the U.S.  Department of Energy and the University of
00015 // California.
00016 //
00017 // This software is provided as a professional and academic
00018 // contribution for joint exchange. Thus it is experimental,
00019 // is provided ``as is'', with no warranties of any kind
00020 // whatsoever, no support, no promise of updates, or printed
00021 // documentation. By using this software, you acknowledge
00022 // that the Lawrence Berkeley National Laboratory and
00023 // Regents of the University of California shall have no
00024 // liability with respect to the infringement of other
00025 // copyrights by any part of this software.
00026 //
00027 //  ANAG, LBNL
00028 
00029 #ifdef HDF5  // if you don't have HDF5, then this file is useless
00030 
00031 #ifndef HDF5_H
00032 #define HDF5_H
00033 
00034 #include <iostream> 
00035 using std::cout;
00036 using std::endl;
00037 
00038 #ifdef MPI
00039 #include <mpi.h>
00040 #endif
00041 
00042 #include "LevelData.H"
00043 #include "HDF5Portable.H"
00044 #include "Vector.H"
00045 #include <hdf5.h>
00046 // hdf5 #defines inline.... duh!
00047 #undef inline
00048 #include <string>
00049 #include <map>
00050 #include "RealVect.H"
00051 
00052 using std::map;
00053 
00054 class HDF5Handle;
00055 
00056 // HDF5.H
00057 // ============
00058 
00059 
00061 
00072 template <class T>
00073 int writeLevel(HDF5Handle& a_handle, 
00074                const int& a_level, 
00075                const LevelData<T>& a_data,
00076                const Real& a_dx, 
00077                const Real& a_dt, 
00078                const Real& a_time, 
00079                const Box& a_domain,
00080                const int& a_refRatio,
00081                const IntVect& outputGhost = IntVect::Zero);
00082 
00083 template <class T>
00084 int readLevel(HDF5Handle& a_handle,  
00085               const int& a_level, 
00086               LevelData<T>& a_data, 
00087               Real& a_dx, 
00088               Real& a_dt, 
00089               Real& a_time, 
00090               Box& a_domain,
00091               int& a_refRatio, 
00092               const Interval& a_comps = Interval(), 
00093               const IntVect& ghost = IntVect::Zero, 
00094               bool setGhost = false);
00095 
00096 
00097 // More basic HDF5 functions.  These can be used at a persons own
00098 // discretion.  Refer to the User's Guide for a description of how these
00099 // functions interact with the convenience functions writeLevel, etc.
00100 
00102 
00109 int write(HDF5Handle& a_handle, 
00110           const BoxLayout& a_layout);
00111 
00113 
00118 template <class T>
00119 int write(HDF5Handle& a_handle, 
00120           const BoxLayoutData<T>& a_data, 
00121           const std::string& a_name,
00122           const IntVect& outputGhost = IntVect::Zero);
00123 
00125 
00132 template <class T>
00133 int write(HDF5Handle& a_handle, 
00134           const LevelData<T>& a_data, 
00135           const std::string& a_name,
00136           const IntVect& outputGhost = IntVect::Zero);
00137 
00139 
00146 int read(HDF5Handle& a_handle, 
00147          Vector<Box>& boxes);
00148 
00150 
00157 int readBoxes(HDF5Handle& a_handle,
00158                           Vector<Vector<Box> >& boxes);
00159  
00160 
00162 
00170 int readFArrayBox(HDF5Handle& a_handle,
00171                                   FArrayBox&  a_fab,
00172                                   int a_level,
00173                                   int a_boxNumber,
00174                                   const Interval& a_components,
00175                                   const std::string& a_dataName = "data" );
00176 
00178 
00184 template <class T>
00185 int read(HDF5Handle& a_handle, 
00186          BoxLayoutData<T>& a_data, 
00187          const std::string& a_name, 
00188          const BoxLayout& a_layout,
00189                  const Interval&  a_comps = Interval(),
00190          bool redefineData = true);
00191 
00193 
00199 template <class T>
00200 int read(HDF5Handle& a_handle, 
00201          LevelData<T>& a_data, 
00202          const std::string& a_name, 
00203          const DisjointBoxLayout& a_layout,
00204                  const Interval& a_comps = Interval(),
00205          bool redefineData = true);
00206 
00208 
00218 class HDF5Handle
00219 {
00220 public:
00222 
00236   enum mode {CREATE, OPEN_RDONLY, OPEN_RDWR};
00237 
00239 
00241 
00246   HDF5Handle();
00247 
00249 
00257   HDF5Handle(const std::string& a_filename, mode a_mode);
00258 
00260 
00262 
00282   int open(const std::string& a_filename, mode a_mode);
00283 
00285 
00288   bool isOpen() const;
00289 
00291 
00296   void close();
00297 
00299 
00301 
00304   void setGroupToLevel(int a_level);
00305 
00307 
00314   int setGroup(const std::string& groupAbsPath);
00315 
00317 
00323   const std::string& getGroup() const;
00324 
00325   const hid_t& fileID() const;
00326   const hid_t& groupID() const;
00327   static hid_t box_id;
00328   static hid_t intvect_id;
00329   static hid_t realvect_id;
00330 
00331 private:
00332 
00333   HDF5Handle(const HDF5Handle&);
00334   HDF5Handle& operator=(const HDF5Handle&);
00335 
00336   hid_t         m_fileID;
00337   hid_t         m_currentGroupID;
00338   bool          m_isOpen;
00339   std::string   m_filename; // keep around for debugging
00340   std::string   m_group;
00341   int           m_level;
00342 
00343   static hid_t  file_access;
00344   static bool   initialized;
00345   static void   initialize();
00346 
00347 };
00348 
00350 
00392 class HDF5HeaderData
00393 {
00394 public:
00395 
00397 
00403   int writeToFile(HDF5Handle& file) const;
00404 
00406 
00414   int readFromFile(HDF5Handle& file);
00415 
00417   void clear();
00418 
00420   map<std::string, Real>        m_real;
00421 
00423   map<std::string, int>         m_int;
00424 
00426   map<std::string, std::string> m_string;
00427 
00429   map<std::string, IntVect>     m_intvect;
00430 
00432   map<std::string, Box>         m_box;
00433 
00435   map<std::string, RealVect>    m_realvect;
00436 
00437   //users should not need these functions in general
00438 
00439   int writeToLocation(hid_t loc_id) const;
00440   int readFromLocation(hid_t loc_id);
00441 
00442 private:
00443   static herr_t attributeScan(hid_t loc_id, const char *name, void *opdata);
00444 };
00445 
00446 extern "C"{
00447 herr_t HDF5HeaderDataattributeScan(hid_t loc_id, const char *name, void *opdata);
00448           }
00449 
00450 std::ostream& operator<<(std::ostream& os, const HDF5HeaderData& data);
00451 
00452 
00453 //=============================================================================
00454 //
00455 // end of declarations.
00456 //
00457 //=============================================================================
00458 
00459 //#include "HDF5Implem.H"
00460 /* _______              __
00461   / ___/ /  ___  __ _  / /  ___
00462  / /__/ _ \/ _ \/  ' \/ _ \/ _ \
00463  \___/_//_/\___/_/_/_/_.__/\___/ 
00464 */
00465 //
00466 // This software is copyright (C) by the Lawrence Berkeley
00467 // National Laboratory.  Permission is granted to reproduce
00468 // this software for non-commercial purposes provided that
00469 // this notice is left intact.
00470 // 
00471 // It is acknowledged that the U.S. Government has rights to
00472 // this software under Contract DE-AC03-765F00098 between
00473 // the U.S.  Department of Energy and the University of
00474 // California.
00475 //
00476 // This software is provided as a professional and academic
00477 // contribution for joint exchange. Thus it is experimental,
00478 // is provided ``as is'', with no warranties of any kind
00479 // whatsoever, no support, no promise of updates, or printed
00480 // documentation. By using this software, you acknowledge
00481 // that the Lawrence Berkeley National Laboratory and
00482 // Regents of the University of California shall have no
00483 // liability with respect to the infringement of other
00484 // copyrights by any part of this software.
00485 //
00486 //  ANAG, LBNL
00487 
00488 #include "LoadBalance.H"
00489 #include "LayoutIterator.H"
00490 #include "Vector.H"
00491 #include "memtrack.H"
00492 
00493 
00494 // non-user code used in implementation of communication
00495 
00496 struct OffsetBuffer
00497 {
00498   Vector<int> index;
00499   Vector<Vector<int> > offsets;
00500   void operator=(const OffsetBuffer& rhs);
00501 };
00502 
00503 ostream& operator<<(ostream& os, const OffsetBuffer& ob);
00504 
00505 //OffsetBuffer specialization of linearSize
00506 template < >
00507 int linearSize(const OffsetBuffer& a_input); 
00508 
00509 //OffsetBuffer specialization of linearIn
00510 template < >
00511 void linearIn(OffsetBuffer& a_outputT, const void* const a_inBuf); 
00512 
00513 //OffsetBuffer specialization of linearOut
00514 template < >
00515 void linearOut(void* const a_outBuf, const OffsetBuffer& a_inputT); 
00516 
00517 template < > int linearSize(const Vector<OffsetBuffer>& a_input);
00518 template < > void linearIn(Vector<OffsetBuffer>& a_outputT, const void* const inBuf);
00519 template < > void linearOut(void* const a_outBuf, const Vector<OffsetBuffer>& a_inputT);
00520 
00521 // First, template specializations for read/write for FArrayBox.
00522 
00523 template <>
00524 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<int>& dummy)
00525 {  
00526   a_types.resize(1); 
00527   a_types[0] = H5T_NATIVE_INT;
00528 }
00529 
00530 /* since many compilers choke on the proper template specialization syntax
00531    I am forced to pass in a dummy specialization argument
00532    */
00533 template <>
00534 inline void dataTypes(Vector<hid_t>& a_types, const FArrayBox& dummy)
00535 {  a_types.resize(1); a_types[0] = H5T_NATIVE_REAL;}
00536 
00537 
00538 template <>
00539 inline void dataSize(const BaseFab<int>& item, Vector<int>& a_sizes, 
00540                      const Box& box, const Interval& comps)
00541 {
00542   a_sizes[0] = box.numPts() * comps.size();
00543 }
00544 
00545 template <>
00546 inline void dataSize(const FArrayBox& item, Vector<int>& a_sizes, 
00547                      const Box& box, const Interval& comps)
00548 {
00549   a_sizes[0] = box.numPts() * comps.size();
00550 }
00551 
00552 template <>
00553 inline const char* name(const FArrayBox& a_dummySpecializationArg)
00554 {
00555   // Attempt to get rid of warnings on IBM...
00556   //static const char* name = "FArrayBox";
00557   const char* name = "FArrayBox";
00558   return name;
00559 }
00560 
00561 template <>
00562 inline const char* name(const BaseFab<int>& a_dummySpecializationArg)
00563 {
00564   // Attempt to get rid of warnings on IBM...
00565   //static const char* name = "BaseFab<int>";
00566   const char* name = "BaseFab<int>";
00567   return name;
00568 }
00569 
00570 //
00571 // now, generic, non-binary portable version of template functions
00572 // for people who just want ot rely on linearIn/linearOut
00573 
00574 template <class T>
00575 inline void dataTypes(Vector<hid_t>& a_types, const T& dummy)
00576 {  a_types.resize(1); a_types[0] = H5T_NATIVE_CHAR;}
00577 
00578 template <class T>
00579 inline void dataSize(const T& item, Vector<int>& a_sizes, 
00580                      const Box& box, const Interval& comps)
00581 {
00582   a_sizes[0] = item.size(box, comps);
00583 }
00584 
00585 
00586 template <class T>
00587 inline void write(const T& item, Vector<void*>& a_allocatedBuffers, 
00588                   const Box& box, const Interval& comps)
00589 {
00590   item.linearOut(a_allocatedBuffers[0], box, comps);
00591 }
00592 
00593 template <class T>
00594 inline void read(T& item, Vector<void*>& a_allocatedBuffers, 
00595                  const Box& box, const Interval& comps)
00596 {
00597   item.linearIn(a_allocatedBuffers[0], box, comps);
00598 }
00599 
00600 template <class T>
00601 inline const char* name(const T& a_dummySpecializationArg)
00602 {
00603   static const char* name = "unknown";
00604   return name;
00605 }
00606 
00607 template <class T>
00608 void getOffsets(Vector<Vector<long long> >& offsets, const BoxLayoutData<T>& a_data,  
00609                 int types, const Interval& comps, const IntVect& outputGhost)
00610 {
00611 
00612 
00613   const BoxLayout& layout = a_data.boxLayout();
00614   offsets.resize(types, Vector<long long>(layout.size()+1));
00615   //  offsets.resize(layout.size() + 1, Vector<long long>(types));
00616   for(int t=0; t<types; t++) offsets[t][0] = 0;
00617   Vector<int> thisSize(types);
00618   if(T::preAllocatable()==0)
00619   { // static preAllocatable
00620     T dummy;
00621     unsigned int index = 1;
00622     for(LayoutIterator it(layout.layoutIterator()); it.ok(); ++it)
00623       {
00624         Box region = layout[it()];
00625         region.grow(outputGhost);
00626         dataSize(dummy, thisSize, region, comps);
00627         for(unsigned int i=0; i<thisSize.size(); ++i) 
00628           {
00629             //offsets[index][i] = offsets[index-1][i] + thisSize[i];
00630             offsets[i][index] = offsets[i][index-1] + thisSize[i];
00631           }
00632         ++index;
00633       }
00634   }
00635   else
00636   { // symmetric and dynamic preallocatable need two pass I/O
00637     OffsetBuffer buff;
00638         int index = 0;
00639     for(DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit, ++index)
00640       {
00641         //int index = dit().intCode();
00642         buff.index.push_back(index);
00643         Box region = layout[dit()];
00644         region.grow(outputGhost);
00645         dataSize(a_data[dit()], thisSize, region, comps);
00646         buff.offsets.push_back(thisSize);
00647       }
00648     Vector<OffsetBuffer> gathering(numProc());
00649     gather(gathering, buff, uniqueProc(SerialTask::compute));
00650     broadcast(gathering,  uniqueProc(SerialTask::compute));
00651     //  pout() << gathering<<endl;
00652     for(int i=0; i<numProc(); ++i)
00653       {
00654         OffsetBuffer& offbuf = gathering[i];
00655         for(int num=0; num<offbuf.index.size(); num++)
00656           {
00657             int index = offbuf.index[num];
00658             for(unsigned int j=0; j<types; ++j) 
00659               {
00660                 //offsets[index+1][j] = offbuf.offsets[num][j];
00661                 offsets[j][index+1] = offbuf.offsets[num][j];
00662               }
00663           }
00664       }
00665     for(int i=0; i<layout.size(); i++)
00666       {
00667         for(unsigned int j=0; j<types; ++j) 
00668           {
00669             //offsets[i+1][j] += offsets[i][j];
00670             offsets[j][i+1] += offsets[j][i];
00671           }
00672       }
00673   }
00674 
00675   // pout() << offsets<<endl;
00676 }
00677 
00678 
00679 //==================================================================
00680 //
00681 // Now, linear IO routines for a BoxLayoutData of T
00682 //
00683 
00684 template <class T>
00685 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data, 
00686           const std::string& a_name, const IntVect& outputGhost)
00687 {
00688   int ret = 0;
00689 
00690   Interval comps = a_data.interval(); // later, we can make comps an argument.....
00691   T dummy; // used for preallocatable methods for dumb compilers.
00692   Vector<hid_t> types;
00693   dataTypes(types, dummy);
00694 
00695   Vector<Vector<long long> > offsets;
00696   Vector<long long> bufferCapacity(types.size(), 1);  // noel (was 0)
00697   Vector<void*> buffers(types.size(), NULL);
00698 
00699   getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00700 
00701   // create datasets collectively.
00702   hsize_t flatdims[1];
00703   char dataname[100];
00704   Vector<hid_t> dataspace(types.size());
00705   Vector<hid_t> dataset(types.size());
00706 
00707 
00708 
00709   herr_t err;
00710   hsize_t count[1];
00711   hssize_t offset[1];
00712 
00713   for(unsigned int i=0; i<types.size(); ++i) 
00714     {
00715       flatdims[0] = offsets[i][offsets[i].size()-1];
00716       sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00717       dataspace[i]      = H5Screate_simple(1, flatdims, NULL);
00718       assert(dataspace[i] >=0);
00719       dataset[i]        = H5Dcreate(a_handle.groupID(), dataname,  
00720                                     types[i],
00721                                     dataspace[i], H5P_DEFAULT);
00722       assert(dataset[i] >= 0);
00723     }
00724 
00725   hid_t offsetspace, offsetData;
00726   for(unsigned int i=0; i<types.size(); ++i) 
00727     {
00728       flatdims[0] =  offsets[i].size();
00729       sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00730       offsetspace =  H5Screate_simple(1, flatdims, NULL);
00731       assert(offsetspace >= 0);
00732       offsetData  =   H5Dcreate(a_handle.groupID(), dataname,  
00733                                 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00734       assert(offsetData >= 0);
00735       if(procID() == 0)
00736       {
00737         hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00738         assert(memdataspace >= 0);
00739         err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00740                        H5P_DEFAULT, &(offsets[i][0]));
00741         assert(err >= 0);
00742         H5Sclose(memdataspace);
00743       }
00744       H5Sclose(offsetspace);
00745       H5Dclose(offsetData);
00746     }
00747 
00748   // write BoxLayoutData attributes into Dataset[0]
00749   HDF5HeaderData info;
00750   info.m_int["comps"] = comps.size();
00751   info.m_string["objectType"] = name(dummy);
00752   std::string group = a_handle.getGroup();
00753   a_handle.setGroup(group+"/"+a_name+"_attributes");
00754   info.writeToFile(a_handle);
00755   a_handle.setGroup(group);
00756 
00757   // collective operations finished, now perform parallel writes
00758   // to specified hyperslabs.
00759 
00760   Vector<size_t> type_size(types.size());
00761   for(unsigned int i=0; i<types.size(); ++i) 
00762     {
00763       type_size[i] = H5Tget_size(types[i]);
00764     }
00765 
00766   Vector<int> thisSize(types.size());
00767 
00768   // step 1, create buffer big enough to hold the biggest linearized T
00769   // that I will have to output.
00770   for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00771     {
00772       unsigned int index = a_data.boxLayout().index(it());
00773       for(unsigned int i=0; i<types.size(); ++i) 
00774         {
00775           long long size = (offsets[i][index+1] - offsets[i][index]) 
00776                       * type_size[i];
00777           assert(size > 0);
00778           if(size > bufferCapacity[i]) // grow buffer if necessary.....
00779             {
00780               bufferCapacity[i] = size;
00781             } 
00782         }
00783     }
00784   for(unsigned int i=0; i<types.size(); ++i) 
00785     {
00786       buffers[i] = malloc(bufferCapacity[i]);
00787       if(buffers[i] == NULL) {
00788         pout() << " i=" << i
00789                << " types.size() = " << types.size()
00790                << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00791                << endl;
00792         MayDay::Error("memory error in buffer allocation write");
00793       }
00794     }
00795 
00796   // Step 2.  actually a) write each of my T objects into the
00797   // buffer, then b) write that buffered data out to the
00798   // write position in the data file using hdf5 hyperslab functions.
00799   for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00800     {
00801       const T& data = a_data[it()];
00802       unsigned int index = a_data.boxLayout().index(it());
00803       Box box = a_data.box(it());
00804       box.grow(outputGhost);
00805       write(data, buffers, box, comps); //write T to buffer
00806       for(unsigned int i=0; i<types.size(); ++i) 
00807         {
00808           offset[0] = offsets[i][index];
00809           count[0] = offsets[i][index+1] - offset[0];
00810           assert(count[0] > 0);
00811           err =  H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET, 
00812                                      offset, NULL, 
00813                                      count, NULL);
00814           assert(err >= 0);
00815           hid_t memdataspace = H5Screate_simple(1, count, NULL);
00816           assert(memdataspace >= 0);
00817           err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
00818                          H5P_DEFAULT, buffers[i]);
00819           assert(err >= 0);
00820           H5Sclose(memdataspace);
00821           if(err < 0) { ret = err; goto cleanup;}
00822         }
00823     }
00824 
00825   // OK, clean up data structures
00826 
00827  cleanup:
00828   for(unsigned int i=0; i<types.size(); ++i) 
00829     {
00830       free(buffers[i]);
00831       H5Sclose(dataspace[i]);
00832       H5Dclose(dataset[i]);
00833     }
00834   return ret;
00835 
00836 }
00837 
00838 template <class T>
00839 int write(HDF5Handle& a_handle, const LevelData<T>& a_data, 
00840           const std::string& a_name, const IntVect& outputGhost)
00841 {
00842   HDF5HeaderData info;
00843   info.m_intvect["ghost"] = a_data.ghostVect();
00844   IntVect og(outputGhost);
00845   og.min(a_data.ghostVect());
00846   info.m_intvect["outputGhost"] = og;
00847   std::string group = a_handle.getGroup();
00848   a_handle.setGroup(group+"/"+a_name+"_attributes");
00849   info.writeToFile(a_handle);
00850   a_handle.setGroup(group);
00851   return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og);
00852 }
00853 
00854 template <class T>
00855 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name, 
00856          const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00857 {
00858   if(a_redefineData)
00859     {
00860       HDF5HeaderData info;
00861       std::string group = a_handle.getGroup();
00862       if(a_handle.setGroup(group+"/"+a_name+"_attributes"))
00863         {
00864           std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00865           MayDay::Warning(message.c_str());
00866           return 1;
00867         }
00868       info.readFromFile(a_handle);
00869       a_handle.setGroup(group);
00870       int ncomp =  info.m_int["comps"];
00871       IntVect ghost = info.m_intvect["ghost"];
00872           if(a_comps.end() > 0 && ncomp < a_comps.end())
00873                 {
00874                   MayDay::Error("attempt to read component interval that is not available");
00875                 }
00876           if(a_comps.size() == 0)
00877                 a_data.define(a_layout, ncomp, ghost);
00878           else
00879                 a_data.define(a_layout, a_comps.size(), ghost);
00880     }
00881   return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
00882 
00883 }
00884 template <class T>
00885 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name, 
00886          const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00887 {
00888   int ret = 0; // return value;
00889 
00890   herr_t err;
00891 
00892   char dataname[100];
00893   hsize_t count[1];
00894   hssize_t offset[1];
00895   Vector<Vector<long long> > offsets;
00896 
00897   T dummy;
00898   Vector<hid_t> types;
00899   dataTypes(types, dummy);
00900   Vector<hid_t> dataspace(types.size());
00901   Vector<hid_t> dataset(types.size());
00902   offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
00903 
00904   Vector<int> bufferCapacity(types.size(), 500);
00905   Vector<void*> buffers(types.size(), NULL);
00906 
00907   for(unsigned int i=0; i<types.size(); ++i) 
00908     {
00909       sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00910       dataset[i]        = H5Dopen(a_handle.groupID(), dataname);
00911       if(dataset[i] < 0) {MayDay::Warning("dataset open failure"); return dataset[i];}
00912       dataspace[i]      = H5Dget_space(dataset[i]);
00913       if(dataspace[i] < 0) {MayDay::Warning("dataspace open failure"); return dataspace[i];}
00914     }
00915 
00916   hid_t offsetspace, offsetData;
00917   hsize_t flatdims[1];
00918   for(unsigned int i=0; i<types.size(); ++i) 
00919     {
00920       flatdims[0] =  offsets[i].size();
00921       sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00922       offsetspace =  H5Screate_simple(1, flatdims, NULL);
00923       assert(offsetspace >= 0);
00924       offsetData  =   H5Dopen(a_handle.groupID(), dataname);  
00925       assert(offsetData >= 0);
00926       hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00927       assert(memdataspace >= 0);
00928       err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00929                      H5P_DEFAULT, &(offsets[i][0]));
00930       assert(err >=0);
00931       H5Sclose(memdataspace);
00932       H5Sclose(offsetspace);
00933       H5Dclose(offsetData);
00934     }
00935 
00936   HDF5HeaderData info;
00937   std::string group = a_handle.getGroup();
00938   if(a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
00939     {
00940       std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00941       MayDay::Warning(message.c_str());
00942       return 1;
00943     }
00944 
00945   info.readFromFile(a_handle);
00946   a_handle.setGroup(group);
00947   int ncomps = info.m_int["comps"];
00948   IntVect outputGhost(IntVect::Zero); // backwards file compatible mode.
00949   if(info.m_intvect.find("outputGhost") != info.m_intvect.end())
00950     {
00951       outputGhost = info.m_intvect["outputGhost"];
00952     }
00953   if(ncomps <= 0){
00954     MayDay::Warning("ncomps <= 0 in read");
00955     return ncomps;
00956   }
00957 
00958   if(a_redefineData){
00959         if(a_comps.size() != 0){
00960           a_data.define(a_layout, a_comps.size());
00961         } else {
00962           a_data.define(a_layout, ncomps);
00963         }
00964   }
00965 
00966   Interval comps(0, ncomps-1);
00967   if(a_comps.size() != 0)  comps = Interval(0, a_comps.size());
00968 
00969   //  getOffsets(offsets, a_data, types.size(), comps);
00970 
00971   Vector<size_t> type_size(types.size());
00972   for(unsigned int i=0; i<types.size(); ++i) 
00973     {
00974       type_size[i] = H5Tget_size(types[i]);
00975       buffers[i] = malloc(bufferCapacity[i]);
00976       if(buffers[i] == NULL) {
00977         pout() << " i= " << i 
00978                << " types.size()=" << types.size() 
00979                << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00980                << endl; 
00981         MayDay::Error("memory error in buffer allocation read");
00982       }
00983     }
00984 
00985   Vector<int> thisSize(types.size());
00986   for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00987     {
00988       T& data = a_data[it()];
00989       unsigned int index = a_data.boxLayout().index(it());
00990       Box box = a_data.box(it());
00991 
00992       for(unsigned int i=0; i<types.size(); ++i) 
00993         {
00994                   if(a_comps.size() == 0){
00995                         offset[0] = offsets[i][index];
00996                         count[0] = offsets[i][index+1] - offset[0];
00997                   } else {
00998                         offset[0] = offsets[i][index] + box.numPts()*a_comps.begin();
00999                         count[0]  = a_comps.size() * box.numPts();
01000                   }
01001           assert(count[0] > 0);
01002           int size = count[0] * type_size[i];
01003           if(size > bufferCapacity[i])
01004             {
01005               free(buffers[i]);
01006               bufferCapacity[i] = Max(2*bufferCapacity[i], size);
01007               buffers[i] = malloc(bufferCapacity[i]);
01008               if(buffers[i] == NULL) {
01009                                 MayDay::Error("memory error in buffer allocation read");
01010                           }
01011             } 
01012 
01013           err =  H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET, 
01014                                      offset, NULL, 
01015                                      count, NULL);
01016           assert(err >= 0);
01017           hid_t memdataspace = H5Screate_simple(1, count, NULL);
01018           assert(memdataspace >= 0);
01019           err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01020                          H5P_DEFAULT, buffers[i]);
01021           assert(err >= 0);
01022           H5Sclose(memdataspace);
01023           if(err < 0) { ret = err; goto cleanup;}
01024         }
01025       box.grow(outputGhost);
01026       read(data, buffers,  box, comps);
01027     }
01028 
01029  cleanup:
01030   for(unsigned int i=0; i<types.size(); ++i) 
01031     {
01032       free(buffers[i]);
01033       H5Sclose(dataspace[i]);
01034       H5Dclose(dataset[i]);
01035     }
01036   return ret;
01037 }
01038 
01039 
01040 template <class T>
01041 int writeLevel(HDF5Handle& a_handle, 
01042                const int&  a_level, 
01043                const LevelData<T>& a_data,
01044                const Real& a_dx, 
01045                const Real& a_dt, 
01046                const Real& a_time, 
01047                const Box&  a_domain,
01048                const int&  a_refRatio,
01049                const IntVect& outputGhost)
01050 {
01051   int error;
01052   char levelName[10];
01053   std::string currentGroup = a_handle.getGroup();
01054   sprintf(levelName, "/level_%i",a_level);
01055   error = a_handle.setGroup(currentGroup + levelName);
01056   if(error != 0) return 1;
01057 
01058   HDF5HeaderData meta;
01059   meta.m_real["dx"] = a_dx;
01060   meta.m_real["dt"] = a_dt;
01061   meta.m_real["time"] = a_time;
01062   meta.m_box["prob_domain"] = a_domain;
01063   meta.m_int["ref_ratio"] = a_refRatio;
01064 
01065   error = meta.writeToFile(a_handle);
01066   if(error != 0) return 2;
01067 
01068   error = write(a_handle, a_data.boxLayout());
01069   if(error != 0) return 3;
01070 
01071   error = write(a_handle, a_data, "data", outputGhost);
01072   if(error != 0) return 4;
01073 
01074   a_handle.setGroup(currentGroup);
01075 
01076   return 0;
01077 }
01078 
01079 
01080 template <class T>
01081 int readLevel(HDF5Handle&   a_handle,  
01082               const int&    a_level, 
01083               LevelData<T>& a_data, 
01084               Real& a_dx, 
01085               Real& a_dt, 
01086               Real& a_time, 
01087               Box&  a_domain,
01088               int&  a_refRatio,
01089               const Interval&   a_comps,
01090               const IntVect& ghost,
01091               bool  setGhost)
01092 {
01093   HDF5HeaderData header;
01094   header.readFromFile(a_handle);
01095   int nComp = header.m_int["num_components"];
01096 
01097   int error;
01098   char levelName[10];
01099   std::string currentGroup = a_handle.getGroup();
01100   sprintf(levelName, "/level_%i",a_level);
01101   error = a_handle.setGroup(currentGroup + levelName);
01102   if(error != 0) return 1;
01103 
01104   HDF5HeaderData meta;
01105   error = meta.readFromFile(a_handle);
01106   if(error != 0) return 2;
01107   a_dx       = meta.m_real["dx"];
01108   a_dt       = meta.m_real["dt"];
01109   a_time     = meta.m_real["time"];
01110   a_domain   = meta.m_box["prob_domain"];
01111   a_refRatio = meta.m_int["ref_ratio"];
01112 
01113   Vector<Box> boxes;
01114   error = read(a_handle, boxes);
01115   Vector<int> procIDs;
01116   LoadBalance(procIDs, boxes);
01117 
01118   DisjointBoxLayout layout(boxes, procIDs);
01119 
01120   layout.close();
01121   if(error != 0) return 3;
01122 
01123   if(!setGhost)
01124     error = read(a_handle, a_data, "data", layout, a_comps);
01125   else
01126     {
01127           if(a_comps.size() !=  0)
01128                 a_data.define(layout, a_comps.size(), ghost);
01129           else
01130                 a_data.define(layout, nComp, ghost);
01131 
01132           error = read(a_handle, a_data, "data", layout, a_comps, false);
01133 
01134     }
01135   if(error != 0) return 4;
01136 
01137   a_handle.setGroup(currentGroup);
01138 
01139   return 0;
01140 }
01141 
01142 
01143 
01144 #endif  // HDF5_H
01145 
01146 #endif // HDF5

Generated on Tue Jul 2 10:42:19 2002 for Chombo by doxygen1.2.16