summaryrefslogtreecommitdiff
path: root/compiler/moco-tf/src/Annotations
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/moco-tf/src/Annotations')
-rw-r--r--compiler/moco-tf/src/Annotations/ConcatData.h44
-rw-r--r--compiler/moco-tf/src/Annotations/PadData.h51
-rw-r--r--compiler/moco-tf/src/Annotations/PaddingData.h49
-rw-r--r--compiler/moco-tf/src/Annotations/ShapeInferenceData.cpp264
-rw-r--r--compiler/moco-tf/src/Annotations/ShapeInferenceData.h75
-rw-r--r--compiler/moco-tf/src/Annotations/ShapeInferenceData.test.cpp174
-rw-r--r--compiler/moco-tf/src/Annotations/StrideData.h48
-rw-r--r--compiler/moco-tf/src/Annotations/WindowData.h46
8 files changed, 751 insertions, 0 deletions
diff --git a/compiler/moco-tf/src/Annotations/ConcatData.h b/compiler/moco-tf/src/Annotations/ConcatData.h
new file mode 100644
index 000000000..4c8e5fa5e
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/ConcatData.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_CONCAT_DATA_H__
+#define __MOCO_TF_CONCAT_DATA_H__
+
+#include <loco.h>
+
+namespace moco
+{
+namespace tf
+{
+
+/**
+ * @brief ConcatData holds temporary axis attribute of Concat while building the graph
+*/
+class ConcatData : public loco::NodeAnnotation
+{
+public:
+ ConcatData(int32_t axis) : _axis(axis) {}
+
+ int32_t axis(void) const { return _axis; }
+
+private:
+ int32_t _axis;
+};
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_CONCAT_DATA_H__
diff --git a/compiler/moco-tf/src/Annotations/PadData.h b/compiler/moco-tf/src/Annotations/PadData.h
new file mode 100644
index 000000000..887a1c503
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/PadData.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_PAD_DATA_H__
+#define __MOCO_TF_PAD_DATA_H__
+
+#include <loco.h>
+
+namespace moco
+{
+namespace tf
+{
+
+/**
+ * @brief PadData holds temporary 'pad' attribute of TFConv2D
+ *
+ * @note This holds the same pad attribute that exist in Canonical Conv2D
+ * to simplify Canonicalizing step of TFConv2D to Conv2D conversion.
+ * Values of 'pad' will be calculated in FixPaddingTransformation.
+ * PadData holds Padding2D where PaddingData holds 'padding' as a string.
+ */
+class PadData : public loco::NodeAnnotation
+{
+public:
+ PadData() = default;
+
+public:
+ const loco::Padding2D *pad(void) const { return &_pad; }
+ loco::Padding2D *pad(void) { return &_pad; }
+
+private:
+ loco::Padding2D _pad;
+};
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_PAD_DATA_H__
diff --git a/compiler/moco-tf/src/Annotations/PaddingData.h b/compiler/moco-tf/src/Annotations/PaddingData.h
new file mode 100644
index 000000000..e875cca7d
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/PaddingData.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_PADDING_DATA_H__
+#define __MOCO_TF_PADDING_DATA_H__
+
+#include <loco.h>
+
+#include <string>
+
+namespace moco
+{
+namespace tf
+{
+
+/**
+ * @brief PaddingData holds temporary padding attribute
+ *
+ * @note Related nodes are AvgPool2D, MaxPool2D, Conv2D and maybe others
+ * PaddingData holds 'padding' as a string where PadData holds Padding2D
+ */
+class PaddingData : public loco::NodeAnnotation
+{
+public:
+ PaddingData(const std::string &padding) : _padding(padding) {}
+
+ const std::string &padding(void) const { return _padding; }
+
+private:
+ std::string _padding;
+};
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_PADDING_DATA_H__
diff --git a/compiler/moco-tf/src/Annotations/ShapeInferenceData.cpp b/compiler/moco-tf/src/Annotations/ShapeInferenceData.cpp
new file mode 100644
index 000000000..e6ffa98ae
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/ShapeInferenceData.cpp
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2019 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 "ShapeInferenceData.h"
+
+#include <stdexcept>
+
+namespace moco
+{
+namespace tf
+{
+
+loco::TensorShape ShapeInferenceData::tensor_shape(void) const
+{
+ assert(_domain == loco::Domain::Tensor);
+
+ loco::TensorShape shape;
+
+ shape.rank(rank());
+ for (uint32_t r = 0; r < rank(); ++r)
+ {
+ if (dim(r).known())
+ shape.dim(r) = dim(r).value();
+ else
+ shape.dim(r).unset();
+ }
+
+ return shape;
+}
+
+loco::FeatureShape ShapeInferenceData::feature_shape(void) const
+{
+ assert(_domain == loco::Domain::Feature);
+
+ loco::FeatureShape shape;
+
+ if (rank() != 4)
+ throw std::runtime_error("Feature should be rank 4");
+
+ shape.count() = dim(0);
+ shape.height() = dim(1);
+ shape.width() = dim(2);
+ shape.depth() = dim(3);
+
+ return shape;
+}
+
+loco::FilterShape ShapeInferenceData::filter_shape(void) const
+{
+ assert(_domain == loco::Domain::Filter);
+
+ loco::FilterShape shape;
+
+ if (rank() != 4)
+ throw std::runtime_error("Filter should be rank 4");
+
+ shape.count() = dim(0);
+ shape.height() = dim(1);
+ shape.width() = dim(2);
+ shape.depth() = dim(3);
+
+ return shape;
+}
+
+loco::DepthwiseFilterShape ShapeInferenceData::depthwisefilter_shape(void) const
+{
+ assert(_domain == loco::Domain::DepthwiseFilter);
+
+ loco::DepthwiseFilterShape shape;
+
+ if (rank() != 4)
+ throw std::runtime_error("DepthwiseFilter should be rank 4");
+
+ shape.height() = dim(0);
+ shape.width() = dim(1);
+ shape.depth() = dim(2);
+ shape.multiplier() = dim(3);
+
+ return shape;
+}
+
+loco::BiasShape ShapeInferenceData::bias_shape(void) const
+{
+ assert(_domain == loco::Domain::Bias);
+
+ loco::BiasShape shape;
+
+ // Note: this may change when loco::BiasShape becomes available
+ shape.length() = dim(0).value();
+
+ return shape;
+}
+
+void ShapeInferenceData::tensor_shape(const loco::TensorShape &shape)
+{
+ _domain = loco::Domain::Tensor;
+
+ rank(shape.rank());
+ for (uint32_t r = 0; r < shape.rank(); ++r)
+ {
+ if (shape.dim(r).known())
+ dim(r) = shape.dim(r).value();
+ else
+ dim(r).unset();
+ }
+}
+
+void ShapeInferenceData::feature_shape(const loco::FeatureShape &shape)
+{
+ _domain = loco::Domain::Feature;
+
+ rank(4);
+ dim(0) = shape.count();
+ dim(1) = shape.height();
+ dim(2) = shape.width();
+ dim(3) = shape.depth();
+}
+
+void ShapeInferenceData::filter_shape(const loco::FilterShape &shape)
+{
+ _domain = loco::Domain::Filter;
+
+ rank(4);
+ dim(0) = shape.count();
+ dim(1) = shape.height();
+ dim(2) = shape.width();
+ dim(3) = shape.depth();
+}
+
+void ShapeInferenceData::depthwisefilter_shape(const loco::DepthwiseFilterShape &shape)
+{
+ _domain = loco::Domain::DepthwiseFilter;
+
+ rank(4);
+ dim(0) = shape.height();
+ dim(1) = shape.width();
+ dim(2) = shape.depth();
+ dim(3) = shape.multiplier();
+}
+
+void ShapeInferenceData::bias_shape(const loco::BiasShape &shape)
+{
+ _domain = loco::Domain::Bias;
+
+ // Note: this may change when loco::BiasShape becomes available
+ rank(1);
+ dim(0) = shape.length();
+}
+
+void as_tensor_shape(ShapeInferenceData &shapedata, const loco::FeatureShape &feature_shape,
+ const TFDataLayout &data_layout)
+{
+ loco::TensorShape tensor_shape;
+
+ tensor_shape.rank(4);
+ if (data_layout == "NHWC")
+ {
+ tensor_shape.dim(0) = feature_shape.count();
+ tensor_shape.dim(1) = feature_shape.height();
+ tensor_shape.dim(2) = feature_shape.width();
+ tensor_shape.dim(3) = feature_shape.depth();
+ }
+ else if (data_layout == "NCHW")
+ {
+ tensor_shape.dim(0) = feature_shape.count();
+ tensor_shape.dim(1) = feature_shape.depth();
+ tensor_shape.dim(2) = feature_shape.height();
+ tensor_shape.dim(3) = feature_shape.width();
+ }
+ else
+ {
+ // TODO support for other data_layout if needed
+ throw std::runtime_error("as_tensor_shape: only supports NHWC or NCHW");
+ }
+
+ shapedata.tensor_shape(tensor_shape);
+}
+
+loco::FeatureShape as_feature_shape(const ShapeInferenceData &shapedata,
+ const TFDataLayout &data_layout)
+{
+ if (shapedata.domain() == loco::Domain::Feature)
+ return shapedata.feature_shape();
+
+ loco::FeatureShape feature_shape;
+
+ // only convert from tensor to feature
+ if (shapedata.domain() != loco::Domain::Tensor)
+ {
+ throw std::runtime_error("as_feature_shape: domain is not tensor");
+ }
+ if (shapedata.rank() != 4)
+ {
+ throw std::runtime_error("as_feature_shape: rank is not 4");
+ }
+
+ // TODO support for other data_layout if needed
+ if (data_layout != "NHWC" && data_layout != "NCHW")
+ {
+ throw std::runtime_error("as_feature_shape: only supports NHWC or NCHW");
+ }
+
+ if (data_layout == "NHWC")
+ {
+ feature_shape.count() = shapedata.dim(0);
+ feature_shape.height() = shapedata.dim(1);
+ feature_shape.width() = shapedata.dim(2);
+ feature_shape.depth() = shapedata.dim(3);
+ }
+ else
+ {
+ feature_shape.count() = shapedata.dim(0);
+ feature_shape.depth() = shapedata.dim(1);
+ feature_shape.height() = shapedata.dim(2);
+ feature_shape.width() = shapedata.dim(3);
+ }
+
+ return feature_shape;
+}
+
+bool operator==(const ShapeInferenceData &lhs, const ShapeInferenceData &rhs)
+{
+ if (lhs.domain() != rhs.domain())
+ return false;
+
+ switch (lhs.domain())
+ {
+ case loco::Domain::Tensor:
+ {
+ auto lhs_t = lhs.tensor_shape();
+ auto rhs_t = rhs.tensor_shape();
+ if (lhs_t.rank() != rhs.rank())
+ return false;
+ for (uint32_t axis = 0; axis < lhs_t.rank(); ++axis)
+ {
+ if (!(lhs_t.dim(axis) == rhs_t.dim(axis)))
+ return false;
+ }
+ return true;
+ }
+ // TODO Support other domains
+ // case loco::Domain::Feature:
+ // case loco::Domain::Filter:
+ // case loco::Domain::Bias:
+ default:
+ throw std::runtime_error("Not supported domain for ShapeInferenceData equality");
+ }
+}
+
+} // namespace tf
+} // namespace moco
diff --git a/compiler/moco-tf/src/Annotations/ShapeInferenceData.h b/compiler/moco-tf/src/Annotations/ShapeInferenceData.h
new file mode 100644
index 000000000..d48699356
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/ShapeInferenceData.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_SHAPEINFERENCE_DATA_H__
+#define __MOCO_TF_SHAPEINFERENCE_DATA_H__
+
+#include <loco.h>
+#include "loco/IR/BiasShape.h"
+
+#include <cassert>
+
+namespace moco
+{
+namespace tf
+{
+
+/// @note Below alias may be introduced as separate class
+using TFDataLayout = std::string;
+
+/**
+ * @brief ShapeInferenceData provides shape inference data tracking from the start(input)
+ *
+ * @note For Feature and Filter, NHWC is used for shape layout
+ */
+class ShapeInferenceData : public loco::NodeAnnotation,
+ public loco::NodeMixin<loco::NodeTrait::TensorShape>
+{
+public:
+ ~ShapeInferenceData(){};
+
+public:
+ loco::Domain domain(void) const { return _domain; }
+
+ loco::TensorShape tensor_shape(void) const;
+ loco::FeatureShape feature_shape(void) const;
+ loco::FilterShape filter_shape(void) const;
+ loco::DepthwiseFilterShape depthwisefilter_shape(void) const;
+ loco::BiasShape bias_shape(void) const;
+
+ void tensor_shape(const loco::TensorShape &shape);
+ void feature_shape(const loco::FeatureShape &shape);
+ void filter_shape(const loco::FilterShape &shape);
+ void depthwisefilter_shape(const loco::DepthwiseFilterShape &shape);
+ void bias_shape(const loco::BiasShape &shape);
+
+private:
+ // TODO set default as Unknown, setting Tensor is to minimize change
+ loco::Domain _domain{loco::Domain::Tensor};
+};
+
+void as_tensor_shape(ShapeInferenceData &shapedata, const loco::FeatureShape &shape,
+ const TFDataLayout &data_layout);
+
+loco::FeatureShape as_feature_shape(const ShapeInferenceData &shapedata,
+ const TFDataLayout &data_layout);
+
+bool operator==(const ShapeInferenceData &lhs, const ShapeInferenceData &rhs);
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_SHAPEINFERENCE_DATA_H__
diff --git a/compiler/moco-tf/src/Annotations/ShapeInferenceData.test.cpp b/compiler/moco-tf/src/Annotations/ShapeInferenceData.test.cpp
new file mode 100644
index 000000000..8b8de535e
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/ShapeInferenceData.test.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2019 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 "ShapeInferenceData.h"
+
+#include <gtest/gtest.h>
+
+TEST(TensorFlowImport, shapeinferencedata_tensor_get)
+{
+ moco::tf::ShapeInferenceData shapedata;
+
+ shapedata.rank(4);
+ shapedata.dim(0) = 1;
+ shapedata.dim(1) = 2;
+ shapedata.dim(2) = 3;
+ shapedata.dim(3) = 4;
+
+ loco::TensorShape tensor = shapedata.tensor_shape();
+
+ ASSERT_EQ(tensor.rank(), 4);
+ ASSERT_EQ(tensor.dim(0), 1);
+ ASSERT_EQ(tensor.dim(1), 2);
+ ASSERT_EQ(tensor.dim(2), 3);
+ ASSERT_EQ(tensor.dim(3), 4);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_feature)
+{
+ loco::FeatureShape feature_s;
+
+ feature_s.count() = 1;
+ feature_s.height() = 2;
+ feature_s.width() = 3;
+ feature_s.depth() = 4;
+
+ moco::tf::ShapeInferenceData shapedata;
+
+ shapedata.feature_shape(feature_s);
+
+ loco::FeatureShape feature_g = shapedata.feature_shape();
+
+ ASSERT_EQ(feature_g.count(), 1);
+ ASSERT_EQ(feature_g.height(), 2);
+ ASSERT_EQ(feature_g.width(), 3);
+ ASSERT_EQ(feature_g.depth(), 4);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_filter)
+{
+ loco::FilterShape filter_s;
+
+ filter_s.count() = 1;
+ filter_s.height() = 2;
+ filter_s.width() = 3;
+ filter_s.depth() = 4;
+
+ moco::tf::ShapeInferenceData shapedata;
+
+ shapedata.filter_shape(filter_s);
+
+ ASSERT_EQ(shapedata.domain(), loco::Domain::Filter);
+
+ loco::FilterShape filter_g = shapedata.filter_shape();
+
+ ASSERT_EQ(filter_g.count(), 1);
+ ASSERT_EQ(filter_g.height(), 2);
+ ASSERT_EQ(filter_g.width(), 3);
+ ASSERT_EQ(filter_g.depth(), 4);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_bias)
+{
+ // Note: this may change when loco::BiasShape becomes available
+
+ loco::BiasShape bias_s;
+
+ bias_s.length() = 3;
+
+ moco::tf::ShapeInferenceData shapedata;
+
+ shapedata.bias_shape(bias_s);
+
+ loco::BiasShape bias_g = shapedata.bias_shape();
+
+ ASSERT_EQ(bias_g.length(), 3);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_as_tensor_set)
+{
+ loco::FeatureShape feature_s;
+
+ feature_s.count() = 1;
+ feature_s.height() = 2;
+ feature_s.width() = 3;
+ feature_s.depth() = 4;
+
+ moco::tf::ShapeInferenceData shapedata;
+
+ as_tensor_shape(shapedata, feature_s, "NHWC");
+
+ loco::TensorShape tensor_g;
+
+ tensor_g = shapedata.tensor_shape();
+
+ ASSERT_EQ(tensor_g.rank(), 4);
+ ASSERT_EQ(tensor_g.dim(0), 1);
+ ASSERT_EQ(tensor_g.dim(1), 2);
+ ASSERT_EQ(tensor_g.dim(2), 3);
+ ASSERT_EQ(tensor_g.dim(3), 4);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_as_feature)
+{
+ loco::TensorShape tensor_s;
+
+ tensor_s.rank(4);
+ tensor_s.dim(0) = 1;
+ tensor_s.dim(1) = 2;
+ tensor_s.dim(2) = 3;
+ tensor_s.dim(3) = 4;
+
+ moco::tf::ShapeInferenceData shapedata;
+
+ shapedata.tensor_shape(tensor_s);
+
+ loco::FeatureShape feature_g = as_feature_shape(shapedata, "NHWC");
+
+ ASSERT_EQ(feature_g.count(), 1);
+ ASSERT_EQ(feature_g.height(), 2);
+ ASSERT_EQ(feature_g.width(), 3);
+ ASSERT_EQ(feature_g.depth(), 4);
+}
+
+TEST(TensorFlowImport, shapeinferencedata_equality_tensor)
+{
+ moco::tf::ShapeInferenceData left;
+ moco::tf::ShapeInferenceData right, wrong1, wrong2;
+
+ left.rank(2);
+ left.dim(0) = 1;
+ left.dim(1) = 2;
+ ASSERT_EQ(left.domain(), loco::Domain::Tensor);
+
+ right.rank(2);
+ right.dim(0) = 1;
+ right.dim(1) = 2;
+ ASSERT_TRUE(left == right);
+
+ wrong1.rank(1);
+ wrong1.dim(0) = 1;
+ ASSERT_FALSE(left == wrong1);
+
+ loco::FeatureShape wrong2_f;
+ wrong2_f.count() = 1;
+ wrong2_f.depth() = 1;
+ wrong2_f.height() = 1;
+ wrong2_f.width() = 1;
+
+ wrong2.feature_shape(wrong2_f);
+ ASSERT_FALSE(left == wrong2);
+}
diff --git a/compiler/moco-tf/src/Annotations/StrideData.h b/compiler/moco-tf/src/Annotations/StrideData.h
new file mode 100644
index 000000000..fb9a4b304
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/StrideData.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_STRIDE_DATA_H__
+#define __MOCO_TF_STRIDE_DATA_H__
+
+#include <loco.h>
+
+namespace moco
+{
+namespace tf
+{
+
+/**
+ * @brief StrideData holds temporary 'stride' attribute of TFConv2D, same thing
+ * like the one in Conv2D used for Canonicalizing TFConv2D to Conv2D.
+ * 'stride' will be calculated in FixShapeTransformation as for now.
+ */
+class StrideData : public loco::NodeAnnotation
+{
+public:
+ StrideData() = default;
+
+public:
+ const loco::Stride<2> *stride(void) const { return &_stride; }
+ loco::Stride<2> *stride(void) { return &_stride; }
+
+private:
+ loco::Stride<2> _stride;
+};
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_STRIDE_DATA_H__
diff --git a/compiler/moco-tf/src/Annotations/WindowData.h b/compiler/moco-tf/src/Annotations/WindowData.h
new file mode 100644
index 000000000..8bd962578
--- /dev/null
+++ b/compiler/moco-tf/src/Annotations/WindowData.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef __MOCO_TF_WINDOW_DATA_H__
+#define __MOCO_TF_WINDOW_DATA_H__
+
+#include <loco.h>
+
+namespace moco
+{
+namespace tf
+{
+
+/**
+ * @brief WindowData holds temporary 'window' attribute of AvgPool2D, MaxPool2D
+ */
+class WindowData : public loco::NodeAnnotation
+{
+public:
+ WindowData() = default;
+
+public:
+ const loco::Window<2> *window(void) const { return &_window; }
+ loco::Window<2> *window(void) { return &_window; }
+
+private:
+ loco::Window<2> _window;
+};
+
+} // namespace tf
+} // namespace moco
+
+#endif // __MOCO_TF_WINDOW_DATA_H__