[cig-commits] [commit] baagaard/feature-output-station-names: Switch to fixed length string dataset in HDF5 to allow parallel I/O. (5b6d812)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Wed Nov 5 15:48:03 PST 2014


Repository : https://github.com/geodynamics/pylith

On branch  : baagaard/feature-output-station-names
Link       : https://github.com/geodynamics/pylith/compare/f33c75b19fd60eedb2a3405db76a1fee333bb1d7...5b6d812b1612809fea3bd331c4e5af98c25a536a

>---------------------------------------------------------------

commit 5b6d812b1612809fea3bd331c4e5af98c25a536a
Author: Brad Aagaard <baagaard at usgs.gov>
Date:   Wed Nov 5 15:39:26 2014 -0800

    Switch to fixed length string dataset in HDF5 to allow parallel I/O.
    
    Variable length string datasets are not implemented for parallel I/O in
    HDF5 1.8.11.


>---------------------------------------------------------------

5b6d812b1612809fea3bd331c4e5af98c25a536a
 libsrc/pylith/meshio/HDF5.cc | 54 +++++++++++++++++++++++++++-----------------
 libsrc/pylith/meshio/HDF5.hh |  8 +++++--
 2 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/libsrc/pylith/meshio/HDF5.cc b/libsrc/pylith/meshio/HDF5.cc
index 3c33b94..d05f5a4 100644
--- a/libsrc/pylith/meshio/HDF5.cc
+++ b/libsrc/pylith/meshio/HDF5.cc
@@ -1111,11 +1111,12 @@ void
 pylith::meshio::HDF5::writeDataset(const char* parent,
 				   const char* name,
 				   const char* const* sarray,
-				   const int nstrings)
+				   const int nstrings,
+				   const int slen)
 { // writeDataset
   PYLITH_METHOD_BEGIN;
 
-  HDF5::writeDataset(_file, parent, name, sarray, nstrings);
+  HDF5::writeDataset(_file, parent, name, sarray, nstrings, slen);
 
   PYLITH_METHOD_END;
 } // writeDataset
@@ -1127,7 +1128,8 @@ pylith::meshio::HDF5::writeDataset(hid_t h5,
 				   const char* parent,
 				   const char* name,
 				   const char* const* sarray,
-				   const int nstrings)
+				   const int nstrings,
+				   const int slen)
 { // writeDataset
   PYLITH_METHOD_BEGIN;
 
@@ -1136,6 +1138,7 @@ pylith::meshio::HDF5::writeDataset(hid_t h5,
   assert(name);
   assert(sarray);
   assert(nstrings > 0);
+  assert(slen > 0);
 
   try {
     // Open group
@@ -1157,10 +1160,20 @@ pylith::meshio::HDF5::writeDataset(hid_t h5,
     hid_t datatype = H5Tcopy(H5T_C_S1);
     if (datatype < 0) 
       throw std::runtime_error("Could not create datatype.");
-    herr_t err = H5Tset_size(datatype, H5T_VARIABLE);
+    herr_t err = H5Tset_size(datatype, slen);
     if (err < 0) 
       throw std::runtime_error("Could not set size of datatype.");
 
+    char* strfixedlen = (nstrings*slen > 0) ? new char[nstrings*slen] : 0;
+    for (int i=0; i < nstrings; ++i) {
+      const int index = i*slen;
+      strncpy(&strfixedlen[index], sarray[i], slen-1);
+      strfixedlen[index+slen-1] = '\0';
+      for (int j=strlen(sarray[i]); j < slen; ++j) {
+	  strfixedlen[index+j] = '\0';
+	} // for
+    } // for
+
 #if defined(PYLITH_HDF5_USE_API_18)
     hid_t dataset = H5Dcreate2(group, name, datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
 #else
@@ -1169,7 +1182,7 @@ pylith::meshio::HDF5::writeDataset(hid_t h5,
     if (dataset < 0) 
       throw std::runtime_error("Could not create dataset.");
 
-    err = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, sarray);
+    err = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, strfixedlen);
     if (err < 0)
       throw std::runtime_error("Could not write dataset.");
 
@@ -1218,7 +1231,7 @@ pylith::meshio::HDF5::readDataset(const char* parent,
   assert(name);
 
   pylith::string_vector data;
-  char** ptrarray = 0;
+  char* strfixedlen = 0;
   try {
     // Open group
 #if defined(PYLITH_HDF5_USE_API_18)
@@ -1238,6 +1251,14 @@ pylith::meshio::HDF5::readDataset(const char* parent,
     if (dataset < 0)
       throw std::runtime_error("Could not open dataset.");
 
+    // Get the datatype
+    hid_t datatype = H5Dget_type(dataset);
+    if (datatype < 0) 
+      throw std::runtime_error("Could not get datatype.");
+    const int slen = H5Tget_size(datatype);
+    if (slen < 0) 
+      throw std::runtime_error("Could not get size of datatype.");
+
     // Get the dataspace
     hid_t dataspace = H5Dget_space(dataset);
     if (dataspace < 0)
@@ -1250,26 +1271,17 @@ pylith::meshio::HDF5::readDataset(const char* parent,
     const int nstrings = dims[0];
     if (nstrings <= 0)
       throw std::runtime_error("Zero size for dataset.");
-    ptrarray = (nstrings > 0) ? new char*[nstrings] : 0;
 
-    // Create the datatype
-    hid_t datatype = H5Tcopy(H5T_C_S1);
-    if (datatype < 0) 
-      throw std::runtime_error("Could not create datatype.");
-    herr_t err = H5Tset_size(datatype, H5T_VARIABLE);
-    if (err < 0) 
-      throw std::runtime_error("Could not set size of datatype.");
+    strfixedlen = (nstrings*slen > 0) ? new char[nstrings*slen] : 0;
 
     // Read the dataset
-    err = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, ptrarray);
+    herr_t err = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, strfixedlen);
 
     data.resize(nstrings);
     for (int i=0; i < nstrings; ++i) {
-      data[i] = ptrarray[i];
+      data[i] = &strfixedlen[i*slen];
     } // for    
-    
-    err = H5Dvlen_reclaim(datatype, dataspace, H5P_DEFAULT, ptrarray);
-    delete[] ptrarray; ptrarray = 0;
+    delete[] strfixedlen; strfixedlen = 0;
 
     err = H5Dclose(dataset);
     if (err < 0)
@@ -1288,7 +1300,7 @@ pylith::meshio::HDF5::readDataset(const char* parent,
       throw std::runtime_error("Could not close group.");
 
   } catch (const std::exception& err) {
-    delete[] ptrarray; ptrarray = 0;
+    delete[] strfixedlen; strfixedlen = 0;
 
     std::ostringstream msg;
     msg << "Error occurred while creating dataset '"
@@ -1296,7 +1308,7 @@ pylith::meshio::HDF5::readDataset(const char* parent,
 	<< err.what();
     throw std::runtime_error(msg.str());
   } catch (...) {
-    delete[] ptrarray; ptrarray = 0;
+    delete[] strfixedlen; strfixedlen = 0;
 
     std::ostringstream msg;
     msg << "Unknown error occurred while writing dataset '" << name << "'.";
diff --git a/libsrc/pylith/meshio/HDF5.hh b/libsrc/pylith/meshio/HDF5.hh
index 1d2a8b9..ff585f1 100644
--- a/libsrc/pylith/meshio/HDF5.hh
+++ b/libsrc/pylith/meshio/HDF5.hh
@@ -273,11 +273,13 @@ public :
    * @param name Name of dataset.
    * @param sarray Array of null terminated C strings.
    * @param nstrings Size of array.
+   * @param slen Fixed length of strings.
    */
   void writeDataset(const char* parent,
 		    const char* name,
 		    const char* const* sarray,
-		    const int nstrings);
+		    const int nstrings,
+		    const int slen =64);
 
   /** Write dataset comprised of an array of strings (used with
    * external handle to HDF5 file, such as PetscHDF5Viewer).
@@ -287,13 +289,15 @@ public :
    * @param name Name of dataset.
    * @param sarray Array of null terminated C strings.
    * @param nstrings Size of array.
+   * @param slen Fixed length of strings.
    */
   static
   void writeDataset(hid_t h5,
 		    const char* parent,
 		    const char* name,
 		    const char* const* sarray,
-		    const int nstrings);
+		    const int nstrings,
+		    const int slen =64);
 
   /** Read dataset comprised of an array of strings.
    *



More information about the CIG-COMMITS mailing list