[enco] Lower Copy as Shuffle (#1650)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Thu, 27 Sep 2018 06:37:24 +0000 (15:37 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Thu, 27 Sep 2018 06:37:24 +0000 (15:37 +0900)
This commit introduces a lowering phase that rewrites Copy as Shuffle.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/enco/core/src/Backend.cpp
contrib/enco/core/src/Lower.cpp [new file with mode: 0644]
contrib/enco/core/src/Lower.h [new file with mode: 0644]

index bab3597..d3a7bb2 100644 (file)
@@ -9,6 +9,8 @@
 #include "Transforms/Optimizations.h"
 #include "Transforms/Split.h"
 
+#include "Lower.h"
+
 #include <stdexcept>
 
 namespace
@@ -62,6 +64,9 @@ void Backend::compile(coco::Module *m, coco::Data *d)
   NormalizePass normalize;
   normalize.runOnCode(&code);
 
+  // Lower Copy as Shuffle
+  lower_copy(&code);
+
   generate_bypass_shuffle(&code);
   hoist_object(&code);
 
diff --git a/contrib/enco/core/src/Lower.cpp b/contrib/enco/core/src/Lower.cpp
new file mode 100644 (file)
index 0000000..efbdd11
--- /dev/null
@@ -0,0 +1,89 @@
+#include "Lower.h"
+
+#include <set>
+#include <cassert>
+
+//
+// Lower Copy as Shuffle
+//
+namespace enco
+{
+
+void lower_copy(enco::Code *code)
+{
+  auto m = code->module();
+
+  std::set<coco::Copy *> lowered_copies;
+
+  for (uint32_t n = 0; n < m->entity()->instr()->size(); ++n)
+  {
+    auto ins = m->entity()->instr()->at(n);
+
+    assert(ins != nullptr);
+
+    if (ins->parent() == nullptr)
+    {
+      // Skip if instruction does not belong to a list
+      continue;
+    }
+
+    auto copy = ins->asCopy();
+
+    if (copy == nullptr)
+    {
+      // Skip if instruction is not a copy
+      continue;
+    }
+
+    // TODO Support non-Feature objects
+    auto ifm = copy->from()->asFeature();
+    auto ofm = copy->into()->asFeature();
+
+    if ((ifm == nullptr) || (ofm == nullptr))
+    {
+      continue;
+    }
+
+    assert(ifm->layout()->batch() == ofm->layout()->batch());
+    assert(ifm->layout()->shape() == ofm->layout()->shape());
+
+    auto shuffle = m->entity()->instr()->create<coco::Shuffle>();
+
+    shuffle->from(ifm->bag());
+    shuffle->into(ofm->bag());
+
+    const uint32_t B = ifm->layout()->batch();
+    const uint32_t C = ifm->layout()->shape().depth();
+    const uint32_t H = ifm->layout()->shape().height();
+    const uint32_t W = ifm->layout()->shape().width();
+
+    for (uint32_t b = 0; b < B; ++b)
+    {
+      for (uint32_t ch = 0; ch < C; ++ch)
+      {
+        for (uint32_t row = 0; row < H; ++row)
+        {
+          for (uint32_t col = 0; col < W; ++col)
+          {
+            const auto from = ifm->layout()->at(b, ch, row, col);
+            const auto into = ofm->layout()->at(b, ch, row, col);
+
+            shuffle->insert(from, into);
+          }
+        }
+      }
+    }
+
+    shuffle->insertBefore(copy);
+    lowered_copies.insert(copy);
+  }
+
+  // Destroy lowered copy
+  for (const auto &copy : lowered_copies)
+  {
+    copy->detach();
+    m->entity()->instr()->destroy(copy);
+  }
+}
+
+} // namespace enco
diff --git a/contrib/enco/core/src/Lower.h b/contrib/enco/core/src/Lower.h
new file mode 100644 (file)
index 0000000..ef48148
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __ENCO_LOWER_H__
+#define __ENCO_LOWER_H__
+
+#include "Code.h"
+
+namespace enco
+{
+
+/**
+ * @brief Lower copy(...) instruction into shuffle(...)
+ */
+void lower_copy(enco::Code *code);
+
+} // namespace enco
+
+#endif // __ENCO_LOWER_H__