[coco] Channel-wise, Channel-major Feature Layout (#1924)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Mon, 22 Oct 2018 07:01:54 +0000 (16:01 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Mon, 22 Oct 2018 07:01:54 +0000 (16:01 +0900)
* [coco] Channel-wise, Channel-major Feature Layout

This commit introduces BC feature layout which allows users to express
channel-wise, channel-major element layout without performance overhead.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
* Fix a typo

contrib/coco/core/include/coco/IR/FeatureLayouts.h
contrib/coco/core/src/IR/FeatureLayouts.cpp
contrib/coco/core/src/IR/FeatureLayouts.test.cpp [new file with mode: 0644]

index 8244d25..45ff4de 100644 (file)
@@ -86,6 +86,47 @@ public:
 };
 
 /**
+ * @brief BC (Channel-wise Channel-major) Feature Layout
+ *
+ * 1. A layout is said to be channel-wise if the following holds:
+ *
+ *  For each pair of valid feature index I and J,
+ *    at(I) == at(J) if batch(I) == batch(J) and channel(I) == channel(J)
+ *
+ * 2. A layout is said to be channel-major if the followings hold:
+ *
+ *   For each pair of valid feature index I and J,
+ *    at(I) + 1 == at(J) if batch(I) == batch(J) and channel(I) + 1 == channel(J)
+ *
+ *   For each pair of valid feature index I and J,
+ *    at(I) + 1 == at(J) if batch(I) + 1 == batch(J), channel(I) == depth - 1, and channel(J) == 0
+ */
+class BC : public coco::FeatureLayout
+{
+private:
+  BC(uint32_t batch, const FeatureShape &shape) : _batch{batch}, _shape{shape}
+  {
+    // DO NOTHING
+  }
+
+public:
+  static const FeatureLayout::ID *uid(void);
+  const FeatureLayout::ID *id(void) const override { return uid(); }
+
+  uint32_t batch(void) const override { return _batch; }
+  const FeatureShape &shape(void) const override { return _shape; }
+
+  coco::ElemID at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const override;
+
+private:
+  uint32_t _batch;
+  FeatureShape _shape;
+
+public:
+  static std::unique_ptr<BC> create(const FeatureShape &shape);
+};
+
+/**
  * @brief Generic Feature Layout
  */
 class Generic final : public FeatureLayout
index ffe066d..d688c24 100644 (file)
@@ -97,6 +97,42 @@ std::unique_ptr<BHWC> BHWC::create(const nncc::core::ADT::feature::Shape &shape)
 } // namespace coco
 
 //
+// BC: Channel-major Channel-wise Layout
+//
+namespace coco
+{
+namespace FeatureLayouts
+{
+
+const FeatureLayout::ID *BC::uid(void)
+{
+  struct LayoutID final : public FeatureLayout::ID
+  {
+  };
+  static LayoutID id;
+  return &id;
+}
+
+ElemID BC::at(uint32_t b, uint32_t ch, uint32_t row, uint32_t col) const
+{
+  uint32_t offset = 0;
+
+  offset += b * _shape.depth();
+  offset += ch;
+
+  return ElemID{offset};
+}
+
+std::unique_ptr<BC> BC::create(const nncc::core::ADT::feature::Shape &shape)
+{
+  // NOTE It is impossible to use make_unique here as the constructor is private
+  return std::unique_ptr<BC>{new BC{1, shape}};
+}
+
+} // namespace FeatureLayouts
+} // namespace coco
+
+//
 // Generic Layout
 //
 namespace coco
diff --git a/contrib/coco/core/src/IR/FeatureLayouts.test.cpp b/contrib/coco/core/src/IR/FeatureLayouts.test.cpp
new file mode 100644 (file)
index 0000000..18a0f3d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "coco/IR/FeatureLayouts.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT;
+
+TEST(FeatureLayoutsTest, BC)
+{
+  const uint32_t B = 2;
+  const uint32_t C = 3;
+  const uint32_t H = 4;
+  const uint32_t W = 5;
+
+  auto l = coco::FeatureLayouts::BC::create(feature::Shape{C, H, W});
+
+  // Check whether BC layout is actually channel-wise
+  for (uint32_t b = 0; b < B; ++b)
+  {
+    for (uint32_t ch = 0; ch < C; ++ch)
+    {
+      for (uint32_t row = 0; row < H; ++row)
+      {
+        for (uint32_t col = 0; col < W; ++col)
+        {
+          ASSERT_EQ(l->at(b, ch, 0, 0), l->at(b, ch, row, col));
+        }
+      }
+    }
+  }
+
+  // Check whether BC layout is actually channel-major
+  for (uint32_t b = 0; b < B; ++b)
+  {
+    for (uint32_t ch = 1; ch < C; ++ch)
+    {
+      ASSERT_EQ(l->at(b, ch - 1, 0, 0).value() + 1, l->at(b, ch, 0, 0).value());
+    }
+  }
+
+  for (uint32_t b = 1; b < B; ++b)
+  {
+    ASSERT_EQ(l->at(b - 1, C - 1, 0, 0).value() + 1, l->at(b, 0, 0, 0).value());
+  }
+}