[enco] Initilize Conv2D kernel overlay (#1206)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 28 Aug 2018 07:06:39 +0000 (16:06 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 28 Aug 2018 07:06:39 +0000 (16:06 +0900)
This commit revises caffe frontend to initialize Conv2D kernel overlay.

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

index 7394297..3357504 100644 (file)
@@ -2,6 +2,8 @@
 #include "ConvolutionSpec.h"
 
 #include <nncc/core/ADT/feature/CHWLayout.h>
+#include <nncc/core/ADT/kernel/Shape.h>
+#include <nncc/core/ADT/kernel/Overlay.h>
 #include <nncc/core/ADT/kernel/NCHWLayout.h>
 #include <nncc/core/ADT/tensor/Shape.h>
 #include <nncc/core/ADT/tensor/LexicalLayout.h>
@@ -41,6 +43,11 @@ tensor::Shape as_tensor_shape(const ::caffe::BlobShape &blob_shape)
   return res;
 }
 
+tensor::Shape as_tensor_shape(const ::caffe::BlobProto *blob_proto)
+{
+  return as_tensor_shape(blob_proto->shape());
+}
+
 } // namespace
 
 Frontend::Frontend() : _prototxt{new ::caffe::NetParameter}, _caffemodel{new ::caffe::NetParameter}
@@ -55,6 +62,27 @@ enco::Bundle Frontend::load(void) const
 
   auto d = coco::Data::create();
 
+  // For weight access
+  std::map<std::string, ::caffe::LayerParameter *> weight_ctx;
+
+  for (uint32_t n = 0; n < _caffemodel->layer_size(); ++n)
+  {
+    auto layer = _caffemodel->mutable_layer(n);
+
+    if (layer->has_name())
+    {
+      weight_ctx[layer->name()] = layer;
+    }
+  }
+
+  auto blob_count = [&weight_ctx](const std::string &name) {
+    return weight_ctx.at(name)->blobs_size();
+  };
+
+  auto blob_get = [&weight_ctx](const std::string &name, uint32_t n) {
+    return weight_ctx.at(name)->mutable_blobs(n);
+  };
+
   // For inter-layer communication
   std::map<std::string, tensor::Shape> shape_ctx;
   std::map<std::string, coco::Bag *> bag_ctx;
@@ -146,7 +174,29 @@ enco::Bundle Frontend::load(void) const
       auto ker_id = d->allocate(num_elements(ker_shape) * sizeof(float));
       d->f32()->link(ker_id, ker_obj);
 
-      // TODO Initializer the kernel overlay
+      // Initialize the kernel overlay
+      assert(blob_count(layer.name()) >= 1);
+      auto ker_blob = blob_get(layer.name(), 0);
+
+      assert(ker_shape == as_tensor_shape(ker_blob));
+
+      auto ker_dst = d->f32()->access(ker_obj);
+      auto ker_src = kernel::OverlayFactory<float, kernel::NCHWLayout>::make(
+          ker_obj->shape(), ker_blob->mutable_data()->begin());
+
+      for (uint32_t n = 0; n < ker_obj->shape().count(); ++n)
+      {
+        for (uint32_t ch = 0; ch < ker_obj->shape().depth(); ++ch)
+        {
+          for (uint32_t row = 0; row < ker_obj->shape().height(); ++row)
+          {
+            for (uint32_t col = 0; col < ker_obj->shape().width(); ++col)
+            {
+              ker_dst->at(n, ch, row, col) = ker_src.at(n, ch, row, col);
+            }
+          }
+        }
+      }
 
       // Create a Conv2D op
       auto op = m->entity()->op()->create<coco::Conv2D>();