#include "CppCode.h"
#include "Transforms/Duplicate.h"
+#include "Transforms/Rewrite.h"
#include "Transforms/Normalize.h"
#include "Transforms/Split.h"
// that share the same bag as their underlying bag
assert(!has_inout_bag(code.module()));
+ AvgPoolRewritePass avgpool_rewrite;
+ avgpool_rewrite.runOnCode(&code);
+
// Insert data ordering if necessary
NormalizePass normalize;
normalize.runOnCode(&code);
--- /dev/null
+#include "Rewrite.h"
+
+#include <cassert>
+
+namespace
+{
+
+bool empty(coco::Padding2D *pad)
+{
+ return (pad->top() == 0) && (pad->bottom() == 0) && (pad->left() == 0) && (pad->right() == 0);
+}
+
+} // namespace
+
+namespace enco
+{
+
+void AvgPoolRewritePass::runOnModule(coco::Module *m) const
+{
+ for (auto B = m->block()->head(); B; B = B->next())
+ {
+ for (auto I = B->instr()->head(); I; I = I->next())
+ {
+ if (auto unit = I->asUnitF())
+ {
+ assert(unit->op() != nullptr);
+ if (auto avgpool = unit->op()->asAvgPool2D())
+ {
+ if (avgpool->divisor() == coco::AvgPool2D::Divisor::Static)
+ {
+ if (empty(avgpool->pad()))
+ {
+ // NOTE If there is no padding, Static and PaddingExcluded schemes are equivalent
+ avgpool->divisor(coco::AvgPool2D::Divisor::PaddingExcluded);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void AvgPoolRewritePass::runOnCode(enco::Code *code) const { runOnModule(code->module()); }
+
+} // namespace enco
--- /dev/null
+#ifndef __REWRITE_H__
+#define __REWRITE_H__
+
+#include "Code.h"
+
+namespace enco
+{
+
+/**
+ * @brief Rewrite NN API-incompatible average pooling
+ */
+class AvgPoolRewritePass
+{
+private:
+ void runOnModule(coco::Module *m) const;
+
+public:
+ void runOnCode(enco::Code *) const;
+};
+
+} // namespace enco
+
+#endif // __REWRITE_H__