00001 #include "EpetraExt_ConfigDefs.h"
00002 #ifdef HAVE_EPETRAEXT_HDF5
00003 #ifdef HAVE_MPI
00004 #include "Epetra_MpiComm.h"
00005 #include "mpi.h"
00006 #else
00007 #include "Epetra_SerialComm.h"
00008 #endif
00009 #include "Teuchos_ParameterList.hpp"
00010 #include "Epetra_BlockMap.h"
00011 #include "Epetra_DistObject.h"
00012 #include "EpetraExt_Exception.h"
00013 #include "EpetraExt_Utils.h"
00014 #include "EpetraExt_HDF5.h"
00015 #include "EpetraExt_HDF5_Handle.h"
00016
00017 #define CHECK_HID(hid_t) \
00018 { if (hid_t < 0) \
00019 throw(EpetraExt::Exception(__FILE__, __LINE__, \
00020 "hid_t is negative")); }
00021
00022 #define CHECK_STATUS(status) \
00023 { if (status < 0) \
00024 throw(EpetraExt::Exception(__FILE__, __LINE__, \
00025 "function H5Giterater returned a negative value")); }
00026
00027
00028 void EpetraExt::HDF5::Write(const std::string& GroupName,
00029 const Handle& obj)
00030 {
00031 int NumMyElements = obj.NumMyElements();
00032 int NumGlobalElements = obj.NumGlobalElements();
00033
00034
00035
00036
00037
00038 std::vector<std::string> IntLabels, DoubleLabels;
00039 std::vector<int> IntLabelsData;
00040 std::vector<double> DoubleLabelsData;
00041
00042 obj.GetLabels(IntLabels, IntLabelsData, DoubleLabels, DoubleLabelsData);
00043
00044 CreateGroup(GroupName);
00045
00046 for (unsigned int i = 0; i < IntLabels.size(); ++i)
00047 Write(GroupName, IntLabels[i], IntLabelsData[i]);
00048
00049 for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
00050 Write(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
00051
00052
00053
00054
00055
00056 std::vector<int> IntSize(NumMyElements);
00057 std::vector<int> DoubleSize(NumMyElements);
00058
00059 int TotalIntSize = 0, TotalDoubleSize = 0;
00060
00061 std::vector<int> IntData;
00062 std::vector<double> DoubleData;
00063
00064 for (int i = 0; i < NumMyElements; ++i)
00065 {
00066 IntSize[i] = obj.IntSize(i);
00067 DoubleSize[i] = obj.DoubleSize(i);
00068 TotalIntSize += IntSize[i];
00069 TotalDoubleSize += DoubleSize[i];
00070 }
00071
00072 IntData.resize(TotalIntSize);
00073 DoubleData.resize(TotalDoubleSize);
00074
00075 int IntCount = 0;
00076 int DoubleCount = 0;
00077
00078
00079
00080
00081
00082 for (int i = 0; i < NumMyElements; ++i)
00083 {
00084 obj.Pack(i, &IntData[IntCount], &DoubleData[DoubleCount]);
00085 IntCount += IntSize[i];
00086 DoubleCount += DoubleSize[i];
00087 }
00088
00089 if (!IsContained(GroupName))
00090 CreateGroup(GroupName);
00091
00092 Write(GroupName, "__type__", obj.Type());
00093 Write(GroupName, "NumGlobalElements", NumGlobalElements);
00094 Write(GroupName, "has int", obj.HasInt());
00095 Write(GroupName, "has double", obj.HasDouble());
00096
00097 if (obj.HasInt())
00098 {
00099 Write(GroupName, "int ptr", NumMyElements,
00100 NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
00101 Write(GroupName, "int data", NumMyElements,
00102 NumGlobalElements, H5T_NATIVE_INT, &IntData[0]);
00103 }
00104
00105 if (obj.HasDouble())
00106 {
00107 Write(GroupName, "double ptr", NumMyElements,
00108 NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
00109 Write(GroupName, "double data", NumMyElements,
00110 NumGlobalElements, H5T_NATIVE_DOUBLE, &DoubleData[0]);
00111 }
00112 }
00113
00114
00115 void EpetraExt::HDF5::Read(const std::string& GroupName, Handle& obj)
00116 {
00117 int NumMyElements = obj.NumMyElements();
00118 int NumGlobalElements = obj.NumGlobalElements();
00119
00120 std::vector<std::string> IntLabels, DoubleLabels;
00121
00122 obj.GetLabels(IntLabels, DoubleLabels);
00123 std::vector<int> IntLabelsData(IntLabels.size());
00124 std::vector<double> DoubleLabelsData(DoubleLabels.size());
00125
00126 for (unsigned int i = 0; i < IntLabels.size(); ++i)
00127 Read(GroupName, IntLabels[i], IntLabelsData[i]);
00128
00129 for (unsigned int i = 0; i < DoubleLabels.size(); ++i)
00130 Read(GroupName, DoubleLabels[i], DoubleLabelsData[i]);
00131
00132 std::vector<int> IntSize(NumMyElements);
00133 std::vector<int> DoubleSize(NumMyElements);
00134
00135 int TotalIntSize = 0, TotalDoubleSize = 0;
00136 int GrandTotalIntSize = 0, GrandTotalDoubleSize = 0;
00137
00138
00139 if (obj.HasInt())
00140 {
00141 Read(GroupName, "int ptr", NumMyElements,
00142 NumGlobalElements, H5T_NATIVE_INT, &IntSize[0]);
00143 for (int i = 0; i < NumMyElements; ++i)
00144 TotalIntSize += IntSize[i];
00145 Comm().SumAll(&TotalIntSize, &GrandTotalIntSize, 1);
00146 }
00147
00148 if (obj.HasDouble())
00149 {
00150 Read(GroupName, "double ptr", NumMyElements,
00151 NumGlobalElements, H5T_NATIVE_INT, &DoubleSize[0]);
00152 for (int i = 0; i < NumMyElements; ++i)
00153 {
00154 TotalDoubleSize += DoubleSize[i];
00155 }
00156 Comm().SumAll(&TotalDoubleSize, &GrandTotalDoubleSize, 1);
00157 }
00158
00159 std::vector<int> IntData(TotalIntSize + 1);
00160 std::vector<double> DoubleData(TotalDoubleSize + 1);
00161
00162
00163 if (obj.HasInt())
00164 Read(GroupName, "int data", TotalIntSize,
00165 GrandTotalIntSize, H5T_NATIVE_INT, &IntData[0]);
00166 if (obj.HasDouble())
00167 Read(GroupName, "double data", TotalDoubleSize,
00168 GrandTotalDoubleSize, H5T_NATIVE_DOUBLE, &DoubleData[0]);
00169
00170
00171 obj.Initialize();
00172
00173 obj.SetLabels(IntLabelsData, DoubleLabelsData);
00174
00175 int IntCount = 0, DoubleCount = 0;
00176 for (int i = 0; i < NumMyElements; ++i)
00177 {
00178 obj.UnPack(i, IntSize[i], &(IntData[IntCount]),
00179 DoubleSize[i], &(DoubleData[DoubleCount]));
00180 IntCount += IntSize[i];
00181 DoubleCount += DoubleSize[i];
00182 }
00183
00184 obj.Finalize();
00185 }
00186
00187
00188 void EpetraExt::HDF5::ReadHandleProperties(const std::string& GroupName,
00189 std::string& Type,
00190 int& NumGlobalElements)
00191 {
00192 if (!IsContained(GroupName))
00193 throw(Exception(__FILE__, __LINE__,
00194 "requested group " + GroupName + " not found"));
00195
00196 Read(GroupName, "__type__", Type);
00197
00198 Read(GroupName, "NumGlobalElements", NumGlobalElements);
00199 }
00200 #endif