};
/**
+ * @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
} // 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
--- /dev/null
+/*
+ * 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());
+ }
+}