summaryrefslogtreecommitdiff
path: root/compiler/angkor/src/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/angkor/src/ADT')
-rw-r--r--compiler/angkor/src/ADT/feature/Accessor.cpp21
-rw-r--r--compiler/angkor/src/ADT/feature/Buffer.test.cpp48
-rw-r--r--compiler/angkor/src/ADT/feature/CHWLayout.cpp43
-rw-r--r--compiler/angkor/src/ADT/feature/CHWLayout.test.cpp45
-rw-r--r--compiler/angkor/src/ADT/feature/HWCLayout.cpp43
-rw-r--r--compiler/angkor/src/ADT/feature/HWCLayout.test.cpp57
-rw-r--r--compiler/angkor/src/ADT/feature/Layout.cpp35
-rw-r--r--compiler/angkor/src/ADT/feature/Layout.test.cpp56
-rw-r--r--compiler/angkor/src/ADT/feature/Overlay.test.cpp72
-rw-r--r--compiler/angkor/src/ADT/feature/Reader.cpp21
-rw-r--r--compiler/angkor/src/ADT/feature/Shape.test.cpp56
-rw-r--r--compiler/angkor/src/ADT/kernel/Buffer.test.cpp49
-rw-r--r--compiler/angkor/src/ADT/kernel/IndexEnumerator.cpp84
-rw-r--r--compiler/angkor/src/ADT/kernel/IndexEnumerator.test.cpp46
-rw-r--r--compiler/angkor/src/ADT/kernel/Layout.cpp38
-rw-r--r--compiler/angkor/src/ADT/kernel/Layout.test.cpp56
-rw-r--r--compiler/angkor/src/ADT/kernel/NCHWLayout.cpp43
-rw-r--r--compiler/angkor/src/ADT/kernel/NCHWLayout.test.cpp53
-rw-r--r--compiler/angkor/src/ADT/kernel/NHWCLayout.cpp43
-rw-r--r--compiler/angkor/src/ADT/kernel/NHWCLayout.test.cpp74
-rw-r--r--compiler/angkor/src/ADT/kernel/Overlay.test.cpp73
-rw-r--r--compiler/angkor/src/ADT/kernel/Reader.cpp20
-rw-r--r--compiler/angkor/src/ADT/kernel/Shape.cpp37
-rw-r--r--compiler/angkor/src/ADT/kernel/Shape.test.cpp58
-rw-r--r--compiler/angkor/src/ADT/tensor/Buffer.test.cpp49
-rw-r--r--compiler/angkor/src/ADT/tensor/Index.cpp81
-rw-r--r--compiler/angkor/src/ADT/tensor/Index.test.cpp119
-rw-r--r--compiler/angkor/src/ADT/tensor/IndexEnumerator.cpp100
-rw-r--r--compiler/angkor/src/ADT/tensor/IndexEnumerator.test.cpp48
-rw-r--r--compiler/angkor/src/ADT/tensor/Layout.cpp35
-rw-r--r--compiler/angkor/src/ADT/tensor/Layout.test.cpp56
-rw-r--r--compiler/angkor/src/ADT/tensor/LexicalLayout.cpp60
-rw-r--r--compiler/angkor/src/ADT/tensor/LexicalLayout.test.cpp54
-rw-r--r--compiler/angkor/src/ADT/tensor/Overlay.test.cpp75
-rw-r--r--compiler/angkor/src/ADT/tensor/Reader.cpp21
-rw-r--r--compiler/angkor/src/ADT/tensor/Shape.cpp91
-rw-r--r--compiler/angkor/src/ADT/tensor/Shape.test.cpp185
37 files changed, 2145 insertions, 0 deletions
diff --git a/compiler/angkor/src/ADT/feature/Accessor.cpp b/compiler/angkor/src/ADT/feature/Accessor.cpp
new file mode 100644
index 000000000..03ff9a31e
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Accessor.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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 "nncc/core/ADT/feature/Accessor.h"
+
+// DO NOT REMOVE THIS FILE
+//
+// This file is introduced to check the self-completeness of 'Accessor.h'
diff --git a/compiler/angkor/src/ADT/feature/Buffer.test.cpp b/compiler/angkor/src/ADT/feature/Buffer.test.cpp
new file mode 100644
index 000000000..1e4430251
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Buffer.test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "nncc/core/ADT/feature/Buffer.h"
+#include "nncc/core/ADT/feature/CHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::feature::Shape;
+using nncc::core::ADT::feature::CHWLayout;
+using nncc::core::ADT::feature::Buffer;
+
+using nncc::core::ADT::feature::make_buffer;
+
+TEST(ADT_FEATURE_BUFFER, ctor)
+{
+ const Shape shape{4, 6, 3};
+ auto buffer = make_buffer<int, CHWLayout>(shape);
+
+ ASSERT_EQ(buffer.shape().depth(), shape.depth());
+ ASSERT_EQ(buffer.shape().height(), shape.height());
+ ASSERT_EQ(buffer.shape().width(), shape.width());
+}
+
+TEST(ADT_FEATURE_BUFFER, access)
+{
+ const Shape shape{4, 6, 3};
+ auto buffer = make_buffer<int, CHWLayout>(shape);
+
+ ASSERT_EQ(buffer.at(3, 5, 2), 0);
+ buffer.at(3, 5, 2) = 4;
+
+ // Casting is introduced to use 'const T &at(...) const' method
+ ASSERT_EQ(static_cast<const Buffer<int> &>(buffer).at(3, 5, 2), 4);
+}
diff --git a/compiler/angkor/src/ADT/feature/CHWLayout.cpp b/compiler/angkor/src/ADT/feature/CHWLayout.cpp
new file mode 100644
index 000000000..31415a1bd
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/CHWLayout.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "nncc/core/ADT/feature/CHWLayout.h"
+
+using nncc::core::ADT::feature::Shape;
+
+static uint32_t CHW_offset(const Shape &shape, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return (ch * shape.height() + row) * shape.width() + col;
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+CHWLayout::CHWLayout() : Layout{CHW_offset}
+{
+ // DO NOTHING
+}
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/feature/CHWLayout.test.cpp b/compiler/angkor/src/ADT/feature/CHWLayout.test.cpp
new file mode 100644
index 000000000..5610df8f3
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/CHWLayout.test.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 "nncc/core/ADT/feature/CHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT::feature;
+
+TEST(ADT_FEATURE_CHW_LAYOUT, col_increase)
+{
+ const Shape shape{4, 3, 6};
+ const CHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 2, 1) + 1, l.offset(shape, 1, 2, 2));
+}
+
+TEST(ADT_FEATURE_CHW_LAYOUT, row_increase)
+{
+ const Shape shape{4, 3, 6};
+ const CHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1) + 6, l.offset(shape, 1, 2, 1));
+}
+
+TEST(ADT_FEATURE_CHW_LAYOUT, ch_increase)
+{
+ const Shape shape{4, 3, 6};
+ const CHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1) + 6 * 3, l.offset(shape, 2, 1, 1));
+}
diff --git a/compiler/angkor/src/ADT/feature/HWCLayout.cpp b/compiler/angkor/src/ADT/feature/HWCLayout.cpp
new file mode 100644
index 000000000..016535625
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/HWCLayout.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "nncc/core/ADT/feature/HWCLayout.h"
+
+using nncc::core::ADT::feature::Shape;
+
+static uint32_t HWC_offset(const Shape &shape, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return (row * shape.width() + col) * shape.depth() + ch;
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+HWCLayout::HWCLayout() : Layout{HWC_offset}
+{
+ // DO NOTHING
+}
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/feature/HWCLayout.test.cpp b/compiler/angkor/src/ADT/feature/HWCLayout.test.cpp
new file mode 100644
index 000000000..d1f359753
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/HWCLayout.test.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "nncc/core/ADT/feature/HWCLayout.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT::feature;
+
+TEST(ADT_FEATURE_HWC_LAYOUT, C_increase)
+{
+ const uint32_t C = 4;
+ const uint32_t H = 3;
+ const uint32_t W = 6;
+
+ const Shape shape{C, H, W};
+ const HWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1) + 1, l.offset(shape, 2, 1, 1));
+}
+
+TEST(ADT_FEATURE_HWC_LAYOUT, W_increase)
+{
+ const uint32_t C = 4;
+ const uint32_t H = 3;
+ const uint32_t W = 6;
+
+ const Shape shape{C, H, W};
+ const HWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 2, 1) + C, l.offset(shape, 1, 2, 2));
+}
+
+TEST(ADT_FEATURE_HWC_LAYOUT, H_increase)
+{
+ const uint32_t C = 4;
+ const uint32_t H = 3;
+ const uint32_t W = 6;
+
+ const Shape shape{C, H, W};
+ const HWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1) + W * C, l.offset(shape, 1, 2, 1));
+}
diff --git a/compiler/angkor/src/ADT/feature/Layout.cpp b/compiler/angkor/src/ADT/feature/Layout.cpp
new file mode 100644
index 000000000..49ab7cbf9
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Layout.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 "nncc/core/ADT/feature/Layout.h"
+
+#include <cassert>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace feature
+{
+
+Layout::Layout(const Func &func) : _func{func} { assert(_func != nullptr); }
+
+} // namespace feature
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/feature/Layout.test.cpp b/compiler/angkor/src/ADT/feature/Layout.test.cpp
new file mode 100644
index 000000000..023594e16
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Layout.test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "nncc/core/ADT/feature/Layout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::feature::Shape;
+using nncc::core::ADT::feature::Layout;
+
+static uint32_t offset_0(const Shape &, uint32_t, uint32_t, uint32_t) { return 0; }
+static uint32_t offset_1(const Shape &, uint32_t, uint32_t, uint32_t) { return 1; }
+
+TEST(ADT_FEATURE_LAYOUT, ctor)
+{
+ Layout l{offset_0};
+
+ ASSERT_EQ(l.offset(Shape{4, 3, 6}, 1, 1, 1), 0);
+}
+
+TEST(ADT_FEATURE_LAYOUT, copy)
+{
+ Layout orig{offset_0};
+ Layout copy{offset_1};
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6}, 1, 1, 1), 1);
+
+ copy = orig;
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6}, 1, 1, 1), 0);
+}
+
+TEST(ADT_FEATURE_LAYOUT, move)
+{
+ Layout orig{offset_0};
+ Layout move{offset_1};
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6}, 1, 1, 1), 1);
+
+ move = std::move(orig);
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6}, 1, 1, 1), 0);
+}
diff --git a/compiler/angkor/src/ADT/feature/Overlay.test.cpp b/compiler/angkor/src/ADT/feature/Overlay.test.cpp
new file mode 100644
index 000000000..c8e2943f8
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Overlay.test.cpp
@@ -0,0 +1,72 @@
+/*
+ * 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 "nncc/core/ADT/feature/Overlay.h"
+#include "nncc/core/ADT/feature/CHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::feature::Shape;
+using nncc::core::ADT::feature::CHWLayout;
+using nncc::core::ADT::feature::Overlay;
+
+using nncc::core::ADT::feature::make_overlay;
+
+TEST(ADT_FEATURE_OVERLAY, ctor)
+{
+ const Shape shape{4, 6, 3};
+
+ int data[4 * 6 * 3] = {
+ 0,
+ };
+ auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+ ASSERT_EQ(overlay.shape().depth(), shape.depth());
+ ASSERT_EQ(overlay.shape().height(), shape.height());
+ ASSERT_EQ(overlay.shape().width(), shape.width());
+}
+
+TEST(ADT_FEATURE_OVERLAY, read)
+{
+ const Shape shape{4, 6, 3};
+
+ int data[4 * 6 * 3] = {
+ 0,
+ };
+ const auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+ CHWLayout layout{};
+
+ ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 0);
+ data[layout.offset(shape, 3, 5, 2)] = 2;
+ ASSERT_EQ(overlay.at(3, 5, 2), 2);
+}
+
+TEST(ADT_FEATURE_OVERLAY, access)
+{
+ const Shape shape{4, 6, 3};
+
+ int data[4 * 6 * 3] = {
+ 0,
+ };
+ auto overlay = make_overlay<int, CHWLayout>(shape, data);
+
+ CHWLayout layout{};
+
+ ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 0);
+ overlay.at(3, 5, 2) = 4;
+ ASSERT_EQ(data[layout.offset(shape, 3, 5, 2)], 4);
+}
diff --git a/compiler/angkor/src/ADT/feature/Reader.cpp b/compiler/angkor/src/ADT/feature/Reader.cpp
new file mode 100644
index 000000000..5f1c0d22b
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Reader.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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 "nncc/core/ADT/feature/Reader.h"
+
+// DO NOT REMOVE THIS FILE
+//
+// This file is introduced to check the self-completeness of 'Reader.h'
diff --git a/compiler/angkor/src/ADT/feature/Shape.test.cpp b/compiler/angkor/src/ADT/feature/Shape.test.cpp
new file mode 100644
index 000000000..9216182f0
--- /dev/null
+++ b/compiler/angkor/src/ADT/feature/Shape.test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 <nncc/core/ADT/feature/Shape.h>
+
+#include <gtest/gtest.h>
+
+TEST(ADT_FEATURE_SHAPE, ctor)
+{
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ nncc::core::ADT::feature::Shape shape{C, H, W};
+
+ ASSERT_EQ(shape.depth(), C);
+ ASSERT_EQ(shape.height(), H);
+ ASSERT_EQ(shape.width(), W);
+}
+
+TEST(ADT_FEATURE_SHAPE, num_elements)
+{
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ using nncc::core::ADT::feature::Shape;
+ using nncc::core::ADT::feature::num_elements;
+
+ ASSERT_EQ(num_elements(Shape{C, H, W}), C * H * W);
+}
+
+TEST(ADT_FEATURE_SHAPE, operator_eq)
+{
+ using nncc::core::ADT::feature::Shape;
+
+ // NOTE We use ASSERT_TRUE/ASSERT_FALSE instead of ASSERT_EQ/ASSERT_NE as it is impossible to
+ // introduce negative tests with ASSERT_NE (it uses operator!= instead of operator==).
+ ASSERT_TRUE(Shape(1, 1, 1) == Shape(1, 1, 1));
+ ASSERT_FALSE(Shape(1, 1, 1) == Shape(2, 1, 1));
+ ASSERT_FALSE(Shape(1, 1, 1) == Shape(1, 2, 1));
+ ASSERT_FALSE(Shape(1, 1, 1) == Shape(1, 1, 2));
+}
diff --git a/compiler/angkor/src/ADT/kernel/Buffer.test.cpp b/compiler/angkor/src/ADT/kernel/Buffer.test.cpp
new file mode 100644
index 000000000..da344593e
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Buffer.test.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Buffer.h"
+#include "nncc/core/ADT/kernel/NCHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::kernel::Shape;
+using nncc::core::ADT::kernel::NCHWLayout;
+using nncc::core::ADT::kernel::Buffer;
+
+using nncc::core::ADT::kernel::make_buffer;
+
+TEST(ADT_KERNEL_BUFFER, ctor)
+{
+ const Shape shape{2, 4, 6, 3};
+ auto buffer = make_buffer<int, NCHWLayout>(shape);
+
+ ASSERT_EQ(buffer.shape().count(), shape.count());
+ ASSERT_EQ(buffer.shape().depth(), shape.depth());
+ ASSERT_EQ(buffer.shape().height(), shape.height());
+ ASSERT_EQ(buffer.shape().width(), shape.width());
+}
+
+TEST(ADT_KERNEL_BUFFER, access)
+{
+ const Shape shape{2, 4, 6, 3};
+ auto buffer = make_buffer<int, NCHWLayout>(shape);
+
+ ASSERT_EQ(buffer.at(1, 3, 5, 2), 0);
+ buffer.at(1, 3, 5, 2) = 4;
+
+ // Casting is introduced to use 'const T &at(...) const' method
+ ASSERT_EQ(static_cast<const Buffer<int> &>(buffer).at(1, 3, 5, 2), 4);
+}
diff --git a/compiler/angkor/src/ADT/kernel/IndexEnumerator.cpp b/compiler/angkor/src/ADT/kernel/IndexEnumerator.cpp
new file mode 100644
index 000000000..0b1db090d
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/IndexEnumerator.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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 "nncc/core/ADT/kernel/IndexEnumerator.h"
+
+#include <cassert>
+#include <algorithm>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace kernel
+{
+
+IndexEnumerator::IndexEnumerator(const Shape &shape) : _cursor(0)
+{
+ _max[0] = shape.width();
+ _max[1] = shape.height();
+ _max[2] = shape.depth();
+ _max[3] = shape.count();
+
+ std::fill(_cur, _cur + 4, 0);
+
+ // NOTE Null dimension should NOT exist
+ assert(std::find(_max, _max + 4, 0) == (_max + 4));
+}
+
+bool IndexEnumerator::valid(void) const { return _cursor < 4; }
+
+uint32_t IndexEnumerator::count(void) const { return _cur[3]; }
+uint32_t IndexEnumerator::depth(void) const { return _cur[2]; }
+uint32_t IndexEnumerator::height(void) const { return _cur[1]; }
+uint32_t IndexEnumerator::width(void) const { return _cur[0]; }
+
+void IndexEnumerator::advance(void)
+{
+ while (_cursor < 4)
+ {
+ if (_cur[_cursor] + 1 < _max[_cursor])
+ {
+ break;
+ }
+
+ ++_cursor;
+ }
+
+ if (_cursor == 4)
+ {
+ return;
+ }
+
+ // Increment index
+ _cur[_cursor] += 1;
+
+ // Reset indices for lower dimensions
+ for (uint32_t head = 0; head < _cursor; ++head)
+ {
+ _cur[head] = 0;
+ }
+
+ // Reset cursor
+ _cursor = 0;
+}
+
+} // namespace kernel
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/kernel/IndexEnumerator.test.cpp b/compiler/angkor/src/ADT/kernel/IndexEnumerator.test.cpp
new file mode 100644
index 000000000..21ba19209
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/IndexEnumerator.test.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "nncc/core/ADT/kernel/IndexEnumerator.h"
+
+#include <vector>
+#include <algorithm>
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::kernel::Shape;
+using nncc::core::ADT::kernel::IndexEnumerator;
+
+TEST(ADT_KERNEL_INDEX_ENUMERATOR, iterate_full_range)
+{
+ const uint32_t N = 2;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ const Shape shape{N, C, H, W};
+
+ std::vector<uint32_t> count;
+ count.resize(N * C * H * W, 0);
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ const uint32_t offset = ((e.count() * C + e.depth()) * H + e.height()) * W + e.width();
+ count.at(offset) += 1;
+ }
+
+ ASSERT_TRUE(std::all_of(count.begin(), count.end(), [](uint32_t n) { return n == 1; }));
+}
diff --git a/compiler/angkor/src/ADT/kernel/Layout.cpp b/compiler/angkor/src/ADT/kernel/Layout.cpp
new file mode 100644
index 000000000..acadd2448
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Layout.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Layout.h"
+
+#include <cassert>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace kernel
+{
+
+Layout::Layout(const Func &func) : _func{func}
+{
+ // DO NOTHING
+}
+
+} // namespace kernel
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/kernel/Layout.test.cpp b/compiler/angkor/src/ADT/kernel/Layout.test.cpp
new file mode 100644
index 000000000..94885cd4e
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Layout.test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Layout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::kernel::Shape;
+using nncc::core::ADT::kernel::Layout;
+
+static uint32_t offset_0(const Shape &, uint32_t, uint32_t, uint32_t, uint32_t) { return 0; }
+static uint32_t offset_1(const Shape &, uint32_t, uint32_t, uint32_t, uint32_t) { return 1; }
+
+TEST(ADT_KERNEL_LAYOUT, ctor)
+{
+ Layout l{offset_0};
+
+ ASSERT_EQ(l.offset(Shape{4, 3, 6, 5}, 1, 1, 1, 1), 0);
+}
+
+TEST(ADT_KERNEL_LAYOUT, copy)
+{
+ Layout orig{offset_0};
+ Layout copy{offset_1};
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6, 5}, 1, 1, 1, 1), 1);
+
+ copy = orig;
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6, 5}, 1, 1, 1, 1), 0);
+}
+
+TEST(ADT_KERNEL_LAYOUT, move)
+{
+ Layout orig{offset_0};
+ Layout move{offset_1};
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6, 5}, 1, 1, 1, 1), 1);
+
+ move = std::move(orig);
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6, 5}, 1, 1, 1, 1), 0);
+}
diff --git a/compiler/angkor/src/ADT/kernel/NCHWLayout.cpp b/compiler/angkor/src/ADT/kernel/NCHWLayout.cpp
new file mode 100644
index 000000000..be7551182
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/NCHWLayout.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "nncc/core/ADT/kernel/NCHWLayout.h"
+
+using nncc::core::ADT::kernel::Shape;
+
+static uint32_t NCHW_offset(const Shape &shape, uint32_t n, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return (((n * shape.depth() + ch) * shape.height() + row) * shape.width() + col);
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace kernel
+{
+
+NCHWLayout::NCHWLayout() : Layout{NCHW_offset}
+{
+ // DO NOTHING
+}
+
+} // namespace kernel
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/kernel/NCHWLayout.test.cpp b/compiler/angkor/src/ADT/kernel/NCHWLayout.test.cpp
new file mode 100644
index 000000000..ba03b7b04
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/NCHWLayout.test.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 "nncc/core/ADT/kernel/NCHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using namespace nncc::core::ADT::kernel;
+
+TEST(ADT_KERNEL_KERNEL_NCHW_LAYOUT, col_increment)
+{
+ const Shape shape{4, 3, 6, 5};
+ const NCHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + 1, l.offset(shape, 1, 1, 1, 2));
+}
+
+TEST(ADT_KERNEL_KERNEL_NCHW_LAYOUT, row_increment)
+{
+ const Shape shape{4, 3, 6, 5};
+ const NCHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + 5, l.offset(shape, 1, 1, 2, 1));
+}
+
+TEST(ADT_KERNEL_KERNEL_NCHW_LAYOUT, ch_increment)
+{
+ const Shape shape{4, 3, 6, 5};
+ const NCHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + 6 * 5, l.offset(shape, 1, 2, 1, 1));
+}
+
+TEST(ADT_KERNEL_KERNEL_NCHW_LAYOUT, n_increment)
+{
+ const Shape shape{4, 3, 6, 5};
+ const NCHWLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + 3 * 6 * 5, l.offset(shape, 2, 1, 1, 1));
+}
diff --git a/compiler/angkor/src/ADT/kernel/NHWCLayout.cpp b/compiler/angkor/src/ADT/kernel/NHWCLayout.cpp
new file mode 100644
index 000000000..8e0524425
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/NHWCLayout.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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 "nncc/core/ADT/kernel/NHWCLayout.h"
+
+using nncc::core::ADT::kernel::Shape;
+
+static uint32_t NHWC_offset(const Shape &shape, uint32_t n, uint32_t ch, uint32_t row, uint32_t col)
+{
+ return ((n * shape.height() + row) * shape.width() + col) * shape.depth() + ch;
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace kernel
+{
+
+NHWCLayout::NHWCLayout() : Layout{NHWC_offset}
+{
+ // DO NOTHING
+}
+
+} // namespace kernel
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/kernel/NHWCLayout.test.cpp b/compiler/angkor/src/ADT/kernel/NHWCLayout.test.cpp
new file mode 100644
index 000000000..2c5df7d89
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/NHWCLayout.test.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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 "nncc/core/ADT/kernel/NHWCLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::kernel::Shape;
+using nncc::core::ADT::kernel::NHWCLayout;
+
+TEST(ADT_KERNEL_KERNEL_NHWC_LAYOUT, ch_increment)
+{
+ const uint32_t N = 4;
+ const uint32_t C = 3;
+ const uint32_t H = 6;
+ const uint32_t W = 5;
+
+ const Shape shape{N, C, H, W};
+ const NHWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + 1, l.offset(shape, 1, 2, 1, 1));
+}
+
+TEST(ADT_KERNEL_KERNEL_NHWC_LAYOUT, col_increment)
+{
+ const uint32_t N = 4;
+ const uint32_t C = 3;
+ const uint32_t H = 6;
+ const uint32_t W = 5;
+
+ const Shape shape{N, C, H, W};
+ const NHWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + C, l.offset(shape, 1, 1, 1, 2));
+}
+
+TEST(ADT_KERNEL_KERNEL_NHWC_LAYOUT, row_increment)
+{
+ const uint32_t N = 4;
+ const uint32_t C = 3;
+ const uint32_t H = 6;
+ const uint32_t W = 5;
+
+ const Shape shape{N, C, H, W};
+ const NHWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + C * W, l.offset(shape, 1, 1, 2, 1));
+}
+
+TEST(ADT_KERNEL_KERNEL_NHWC_LAYOUT, n_increment)
+{
+ const uint32_t N = 4;
+ const uint32_t C = 3;
+ const uint32_t H = 6;
+ const uint32_t W = 5;
+
+ const Shape shape{N, C, H, W};
+ const NHWCLayout l;
+
+ ASSERT_EQ(l.offset(shape, 1, 1, 1, 1) + H * W * C, l.offset(shape, 2, 1, 1, 1));
+}
diff --git a/compiler/angkor/src/ADT/kernel/Overlay.test.cpp b/compiler/angkor/src/ADT/kernel/Overlay.test.cpp
new file mode 100644
index 000000000..e80ebbc30
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Overlay.test.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Overlay.h"
+#include "nncc/core/ADT/kernel/NCHWLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::kernel::Shape;
+using nncc::core::ADT::kernel::NCHWLayout;
+using nncc::core::ADT::kernel::Overlay;
+
+using nncc::core::ADT::kernel::make_overlay;
+
+TEST(ADT_KERNEL_OVERLAY, ctor)
+{
+ const Shape shape{2, 4, 6, 3};
+
+ int data[2 * 4 * 6 * 3] = {
+ 0,
+ };
+ auto overlay = make_overlay<int, NCHWLayout>(shape, data);
+
+ ASSERT_EQ(overlay.shape().count(), shape.count());
+ ASSERT_EQ(overlay.shape().depth(), shape.depth());
+ ASSERT_EQ(overlay.shape().height(), shape.height());
+ ASSERT_EQ(overlay.shape().width(), shape.width());
+}
+
+TEST(ADT_KERNEL_OVERLAY, read)
+{
+ const Shape shape{2, 4, 6, 3};
+
+ int data[2 * 4 * 6 * 3] = {
+ 0,
+ };
+ const auto overlay = make_overlay<int, NCHWLayout>(shape, data);
+
+ NCHWLayout layout{};
+
+ ASSERT_EQ(data[layout.offset(shape, 1, 3, 5, 2)], 0);
+ data[layout.offset(shape, 1, 3, 5, 2)] = 2;
+ ASSERT_EQ(overlay.at(1, 3, 5, 2), 2);
+}
+
+TEST(ADT_KERNEL_OVERLAY, access)
+{
+ const Shape shape{2, 4, 6, 3};
+
+ int data[2 * 4 * 6 * 3] = {
+ 0,
+ };
+ auto overlay = make_overlay<int, NCHWLayout>(shape, data);
+
+ NCHWLayout layout{};
+
+ ASSERT_EQ(data[layout.offset(shape, 1, 3, 5, 2)], 0);
+ overlay.at(1, 3, 5, 2) = 4;
+ ASSERT_EQ(data[layout.offset(shape, 1, 3, 5, 2)], 4);
+}
diff --git a/compiler/angkor/src/ADT/kernel/Reader.cpp b/compiler/angkor/src/ADT/kernel/Reader.cpp
new file mode 100644
index 000000000..9e34167c8
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Reader.cpp
@@ -0,0 +1,20 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Reader.h"
+
+// DO NOT REMOVE THIS FILE
+// This file is introduced to test the self-completeness of 'Reader.h'
diff --git a/compiler/angkor/src/ADT/kernel/Shape.cpp b/compiler/angkor/src/ADT/kernel/Shape.cpp
new file mode 100644
index 000000000..8ad1edb67
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Shape.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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 "nncc/core/ADT/kernel/Shape.h"
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace kernel
+{
+
+bool operator==(const Shape &l, const Shape &r)
+{
+ return (l.count() == r.count()) && (l.depth() == r.depth()) && (l.height() == r.height()) &&
+ (l.width() == r.width());
+}
+
+} // namespace kernel
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/kernel/Shape.test.cpp b/compiler/angkor/src/ADT/kernel/Shape.test.cpp
new file mode 100644
index 000000000..da608fb7f
--- /dev/null
+++ b/compiler/angkor/src/ADT/kernel/Shape.test.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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 <nncc/core/ADT/kernel/Shape.h>
+
+#include <gtest/gtest.h>
+
+TEST(ADT_KERNEL_SHAPE, ctor)
+{
+ const uint32_t N = 1;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ nncc::core::ADT::kernel::Shape shape{N, C, H, W};
+
+ ASSERT_EQ(shape.count(), N);
+ ASSERT_EQ(shape.depth(), C);
+ ASSERT_EQ(shape.height(), H);
+ ASSERT_EQ(shape.width(), W);
+}
+
+TEST(ADT_KERNEL_SHAPE, num_elements)
+{
+ const uint32_t N = 1;
+ const uint32_t C = 3;
+ const uint32_t H = 4;
+ const uint32_t W = 5;
+
+ using nncc::core::ADT::kernel::Shape;
+ using nncc::core::ADT::kernel::num_elements;
+
+ ASSERT_EQ(num_elements(Shape{N, C, H, W}), N * C * H * W);
+}
+
+TEST(ADT_KERNEL_SHAPE, operator_eq)
+{
+ using nncc::core::ADT::kernel::Shape;
+
+ EXPECT_TRUE(Shape(1, 1, 1, 1) == Shape(1, 1, 1, 1));
+ EXPECT_FALSE(Shape(1, 1, 1, 1) == Shape(1, 1, 1, 2));
+ EXPECT_FALSE(Shape(1, 1, 1, 1) == Shape(1, 1, 2, 1));
+ EXPECT_FALSE(Shape(1, 1, 1, 1) == Shape(1, 2, 1, 1));
+ EXPECT_FALSE(Shape(1, 1, 1, 1) == Shape(2, 1, 1, 1));
+}
diff --git a/compiler/angkor/src/ADT/tensor/Buffer.test.cpp b/compiler/angkor/src/ADT/tensor/Buffer.test.cpp
new file mode 100644
index 000000000..c2b6a9983
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Buffer.test.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Buffer.h"
+#include "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::LexicalLayout;
+using nncc::core::ADT::tensor::Buffer;
+
+using nncc::core::ADT::tensor::make_buffer;
+
+TEST(ADT_TENSOR_BUFFER, ctor)
+{
+ const Shape shape{2, 3};
+ auto buffer = make_buffer<int, LexicalLayout>(shape);
+
+ ASSERT_EQ(buffer.shape(), shape);
+}
+
+TEST(ADT_TENSOR_BUFFER, access)
+{
+ const Shape shape{2, 3};
+ auto buffer = make_buffer<int, LexicalLayout>(shape);
+
+ const Index index{1, 2};
+
+ ASSERT_EQ(buffer.at(index), 0);
+ buffer.at(index) = 4;
+
+ // Casting is introduced to use 'const T &at(...) const' method
+ ASSERT_EQ(static_cast<const Buffer<int> &>(buffer).at(index), 4);
+}
diff --git a/compiler/angkor/src/ADT/tensor/Index.cpp b/compiler/angkor/src/ADT/tensor/Index.cpp
new file mode 100644
index 000000000..61f0a7106
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Index.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Index.h"
+
+#include <stdexcept>
+#include <algorithm>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+Index::Index(std::initializer_list<uint32_t> &&l) : _indices{l}
+{
+ // DO NOTHING
+}
+
+uint32_t Index::rank(void) const { return _indices.size(); }
+Index &Index::resize(uint32_t size)
+{
+ _indices.resize(size);
+ return *this;
+}
+
+Index &Index::fill(uint32_t index)
+{
+ std::fill(_indices.begin(), _indices.end(), index);
+ return (*this);
+}
+
+uint32_t &Index::at(uint32_t axis) { return _indices.at(axis); }
+uint32_t Index::at(uint32_t axis) const { return _indices.at(axis); }
+
+Index operator+(const Index &lhs, const Index &rhs)
+{
+ if (lhs.rank() != rhs.rank())
+ throw std::runtime_error("Two tensors should have same rank");
+
+ Index ret;
+ ret.resize(lhs.rank());
+ for (uint32_t axis = 0; axis < lhs.rank(); axis++)
+ {
+ ret.at(axis) = lhs.at(axis) + rhs.at(axis);
+ }
+ return ret;
+}
+
+bool operator==(const Index &lhs, const Index &rhs)
+{
+ if (lhs.rank() != rhs.rank())
+ return false;
+ for (uint32_t axis = 0; axis < lhs.rank(); axis++)
+ {
+ if (lhs.at(axis) != rhs.at(axis))
+ return false;
+ }
+ return true;
+}
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/tensor/Index.test.cpp b/compiler/angkor/src/ADT/tensor/Index.test.cpp
new file mode 100644
index 000000000..230602816
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Index.test.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Index.h"
+
+#include <gtest/gtest.h>
+
+TEST(ADT_TENSOR_INDEX, ctor)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ ASSERT_EQ(index.rank(), 0);
+}
+
+TEST(ADT_TENSOR_INDEX, ctor_initializer_list)
+{
+ const nncc::core::ADT::tensor::Index index{1, 3, 5, 7};
+
+ ASSERT_EQ(index.rank(), 4);
+
+ ASSERT_EQ(index.at(0), 1);
+ ASSERT_EQ(index.at(1), 3);
+ ASSERT_EQ(index.at(2), 5);
+ ASSERT_EQ(index.at(3), 7);
+}
+
+TEST(ADT_TENSOR_INDEX, operator_add)
+{
+ nncc::core::ADT::tensor::Index index1{1, 2, 3, 4};
+ nncc::core::ADT::tensor::Index index2{5, 6, 7, 8};
+ nncc::core::ADT::tensor::Index result{index1 + index2};
+
+ ASSERT_EQ(result.at(0), 6);
+ ASSERT_EQ(result.at(1), 8);
+ ASSERT_EQ(result.at(2), 10);
+ ASSERT_EQ(result.at(3), 12);
+}
+
+TEST(ADT_TENSOR_INDEX, operator_eqaul)
+{
+ nncc::core::ADT::tensor::Index index1{1, 2, 3, 4};
+ nncc::core::ADT::tensor::Index index2{1, 2, 3, 4};
+ nncc::core::ADT::tensor::Index index3{5, 6, 7, 8};
+ nncc::core::ADT::tensor::Index index4{1, 2};
+
+ ASSERT_TRUE(index1 == index2);
+ ASSERT_FALSE(index1 == index3);
+ ASSERT_FALSE(index1 == index4);
+}
+
+TEST(ADT_TENSOR_INDEX, operator_add_different_size)
+{
+ nncc::core::ADT::tensor::Index index1{1, 2, 3, 4};
+ nncc::core::ADT::tensor::Index index2{5, 6};
+
+ EXPECT_THROW(index1 + index2, std::runtime_error);
+}
+
+TEST(ADT_TENSOR_INDEX, resize)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ index.resize(4);
+
+ ASSERT_EQ(index.rank(), 4);
+}
+
+TEST(ADT_TENSOR_INDEX, at)
+{
+ nncc::core::ADT::tensor::Index index;
+
+ index.resize(4);
+
+ uint32_t indices[4] = {3, 5, 2, 7};
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ index.at(axis) = indices[axis];
+ ASSERT_EQ(index.at(axis), indices[axis]);
+ }
+}
+
+TEST(ADT_TENSOR_INDEX, copy)
+{
+ const nncc::core::ADT::tensor::Index original{3, 5, 2, 7};
+ const nncc::core::ADT::tensor::Index copied{original};
+
+ ASSERT_EQ(original.rank(), copied.rank());
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ ASSERT_EQ(original.at(axis), copied.at(axis));
+ }
+}
+
+TEST(ADT_TENSOR_INDEX, fill)
+{
+ nncc::core::ADT::tensor::Index index{1, 6};
+
+ index.fill(3);
+
+ ASSERT_EQ(index.rank(), 2);
+
+ ASSERT_EQ(index.at(0), 3);
+ ASSERT_EQ(index.at(1), 3);
+}
diff --git a/compiler/angkor/src/ADT/tensor/IndexEnumerator.cpp b/compiler/angkor/src/ADT/tensor/IndexEnumerator.cpp
new file mode 100644
index 000000000..623313a2e
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/IndexEnumerator.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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 "nncc/core/ADT/tensor/IndexEnumerator.h"
+
+#include <cassert>
+
+using nncc::core::ADT::tensor::Shape;
+
+inline uint32_t axis_of(const Shape &shape, uint32_t cursor)
+{
+ const uint32_t rank = shape.rank();
+ assert(cursor < rank);
+ return rank - cursor - 1;
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+IndexEnumerator::IndexEnumerator(const Shape &shape) : _shape{shape}, _cursor(0)
+{
+ const uint32_t rank = _shape.rank();
+
+ // Initialize _index
+ _index.resize(rank);
+ for (uint32_t axis = 0; axis < rank; ++axis)
+ {
+ _index.at(axis) = 0;
+ }
+
+ // Initialize _cursor
+ for (_cursor = 0; _cursor < rank; ++_cursor)
+ {
+ const auto axis = axis_of(_shape, _cursor);
+
+ if (_index.at(axis) < _shape.dim(axis))
+ {
+ break;
+ }
+ }
+}
+
+void IndexEnumerator::advance(void)
+{
+ const uint32_t rank = _shape.rank();
+
+ // Find axis to be updated
+ while (_cursor < rank)
+ {
+ const auto axis = axis_of(_shape, _cursor);
+
+ if ((_index.at(axis)) + 1 < _shape.dim(axis))
+ {
+ break;
+ }
+
+ ++_cursor;
+ }
+
+ if (_cursor == rank)
+ {
+ return;
+ }
+
+ // Update index
+ _index.at(axis_of(_shape, _cursor)) += 1;
+
+ for (uint32_t pos = 0; pos < _cursor; ++pos)
+ {
+ const auto axis = axis_of(_shape, pos);
+ _index.at(axis) = 0;
+ }
+
+ // Reset cursor
+ _cursor = 0;
+}
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/tensor/IndexEnumerator.test.cpp b/compiler/angkor/src/ADT/tensor/IndexEnumerator.test.cpp
new file mode 100644
index 000000000..204a8aa21
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/IndexEnumerator.test.cpp
@@ -0,0 +1,48 @@
+/*
+ * 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 "nncc/core/ADT/tensor/IndexEnumerator.h"
+
+#include <vector>
+#include <algorithm>
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::IndexEnumerator;
+
+TEST(ADT_TENSOR_INDEX_ENUMERATOR, iterate_full_range)
+{
+ const uint32_t H = 3;
+ const uint32_t W = 4;
+
+ const Shape shape{H, W};
+
+ std::vector<uint32_t> count;
+
+ count.resize(H * W, 0);
+
+ for (IndexEnumerator e{shape}; e.valid(); e.advance())
+ {
+ const auto &ind = e.current();
+
+ ASSERT_EQ(ind.rank(), 2);
+ count.at(ind.at(0) * W + ind.at(1)) += 1;
+ }
+
+ ASSERT_TRUE(std::all_of(count.begin(), count.end(), [](uint32_t n) { return n == 1; }));
+}
diff --git a/compiler/angkor/src/ADT/tensor/Layout.cpp b/compiler/angkor/src/ADT/tensor/Layout.cpp
new file mode 100644
index 000000000..7faf7507d
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Layout.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Layout.h"
+
+#include <cassert>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+Layout::Layout(const Func &func) : _func{func} { assert(_func != nullptr); }
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/tensor/Layout.test.cpp b/compiler/angkor/src/ADT/tensor/Layout.test.cpp
new file mode 100644
index 000000000..145adfecc
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Layout.test.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Layout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+
+static uint32_t offset_0(const Shape &, const Index &) { return 0; }
+static uint32_t offset_1(const Shape &, const Index &) { return 1; }
+
+TEST(ADT_TENSOR_LAYOUT, ctor)
+{
+ nncc::core::ADT::tensor::Layout l{offset_0};
+
+ ASSERT_EQ(l.offset(Shape{4, 3, 6}, Index{1, 1, 1}), 0);
+}
+
+TEST(ADT_TENSOR_LAYOUT, copy)
+{
+ nncc::core::ADT::tensor::Layout orig{offset_0};
+ nncc::core::ADT::tensor::Layout copy{offset_1};
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6}, Index{1, 1, 1}), 1);
+
+ copy = orig;
+
+ ASSERT_EQ(copy.offset(Shape{4, 3, 6}, Index{1, 1, 1}), 0);
+}
+
+TEST(ADT_TENSOR_LAYOUT, move)
+{
+ nncc::core::ADT::tensor::Layout orig{offset_0};
+ nncc::core::ADT::tensor::Layout move{offset_1};
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6}, Index{1, 1, 1}), 1);
+
+ move = std::move(orig);
+
+ ASSERT_EQ(move.offset(Shape{4, 3, 6}, Index{1, 1, 1}), 0);
+}
diff --git a/compiler/angkor/src/ADT/tensor/LexicalLayout.cpp b/compiler/angkor/src/ADT/tensor/LexicalLayout.cpp
new file mode 100644
index 000000000..671c60cec
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/LexicalLayout.cpp
@@ -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 "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <cassert>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+
+// NOTE This forward declaration is introduced to minimize code diff
+static uint32_t lexical_offset(const Shape &shape, const Index &index)
+{
+ assert(shape.rank() > 0);
+ assert(shape.rank() == index.rank());
+
+ const uint32_t rank = shape.rank();
+
+ uint32_t res = index.at(0);
+
+ for (uint32_t axis = 1; axis < rank; ++axis)
+ {
+ res *= shape.dim(axis);
+ res += index.at(axis);
+ }
+
+ return res;
+}
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+LexicalLayout::LexicalLayout() : Layout(lexical_offset)
+{
+ // DO NOTHING
+}
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/tensor/LexicalLayout.test.cpp b/compiler/angkor/src/ADT/tensor/LexicalLayout.test.cpp
new file mode 100644
index 000000000..8f9b7296f
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/LexicalLayout.test.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <type_traits>
+
+#include <gtest/gtest.h>
+
+TEST(ADT_TENSOR_LEXICAL_LAYOUT, last)
+{
+ const nncc::core::ADT::tensor::Shape shape{4, 3, 6};
+ const nncc::core::ADT::tensor::Index curr{1, 1, 1};
+ const nncc::core::ADT::tensor::Index next{1, 1, 2};
+
+ const nncc::core::ADT::tensor::LexicalLayout l;
+
+ ASSERT_EQ(l.offset(shape, curr) + 1, l.offset(shape, next));
+}
+
+TEST(ADT_TENSOR_LEXICAL_LAYOUT, lexical_middle)
+{
+ const nncc::core::ADT::tensor::Shape shape{4, 3, 6};
+ const nncc::core::ADT::tensor::Index curr{1, 1, 1};
+ const nncc::core::ADT::tensor::Index next{1, 2, 1};
+
+ const nncc::core::ADT::tensor::LexicalLayout l;
+
+ ASSERT_EQ(l.offset(shape, curr) + 6, l.offset(shape, next));
+}
+
+TEST(ADT_TENSOR_LEXICAL_LAYOUT, lexical_first)
+{
+ const nncc::core::ADT::tensor::Shape shape{4, 3, 6};
+ const nncc::core::ADT::tensor::Index curr{1, 1, 1};
+ const nncc::core::ADT::tensor::Index next{2, 1, 1};
+
+ const nncc::core::ADT::tensor::LexicalLayout l;
+
+ ASSERT_EQ(l.offset(shape, curr) + 6 * 3, l.offset(shape, next));
+}
diff --git a/compiler/angkor/src/ADT/tensor/Overlay.test.cpp b/compiler/angkor/src/ADT/tensor/Overlay.test.cpp
new file mode 100644
index 000000000..aacb5a9a1
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Overlay.test.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Overlay.h"
+#include "nncc/core/ADT/tensor/LexicalLayout.h"
+
+#include <gtest/gtest.h>
+
+using nncc::core::ADT::tensor::Shape;
+using nncc::core::ADT::tensor::Index;
+using nncc::core::ADT::tensor::LexicalLayout;
+using nncc::core::ADT::tensor::Overlay;
+
+using nncc::core::ADT::tensor::make_overlay;
+
+TEST(ADT_TENSOR_OVERLAY, ctor)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ ASSERT_EQ(view.shape(), shape);
+}
+
+TEST(ADT_TENSOR_OVERLAY, read)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ const auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ LexicalLayout layout{};
+
+ const Index index{1, 2};
+
+ ASSERT_EQ(data[layout.offset(shape, index)], 0);
+ data[layout.offset(shape, index)] = 2;
+ ASSERT_EQ(view.at(index), 2);
+}
+
+TEST(ADT_TENSOR_OVERLAY, access)
+{
+ const Shape shape{2, 3};
+
+ int data[2 * 3] = {
+ 0,
+ };
+ auto view = make_overlay<int, LexicalLayout>(shape, data);
+
+ LexicalLayout layout{};
+
+ const Index index{1, 2};
+
+ ASSERT_EQ(data[layout.offset(shape, index)], 0);
+ view.at(index) = 4;
+ ASSERT_EQ(data[layout.offset(shape, index)], 4);
+}
diff --git a/compiler/angkor/src/ADT/tensor/Reader.cpp b/compiler/angkor/src/ADT/tensor/Reader.cpp
new file mode 100644
index 000000000..d79e66dac
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Reader.cpp
@@ -0,0 +1,21 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Reader.h"
+
+// DO NOT REMOVE THIS FILE
+//
+// This file is introduced to check the self-completeness of 'Reader.h'
diff --git a/compiler/angkor/src/ADT/tensor/Shape.cpp b/compiler/angkor/src/ADT/tensor/Shape.cpp
new file mode 100644
index 000000000..fb39ba192
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Shape.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Shape.h"
+
+#include <algorithm>
+
+namespace nncc
+{
+namespace core
+{
+namespace ADT
+{
+namespace tensor
+{
+
+Shape::Shape(std::initializer_list<uint32_t> &&l) : _dims{l}
+{
+ // DO NOTHING
+}
+
+uint32_t Shape::rank(void) const { return _dims.size(); }
+Shape &Shape::resize(uint32_t size)
+{
+ _dims.resize(size);
+ return *this;
+}
+
+uint32_t &Shape::dim(uint32_t axis) { return _dims.at(axis); }
+uint32_t Shape::dim(uint32_t axis) const { return _dims.at(axis); }
+
+Shape &Shape::squeeze(void)
+{
+ _dims.erase(std::remove(_dims.begin(), _dims.end(), 1), _dims.end());
+ return *this;
+}
+
+uint64_t num_elements(const Shape &shape)
+{
+ uint64_t res = 1;
+
+ for (uint32_t axis = 0; axis < shape.rank(); ++axis)
+ {
+ res *= shape.dim(axis);
+ }
+
+ return res;
+}
+
+Shape squeeze(const Shape &shape)
+{
+ Shape res{shape};
+ res.squeeze();
+ return res;
+}
+
+bool operator==(const Shape &lhs, const Shape &rhs)
+{
+ if (lhs.rank() != rhs.rank())
+ {
+ return false;
+ }
+
+ for (uint32_t axis = 0; axis < lhs.rank(); ++axis)
+ {
+ if (lhs.dim(axis) != rhs.dim(axis))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace tensor
+} // namespace ADT
+} // namespace core
+} // namespace nncc
diff --git a/compiler/angkor/src/ADT/tensor/Shape.test.cpp b/compiler/angkor/src/ADT/tensor/Shape.test.cpp
new file mode 100644
index 000000000..711ae3d40
--- /dev/null
+++ b/compiler/angkor/src/ADT/tensor/Shape.test.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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 "nncc/core/ADT/tensor/Shape.h"
+
+#include <gtest/gtest.h>
+
+TEST(ADT_TENSOR_SHAPE, ctor)
+{
+ nncc::core::ADT::tensor::Shape shape;
+
+ ASSERT_EQ(shape.rank(), 0);
+}
+
+TEST(ADT_TENSOR_SHAPE, ctor_initializer_list)
+{
+ nncc::core::ADT::tensor::Shape shape{1, 3, 5, 7};
+
+ ASSERT_EQ(shape.rank(), 4);
+
+ ASSERT_EQ(shape.dim(0), 1);
+ ASSERT_EQ(shape.dim(1), 3);
+ ASSERT_EQ(shape.dim(2), 5);
+ ASSERT_EQ(shape.dim(3), 7);
+}
+
+TEST(ADT_TENSOR_SHAPE, resize)
+{
+ nncc::core::ADT::tensor::Shape shape;
+
+ shape.resize(4);
+
+ ASSERT_EQ(shape.rank(), 4);
+}
+
+TEST(ADT_TENSOR_SHAPE, dim)
+{
+ nncc::core::ADT::tensor::Shape shape;
+
+ shape.resize(4);
+
+ uint32_t dims[4] = {3, 5, 2, 7};
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ shape.dim(axis) = dims[axis];
+ ASSERT_EQ(shape.dim(axis), dims[axis]);
+ }
+}
+
+TEST(ADT_TENSOR_SHAPE, copy)
+{
+ const nncc::core::ADT::tensor::Shape original{3, 5, 2, 7};
+ const nncc::core::ADT::tensor::Shape copied{original};
+
+ ASSERT_EQ(original.rank(), copied.rank());
+
+ for (uint32_t axis = 0; axis < 4; ++axis)
+ {
+ ASSERT_EQ(original.dim(axis), copied.dim(axis));
+ }
+}
+
+TEST(ADT_TENSOR_SHAPE, num_elements_rank_0)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::num_elements;
+
+ Shape rank_0_shape;
+
+ ASSERT_EQ(num_elements(rank_0_shape), 1);
+}
+
+TEST(ADT_TENSOR_SHAPE, num_elements_zero)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::num_elements;
+
+ ASSERT_EQ(num_elements(Shape{0, 0, 0, 0}), 0);
+}
+
+TEST(ADT_TENSOR_SHAPE, num_elements_nonzero)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::num_elements;
+
+ ASSERT_EQ(num_elements(Shape{2, 3}), 6);
+}
+
+TEST(ADT_TENSOR_SHAPE, num_elements_nulldim)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::num_elements;
+
+ ASSERT_EQ(num_elements(Shape{2, 0, 3}), 0);
+}
+
+TEST(ADT_TENSOR_SHAPE, squeeze_neg)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::squeeze;
+
+ auto squeezed = squeeze(Shape{3, 5, 2});
+
+ ASSERT_EQ(squeezed.rank(), 3);
+ ASSERT_EQ(squeezed.dim(0), 3);
+ ASSERT_EQ(squeezed.dim(1), 5);
+ ASSERT_EQ(squeezed.dim(2), 2);
+}
+
+TEST(ADT_TENSOR_SHAPE, squeeze_neg_0)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::squeeze;
+
+ auto squeezed = squeeze(Shape{3, 0, 2});
+
+ ASSERT_EQ(squeezed.rank(), 3);
+ ASSERT_EQ(squeezed.dim(0), 3);
+ ASSERT_EQ(squeezed.dim(1), 0);
+ ASSERT_EQ(squeezed.dim(2), 2);
+}
+
+TEST(ADT_TENSOR_SHAPE, squeeze_pos)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::squeeze;
+
+ auto squeezed = squeeze(Shape{3, 1, 2});
+
+ ASSERT_EQ(squeezed.rank(), 2);
+ ASSERT_EQ(squeezed.dim(0), 3);
+ ASSERT_EQ(squeezed.dim(1), 2);
+}
+
+TEST(ADT_TENSOR_SHAPE, squeeze_nested)
+{
+ using nncc::core::ADT::tensor::Shape;
+ using nncc::core::ADT::tensor::squeeze;
+
+ Shape shape{3, 1, 2};
+
+ shape.squeeze().squeeze();
+
+ ASSERT_EQ(shape.rank(), 2);
+ ASSERT_EQ(shape.dim(0), 3);
+ ASSERT_EQ(shape.dim(1), 2);
+}
+
+TEST(ADT_TENSOR_SHAPE, eq_negative_on_unmatched_rank)
+{
+ const nncc::core::ADT::tensor::Shape left{1, 1, 1};
+ const nncc::core::ADT::tensor::Shape right{1, 1, 1, 1};
+
+ ASSERT_FALSE(left == right);
+}
+
+TEST(ADT_TENSOR_SHAPE, eq_negative_on_unmatched_dim)
+{
+ const nncc::core::ADT::tensor::Shape left{2, 3};
+ const nncc::core::ADT::tensor::Shape right{2, 4};
+
+ ASSERT_FALSE(left == right);
+}
+
+TEST(ADT_TENSOR_SHAPE, eq_positive)
+{
+ const nncc::core::ADT::tensor::Shape left{2, 3};
+ const nncc::core::ADT::tensor::Shape right{2, 3};
+
+ ASSERT_TRUE(left == right);
+}