[nnkit] Introduce HDF5 export action (#370)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 26 Jun 2018 08:28:03 +0000 (17:28 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 26 Jun 2018 08:28:03 +0000 (17:28 +0900)
This commit introduces HDF5 export action which allows us to record
tensor state before/after inference as HDF5 file (.h5).

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/nnkit/CMakeLists.txt
contrib/nnkit/actions/CMakeLists.txt [new file with mode: 0644]
contrib/nnkit/actions/HDF5/CMakeLists.txt [new file with mode: 0644]
contrib/nnkit/actions/HDF5/Export.cpp [new file with mode: 0644]

index b3ac99f..230ce83 100644 (file)
@@ -11,4 +11,5 @@ endmacro(nnkit_add_backend)
 
 add_subdirectory(libs)
 add_subdirectory(backends)
+add_subdirectory(actions)
 add_subdirectory(tools)
diff --git a/contrib/nnkit/actions/CMakeLists.txt b/contrib/nnkit/actions/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5ea6cda
--- /dev/null
@@ -0,0 +1 @@
+add_subdirectories()
diff --git a/contrib/nnkit/actions/HDF5/CMakeLists.txt b/contrib/nnkit/actions/HDF5/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8144bf7
--- /dev/null
@@ -0,0 +1,9 @@
+find_package(HDF5 COMPONENTS CXX QUIET)
+
+if(NOT HDF5_FOUND)
+  return()
+endif(NOT HDF5_FOUND)
+
+add_library(nnkit_HDF5_export_action SHARED Export.cpp)
+target_link_libraries(nnkit_HDF5_export_action nnkit_intf_action)
+target_link_libraries(nnkit_HDF5_export_action ${HDF5_CXX_LIBRARIES})
diff --git a/contrib/nnkit/actions/HDF5/Export.cpp b/contrib/nnkit/actions/HDF5/Export.cpp
new file mode 100644 (file)
index 0000000..f6cafa7
--- /dev/null
@@ -0,0 +1,75 @@
+#include <nnkit/Action.h>
+
+#include <nncc/core/ADT/tensor/IndexRange.h>
+#include <nncc/core/ADT/tensor/LexicalLayout.h>
+
+#include <H5Cpp.h>
+
+using nnkit::TensorContext;
+
+class HD5ExportAction final : public nnkit::Action
+{
+public:
+  HD5ExportAction(const std::string &path) : _file{path, H5F_ACC_TRUNC}
+  {
+    // DO NOTHING
+  }
+
+public:
+  void run(TensorContext &ctx) override
+  {
+    for (uint32_t n = 0; n < ctx.size(); ++n)
+    {
+      using nncc::core::ADT::tensor::Reader;
+
+      // TODO Support other data types
+      auto fn = [this] (const TensorContext &ctx, uint32_t n, const Reader<float> &t)
+      {
+        const auto shape = ctx.shape(n);
+
+        const auto rank = shape.rank();
+
+        hsize_t dims[rank];
+
+        for (uint32_t axis = 0; axis < rank; ++axis)
+        {
+          dims[axis] = shape.dim(axis);
+        }
+
+        H5::DataSpace dataspace(rank, dims);
+
+        auto dataset = _file.createDataSet(ctx.name(n), H5::PredType::IEEE_F32BE, dataspace);
+
+        float *data = new float[nncc::core::ADT::tensor::num_elements(shape)];
+
+        using nncc::core::ADT::tensor::range;
+        using nncc::core::ADT::tensor::Index;
+        using nncc::core::ADT::tensor::LexicalLayout;
+
+        LexicalLayout layout{};
+
+        range(shape).iterate() << [data, &t, &shape, &layout] (const Index &i)
+        {
+          data[layout.offset(shape, i)] = t.at(i);
+        };
+
+        dataset.write(data, H5::PredType::NATIVE_FLOAT);
+
+        delete[] data;
+      };
+
+      ctx.getConstFloatTensor(n, fn);
+    }
+  }
+
+private:
+  H5::H5File _file;
+};
+
+#include <nnkit/CmdlineArguments.h>
+#include <nncc/foundation/Memory.h>
+
+extern "C" std::unique_ptr<nnkit::Action> make_action(const nnkit::CmdlineArguments &args)
+{
+  return nncc::foundation::make_unique<HD5ExportAction>(args.at(0));
+}