[enco] Support simple convolution IR generation (#1194)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 28 Aug 2018 00:57:35 +0000 (09:57 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 28 Aug 2018 00:57:35 +0000 (09:57 +0900)
With this commit, enco caffe frontend is now able to process convolution
layers that satisfy the following conditions:
- 2D convolution with no bias
- Padding is 0 for all the spatial axes
- Stride is 1 for all the spatial axes
- Dilation is 1 for all the spatial axes

Note that this commit does not pass kernel weight, yet.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
contrib/enco/frontend/caffe/CMakeLists.txt
contrib/enco/frontend/caffe/src/Frontend.cpp

index f0fb1f1..4de5445 100644 (file)
@@ -15,6 +15,7 @@ target_link_libraries(enco_caffe_frontend coco_generic)
 target_link_libraries(enco_caffe_frontend enco_intf_frontend)
 target_link_libraries(enco_caffe_frontend enco_intf_cmdline)
 target_link_libraries(enco_caffe_frontend nncc_foundation)
+target_link_libraries(enco_caffe_frontend morph)
 target_link_libraries(enco_caffe_frontend caffeproto)
 
 nncc_find_package(GTest QUIET)
index 1dbeb4d..7394297 100644 (file)
@@ -1,8 +1,13 @@
 #include "Frontend.h"
+#include "ConvolutionSpec.h"
 
+#include <nncc/core/ADT/feature/CHWLayout.h>
+#include <nncc/core/ADT/kernel/NCHWLayout.h>
 #include <nncc/core/ADT/tensor/Shape.h>
 #include <nncc/core/ADT/tensor/LexicalLayout.h>
 
+#include <morph/caffe.h>
+
 #include <map>
 #include <set>
 #include <string>
@@ -46,6 +51,8 @@ Frontend::Frontend() : _prototxt{new ::caffe::NetParameter}, _caffemodel{new ::c
 enco::Bundle Frontend::load(void) const
 {
   auto m = coco::Module::create();
+  auto blk = m->entity()->block()->create();
+
   auto d = coco::Data::create();
 
   // For inter-layer communication
@@ -85,6 +92,81 @@ enco::Bundle Frontend::load(void) const
         shape_ctx[name] = shape;
       }
     }
+    else if (layer.type() == "Convolution")
+    {
+      assert(layer.bottom().size() == 1);
+      assert(layer.top().size() == 1);
+
+      assert(layer.has_convolution_param());
+      const auto &param = layer.convolution_param();
+
+      // NOTE Bias is not supported, yet
+      // TODO Support bias term
+      assert(!param.bias_term());
+
+      ConvolutionSpec spec{param};
+      {
+        const auto ifm_name = layer.bottom(0);
+        const auto ifm_shape = shape_ctx.at(ifm_name);
+        spec.ifm_shape(ifm_shape);
+      }
+
+      // NOTE The current implementation focuses on 2D convolution
+      // TODO Support general ND convolution
+      assert(spec.num_batch_axes() == 1);
+      assert(spec.num_spatial_axes() == 2);
+
+      // Create an object for an input feature map
+      const auto ifm_name = layer.bottom(0);
+      const auto ifm_shape = shape_ctx.at(ifm_name);
+      auto ifm_bag = bag_ctx.at(ifm_name);
+      auto ifm_obj = m->entity()->object()->create(morph::caffe::as_feature_shape(ifm_shape));
+
+      ifm_obj->bag(ifm_bag);
+      ifm_obj->reorder<feature::CHWLayout>();
+
+      // Create an object for an output feature map
+      const auto ofm_name = layer.top(0);
+      const auto ofm_shape = spec.ofm_shape();
+      auto ofm_bag = m->entity()->bag()->create(num_elements(ofm_shape));
+      auto ofm_obj = m->entity()->object()->create(morph::caffe::as_feature_shape(ofm_shape));
+
+      ofm_obj->bag(ofm_bag);
+      ofm_obj->reorder<feature::CHWLayout>();
+
+      // Create an object for kernel
+      const auto ker_shape = spec.ker_shape();
+      auto ker_bag = m->entity()->bag()->create(num_elements(ker_shape));
+      auto ker_obj = m->entity()->object()->create(morph::caffe::as_kernel_shape(ker_shape));
+
+      ker_obj->bag(ker_bag);
+      ker_obj->reorder<kernel::NCHWLayout>();
+
+      // Create a kernel overlay for the kernel object
+      auto ker_id = d->allocate(num_elements(ker_shape) * sizeof(float));
+      d->f32()->link(ker_id, ker_obj);
+
+      // TODO Initializer the kernel overlay
+
+      // Create a Conv2D op
+      auto op = m->entity()->op()->create<coco::Conv2D>();
+
+      op->ker(ker_obj);
+
+      // Create a UnitF instruction
+      auto ins = m->entity()->instr()->create<coco::UnitF>();
+
+      ins->ifm(ifm_obj);
+      ins->ofm(ofm_obj);
+      ins->op(op);
+
+      // Append the instruction to the block
+      blk->instr()->append(ins);
+
+      // Update bag and shape context
+      bag_ctx[ofm_name] = ofm_bag;
+      shape_ctx[ofm_name] = ofm_shape;
+    }
     else
     {
       throw std::runtime_error{"Not supported: " + layer.type()};