EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_HDF5_DistObject.cpp
Go to the documentation of this file.
00001 /*
00002 //@HEADER
00003 // ***********************************************************************
00004 //
00005 //     EpetraExt: Epetra Extended - Linear Algebra Services Package
00006 //                 Copyright (2011) Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //@HEADER
00042 */
00043 
00044 #include "EpetraExt_ConfigDefs.h"
00045 #ifdef HAVE_EPETRAEXT_HDF5
00046 #ifdef HAVE_MPI
00047 #include "Epetra_MpiComm.h"
00048 #include "mpi.h"
00049 #else
00050 #include "Epetra_SerialComm.h"
00051 #endif
00052 #include "Teuchos_ParameterList.hpp"
00053 #include "Epetra_BlockMap.h"
00054 #include "Epetra_DistObject.h"
00055 #include "EpetraExt_Exception.h"
00056 #include "EpetraExt_Utils.h"
00057 #include "EpetraExt_HDF5.h"
00058 #include "EpetraExt_HDF5_Handle.h"
00059 
00060 #define CHECK_HID(hid_t) \
00061   { if (hid_t < 0) \
00062     throw(EpetraExt::Exception(__FILE__, __LINE__, \
00063                     "hid_t is negative")); }
00064 
00065 #define CHECK_STATUS(status) \
00066   { if (status < 0) \
00067     throw(EpetraExt::Exception(__FILE__, __LINE__, \
00068                     "function H5Giterater returned a negative value")); }
00069 
00070 // ==========================================================================
00071 void EpetraExt::HDF5::Write(const std::string& GroupName, 
00072                             const Handle& obj)
00073 {
00074   int NumMyElements = obj.NumMyElements();
00075   int NumGlobalElements = obj.NumGlobalElements();
00076 
00077   // ===================== //
00078   // first get global info //
00079   // ===================== //
00080   
00081   std::vector<std::string> IntLabels, DoubleLabels;
00082   std::vector<int> IntLabelsData;
00083   std::vector<double> DoubleLabelsData;
00084 
00085   obj.GetLabels(IntLabels, IntLabelsData, DoubleLabels, DoubleLabelsData);
00086 
00087   CreateGroup(GroupName);
00088 
00089   for (unsigned int i = 0; i < IntLabels.size(); ++i)
00090     Write(GroupName, IntLabels[i], IntLabelsData[i]);
00091 
00092   for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
00093     Write(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
00094 
00095   // ====================================================== //
00096   // not compute the storage required by each local element //
00097   // ====================================================== //
00098   
00099   std::vector<int> IntSize(NumMyElements);
00100   std::vector<int> DoubleSize(NumMyElements);
00101 
00102   int TotalIntSize = 0, TotalDoubleSize = 0;
00103 
00104   std::vector<int> IntData;
00105   std::vector<double> DoubleData;
00106 
00107   for (int i = 0; i < NumMyElements; ++i)
00108   {
00109     IntSize[i] = obj.IntSize(i);
00110     DoubleSize[i] = obj.DoubleSize(i);
00111     TotalIntSize += IntSize[i];
00112     TotalDoubleSize += DoubleSize[i];
00113   }
00114 
00115   IntData.resize(TotalIntSize);
00116   DoubleData.resize(TotalDoubleSize);
00117 
00118   int IntCount = 0;
00119   int DoubleCount = 0;
00120 
00121   // ================================== //
00122   // pack all data and write it to file //
00123   // ================================== //
00124 
00125   for (int i = 0; i < NumMyElements; ++i)
00126   {
00127     obj.Pack(i, &IntData[IntCount], &DoubleData[DoubleCount]);
00128     IntCount += IntSize[i];
00129     DoubleCount += DoubleSize[i];
00130   }
00131 
00132   if (!IsContained(GroupName))
00133     CreateGroup(GroupName);
00134   
00135   Write(GroupName, "__type__", obj.Type());
00136   Write(GroupName, "NumGlobalElements", NumGlobalElements);
00137   Write(GroupName, "has int", obj.HasInt());  
00138   Write(GroupName, "has double", obj.HasDouble());  
00139 
00140   if (obj.HasInt())
00141   {
00142     Write(GroupName, "int ptr", NumMyElements, 
00143           NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
00144     Write(GroupName, "int data", NumMyElements, 
00145           NumGlobalElements, H5T_NATIVE_INT, &IntData[0]);
00146   }
00147 
00148   if (obj.HasDouble())
00149   {
00150     Write(GroupName, "double ptr", NumMyElements, 
00151           NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
00152     Write(GroupName, "double data", NumMyElements, 
00153           NumGlobalElements, H5T_NATIVE_DOUBLE, &DoubleData[0]);
00154   }
00155 }
00156 
00157 // ==========================================================================
00158 void EpetraExt::HDF5::Read(const std::string& GroupName, Handle& obj)
00159 {
00160   int NumMyElements = obj.NumMyElements();
00161   int NumGlobalElements = obj.NumGlobalElements();
00162 
00163   std::vector<std::string> IntLabels, DoubleLabels;
00164 
00165   obj.GetLabels(IntLabels, DoubleLabels);
00166   std::vector<int> IntLabelsData(IntLabels.size());
00167   std::vector<double> DoubleLabelsData(DoubleLabels.size());
00168 
00169   for (unsigned int i = 0; i < IntLabels.size(); ++i)
00170     Read(GroupName, IntLabels[i], IntLabelsData[i]);
00171 
00172   for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
00173     Read(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
00174 
00175   std::vector<int> IntSize(NumMyElements);
00176   std::vector<int> DoubleSize(NumMyElements);
00177 
00178   int TotalIntSize = 0, TotalDoubleSize = 0;
00179   int GrandTotalIntSize = 0, GrandTotalDoubleSize = 0;
00180 
00181   // read linear distribution
00182   if (obj.HasInt())
00183   {
00184     Read(GroupName, "int ptr", NumMyElements, 
00185          NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
00186     for (int i = 0; i < NumMyElements; ++i)
00187       TotalIntSize += IntSize[i];
00188     Comm().SumAll(&TotalIntSize, &GrandTotalIntSize, 1);
00189   }
00190 
00191   if (obj.HasDouble())
00192   {
00193     Read(GroupName, "double ptr", NumMyElements, 
00194          NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
00195     for (int i = 0; i < NumMyElements; ++i)
00196     {
00197       TotalDoubleSize += DoubleSize[i];
00198     }
00199     Comm().SumAll(&TotalDoubleSize, &GrandTotalDoubleSize, 1);
00200   }
00201 
00202   std::vector<int> IntData(TotalIntSize + 1);
00203   std::vector<double> DoubleData(TotalDoubleSize + 1);
00204 
00205   // read actual data
00206   if (obj.HasInt())
00207     Read(GroupName, "int data", TotalIntSize, 
00208          GrandTotalIntSize, H5T_NATIVE_INT, &IntData[0]);
00209   if (obj.HasDouble())
00210     Read(GroupName, "double data", TotalDoubleSize, 
00211          GrandTotalDoubleSize, H5T_NATIVE_DOUBLE, &DoubleData[0]);
00212   
00213   // now unpack data
00214   obj.Initialize();
00215 
00216   obj.SetLabels(IntLabelsData, DoubleLabelsData);
00217 
00218   int IntCount = 0, DoubleCount = 0;
00219   for (int i = 0; i < NumMyElements; ++i)
00220   {
00221     obj.UnPack(i, IntSize[i], &(IntData[IntCount]),
00222                DoubleSize[i], &(DoubleData[DoubleCount]));
00223     IntCount += IntSize[i];
00224     DoubleCount += DoubleSize[i];
00225   }
00226 
00227   obj.Finalize();
00228 }
00229 
00230 // ==========================================================================
00231 void EpetraExt::HDF5::ReadHandleProperties(const std::string& GroupName, 
00232                                            std::string& Type,
00233                                            int& NumGlobalElements)
00234 {
00235   if (!IsContained(GroupName))
00236     throw(Exception(__FILE__, __LINE__,
00237                     "requested group " + GroupName + " not found"));
00238 
00239   Read(GroupName, "__type__", Type);
00240 
00241   Read(GroupName, "NumGlobalElements", NumGlobalElements);
00242 }
00243 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines