From a50b0a96215f0f3f71c8d2fbc840ed0bff74fd38 Mon Sep 17 00:00:00 2001 From: "Efimov Alexander/AI Tools Lab/./Samsung Electronics" Date: Wed, 8 Aug 2018 16:20:56 +0300 Subject: [PATCH] Softbackend: move serialization out of ModelAnalyzer (#859) Check limits of char parameters properly, split max and average pool in defferent calls, serialize output shape where needed Signed-off-by: Efimov Alexander --- contrib/nnc/libs/backend/soft/CMakeLists.txt | 2 +- .../nnc/libs/backend/soft/include/base_generator.h | 6 +- .../nnc/libs/backend/soft/include/c_generator.h | 2 +- .../nnc/libs/backend/soft/include/cpp_generator.h | 2 +- .../libs/backend/soft/include/cpp_operations.def | 2 + .../nnc/libs/backend/soft/include/model_analyzer.h | 35 +--- contrib/nnc/libs/backend/soft/include/serializer.h | 78 +++++++ .../nnc/libs/backend/soft/src/base_generator.cpp | 16 +- contrib/nnc/libs/backend/soft/src/c_generator.cpp | 2 +- .../nnc/libs/backend/soft/src/cpp_generator.cpp | 5 +- .../nnc/libs/backend/soft/src/model_analyzer.cpp | 123 +---------- contrib/nnc/libs/backend/soft/src/serializer.cpp | 227 +++++++++++++++++++++ contrib/nnc/libs/backend/soft/src/soft_backend.cpp | 2 - 13 files changed, 335 insertions(+), 167 deletions(-) create mode 100644 contrib/nnc/libs/backend/soft/include/serializer.h create mode 100644 contrib/nnc/libs/backend/soft/src/serializer.cpp diff --git a/contrib/nnc/libs/backend/soft/CMakeLists.txt b/contrib/nnc/libs/backend/soft/CMakeLists.txt index f943735..5c53acd 100644 --- a/contrib/nnc/libs/backend/soft/CMakeLists.txt +++ b/contrib/nnc/libs/backend/soft/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOFT_BACKEND_COMMON_SOURCES src/soft_backend.cpp src/base_generator.cpp src/model_analyzer.cpp) +set(SOFT_BACKEND_COMMON_SOURCES src/soft_backend.cpp src/base_generator.cpp src/model_analyzer.cpp src/serializer.cpp) set(SOFT_BACKEND_CPP_SOURCES src/cpp_backend.cpp src/cpp_generator.cpp) set(SOFT_BACKEND_C_SOURCES src/c_backend.cpp src/c_generator.cpp) set(DEF_CONV src/def2src.cpp) diff --git a/contrib/nnc/libs/backend/soft/include/base_generator.h b/contrib/nnc/libs/backend/soft/include/base_generator.h index 134160b..17a3ca1 100644 --- a/contrib/nnc/libs/backend/soft/include/base_generator.h +++ b/contrib/nnc/libs/backend/soft/include/base_generator.h @@ -17,6 +17,8 @@ namespace soft class ModelAnalyzer; +class Serializer; + class BaseCodeGenerator { public: @@ -25,8 +27,8 @@ public: protected: virtual void formatTensorNames(const ModelAnalyzer &ma) = 0; virtual void materializeHeader(std::ostream &out, const ModelAnalyzer &ma) = 0; - virtual void materializeCode(std::ostream &out, const ModelAnalyzer &ma) = 0; - void materializeModelParams(std::ostream &out, const ModelAnalyzer &ma); + virtual void materializeCode(std::ostream &out, const ModelAnalyzer &ma, const Serializer &s) = 0; + void materializeModelParams(std::ostream &out, const Serializer &s); BaseCodeGenerator(BaseCodeGenerator &g) = default; diff --git a/contrib/nnc/libs/backend/soft/include/c_generator.h b/contrib/nnc/libs/backend/soft/include/c_generator.h index 5ccfdea..a19afc8 100644 --- a/contrib/nnc/libs/backend/soft/include/c_generator.h +++ b/contrib/nnc/libs/backend/soft/include/c_generator.h @@ -29,7 +29,7 @@ public: protected: void formatTensorNames(const ModelAnalyzer &ma) override; void materializeHeader(std::ostream &out, const ModelAnalyzer &ma) override; - void materializeCode(std::ostream &out, const ModelAnalyzer &ma) override; + void materializeCode(std::ostream &out, const ModelAnalyzer &ma, const Serializer &s) override; }; } // namespace soft diff --git a/contrib/nnc/libs/backend/soft/include/cpp_generator.h b/contrib/nnc/libs/backend/soft/include/cpp_generator.h index 523d8ac..46ff6f7 100644 --- a/contrib/nnc/libs/backend/soft/include/cpp_generator.h +++ b/contrib/nnc/libs/backend/soft/include/cpp_generator.h @@ -34,7 +34,7 @@ protected: const std::vector &argIds, std::vector &args); void materializeInferenceSequence(std::ostream &out, const ModelAnalyzer &ma); - void materializeCode(std::ostream &out, const ModelAnalyzer &ma) override; + void materializeCode(std::ostream &out, const ModelAnalyzer &ma, const Serializer &s) override; }; } // namespace soft diff --git a/contrib/nnc/libs/backend/soft/include/cpp_operations.def b/contrib/nnc/libs/backend/soft/include/cpp_operations.def index 86e9d04..6b7077d 100644 --- a/contrib/nnc/libs/backend/soft/include/cpp_operations.def +++ b/contrib/nnc/libs/backend/soft/include/cpp_operations.def @@ -9,6 +9,8 @@ using namespace std; +static_assert(numeric_limits::is_iec559, "Unsupported float type"); + void readParameters(char *&data, size_t &len, const string &path, uint32_t expectedVersion, uint32_t expectedHash) { diff --git a/contrib/nnc/libs/backend/soft/include/model_analyzer.h b/contrib/nnc/libs/backend/soft/include/model_analyzer.h index 2bc0f1d..77461f2 100644 --- a/contrib/nnc/libs/backend/soft/include/model_analyzer.h +++ b/contrib/nnc/libs/backend/soft/include/model_analyzer.h @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -22,12 +21,13 @@ namespace backend namespace soft { -namespace ADT = nncc::contrib::core::IR::model::ADT; -namespace ops = nncc::contrib::core::IR::model::ops; +namespace model = nncc::contrib::core::IR::model; +namespace ADT = model::ADT; +namespace ops = model::ops; const size_t INVALID_TENSOR_ID = std::numeric_limits::max(); -class ModelAnalyzer: public nncc::contrib::core::IR::model::Visitor +class ModelAnalyzer: public model::Visitor { public: void visit(ADT::INode *node, ops::ConcatOp &op) override; @@ -89,14 +89,9 @@ public: return _inferenceSequence; } - const std::vector &getPackedParameters() const + std::list &getInferenceSequence() { - return _packedParameters; - } - - uint32_t getFormatVersion() const - { - return _formatVersion; + return _inferenceSequence; } const std::string &getModelName() const @@ -104,30 +99,12 @@ public: return _modelName; } - // generate hash from analyzed Model IR - uint32_t getModelHash() const - { - assert(!_inferenceSequence.empty() && "Empty model! Did you apply visitor?"); - return _modelHash; - } - private: void addOpDescr(ADT::INode *node, const std::string &name); size_t allocateTensor(const std::string &name = std::string(), bool isNNInput = false, bool isNNOutput = false); - 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); - template - void serializePads(const Op &op, uint32_t padsRank); std::string _modelName = "NN"; - const uint32_t _formatVersion = 1; - uint32_t _modelHash = 0; - std::vector _packedParameters; std::list _inferenceSequence; size_t _allocatedTensors = 0; std::vector _inputs; diff --git a/contrib/nnc/libs/backend/soft/include/serializer.h b/contrib/nnc/libs/backend/soft/include/serializer.h new file mode 100644 index 0000000..b704772 --- /dev/null +++ b/contrib/nnc/libs/backend/soft/include/serializer.h @@ -0,0 +1,78 @@ +#ifndef _NNC_SOFT_BACKEND_SERIALIZER_H_ +#define _NNC_SOFT_BACKEND_SERIALIZER_H_ + +#include "nnc/core/IR/model/visitor/visitor.h" +#include "nncc/core/ADT/tensor/Shape.h" +#include "nnc/core/linalg/TensorVariant.h" +#include "model_analyzer.h" + +#include +#include + +namespace nncc +{ +namespace contrib +{ +namespace backend +{ +namespace soft +{ + +namespace model = nncc::contrib::core::IR::model; +namespace ADT = model::ADT; +namespace ops = model::ops; + +class Serializer: public model::Visitor +{ +public: + + void visit(ADT::INode *node, ops::ConcatOp &op) override; + void visit(ADT::INode *node, ops::Conv2DOp &op) override; + void visit(ADT::INode *node, ops::DepthwiseConv2DOp &op) override; + void visit(ADT::INode *node, ops::SoftmaxOp &op) override; + void visit(ADT::INode *node, ops::PoolOp &op) override; + void visit(ADT::INode *node, ops::FullyConnectedOp &op) override; + void visit(ADT::INode *node, ops::CappedReluOp &op) override; + void visit(ADT::INode *node, ops::BiasAddOp &op) override; + void visit(ADT::INode *node, ops::VariableOp &op) override; + void visit(ADT::INode *node, ops::ReluOp &op) override; + void visit(ADT::INode *node, ops::ReshapeOp &op) override; + + void serialize(std::list &inferenceSequence); + + const std::vector &getBuffer() const + { + return _buffer; + } + + uint32_t getFormatVersion() const + { + return _formatVersion; + } + + uint32_t getModelHash() const + { + return _modelHash; + } +private: + 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); + template + void serializePads(const Op &op, uint32_t padsRank); + + ModelAnalyzer::OpDescr *_curOp; + const uint32_t _formatVersion = 1; + uint32_t _modelHash = 0; + std::vector _buffer; +}; + +} // namespace soft +} // namespace backend +} // namespace contrib +} // namespace nncc + +#endif //_NNC_SOFT_BACKEND_SERIALIZER_H_ + diff --git a/contrib/nnc/libs/backend/soft/src/base_generator.cpp b/contrib/nnc/libs/backend/soft/src/base_generator.cpp index e911a3e..b6671e5 100644 --- a/contrib/nnc/libs/backend/soft/src/base_generator.cpp +++ b/contrib/nnc/libs/backend/soft/src/base_generator.cpp @@ -1,5 +1,6 @@ #include "base_generator.h" #include "model_analyzer.h" +#include "serializer.h" #include "PluginException.h" #include "nnc/core/IR/model/actions/ShapeInference.h" @@ -112,14 +113,14 @@ void BaseCodeGenerator::checkCorrectness() } } -void BaseCodeGenerator::materializeModelParams(ostream &out, const ModelAnalyzer &ma) +void BaseCodeGenerator::materializeModelParams(ostream &out, const Serializer &s) { using namespace parameters_format; // First form a dump header char header[HEADER_LEN]; - uint32_t version = ma.getFormatVersion(); - uint32_t hash = ma.getModelHash(); + uint32_t version = s.getFormatVersion(); + uint32_t hash = s.getModelHash(); static_assert(VERSION_LEN == sizeof(version), "version length mismatch"); static_assert(HASH_LEN == sizeof(hash), "hash length mismatch"); memcpy(header, MAGIC, MAGIC_LEN); @@ -131,7 +132,7 @@ void BaseCodeGenerator::materializeModelParams(ostream &out, const ModelAnalyzer { throw PluginException("Failed to write model parameters header"); } - auto ¶ms = ma.getPackedParameters(); + auto ¶ms = s.getBuffer(); out.write(params.data(), params.size()); if (out.fail()) { @@ -147,6 +148,9 @@ void BaseCodeGenerator::generate(Graph *g) // visit and analyze graph ModelAnalyzer ma; g->accept(&ma); + // serialize parameters + Serializer serializer; + serializer.serialize(ma.getInferenceSequence()); // rename tensors for specific backend language formatTensorNames(ma); // Print header @@ -156,12 +160,12 @@ void BaseCodeGenerator::generate(Graph *g) // Print code auto codeStream = getStream(_codeFile); - materializeCode(*codeStream, ma); + materializeCode(*codeStream, ma, serializer); codeStream.reset(); // Print model parameters auto modelStream = getStream(_modelFile); - materializeModelParams(*modelStream, ma); + materializeModelParams(*modelStream, serializer); modelStream.reset(); } diff --git a/contrib/nnc/libs/backend/soft/src/c_generator.cpp b/contrib/nnc/libs/backend/soft/src/c_generator.cpp index bb07423..074351e 100644 --- a/contrib/nnc/libs/backend/soft/src/c_generator.cpp +++ b/contrib/nnc/libs/backend/soft/src/c_generator.cpp @@ -33,7 +33,7 @@ void CCodeGenerator::materializeHeader(ostream &out, const ModelAnalyzer &ma) // TODO emit C header to out stream } -void CCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma) +void CCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma, const Serializer &s) { // TODO emit C code to out stream } diff --git a/contrib/nnc/libs/backend/soft/src/cpp_generator.cpp b/contrib/nnc/libs/backend/soft/src/cpp_generator.cpp index 630c05c..e4f7ac1 100644 --- a/contrib/nnc/libs/backend/soft/src/cpp_generator.cpp +++ b/contrib/nnc/libs/backend/soft/src/cpp_generator.cpp @@ -1,5 +1,6 @@ #include "cpp_generator.h" #include "model_analyzer.h" +#include "serializer.h" #include "PluginException.h" #include "param_constants.def" @@ -193,7 +194,7 @@ void CPPCodeGenerator::materializeInferenceSequence(ostream &out, const ModelAna } // TODO think about better string formatting to make code more readable -void CPPCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma) +void CPPCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma, const Serializer &s) { string className = ma.getModelName() + "Model"; @@ -220,7 +221,7 @@ void CPPCodeGenerator::materializeCode(ostream &out, const ModelAnalyzer &ma) out << className << "::" << className << "(const string ¶metersPath)\n" "{\n" " readParameters(_parameters, _paramSize, parametersPath, " - << ma.getFormatVersion() << ", " << ma.getModelHash() << ");\n" + << s.getFormatVersion() << ", " << s.getModelHash() << ");\n" "}\n\n"; // gen NN destructor out << className << "::~" << className << "()\n" diff --git a/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp b/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp index 474af6b..6abf348 100644 --- a/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp +++ b/contrib/nnc/libs/backend/soft/src/model_analyzer.cpp @@ -33,83 +33,8 @@ 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 < numeric_limits::max()); - 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()) < numeric_limits::max()); - serializeT(etoi(t.getDataType())); - // seriazlie data size - size_t eSize = t.getElementSize(); - assert(eSize < numeric_limits::max()); - 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); - } -} - -template -void ModelAnalyzer::serializePads(const Op &op, uint32_t padsRank) -{ - // serialize padding type - assert(etoi(op.getPaddingType()) < numeric_limits::max()); - serializeT(etoi(op.getPaddingType())); - // serialize pads - assert(padsRank < numeric_limits::max()); - serializeT(padsRank); - for (int i = 0; i < padsRank; ++i) - { - auto pad = op.getPadding(i); - assert(pad <= numeric_limits::max()); - assert(pad >= 0); - serializeT(pad); - } -} - void ModelAnalyzer::addOpDescr(ADT::INode *node, const string &opName) { - size_t offset = _packedParameters.size(); OpDescr::Type type = OpDescr::Type::ORDINARY; vector nodeOutputs; const std::string &name = node->getName(); @@ -149,9 +74,8 @@ void ModelAnalyzer::addOpDescr(ADT::INode *node, const string &opName) _inferenceSequence.push_back({type, node, opName, std::move(nodeInputs), std::move(nodeOutputs), - offset}); + 0}); _nodeToDescr[node] = &_inferenceSequence.back(); - // TODO add model hashing } size_t ModelAnalyzer::allocateTensor(const string &name, bool isNNInput, bool isNNOutput) @@ -166,48 +90,21 @@ size_t ModelAnalyzer::allocateTensor(const string &name, bool isNNInput, bool is void ModelAnalyzer::visit(ADT::INode *node, ops::ConcatOp &op) { addOpDescr(node, "concat"); - // axis number should fit into one byte - assert(op.getAxis() < numeric_limits::max()); - serializeT(op.getAxis()); - serializeShape(op.getOutputShape(0)); } void ModelAnalyzer::visit(ADT::INode *node, ops::Conv2DOp &op) { addOpDescr(node, "conv2d"); - // serialize kernel - const TensorVariant &kernel = op.getKernel(); - serializeTensor(kernel); - // serialize strides - serializeShape(op.getStrides()); - // serialize pads - uint32_t padsRank = op.getInputShape(0).rank(); - serializePads(op, padsRank); - // serialize output shape - serializeShape(op.getOutputShape(0)); } void ModelAnalyzer::visit(ADT::INode *node, ops::DepthwiseConv2DOp &op) { addOpDescr(node, "depthwiseConv2d"); - // serialize kernel - const TensorVariant &kernel = op.getKernel(); - serializeTensor(kernel); - // serialize strides - serializeShape(op.getStrides()); - // serialize pads - uint32_t padsRank = kernel.getShape().rank(); - serializePads(op, padsRank); - // serialize output shape - serializeShape(op.getOutputShape(0)); } void ModelAnalyzer::visit(ADT::INode *node, ops::SoftmaxOp &op) { addOpDescr(node, "softmax"); - // axis number should fit into one byte - assert(op.getAxis() < numeric_limits::max()); - serializeT(op.getAxis()); } void ModelAnalyzer::visit(ADT::INode *node, ops::PoolOp &op) @@ -225,55 +122,37 @@ void ModelAnalyzer::visit(ADT::INode *node, ops::PoolOp &op) assert(false && "unsupported pooling type"); } addOpDescr(node, funcName); - // serialize window shape - const Shape &windowShape = op.getWindowShape(); - serializeShape(windowShape); - // serialize strides - serializeShape(op.getStrides()); - // serialize pads - uint32_t padsRank = windowShape.rank(); - serializePads(op, padsRank); - // serialize output shape - serializeShape(op.getOutputShape(0)); } void ModelAnalyzer::visit(ADT::INode *node, ops::FullyConnectedOp &op) { addOpDescr(node, "fullConnect"); - serializeTensor(op.getWeights()); - serializeShape(op.getOutputShape(0)); } void ModelAnalyzer::visit(ADT::INode *node, ops::CappedReluOp &op) { addOpDescr(node, "cappedRelu"); - static_assert(sizeof(float) == 4, "unsupported float type"); - serializeT(op.getCap()); } void ModelAnalyzer::visit(ADT::INode *node, ops::BiasAddOp &op) { addOpDescr(node, "biasAdd"); - serializeTensor(op.getWeights()); } void ModelAnalyzer::visit(ADT::INode *node, ops::VariableOp &op) { assert(node->getPrevNodes().empty()); addOpDescr(node, "in"); - // no parameters to dump } void ModelAnalyzer::visit(ADT::INode *node, ops::ReluOp &op) { addOpDescr(node, "relu"); - // no parameters to dump } void ModelAnalyzer::visit(ADT::INode *node, ops::ReshapeOp &op) { addOpDescr(node, "reshape"); - serializeShape(op.getOutputShape(0)); } } // namespace soft diff --git a/contrib/nnc/libs/backend/soft/src/serializer.cpp b/contrib/nnc/libs/backend/soft/src/serializer.cpp new file mode 100644 index 0000000..6828238 --- /dev/null +++ b/contrib/nnc/libs/backend/soft/src/serializer.cpp @@ -0,0 +1,227 @@ +#include "serializer.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" +#include "nnc/core/IR/model/graph/ir_node.h" + +#include + +namespace nncc +{ +namespace contrib +{ +namespace backend +{ +namespace soft +{ + +static_assert(std::numeric_limits::is_iec559, "Unsupported float type"); + +using namespace std; + +using nncc::core::ADT::tensor::Shape; +using nncc::core::ADT::tensor::Index; +using nncc::contrib::core::data::ShapeRange; +using nncc::contrib::core::ADT::TensorVariant; + +namespace +{ + const auto MAX_DIMS = numeric_limits::max(); + const auto MAX_DIM_SIZE = numeric_limits::max(); + const auto MAX_ENUM_VAL = numeric_limits::max(); +} // unnamed namespace + +void Serializer::packData(const void *data, size_t size) +{ + const char *p = static_cast(data); + size_t old_size = _buffer.size(); + _buffer.resize(old_size + size); + copy(p, p + size, _buffer.data() + old_size); +} + +template +void Serializer::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 Serializer::serializeShape(const Shape &s) +{ + uint32_t rank = s.rank(); + assert(rank < MAX_DIMS); + serializeT(s.rank()); + for (uint32_t i = 0; i < rank; ++i) + { + uint32_t dim = s.dim(i); + serializeT(dim); + } +} + +void Serializer::serializeTensor(const TensorVariant &t) +{ + // serialize type + assert(etoi(t.getDataType()) < MAX_ENUM_VAL); + serializeT(etoi(t.getDataType())); + // seriazlie data size + size_t eSize = t.getElementSize(); + assert(eSize < MAX_DIMS); + serializeT(eSize); + // serialize shape + const Shape &shape = t.getShape(); + serializeShape(shape); + // serialize actual data + size_t tSize = eSize * num_elements(shape); + + size_t oldSize = _buffer.size(); + _buffer.reserve(oldSize + tSize); + for (const Index &idx: ShapeRange(shape)) + { + packData(t.at(idx), eSize); + } +} + +template +void Serializer::serializePads(const Op &op, uint32_t padsRank) +{ + // serialize padding type + assert(etoi(op.getPaddingType()) < MAX_ENUM_VAL); + serializeT(etoi(op.getPaddingType())); + // serialize pads + assert(padsRank < MAX_DIMS); + serializeT(padsRank); + for (int i = 0; i < padsRank; ++i) + { + auto pad = op.getPadding(i); + assert(pad <= MAX_DIM_SIZE); + assert(pad >= 0); + serializeT(op.getPadding(i)); + } +} + +void Serializer::visit(ADT::INode *node, ops::ConcatOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + // axis number should fit into one byte + assert(op.getAxis() < MAX_DIMS); + serializeT(op.getAxis()); + serializeShape(op.getOutputShape(0)); +} + +void Serializer::visit(ADT::INode *node, ops::Conv2DOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + // serialize kernel + const TensorVariant &kernel = op.getKernel(); + serializeTensor(kernel); + // serialize strides + serializeShape(op.getStrides()); + // serialize pads + uint32_t padsRank = op.getInputShape(0).rank(); + serializePads(op, padsRank); + // serialize output shape + serializeShape(op.getOutputShape(0)); +} + +void Serializer::visit(ADT::INode *node, ops::DepthwiseConv2DOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + // serialize kernel + const TensorVariant &kernel = op.getKernel(); + serializeTensor(kernel); + // serialize strides + serializeShape(op.getStrides()); + // serialize pads + uint32_t padsRank = kernel.getShape().rank(); + serializePads(op, padsRank); + // serialize output shape + serializeShape(op.getOutputShape(0)); +} + +void Serializer::visit(ADT::INode *node, ops::SoftmaxOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + // axis number should fit into one byte + assert(op.getAxis() < MAX_DIMS); + serializeT(op.getAxis()); +} + +void Serializer::visit(ADT::INode *node, ops::PoolOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + // serialize window shape + const Shape &windowShape = op.getWindowShape(); + serializeShape(windowShape); + // serialize strindes + serializeShape(op.getStrides()); + // serialize pads + uint32_t padsRank = windowShape.rank(); + serializePads(op, padsRank); + // serialize output shape + serializeShape(op.getOutputShape(0)); +} + +void Serializer::visit(ADT::INode *node, ops::FullyConnectedOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + serializeTensor(op.getWeights()); + serializeShape(op.getOutputShape(0)); +} + +void Serializer::visit(ADT::INode *node, ops::CappedReluOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + serializeT(op.getCap()); +} + +void Serializer::visit(ADT::INode *node, ops::BiasAddOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + serializeTensor(op.getWeights()); +} + +void Serializer::visit(ADT::INode *node, ops::VariableOp &op) +{ + // no parameters to dump +} + +void Serializer::visit(ADT::INode *node, ops::ReluOp &op) +{ + // no parameters to dump +} + +void Serializer::visit(ADT::INode *node, ops::ReshapeOp &op) +{ + _curOp->_paramStartOffset = _buffer.size(); + serializeShape(op.getOutputShape(0)); +} + +void Serializer::serialize(list &inferenceSequence) +{ + for (ModelAnalyzer::OpDescr &descr: inferenceSequence) + { + ADT::INode *node = descr._node; + _curOp = &descr; + node->accept(this); + } +} + +} // namespace soft +} // namespace backend +} // namespace contrib +} // namespace nncc diff --git a/contrib/nnc/libs/backend/soft/src/soft_backend.cpp b/contrib/nnc/libs/backend/soft/src/soft_backend.cpp index 381ddb0..ca8188e 100644 --- a/contrib/nnc/libs/backend/soft/src/soft_backend.cpp +++ b/contrib/nnc/libs/backend/soft/src/soft_backend.cpp @@ -8,8 +8,6 @@ #include "ConfigException.h" #include "PluginType.h" #include "nnc/core/IR/model/graph/graph.h" -#include "cpp_generator.h" -#include "c_generator.h" using namespace std; using namespace nncc::contrib; -- 2.7.4