diff options
Diffstat (limited to 'compiler/nnc/backends/acl_soft_backend/AclCppOpGenerator.h')
-rw-r--r-- | compiler/nnc/backends/acl_soft_backend/AclCppOpGenerator.h | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/compiler/nnc/backends/acl_soft_backend/AclCppOpGenerator.h b/compiler/nnc/backends/acl_soft_backend/AclCppOpGenerator.h new file mode 100644 index 000000000..79a7a6f3f --- /dev/null +++ b/compiler/nnc/backends/acl_soft_backend/AclCppOpGenerator.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _NNC_ACL_CPP_OP_GENERATOR_H_ +#define _NNC_ACL_CPP_OP_GENERATOR_H_ + +#include "mir/Visitor.h" +#include "mir/TensorVariant.h" +#include "mir/Operation.h" +#include "mir/Graph.h" +#include "ArtifactModel.h" +#include "ArtifactGeneratorCppCode.h" +#include "ArtifactGeneratorCppDecl.h" + +#include <set> + +namespace nnc +{ + +/** + * @brief Implements the visitor for the model IR which generates the DOM description + * translated to C++ source/header files by the ACL soft backend code generators. + */ +class AclCppOpGenerator : public mir::Visitor +{ +public: + AclCppOpGenerator(const std::string &name, std::ostream &par_out); + /** + * @brief The main interface function to the class. Convers the model IR to the DOM. + * @param g - pointer the model IR graph. + * @return - reference to the top-level DOM entity. + */ + const ArtifactModule &generate(mir::Graph *g); + + /** + * @brief Implementations of the MIR visitors. + * @param op + */ + void visit(mir::ops::AddOp &op) override; + void visit(mir::ops::AvgPool2DOp &op) override; + void visit(mir::ops::CappedReluOp &op) override; + void visit(mir::ops::ConcatOp &op) override; + void visit(mir::ops::ConstantOp &op) override; + void visit(mir::ops::Conv2DOp &op) override; + void visit(mir::ops::DeConv2DOp &op) override; + void visit(mir::ops::DepthwiseConv2DOp &op) override; + void visit(mir::ops::DivOp &op) override; + void visit(mir::ops::EluOp &op) override; + void visit(mir::ops::FullyConnectedOp &op) override; + void visit(mir::ops::GatherOp &op) override; + void visit(mir::ops::InputOp &op) override; + void visit(mir::ops::LeakyReluOp &op) override; + void visit(mir::ops::MaxOp &op) override; + void visit(mir::ops::MaxPool2DOp &op) override; + void visit(mir::ops::MulOp &op) override; + void visit(mir::ops::OutputOp &op) override; + void visit(mir::ops::PadOp &op) override; + void visit(mir::ops::ReluOp &op) override; + void visit(mir::ops::ReshapeOp &op) override; + void visit(mir::ops::ResizeOp &op) override; + void visit(mir::ops::SigmoidOp &op) override; + void visit(mir::ops::SliceOp &op) override; + void visit(mir::ops::SoftmaxOp &op) override; + void visit(mir::ops::SqrtOp &op) override; + void visit(mir::ops::SqueezeOp &op) override; + void visit(mir::ops::SubOp &op) override; + void visit(mir::ops::TanhOp &op) override; + void visit(mir::ops::TransposeOp &op) override; + +protected: + void visit_fallback(mir::Operation &op) override; + +private: + using AF = ArtifactFactory; + + /** + * @brief generate transpose of input tensor NHWC -> NCHW + * @param name name of tensor containing transposed data + * @param input_shape shape of @p input + * @param input id of input tensor + * @return Id of result tensor + */ + std::shared_ptr<ArtifactId> genTransposeMIRtoACL(const std::string &name, + const mir::Shape &input_shape, + const std::shared_ptr<ArtifactId> &input); + + /** + * @brief generate transpose NCHW -> NHWC + * @param name name of tensor containing transposed data + * @param input_shape shape of @p input + * @param input id of input tensor + * @return Id of result tensor + */ + std::shared_ptr<ArtifactId> genTransposeACLtoMIR(const std::string &name, + const mir::Shape &input_shape, + const std::shared_ptr<ArtifactId> &input); + + /** + * @brief Generate DOM for PadStrideInfo object + * @tparam Oper Class of operation with pad and stride properties + * @param op Operation entity to generate variable for + * @param prefix First part of generated variable name + * @param block Code block where insert variable declaration + * @return generated variable + */ + template <typename Op> + std::shared_ptr<ArtifactVariable> genPadStrideInfo(const Op &op, const std::string &prefix, + ArtifactBlock *block); + + template <typename Op> + void genPooling(Op &op, const std::string &pooling_type, bool exclude_padding); + + /** + * @brief The common part of the convolution and the depthwise convolution. + */ + template <typename Op> + void genConvolution(Op &op, const std::string &acl_func_name, const std::string &suffix); + + /** + * @brief Generates different types of activation functions: ReLU, Tanh etc. + * @param activation_name - names of activation functions used in ACL: RELU, TANH etc. + * @param a - alpha parameter used by some activation functions: BOUNDED_RELU, LU_BOUNDED_RELU, + * LINEAR, TANH. + * @param b - betha parameter used by some activation functions: LINEAR, LU_BOUNDED_RELU, TANH. + */ + void genActivation(const mir::Operation &op, const std::string &activation_name, float a = 0, + float b = 0); + + /** + * @brief Used to generate a binary addition operation in handling of the elementwise. + * + * @param prefix - the name (in the DOM) of operation called this method. + * @param index - the index of the call in the elementwise loop. + * @param ir_shape - the shape of the operands in the IR. + * @param in1 - the descriptor of the first operand in the DOM. Can be either original tensor + * identifier in the input sequence or a variable storing the partial result of + * applying the operation to the previous terms in the sequence. + * @param in2 - the descriptor of the second operand in the DOM. + * @param out - the descriptor for storing the operation result. If it is not nullptr, it is + * used to return the result. If it is nullptr (the default), a new tensor is + * allocated in the DOM to return the result. + * @return - the DOM ID of the temporary variable storing the partial sum of the elements + * to the left of and including the in2 term, or the operation out if in2 was + * the last term in the sequence. + */ + std::shared_ptr<ArtifactId> genAddition(const std::string &prefix, size_t index, + const mir::Shape &ir_shape, + const std::shared_ptr<ArtifactId> &in1, + const std::shared_ptr<ArtifactId> &in2, + std::shared_ptr<ArtifactId> out = nullptr); + + /** + * @brief Used to generate a binary multiplication operation in handling of the + * elementwise. As there is currently no the CLArithmeticMultiplication in the + * ACL library, in1 * in2 is emulated as: in1 / (1 / in2) with + * CLArithmeticDivision. + * + * @param prefix - the name (in the DOM) of operation called this method. + * @param index - the index of the call in the elementwise loop. + * @param ir_shape - the shape of the operands in the IR. + * @param in1 - the descriptor of the first operand in the DOM. Can be either original tensor + * identifier in the input sequence or a variable storing the partial result of + * applying the operation to the previous terms in the sequence. + * @param in2 - the descriptor of the second operand in the DOM. + * @param out - the descriptor for storing the operation result. If it is not nullptr, it is + * used to return the result. If it is nullptr (the default), a new tensor is + * allocated in the DOM to return the result. + * @return - the DOM ID of the temporary variable storing the partial product of the + * elements to the left of and including the in2 term, or the operation out if + * in2 was the last term in the sequence. + */ + std::shared_ptr<ArtifactId> genMultiplication(const std::string &prefix, size_t index, + const mir::Shape &ir_shape, + const std::shared_ptr<ArtifactId> &in1, + const std::shared_ptr<ArtifactId> &in2, + std::shared_ptr<ArtifactId> out = nullptr); + + /** + * @brief Generates a unique name for the tensor. + */ + std::string tensorName(const mir::Operation::Output *ir_tensor) const; + + /** + * @brief Generates variables tensor shape in DOM. + * @param block - DOM block where to create this shape: artifact constructor, inference function. + * @param name - prefix used for generating the unique name for this shape. + * @param shape - model IR shape for which we create a DOM analogue. + * @return - a DOM identifier for the created shape. + */ + template <typename T> + std::shared_ptr<ArtifactId> genVectorInitializedVar(ArtifactBlock *block, const std::string &type, + const std::string &name, + const std::vector<T> &init); + + /** + * @brief Generates a DOM tensor. + * @param name - its name. + * @param ir_shape - IR shape used to construct the tensor. + * @param gen_accessor - whether to generate an accessor function for this tensor + * in the artifact class. + * @return - a DOM identifier for the created tensor. + */ + std::shared_ptr<ArtifactId> genTensor(const std::string &name, const mir::Shape &ir_shape, + bool gen_accessor = false); + + /** + * @brief Generates a DOM tensor. + * @param ir_tensor - the ModelIR tensor. + * @return - a DOM identifier for the created tensor. + */ + std::shared_ptr<ArtifactId> genTensor(const mir::Operation::Output *ir_tensor); + + /** + * @brief generate transposing operation, @p mir_perm contains dimensions in MIR order (batch has + * index 0) + * @param input id of input tensor + * @param output id out output tensor + * @param mir_perm new order of dimensions + */ + void genTranspose(const std::shared_ptr<nnc::ArtifactId> &input, + const std::shared_ptr<nnc::ArtifactId> &output, + const std::vector<size_t> &mir_perm, bool allocate_at_inference); + + /** + * @brief Generates accessors for the input/output tensors. + * @param graph - the ModelIR graph. + */ + void genNamed(mir::Graph *graph); + + /** + * @brief Schedule a tensor serialization. + * @param tensor_id - an artifact ID of the tensor. + * @param ir_tensor - the IR source of the tensor. + */ + void serializeTensor(const std::shared_ptr<ArtifactId> &tensor_id, + const mir::TensorVariant &ir_tensor); + + /** + * @brief Serialize an IR tensor in a file. + * @param tensor - tensor to serialize. + */ + void serializeIRTensor(const mir::TensorVariant &tensor); + + /** + * @brief Generate the deserialization calls in right places in the artifact. + */ + void genDeserializations(); + + /** + * @brief Generate procedure calls for filling tensors with constant scalar values. + */ + void genFillings(); + + /** + * @brief Store the tensor ID and its value for the successive generation (for uniform tensors). + * @param tensor_id - ID of the tensor. + * @param val - its value. + */ + void fillTensor(const std::shared_ptr<ArtifactId> &tensor_id, const std::string &val); + + /** + * @brief Schedule the tensor allocation in the artifact constructor. + * @param tensor_id - ID of the scheduled tensor. + */ + void addToPersistentTensors(const std::shared_ptr<ArtifactId> &tensor_id); + + /** + * @brief Generate allocation of tensor + * @param block Block to insert allocation in + * @param tensor Id of tensor to allocate + */ + std::shared_ptr<ArtifactFunctionCall> + genTensorAllocation(ArtifactBlock *block, const std::shared_ptr<ArtifactId> &tensor); + + /** + * @brief Generate deallocation of tensor + * @param block Block to insert deallocation in + * @param tensor Id of tensor to deallocate + */ + std::shared_ptr<ArtifactFunctionCall> + genTensorDeallocation(ArtifactBlock *block, const std::shared_ptr<ArtifactId> &tensor); + + /** + * @brief Generate all the scheduled tensor allocations. + */ + void genPersistentTensorAllocations(); + + /** + * @brief Generate the layer declaration and the configure() call. + * @param layer_type - ACL layer type. + * @param layer_name - name of the layer variable in the artifact. + * @param config_params - input/output tensor names and the other configuration information. + * @return - generated tensor ID. + */ + std::shared_ptr<ArtifactId> + genLayer(const std::string &layer_type, const std::string &layer_name, + const std::list<std::shared_ptr<ArtifactExpr>> &config_params); + + /** + * @brief Generate the layer run() call. + * @param layer_id - layer ID. + */ + void genLayerExecution(const std::shared_ptr<ArtifactId> &layer_id); + + /** + * @brief All named tensors names. + */ + std::set<std::string> _tensorNames; + + /** + * @brief The stream for tensors serialization. + */ + std::ostream &_parOut; + + /** + * @brief The whole artifact module in the DOM. + */ + ArtifactModule _module; + + /** + * @brief The artifact class. + */ + std::shared_ptr<ArtifactClass> _artifactClass; + + /** + * @brief The artifact inference function. + */ + std::shared_ptr<ArtifactClassFunction> _inferenceFunction; + + /** + * @brief The constuctor block of DOM instructions. + */ + ArtifactBlock *_constrBlock; + + /** + * @brief The inference function block of DOM instruction. + */ + ArtifactBlock *_infBlock; + + /** + * @brief The variable describing the input stream for tensors deserialization. + */ + std::shared_ptr<ArtifactVariable> _parInVar; + + /** + * @brief The identifier to reference the previous variable. + */ + std::shared_ptr<ArtifactId> _parIn; + + /** + * @brief The CLScheduler class representation in the DOM. + */ + std::shared_ptr<ArtifactId> _clScheduler; + + /** + * @brief Tensors which need to be allocated at the artifact construction time. + */ + std::list<std::shared_ptr<ArtifactId>> _persistent_tensors; + + /** + * @brief Tensors which are serialized from the Model IR and need to be deserialized in the + * artifact. + */ + std::list<std::shared_ptr<ArtifactId>> _serializations; + + /** + * @brief Tensors which must be filled with constant values and the corresponding values. + */ + std::list<std::pair<std::shared_ptr<ArtifactId>, std::string>> _fillings; +}; + +} // namespace nnc + +#endif //_NNC_ACL_CPP_OP_GENERATOR_H_ |