EpetraExt Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HDF5_IO.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_MPI
46 #include "mpi.h"
47 #include "Epetra_MpiComm.h"
48 #else
49 #include "Epetra_SerialComm.h"
50 #endif
51 #include <vector>
52 #include "Epetra_Map.h"
53 #include "Epetra_CrsMatrix.h"
54 #include "Epetra_MultiVector.h"
55 #include "EpetraExt_HDF5.h"
56 #include "EpetraExt_Utils.h"
57 #include "EpetraExt_Exception.h"
59 
60 // Showing the usage of HDF5 I/O.
61 // This example can be run with any number of processors.
62 //
63 // \author Marzio Sala, D-INFK/ETHZ.
64 //
65 // \date Last modified on 09-Mar-06.
66 
67 int main (int argc, char **argv)
68 {
69 #ifdef HAVE_MPI
70  MPI_Init(&argc, &argv);
71  Epetra_MpiComm Comm(MPI_COMM_WORLD);
72 #else
73  Epetra_SerialComm Comm;
74 #endif
75 
76  try
77  {
78  int n = Comm.NumProc() * 4;
79  Epetra_Map Map(n, 0, Comm);
80  Epetra_MultiVector x(Map, 2); x.Random();
81  Epetra_MultiVector b(Map, 2); x.Random();
82  Epetra_CrsMatrix Matrix(Copy, Map, 0);
83  // diagonal matrix
84  for (int i = 0; i < Map.NumMyElements(); ++i)
85  {
86  int ii = Map.GID(i);
87  double one = 1.0;
88  Matrix.InsertGlobalValues(ii, 1, &one, &ii);
89  }
90  Matrix.FillComplete();
91 
92  // create a Teuchos::ParameterList and populate it
94  List.set("bool type", true);
95  List.set("int type", 2);
96  List.set("double type", 3.0);
97  List.set("std::string type", "a std::string");
98 
99  // This is the HDF5 file manager
100  EpetraExt::HDF5 HDF5(Comm);
101 
102  // creates a new file. To open an existing file, use Open("myfile.h5")
103  HDF5.Create("myfile.h5");
104 
105  // =========================== //
106  // P A R T I: W R I T I N G //
107  // =========================== //
108 
109  if (Comm.MyPID() == 0)
110  std::cout << "Writing objects to HDF5 file myfile.h5..." << std::endl << std::endl;
111 
112  // We first write the map, whose name contains the number of processors
113  HDF5.Write("map-" + EpetraExt::toString(Comm.NumProc()), Map);
114  // Then we write the matrix...
115  HDF5.Write("matrix", Matrix);
116  // ... and the x, b vectors
117  HDF5.Write("x", x);
118  HDF5.Write("b", b);
119  // we can associate basic data types with a given group, for example:
120  HDF5.Write("matrix", "integration order", 1);
121  HDF5.Write("matrix", "numerical drop", 0.1);
122  HDF5.Write("matrix", "package name", "EpetraExt");
123  HDF5.Write("matrix", "author", "Marzio Sala");
124  HDF5.Write("matrix", "institution", "ETHZ/D-INFK");
125  // or put them in a new group
126  HDF5.Write("my parameters", "latitude", 12);
127  HDF5.Write("my parameters", "longitude", 67);
128 
129  // Now we write the parameter list we have used to create the matrix
130  HDF5.Write("List", List);
131  // We can also write integers/doubles/arrays. All these quantities are
132  // supposed to have the same value on all processors.
133  std::vector<int> iarray(3);
134  iarray[0] = 0, iarray[1] = 1; iarray[2] = 2;
135  HDF5.Write("my parameters", "int array", H5T_NATIVE_INT, 3, &iarray[0]);
136 
137  std::vector<double> darray(3);
138  darray[0] = 0.1, darray[1] = 1.1; darray[2] = 2.1;
139  HDF5.Write("my parameters", "double array", H5T_NATIVE_DOUBLE, 3, &darray[0]);
140 
141  // To analyze the content of the file, one can use
142  // "h5dump filename.h5" or "h5dump filename.h5 -H" o
143 
144  // ============================ //
145  // P A R T II: R E A D I N G //
146  // ============================ //
147 
148  if (Comm.MyPID() == 0)
149  std::cout << "Reading objects from HDF5 file myfile.h5..." << std::endl << std::endl;
150 
151  Epetra_Map* NewMap = 0;
152  Epetra_CrsMatrix* NewMatrix = 0;
153  Epetra_MultiVector* NewX,* NewB;
154 
155  // Check if the map is there (in this case it is). If it is, read the
156  // matrix using the map, otherwise read the matrix with a linear map.
157  if (HDF5.IsContained("map-" + EpetraExt::toString(Comm.NumProc())))
158  {
159  HDF5.Read("map-" + EpetraExt::toString(Comm.NumProc()), NewMap);
160  HDF5.Read("matrix", *NewMap, *NewMap, NewMatrix);
161  }
162  else
163  {
164  int NumGlobalRows;
165  HDF5.Read("matrix", "NumGlobalRows", NumGlobalRows);
166  NewMap = new Epetra_Map(NumGlobalRows, 0, Comm);
167  HDF5.Read("matrix", *NewMap, *NewMap, NewMatrix);
168  }
169 
170  // read the number of nonzeros from file, compare them with the
171  // actual number of NewMatrix
172  int NewNumGlobalNonzeros;
173  HDF5.Read("matrix", "NumGlobalNonzeros", NewNumGlobalNonzeros);
174 
175  assert (Matrix.NumGlobalNonzeros() == NewNumGlobalNonzeros);
176 
177  // Now read the MultiVector's
178  HDF5.Read("x", NewX);
179  HDF5.Read("b", NewB);
180 
181  // the int/double values, and the int/double arrays
182  int new_latitude, new_longitude;
183  std::vector<int> new_iarray(3);
184  std::vector<double> new_darray(3);
185  HDF5.Read("my parameters", "latitude", new_latitude);
186  HDF5.Read("my parameters", "longitude", new_longitude);
187  HDF5.Read("my parameters", "int array", H5T_NATIVE_INT, 3, &new_iarray[0]);
188  HDF5.Read("my parameters", "double array", H5T_NATIVE_DOUBLE, 3, &new_darray[0]);
189  // and the std::string values associated with group "matrix", recordered
190  // with dataset "package name".
191  std::string PackageName;
192  HDF5.Read("matrix", "package name", PackageName);
193 
194  Teuchos::ParameterList newList;
195  HDF5.Read("List", newList);
196  if (Comm.MyPID() == 0)
197  {
198  std::cout << "New list as read from file is:" << std::endl;
199  std::cout << "bool type = " << newList.get("bool type", false) << std::endl;
200  std::cout << "int type = " << newList.get("int type", -1) << std::endl;
201  std::cout << "double type = " << newList.get("double type", -1.0) << std::endl;
202  std::cout << "std::string type = " << newList.get("std::string type", "not-set") << std::endl;
203  std::cout << std::endl;
204 
205  std::cout << "Checking some read and written data..." << std::endl;
206  for (int i = 0; i < 3; ++i) {
207  std::cout << "iarray[" << i << "] = " << iarray[i] << " should be " << new_iarray[i] << std::endl;
208  if(iarray[i] != new_iarray[i]) {
209  std::cout << "Test failed." << std::endl;
210  return EXIT_FAILURE;
211  }
212  }
213 
214  for (int i = 0; i < 3; ++i) {
215  std::cout << "darray[" << i << "] = " << darray[i] << " should be " << new_darray[i] << std::endl;
216  if(darray[i] != new_darray[i]) {
217  std::cout << "Test failed." << std::endl;
218  return EXIT_FAILURE;
219  }
220  }
221 
222  std::cout << std::endl;
223  std::cout << "Try to print out the content of myfile.h5 using the command" << std::endl;
224  std::cout << " h5dump myfile.h5" << std::endl;
225  }
226 
227  // We finally close the file. Better to close it before calling
228  // MPI_Finalize() to avoid MPI-related errors, since Close() might call MPI
229  // functions.
230  HDF5.Close();
231 
232  // delete memory
233  if (NewMap ) delete NewMap;
234  if (NewMatrix) delete NewMatrix;
235  if (NewX ) delete NewX;
236  if (NewB ) delete NewB;
237  }
238  catch(EpetraExt::Exception& rhs)
239  {
240  rhs.Print();
241  return EXIT_FAILURE;
242  }
243  catch (...)
244  {
245  std::cerr << "Caught generic std::exception" << std::endl;
246  return EXIT_FAILURE;
247  }
248 
249 #ifdef HAVE_MPI
250  MPI_Finalize();
251 #endif
252 
253  return(EXIT_SUCCESS);
254 }
void Write(const std::string &GroupName, const std::string &DataSetName, int data)
Write an integer in group GroupName using the given DataSetName.
T & get(ParameterList &l, const std::string &name)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
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.
int MyPID() const
int FillComplete(bool OptimizeDataStorage=true)
int main(int argc, char **argv)
Definition: HDF5_IO.cpp:67
int NumMyElements() const
int GID(int LID) const
int NumGlobalNonzeros() const
int NumProc() const
class HDF5: A class for storing Epetra objects in parallel binary files
void Close()
Close the file.
void Create(const std::string FileName)
Create a new file.
int n
std::string toString(const int &x)