#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>
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
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 ¶m = 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()};