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

Generated on Wed Apr 30 18:14:23 2003 for Chombo&INS by doxygen1.2.16