EpetraExt Development
Loading...
Searching...
No Matches
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
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"
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// ==========================================================================
71void 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// ==========================================================================
158void 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// ==========================================================================
231void 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
bool IsContained(std::string Name, std::string GroupName="")
Return true if Name is contained in the database.
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.
void CreateGroup(const std::string &GroupName)
Create group GroupName.
void Read(const std::string &GroupName, const std::string &DataSetName, int &data)
Read an integer from group /GroupName/DataSetName.
virtual int Finalize()=0
Performs any finalization procedure after unpacking.
virtual int NumGlobalElements() const =0
Returns the global number of elements.
virtual int IntSize(const int EID) const =0
Returns the size of integer data for local element EID.
virtual bool HasInt() const =0
virtual int DoubleSize(const int EID) const =0
Returns the size of double data for local element EID.
virtual int NumMyElements() const =0
Returns the local number of elements.
virtual std::string Type() const =0
Returns the identifier of the distributed object.
virtual bool HasDouble() const =0
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 int GetLabels(std::vector< std::string > &IntLabels, std::vector< std::string > &DoubleLabels) const =0
Packs all global information.
virtual int Pack(const int EID, int *IntData, double *DoubleData) const =0
Packs all data for local element EID in the specified arrays.
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.