[morph] Initial commit (#885)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Fri, 3 Aug 2018 02:01:54 +0000 (11:01 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 3 Aug 2018 02:01:54 +0000 (11:01 +0900)
This commit creates 'morph' library project, which will include
shape conversion routines for various NN frameworks.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/morph/.FORMATCHECKED [new file with mode: 0644]
contrib/morph/CMakeLists.txt [new file with mode: 0644]
contrib/morph/README.md [new file with mode: 0644]
contrib/morph/include/morph/caffe.h [new file with mode: 0644]
contrib/morph/src/caffe.cpp [new file with mode: 0644]
contrib/morph/src/caffe.test.cpp [new file with mode: 0644]

diff --git a/contrib/morph/.FORMATCHECKED b/contrib/morph/.FORMATCHECKED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/contrib/morph/CMakeLists.txt b/contrib/morph/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0d16242
--- /dev/null
@@ -0,0 +1,20 @@
+file(GLOB_RECURSE SOURCES "src/*.cpp")
+file(GLOB_RECURSE TESTS "src/*.test.cpp")
+list(REMOVE_ITEM SOURCES ${TESTS})
+
+add_library(morph STATIC ${SOURCES})
+set_target_properties(morph PROPERTIES POSITION_INDEPENDENT_CODE ON)
+target_include_directories(morph PUBLIC include)
+target_link_libraries(morph PRIVATE nncc_common)
+target_link_libraries(morph PUBLIC nncc_core)
+
+nncc_find_package(GTest QUIET)
+
+if(NOT GTest_FOUND)
+  return()
+endif(NOT GTest_FOUND)
+
+add_executable(morph_test ${TESTS})
+target_link_libraries(morph_test morph)
+target_link_libraries(morph_test gtest_main)
+add_test(morph_test morph_test)
diff --git a/contrib/morph/README.md b/contrib/morph/README.md
new file mode 100644 (file)
index 0000000..45ca360
--- /dev/null
@@ -0,0 +1,3 @@
+# morph
+
+``morph`` is a collection of shape conversion routines for various NN frameworks, such as Caffe.
diff --git a/contrib/morph/include/morph/caffe.h b/contrib/morph/include/morph/caffe.h
new file mode 100644 (file)
index 0000000..1e01016
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __MORPH_CAFFE_H__
+#define __MORPH_CAFFE_H__
+
+#include <nncc/core/ADT/tensor/Shape.h>
+#include <nncc/core/ADT/feature/Shape.h>
+#include <nncc/core/ADT/kernel/Shape.h>
+
+namespace morph
+{
+
+nncc::core::ADT::tensor::Shape as_tensor_shape(const nncc::core::ADT::feature::Shape &);
+nncc::core::ADT::tensor::Shape as_tensor_shape(const nncc::core::ADT::kernel::Shape &);
+
+nncc::core::ADT::feature::Shape as_feature_shape(const nncc::core::ADT::tensor::Shape &);
+nncc::core::ADT::kernel::Shape as_kernel_shape(const nncc::core::ADT::tensor::Shape &);
+
+} // namespace morph
+
+#endif // __MORPH_CAFFE_H__
diff --git a/contrib/morph/src/caffe.cpp b/contrib/morph/src/caffe.cpp
new file mode 100644 (file)
index 0000000..0073fe7
--- /dev/null
@@ -0,0 +1,49 @@
+#include "morph/caffe.h"
+
+#include <cassert>
+
+using namespace nncc::core::ADT;
+
+namespace morph
+{
+
+tensor::Shape as_tensor_shape(const feature::Shape &shape)
+{
+  tensor::Shape res;
+
+  res.resize(4);
+  res.dim(0) = 1;
+  res.dim(1) = shape.depth();
+  res.dim(2) = shape.height();
+  res.dim(3) = shape.width();
+
+  return res;
+}
+
+tensor::Shape as_tensor_shape(const kernel::Shape &shape)
+{
+  tensor::Shape res;
+
+  res.resize(4);
+  res.dim(0) = shape.count();
+  res.dim(1) = shape.depth();
+  res.dim(2) = shape.height();
+  res.dim(3) = shape.width();
+
+  return res;
+}
+
+feature::Shape as_feature_shape(const tensor::Shape &shape)
+{
+  assert(shape.rank() == 4);
+  assert(shape.dim(0) == 1);
+  return feature::Shape{shape.dim(1), shape.dim(2), shape.dim(3)};
+}
+
+kernel::Shape as_kernel_shape(const tensor::Shape &shape)
+{
+  assert(shape.rank() == 4);
+  return kernel::Shape{shape.dim(0), shape.dim(1), shape.dim(2), shape.dim(3)};
+}
+
+} // namespace morph
diff --git a/contrib/morph/src/caffe.test.cpp b/contrib/morph/src/caffe.test.cpp
new file mode 100644 (file)
index 0000000..2407ddd
--- /dev/null
@@ -0,0 +1,49 @@
+#include "morph/caffe.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+TEST(MORPH_CAFFE, as_feature_shape)
+{
+  auto shape = morph::as_feature_shape(tensor::Shape{1, 3, 4, 5});
+
+  ASSERT_EQ(shape.depth(), 3);
+  ASSERT_EQ(shape.height(), 4);
+  ASSERT_EQ(shape.width(), 5);
+}
+
+TEST(MORPH_CAFFE, as_kernel_shape)
+{
+  auto shape = morph::as_kernel_shape(tensor::Shape{2, 3, 4, 5});
+
+  ASSERT_EQ(shape.count(), 2);
+  ASSERT_EQ(shape.depth(), 3);
+  ASSERT_EQ(shape.height(), 4);
+  ASSERT_EQ(shape.width(), 5);
+}
+
+TEST(MORPH_CAFFE, as_tensor_shape)
+{
+  // From feature::Shape
+  {
+    auto shape = morph::as_tensor_shape(feature::Shape{2, 3, 4});
+
+    ASSERT_EQ(shape.rank(), 4);
+    ASSERT_EQ(shape.dim(0), 1);
+    ASSERT_EQ(shape.dim(1), 2);
+    ASSERT_EQ(shape.dim(2), 3);
+    ASSERT_EQ(shape.dim(3), 4);
+  }
+
+  // From kernel::Shape
+  {
+    auto shape = morph::as_tensor_shape(kernel::Shape{2, 3, 4, 5});
+
+    ASSERT_EQ(shape.rank(), 4);
+    ASSERT_EQ(shape.dim(0), 2);
+    ASSERT_EQ(shape.dim(1), 3);
+    ASSERT_EQ(shape.dim(2), 4);
+    ASSERT_EQ(shape.dim(3), 5);
+  }
+}