#include "GraphBuilder.h"
#include "GraphBuilderContext.h"
+#include "Annotations/PaddingData.h"
+
#include <moco/tf/Names.h>
#include <loco.h>
#include <loco/IR/PermutingCodec.h>
stride->vertical(tf_strides.i(2));
stride->horizontal(tf_strides.i(3));
}
+
+ // tf paddings -> PaddingData annotation
+ auto tf_padding = get_string_attr(node, "padding");
+ auto padding_data = stdex::make_unique<PaddingData>(tf_padding);
+ maxpool2d_node->annot(std::move(padding_data));
}
// FeatureDecode
bool fix_shape(loco::MaxPool2D *node)
{
- // Output shape is same as the ifm
+ auto shapedata = node->annot<ShapeInferenceData>();
+ if (shapedata != nullptr)
+ {
+ // shape inference is already done for MaxPool2D
+ return false;
+ }
auto ifm = node->ifm();
- return copy_shapedata(ifm, node);
+ auto ifm_shapedata = ifm->annot<ShapeInferenceData>();
+ if (ifm_shapedata == nullptr)
+ {
+ // input node shape inference is not ready
+ return false;
+ }
+
+ auto padding_data = node->annot<PaddingData>();
+ if (padding_data == nullptr)
+ {
+ // PaddingData should exist
+ assert(false && "fix_shape for MaxPool2D failed as PaddingData is missing");
+ return false;
+ }
+
+ auto ifm_feature_shape = ifm_shapedata->feature_shape();
+
+ uint32_t input_height = ifm_feature_shape.height().value();
+ uint32_t input_width = ifm_feature_shape.width().value();
+ uint32_t stride_height = node->stride()->vertical();
+ uint32_t stride_width = node->stride()->horizontal();
+ uint32_t window_height = node->window()->vertical();
+ uint32_t window_width = node->window()->horizontal();
+ uint32_t dilation_height = 1; // dilation for MaxPool2D is 1
+ uint32_t dilation_width = 1;
+ uint32_t effective_window_height = dilation_height * (window_height - 1) + 1;
+ uint32_t effective_window_width = dilation_width * (window_width - 1) + 1;
+ uint32_t output_height;
+ uint32_t output_width;
+
+ if (padding_data->padding() == "VALID")
+ {
+ output_height = (input_height + stride_height - effective_window_height) / stride_height;
+ output_width = (input_width + stride_width - effective_window_width) / stride_width;
+ }
+ else if (padding_data->padding() == "SAME")
+ {
+ output_height = (input_height + stride_height - 1) / stride_height;
+ output_width = (input_width + stride_width - 1) / stride_width;
+ }
+ else
+ throw std::runtime_error("Not supported padding type in FixShapeTransform MaxPool2D");
+
+ loco::FeatureShape ofm_feature_shape;
+ ofm_feature_shape.count() = ifm_feature_shape.count();
+ ofm_feature_shape.height() = output_height;
+ ofm_feature_shape.width() = output_width;
+ ofm_feature_shape.depth() = ifm_feature_shape.depth();
+
+ auto shape_data = stdex::make_unique<ShapeInferenceData>();
+ shape_data->feature_shape(ofm_feature_shape);
+ node->annot(std::move(shape_data));
+
+ LOGGER(fixshape_maxpool2d);
+ INFO(fixshape_maxpool2d) << "Fix MaxPool2D shape = ifm(" << ifm_feature_shape.count().value()
+ << "," << ifm_feature_shape.height().value() << ","
+ << ifm_feature_shape.width().value() << ","
+ << ifm_feature_shape.depth().value() << ") --> ofm("
+ << ofm_feature_shape.count().value() << ","
+ << ofm_feature_shape.height().value() << ","
+ << ofm_feature_shape.width().value() << ","
+ << ofm_feature_shape.depth().value() << ")" << std::endl;
+ return true;
}
bool fix_shape(loco::Pull *node)