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

Generated on Thu Aug 29 11:05:45 2002 for Chombo&INS by doxygen1.2.16