EpetraExt  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EpetraExt_HDF5_DistObject.cpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ***********************************************************************
4 //
5 // EpetraExt: Epetra Extended - Linear Algebra Services Package
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 //@HEADER
42 */
43 
44 #include "EpetraExt_ConfigDefs.h"
45 #ifdef HAVE_EPETRAEXT_HDF5
46 #ifdef HAVE_MPI
47 #include "Epetra_MpiComm.h"
48 #include "mpi.h"
49 #else
50 #include "Epetra_SerialComm.h"
51 #endif
52 #include "Teuchos_ParameterList.hpp"
53 #include "Epetra_BlockMap.h"
54 #include "Epetra_DistObject.h"
55 #include "EpetraExt_Exception.h"
56 #include "EpetraExt_Utils.h"
57 #include "EpetraExt_HDF5.h"
58 #include "EpetraExt_HDF5_Handle.h"
59 
60 #define CHECK_HID(hid_t) \
61  { if (hid_t < 0) \
62  throw(EpetraExt::Exception(__FILE__, __LINE__, \
63  "hid_t is negative")); }
64 
65 #define CHECK_STATUS(status) \
66  { if (status < 0) \
67  throw(EpetraExt::Exception(__FILE__, __LINE__, \
68  "function H5Giterater returned a negative value")); }
69 
70 // ==========================================================================
71 void EpetraExt::HDF5::Write(const std::string& GroupName,
72  const Handle& obj)
73 {
74  int NumMyElements = obj.NumMyElements();
75  int NumGlobalElements = obj.NumGlobalElements();
76 
77  // ===================== //
78  // first get global info //
79  // ===================== //
80 
81  std::vector<std::string> IntLabels, DoubleLabels;
82  std::vector<int> IntLabelsData;
83  std::vector<double> DoubleLabelsData;
84 
85  obj.GetLabels(IntLabels, IntLabelsData, DoubleLabels, DoubleLabelsData);
86 
87  CreateGroup(GroupName);
88 
89  for (unsigned int i = 0; i < IntLabels.size(); ++i)
90  Write(GroupName, IntLabels[i], IntLabelsData[i]);
91 
92  for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
93  Write(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
94 
95  // ====================================================== //
96  // not compute the storage required by each local element //
97  // ====================================================== //
98 
99  std::vector<int> IntSize(NumMyElements);
100  std::vector<int> DoubleSize(NumMyElements);
101 
102  int TotalIntSize = 0, TotalDoubleSize = 0;
103 
104  std::vector<int> IntData;
105  std::vector<double> DoubleData;
106 
107  for (int i = 0; i < NumMyElements; ++i)
108  {
109  IntSize[i] = obj.IntSize(i);
110  DoubleSize[i] = obj.DoubleSize(i);
111  TotalIntSize += IntSize[i];
112  TotalDoubleSize += DoubleSize[i];
113  }
114 
115  IntData.resize(TotalIntSize);
116  DoubleData.resize(TotalDoubleSize);
117 
118  int IntCount = 0;
119  int DoubleCount = 0;
120 
121  // ================================== //
122  // pack all data and write it to file //
123  // ================================== //
124 
125  for (int i = 0; i < NumMyElements; ++i)
126  {
127  obj.Pack(i, &IntData[IntCount], &DoubleData[DoubleCount]);
128  IntCount += IntSize[i];
129  DoubleCount += DoubleSize[i];
130  }
131 
132  if (!IsContained(GroupName))
133  CreateGroup(GroupName);
134 
135  Write(GroupName, "__type__", obj.Type());
136  Write(GroupName, "NumGlobalElements", NumGlobalElements);
137  Write(GroupName, "has int", obj.HasInt());
138  Write(GroupName, "has double", obj.HasDouble());
139 
140  if (obj.HasInt())
141  {
142  Write(GroupName, "int ptr", NumMyElements,
143  NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
144  Write(GroupName, "int data", NumMyElements,
145  NumGlobalElements, H5T_NATIVE_INT, &IntData[0]);
146  }
147 
148  if (obj.HasDouble())
149  {
150  Write(GroupName, "double ptr", NumMyElements,
151  NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
152  Write(GroupName, "double data", NumMyElements,
153  NumGlobalElements, H5T_NATIVE_DOUBLE, &DoubleData[0]);
154  }
155 }
156 
157 // ==========================================================================
158 void EpetraExt::HDF5::Read(const std::string& GroupName, Handle& obj)
159 {
160  int NumMyElements = obj.NumMyElements();
161  int NumGlobalElements = obj.NumGlobalElements();
162 
163  std::vector<std::string> IntLabels, DoubleLabels;
164 
165  obj.GetLabels(IntLabels, DoubleLabels);
166  std::vector<int> IntLabelsData(IntLabels.size());
167  std::vector<double> DoubleLabelsData(DoubleLabels.size());
168 
169  for (unsigned int i = 0; i < IntLabels.size(); ++i)
170  Read(GroupName, IntLabels[i], IntLabelsData[i]);
171 
172  for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
173  Read(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
174 
175  std::vector<int> IntSize(NumMyElements);
176  std::vector<int> DoubleSize(NumMyElements);
177 
178  int TotalIntSize = 0, TotalDoubleSize = 0;
179  int GrandTotalIntSize = 0, GrandTotalDoubleSize = 0;
180 
181  // read linear distribution
182  if (obj.HasInt())
183  {
184  Read(GroupName, "int ptr", NumMyElements,
185  NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
186  for (int i = 0; i < NumMyElements; ++i)
187  TotalIntSize += IntSize[i];
188  Comm().SumAll(&TotalIntSize, &GrandTotalIntSize, 1);
189  }
190 
191  if (obj.HasDouble())
192  {
193  Read(GroupName, "double ptr", NumMyElements,
194  NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
195  for (int i = 0; i < NumMyElements; ++i)
196  {
197  TotalDoubleSize += DoubleSize[i];
198  }
199  Comm().SumAll(&TotalDoubleSize, &GrandTotalDoubleSize, 1);
200  }
201 
202  std::vector<int> IntData(TotalIntSize + 1);
203  std::vector<double> DoubleData(TotalDoubleSize + 1);
204 
205  // read actual data
206  if (obj.HasInt())
207  Read(GroupName, "int data", TotalIntSize,
208  GrandTotalIntSize, H5T_NATIVE_INT, &IntData[0]);
209  if (obj.HasDouble())
210  Read(GroupName, "double data", TotalDoubleSize,
211  GrandTotalDoubleSize, H5T_NATIVE_DOUBLE, &DoubleData[0]);
212 
213  // now unpack data
214  obj.Initialize();
215 
216  obj.SetLabels(IntLabelsData, DoubleLabelsData);
217 
218  int IntCount = 0, DoubleCount = 0;
219  for (int i = 0; i < NumMyElements; ++i)
220  {
221  obj.UnPack(i, IntSize[i], &(IntData[IntCount]),
222  DoubleSize[i], &(DoubleData[DoubleCount]));
223  IntCount += IntSize[i];
224  DoubleCount += DoubleSize[i];
225  }
226 
227  obj.Finalize();
228 }
229 
230 // ==========================================================================
231 void EpetraExt::HDF5::ReadHandleProperties(const std::string& GroupName,
232  std::string& Type,
233  int& NumGlobalElements)
234 {
235  if (!IsContained(GroupName))
236  throw(Exception(__FILE__, __LINE__,
237  "requested group " + GroupName + " not found"));
238 
239  Read(GroupName, "__type__", Type);
240 
241  Read(GroupName, "NumGlobalElements", NumGlobalElements);
242 }
243 #endif
void Write(const std::string &GroupName, const std::string &DataSetName, int data)
Write an integer in group GroupName using the given DataSetName.
void ReadHandleProperties(const std::string &GroupName, std::string &Type, int &NumGlobalElements)
Read the global number of elements and type for a generic handle object.
virtual int GetLabels(std::vector< std::string > &IntLabels, std::vector< std::string > &DoubleLabels) const =0
Packs all global information.
void CreateGroup(const std::string &GroupName)
Create group GroupName.
bool IsContained(std::string Name, std::string GroupName="")
Return true if Name is contained in the database.
void Read(const std::string &GroupName, const std::string &DataSetName, int &data)
Read an integer from group /GroupName/DataSetName.
virtual int NumMyElements() const =0
Returns the local number of elements.
virtual int Finalize()=0
Performs any finalization procedure after unpacking.
virtual int UnPack(const int EID, int IntSize, int *IntData, int DoubleSize, double *DoubleData)=0
Unpacks all data for local element EID in the specified arrays.
virtual bool HasDouble() const =0
virtual int IntSize(const int EID) const =0
Returns the size of integer data for local element EID.
virtual int DoubleSize(const int EID) const =0
Returns the size of double data for local element EID.
virtual int Initialize()=0
Performs any initialization procedure before unpacking.
virtual int SetLabels(const std::vector< int > &IntLabelsData, const std::vector< double > &DoubleLabelsData)=0
Sets global information.
virtual int NumGlobalElements() const =0
Returns the global number of elements.
virtual int Pack(const int EID, int *IntData, double *DoubleData) const =0
Packs all data for local element EID in the specified arrays.
virtual std::string Type() const =0
Returns the identifier of the distributed object.
virtual bool HasInt() const =0