[nnkit] Introduce HDF5 import action (#380)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 4 Jul 2018 07:06:48 +0000 (16:06 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 4 Jul 2018 07:06:48 +0000 (16:06 +0900)
This commit introduces HDF5 import action, which fills tensor with the
values loaded from HDF5 file.

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

index ef9f408..1899972 100644 (file)
@@ -8,3 +8,8 @@ add_library(nnkit_HDF5_export_action SHARED Export.cpp)
 target_include_directories(nnkit_HDF5_export_action PRIVATE ${HDF5_INCLUDE_DIRS})
 target_link_libraries(nnkit_HDF5_export_action nnkit_intf_action)
 target_link_libraries(nnkit_HDF5_export_action ${HDF5_CXX_LIBRARIES})
+
+add_library(nnkit_HDF5_import_action SHARED Import.cpp)
+target_include_directories(nnkit_HDF5_import_action PRIVATE ${HDF5_INCLUDE_DIRS})
+target_link_libraries(nnkit_HDF5_import_action nnkit_intf_action)
+target_link_libraries(nnkit_HDF5_import_action ${HDF5_CXX_LIBRARIES})
diff --git a/contrib/nnkit/actions/HDF5/Import.cpp b/contrib/nnkit/actions/HDF5/Import.cpp
new file mode 100644 (file)
index 0000000..7bc76a1
--- /dev/null
@@ -0,0 +1,79 @@
+#include <nnkit/Action.h>
+
+#include <nncc/core/ADT/tensor/IndexRange.h>
+#include <nncc/core/ADT/tensor/LexicalLayout.h>
+
+#include <H5Cpp.h>
+
+#include <cassert>
+
+using nnkit::TensorContext;
+
+class HD5ImportAction final : public nnkit::Action
+{
+public:
+  HD5ImportAction(const std::string &path) : _file{path, H5F_ACC_RDONLY}
+  {
+    // DO NOTHING
+  }
+
+public:
+  void run(TensorContext &ctx) override
+  {
+    for (uint32_t n = 0; n < ctx.size(); ++n)
+    {
+      using nncc::core::ADT::tensor::Accessor;
+
+      auto fn = [this] (const TensorContext &ctx, uint32_t n, Accessor<float> &t)
+      {
+        const auto name = ctx.name(n);
+
+        auto dataset = _file.openDataSet(name);
+
+        // TODO Support non-float tensors
+        assert(dataset.getDataType() == H5::PredType::IEEE_F32BE);
+
+        // TODO Check whether shape is consistent
+        const auto shape = ctx.shape(n);
+
+        std::vector<float> buffer;
+
+        using nncc::core::ADT::tensor::num_elements;
+        buffer.resize(num_elements(shape));
+
+        dataset.read(buffer.data(), H5::PredType::NATIVE_FLOAT);
+
+        using nncc::core::ADT::tensor::range;
+        using nncc::core::ADT::tensor::Index;
+        using nncc::core::ADT::tensor::LexicalLayout;
+
+        LexicalLayout layout{};
+
+        range(shape).iterate() << [&buffer, &t, &shape, &layout] (const Index &i)
+        {
+          t.at(i) = buffer[layout.offset(shape, i)];
+        };
+      };
+
+      try
+      {
+        ctx.getMutableFloatTensor(n, fn);
+      }
+      catch (const H5::FileIException &)
+      {
+        // Skip if data is not present in HDF5 file
+      }
+    }
+  }
+
+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<HD5ImportAction>(args.at(0));
+}