From: Efimov Alexander/AI Tools Lab/./Samsung Electronics Date: Sun, 15 Jul 2018 06:30:30 +0000 (+0300) Subject: Serialize parameters (#602) X-Git-Tag: nncc_backup~2426 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=385a3317f0122eac6095dd6f4b3721aa3f742d42;p=platform%2Fcore%2Fml%2Fnnfw.git Serialize parameters (#602) Implementation of compressed parameters dump Signed-off-by: Efimov Alexander --- diff --git a/contrib/nnc/libs/backend/soft/include/model_analyzer.h b/contrib/nnc/libs/backend/soft/include/model_analyzer.h index bd556ce..74e895d 100644 --- a/contrib/nnc/libs/backend/soft/include/model_analyzer.h +++ b/contrib/nnc/libs/backend/soft/include/model_analyzer.h @@ -2,6 +2,8 @@ #define _NNC_SOFT_BACKEND_MODEL_ANALYZER_H_ #include "nnc/core/IR/model/visitor/visitor.h" +#include "nncc/core/ADT/tensor/Shape.h" +#include "nnc/core/linalg/TensorVariant.h" #include #include @@ -93,6 +95,12 @@ public: private: void addOpDescr(ADT::INode *node, const std::string &name); + void packData(const void *data, size_t size); + + template + void serializeT(const T &obj); + void serializeShape(const nncc::core::ADT::tensor::Shape &s); + void serializeTensor(const contrib::core::ADT::TensorVariant &t); const uint32_t _formatVersion = 1; uint32_t _modelHash = 0; diff --git a/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp b/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp index c7cc374..eb7702b 100644 --- a/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp +++ b/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp @@ -1,5 +1,21 @@ +#include +#include + #include "model_analyzer.h" #include "nnc/core/IR/model/graph/ir_node.h" +#include "nncc/core/ADT/tensor/Shape.h" +#include "nnc/core/linalg/ShapeRange.h" + +#include "nnc/core/IR/model/operations/concat_op.h" +#include "nnc/core/IR/model/operations/conv_2d_op.h" +#include "nnc/core/IR/model/operations/depthwise_conv2d_op.h" +#include "nnc/core/IR/model/operations/softmax_op.h" +#include "nnc/core/IR/model/operations/pool_op.h" +#include "nnc/core/IR/model/operations/fully_connected_op.h" +#include "nnc/core/IR/model/operations/capped_relu_op.h" +#include "nnc/core/IR/model/operations/bias_add_op.h" +#include "nnc/core/IR/model/operations/relu_op.h" +#include "nnc/core/IR/model/operations/reshape_op.h" using namespace std; @@ -12,6 +28,67 @@ namespace backend namespace soft { +using nncc::core::ADT::tensor::Shape; +using nncc::core::ADT::tensor::Index; +using nncc::contrib::core::data::ShapeRange; +using nncc::contrib::core::ADT::TensorVariant; + +void ModelAnalyzer::packData(const void *data, size_t size) +{ + const char *p = static_cast(data); + size_t old_size = _packedParameters.size(); + _packedParameters.resize(old_size + size); + copy(p, p + size, _packedParameters.data() + old_size); +} + +template +void ModelAnalyzer::serializeT(const T &obj) +{ + packData(&obj, sizeof(T)); +} + +// convert enum to it's underlying type +template +typename underlying_type::type etoi(E enumVal) +{ + return static_cast::type>(enumVal); +} + +void ModelAnalyzer::serializeShape(const Shape &s) +{ + uint32_t rank = s.rank(); + assert(rank < 100); + serializeT(s.rank()); + for (uint32_t i = 0; i < rank; ++i) + { + uint32_t dim = s.dim(i); + serializeT(dim); + } +} + +void ModelAnalyzer::serializeTensor(const TensorVariant &t) +{ + // serialize type + assert(etoi(t.getDataType()) < 100); + serializeT(etoi(t.getDataType())); + // seriazlie data size + size_t eSize = t.getElementSize(); + assert(eSize < 100); + serializeT(eSize); + // serialize shape + const Shape &shape = t.getShape(); + serializeShape(shape); + // serialize actual data + size_t tSize = eSize * num_elements(shape); + + size_t oldSize = _packedParameters.size(); + _packedParameters.reserve(oldSize + tSize); + for (const Index &idx: ShapeRange(shape)) + { + packData(t.at(idx), eSize); + } +} + void ModelAnalyzer::addOpDescr(ADT::INode *node, const string &opName) { size_t offset = _packedParameters.size(); @@ -42,68 +119,129 @@ void ModelAnalyzer::addOpDescr(ADT::INode *node, const string &opName) void ModelAnalyzer::visit(ADT::INode *node, ops::ConcatOp &op) { addOpDescr(node, "concat"); - // TODO add parameters dump + // axis number should fit into one byte + assert(op.getAxis() < 100); + serializeT(op.getAxis()); } void ModelAnalyzer::visit(ADT::INode *node, ops::Conv2DOp &op) { addOpDescr(node, "conv2d"); - // TODO add parameters dump + // serialize kernel + const TensorVariant &kernel = op.getKernel(); + serializeTensor(kernel); + // serialize strides + serializeShape(op.getStrides()); + // serialize padding type + assert(etoi(op.getPaddingType()) < 100); + serializeT(etoi(op.getPaddingType())); + // serialize pads + uint32_t padsRank = op.getInputShape(0).rank(); + assert(padsRank < 100); + serializeT(padsRank); + for (int i = 0; i < padsRank; ++i) + { + auto pad = op.getPadding(i); + assert(pad <= numeric_limits::max()); + assert(pad >= 0); + serializeT(op.getPadding(i)); + } } void ModelAnalyzer::visit(ADT::INode *node, ops::DepthwiseConv2DOp &op) { addOpDescr(node, "depthwiseConv2d"); - // TODO add parameters dump + // serialize kernel + const TensorVariant &kernel = op.getKernel(); + serializeTensor(kernel); + // serialize strides + serializeShape(op.getStrides()); + // serialize padding type + assert(etoi(op.getPaddingType()) < 100); + serializeT(etoi(op.getPaddingType())); + // serialize pads + uint32_t padsRank = kernel.getShape().rank(); + assert(padsRank < 100); + serializeT(padsRank); + for (uint32_t i = 0; i < padsRank; ++i) + { + auto pad = op.getPadding(i); + assert(pad <= numeric_limits::max()); + assert(pad >= 0); + serializeT(pad); + } } void ModelAnalyzer::visit(ADT::INode *node, ops::SoftmaxOp &op) { addOpDescr(node, "softmax"); - // TODO add parameters dump + // axis number should fit into one byte + assert(op.getAxis() < 100); + serializeT(op.getAxis()); } void ModelAnalyzer::visit(ADT::INode *node, ops::PoolOp &op) { addOpDescr(node, "pool"); - // TODO add parameters dump + // serialize padding type + assert(etoi(op.getPaddingType()) < 100); + serializeT(etoi(op.getPaddingType())); + // serialize pooling type + assert(etoi(op.getPoolingType()) < 100); + serializeT(etoi(op.getPoolingType())); + // serialize window shape + const Shape &windowShape = op.getWindowShape(); + serializeShape(windowShape); + // serialize strindes + serializeShape(op.getStrides()); + // serialize padding + int rank = windowShape.rank(); + assert(rank < 100); + for (uint32_t i = 0; i < rank; ++i) + { + auto pad = op.getPadding(i); + assert(pad <= numeric_limits::max()); + assert(pad >= 0); + serializeT(pad); + } } void ModelAnalyzer::visit(ADT::INode *node, ops::FullyConnectedOp &op) { addOpDescr(node, "fullConnect"); - // TODO add parameters dump + serializeTensor(op.getWeights()); } void ModelAnalyzer::visit(ADT::INode *node, ops::CappedReluOp &op) { addOpDescr(node, "cappedRelu"); - // TODO add parameters dump + static_assert(sizeof(float) == 4, "unsupported float type"); + serializeT(op.getCap()); } void ModelAnalyzer::visit(ADT::INode *node, ops::BiasAddOp &op) { addOpDescr(node, "biasAdd"); - // TODO add parameters dump + serializeTensor(op.getWeights()); } void ModelAnalyzer::visit(ADT::INode *node, ops::VariableOp &op) { assert(node->getPrevNodes().empty()); addOpDescr(node, "in"); - // TODO add parameters dump + // no parameters to dump } void ModelAnalyzer::visit(ADT::INode *node, ops::ReluOp &op) { addOpDescr(node, "relu"); - // TODO add parameters dump + // no parameters to dump } void ModelAnalyzer::visit(ADT::INode *node, ops::ReshapeOp &op) { addOpDescr(node, "reshape"); - // TODO add parameters dump + serializeShape(op.getOutputShape(0)); } } // namespace soft