[nnpackage_run] Use HDF5 C++ interface (#8671)
authorSergei Barannikov/AI Tools Lab /SRR/Engineer/Samsung Electronics <s.barannikov@samsung.com>
Fri, 1 Nov 2019 08:19:32 +0000 (11:19 +0300)
committer오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Fri, 1 Nov 2019 08:19:32 +0000 (17:19 +0900)
Use HDF5 C++ interface instead of C.

Signed-off-by: Sergei Barannikov <s.barannikov@samsung.com>
tests/tools/nnpackage_run/CMakeLists.txt
tests/tools/nnpackage_run/src/nnpackage_run.cc

index 79a1da7..fbb2284 100644 (file)
@@ -6,12 +6,15 @@ if(NOT BUILD_NEURUN)
   return()
 endif(NOT BUILD_NEURUN)
 
-nnfw_find_package(HDF5 QUIET)
+find_package(HDF5 COMPONENTS CXX QUIET)
 if(NOT HDF5_FOUND)
   message(WARNING "HDF5 NOT found. Install libhdf5-dev to build nnpackage_run.")
   return()
 endif(NOT HDF5_FOUND)
 
+# Append missing libaec, which is required by libsz, which is required by libhdf5.
+list(APPEND HDF5_CXX_LIBRARIES aec)
+
 list(APPEND NNPACKAGE_RUN_SRCS "src/nnpackage_run.cc")
 list(APPEND NNPACKAGE_RUN_SRCS "src/args.cc")
 list(APPEND NNPACKAGE_RUN_SRCS "src/tensor_dumper.cc")
@@ -27,6 +30,6 @@ target_link_libraries(nnpackage_run neurun_core neurun tflite_loader)
 target_link_libraries(nnpackage_run tensorflow-lite ${LIB_PTHREAD} dl nnfw_lib_tflite)
 target_link_libraries(nnpackage_run nnfw-dev)
 target_link_libraries(nnpackage_run boost_program_options boost_system boost_filesystem)
-target_link_libraries(nnpackage_run ${HDF5_LIBRARIES})
+target_link_libraries(nnpackage_run ${HDF5_CXX_LIBRARIES})
 
 install(TARGETS nnpackage_run DESTINATION bin)
index fb390ad..bc338a9 100644 (file)
 #include "args.h"
 #include "tflite/Diff.h"
 #include "tensor_dumper.h"
-#include "hdf5.h"
 #include "nnfw.h"
 
-#include <assert.h>
-#include <iostream>
+#include <H5Cpp.h>
 
+#include <cassert>
 #include <chrono>
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
 
 #define NNPR_ENSURE_STATUS(a)        \
   do                                 \
@@ -51,7 +53,7 @@ uint64_t num_elems(const nnfw_tensorinfo *ti)
     n *= ti->dims[i];
   }
   return n;
-};
+}
 
 std::vector<float> randomData(RandomGenerator &randgen, uint64_t size)
 {
@@ -131,58 +133,49 @@ int main(const int argc, char **argv)
 
   std::vector<std::vector<float>> inputs(num_inputs);
 
-  auto loadInputs = [session, num_inputs, &inputs](std::string filename) {
-    hid_t file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
-    if (file_id < 0)
+  auto loadInputs = [session, num_inputs, &inputs](const std::string &filename) {
+    try
     {
-      std::cerr << "error during opening file " << filename << "." << std::endl;
-      exit(-1);
+      // Turn off the automatic error printing.
+      H5::Exception::dontPrint();
+
+      H5::H5File file(filename, H5F_ACC_RDONLY);
+      H5::Group value_group = file.openGroup(h5_value_grpname);
+      for (uint32_t i = 0; i < num_inputs; ++i)
+      {
+        nnfw_tensorinfo ti;
+        NNPR_ENSURE_STATUS(nnfw_input_tensorinfo(session, i, &ti));
+
+        H5::DataSet data_set = value_group.openDataSet(std::to_string(i));
+
+        // check type
+        H5::DataType type = data_set.getDataType();
+        if (!(type == H5::PredType::IEEE_F32BE || type == H5::PredType::IEEE_F32LE))
+        {
+          throw std::runtime_error(
+              "h5 input has non-float32 type. nnpkg_run supports float32 only.");
+        }
+
+        // allocate memory for data
+        auto sz = num_elems(&ti);
+        inputs[i].resize(sz);
+        // read data
+        data_set.read(inputs[i].data(), H5::PredType::NATIVE_FLOAT);
+
+        NNPR_ENSURE_STATUS(nnfw_set_input(session, i, NNFW_TYPE_TENSOR_FLOAT32, inputs[i].data(),
+                                          sizeof(float) * num_elems(&ti)));
+      }
     }
-    hid_t valgrp_id = H5Gopen(file_id, h5_value_grpname, H5P_DEFAULT);
-    if (valgrp_id < 0)
+    catch (const H5::Exception &e)
     {
-      std::cerr << "error during opening group " << h5_value_grpname << "." << std::endl;
-      H5Fclose(file_id);
-      exit(-1);
+      H5::Exception::printErrorStack();
+      std::exit(-1);
     }
-    for (uint32_t i = 0; i < num_inputs; ++i)
+    catch (const std::exception &e)
     {
-      nnfw_tensorinfo ti;
-      NNPR_ENSURE_STATUS(nnfw_input_tensorinfo(session, i, &ti));
-
-      hid_t dset_id = H5Dopen(valgrp_id, std::to_string(i).c_str(), H5P_DEFAULT);
-      if (dset_id < 0)
-      {
-        std::cerr << "error during opening dataset " << std::to_string(i) << "." << std::endl;
-        H5Gclose(valgrp_id);
-        H5Fclose(file_id);
-        exit(-1);
-      }
-
-      // check type
-      hid_t type = H5Dget_type(dset_id);
-      if (!H5Tequal(type, H5T_IEEE_F32BE) && !H5Tequal(type, H5T_IEEE_F32LE))
-      {
-        std::cerr << "h5 input has non-float32 type. nnpkg_run supports float32 only." << std::endl;
-        H5Dclose(dset_id);
-        H5Gclose(valgrp_id);
-        H5Fclose(file_id);
-        exit(-1);
-      }
-
-      // allocate memory for data
-      auto sz = num_elems(&ti);
-      inputs[i].resize(sz);
-      // read data
-      H5Dread(dset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, inputs[i].data());
-
-      NNPR_ENSURE_STATUS(nnfw_set_input(session, i, NNFW_TYPE_TENSOR_FLOAT32, inputs[i].data(),
-                                        sizeof(float) * num_elems(&ti)));
-      // clean up
-      H5Dclose(dset_id);
+      std::cerr << e.what() << std::endl;
+      std::exit(-1);
     }
-    H5Gclose(valgrp_id);
-    H5Fclose(file_id);
   };
 
   auto generateInputs = [session, num_inputs, &inputs]() {
@@ -227,29 +220,35 @@ int main(const int argc, char **argv)
 
   // dump output tensors
 
-  auto dumpOutputs = [session, num_outputs, &outputs](std::string filename) {
-    hid_t file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
-    hid_t valgrp_id = H5Gcreate(file_id, h5_value_grpname, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
-    for (uint32_t i = 0; i < num_outputs; i++)
+  auto dumpOutputs = [session, num_outputs, &outputs](const std::string &filename) {
+    try
     {
-      nnfw_tensorinfo ti;
-      NNPR_ENSURE_STATUS(nnfw_output_tensorinfo(session, i, &ti));
-      std::vector<hsize_t> dims;
-      dims.resize(ti.rank);
-      for (uint32_t j = 0; j < ti.rank; ++j)
+      // Turn off the automatic error printing.
+      H5::Exception::dontPrint();
+
+      H5::H5File file(filename, H5F_ACC_TRUNC);
+      H5::Group value_group = file.createGroup(h5_value_grpname);
+      for (uint32_t i = 0; i < num_outputs; i++)
       {
-        assert(ti.dims[j] >= 0);
-        dims[j] = ti.dims[j];
+        nnfw_tensorinfo ti;
+        NNPR_ENSURE_STATUS(nnfw_output_tensorinfo(session, i, &ti));
+        std::vector<hsize_t> dims(ti.rank);
+        for (uint32_t j = 0; j < ti.rank; ++j)
+        {
+          assert(ti.dims[j] >= 0);
+          dims[j] = ti.dims[j];
+        }
+        H5::DataSpace data_space(ti.rank, dims.data());
+        H5::DataSet data_set =
+            value_group.createDataSet(std::to_string(i), H5::PredType::IEEE_F32BE, data_space);
+        data_set.write(outputs[i].data(), H5::PredType::NATIVE_FLOAT);
       }
-      hid_t dsp_id = H5Screate_simple(ti.rank, dims.data(), nullptr);
-      hid_t dset_id = H5Dcreate2(valgrp_id, std::to_string(i).c_str(), H5T_IEEE_F32BE, dsp_id,
-                                 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
-      H5Dwrite(dset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, outputs[i].data());
-      H5Dclose(dset_id);
-      H5Sclose(dsp_id);
     }
-    H5Gclose(valgrp_id);
-    H5Fclose(file_id);
+    catch (const H5::Exception &e)
+    {
+      H5::Exception::printErrorStack();
+      std::exit(-1);
+    }
   };
 
   if (!args.getDumpFilename().empty())