/* * Copyright (c) 2022 Arm Limited. * * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef ENABLE_EXPERIMENTAL_DYNAMIC_FUSION #error "This experimental feature must be enabled with -DENABLE_EXPERIMENTAL_DYNAMIC_FUSION" #endif /* ENABLE_EXPERIMENTAL_DYNAMIC_FUSION */ #ifndef ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_OPERATORGRAPH #define ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_OPERATORGRAPH #include "arm_compute/core/Error.h" #include "arm_compute/core/ITensorInfo.h" #include namespace arm_compute { namespace experimental { namespace dynamic_fusion { /** Graph of operators to execute within a Workload. This is a pure descriptive construct. */ class OperatorGraph final { public: struct Implementation; OperatorGraph(); ~OperatorGraph(); public: Implementation *impl(); const Implementation *impl() const; private: std::unique_ptr _impl; }; /** Return the validity of @p op_graph, usually after performing an operation (e.g. add_tensor) on it * * @param[in,out] op_graph OperatorGraph to be validated * * @return Status */ Status validate(const OperatorGraph &op_graph); /** Operator Tensor Handle * This can be either an argument tensor, or an intermediate tensor linking 2 @ref Operator s */ class OpTensor final { public: using Id = int; OpTensor(Id id = {}); /** Id of the OpTensor * @return Id */ Id id() const; private: Id _id{}; }; /** Provide order of @ref OpTensor by checking if @p t0 is "lower than" @p t1 * * @param[in] t0 OpTensor * @param[in] t1 OpTensor * * @return true if @p t0 is lower than @p t1 * @return false otherwise */ bool operator<(const OpTensor &t0, const OpTensor &t1); /** Associate a TensorInfo with a newly created @ref OpTensor in the @p graph. * * @note @p info needs to remain in scope and valid until the workload has finished building * @note Can pass in an empty TensorInfo for a destination Tensor, in which case @p info will be inferred from the source tensors * * @param[in,out] graph OperatorGraph where the tensor is added * @param[in] info TensorInfo to be associated * * @return OpTensor */ OpTensor add_tensor(OperatorGraph &graph, ITensorInfo &info); /** Operator Handle * This can be used to further modify an existing operator */ class Operator final { public: using Id = int; Operator(Id id = {}); /** Id of the Operator * @return Id */ Id id() const; private: Id _id{}; }; /** Provide order of @ref Operator by checking if @p op0 is "lower than" @p op1 * * @param[in] op0 Operator * @param[in] op1 Operator * * @return true if @p op0 is lower than @p op1 * @return false otherwise */ bool operator<(const Operator &op0, const Operator &op1); /** Padding information for 2D operations like Conv2dDescriptor */ struct Padding2D { Padding2D() = default; Padding2D(size_t left, size_t right, size_t top, size_t bottom) : left(left), right(right), top(top), bottom(bottom) { } size_t left = { 0 }; /**< Padding across the width dimension on the left, in elements. */ size_t right = { 0 }; /**< Padding across the width dimension on the right, in elements. */ size_t top = { 0 }; /**< Padding across the height dimension on the top, in elements. */ size_t bottom = { 0 }; /**< Padding across the height dimension on the bottom, in elements. */ }; /** Descriptor for Conv2dDescriptor operation */ struct Conv2dDescriptor { /* TOSA compliant attribute parameters start */ Padding2D pad{}; Size2D stride{ 1U, 1U }; Size2D dilation{ 1U, 1U }; /* TOSA compliant attribute parameters end */ /* Non-TOSA compliant attribute parameters start */ /* Non-TOSA compliant attribute parameters end */ }; /** Add op Conv2d to @p graph * * @param[in,out] graph OperatorGraph where the operator is added to * @param[in] desc Operator descriptor * @param[in] input Input OpTensor * @param[in] weights Weights OpTensor * @param[in] bias (Optional) bias OpTensor * @param[in] dst Destination OpTensor * * @return Operator */ Operator add_op_conv2d(OperatorGraph &graph, const Conv2dDescriptor &desc, OpTensor input, OpTensor weights, OpTensor bias, OpTensor dst); Operator add_op_conv2d(OperatorGraph &graph, const Conv2dDescriptor &desc, OpTensor input, OpTensor weights, OpTensor dst); /** (Only for Debuging and Testing) Force a conv2d method * * @param[in,out] graph OperatorGraph where conv2d op is located * @param[in] conv2d Conv2d Op * @param[in] method Forced ConvolutionMethod */ void force_conv2d_method(OperatorGraph &graph, Operator conv2d, ConvolutionMethod method); /** Descriptor for Addition operation * */ struct AddDescriptor { /* TOSA compliant attribute parameters start */ /* TOSA compliant attribute parameters end */ /* Non-TOSA compliant attribute parameters start */ /* Non-TOSA compliant attribute parameters end */ }; /** Add op Add to @p graph, and optionally describes fusion through passing of intermediate @ref OpTensor s * * @param[in,out] graph OperatorGraph where the operator is added to * @param[in] desc Operator descriptor * @param[in] lhs Lhs OpTensor * @param[in] rhs Rhs OpTensor * @param[in] dst Destination OpTensor * * @return Operator */ Operator add_op_elementwise_add(OperatorGraph &graph, const AddDescriptor &desc, OpTensor lhs, OpTensor rhs, OpTensor dst); bool operator==(const OpTensor &t0, const OpTensor &t1); bool operator==(const Padding2D &pad0, const Padding2D &pad1); bool operator==(const Conv2dDescriptor &conv2d0, const Conv2dDescriptor &conv2d1); bool operator==(const AddDescriptor &, const AddDescriptor &); } // namespace dynamic_fusion } // namespace experimental } // namespace arm_compute #endif //ARM_COMPUTE_EXPERIMENTAL_DYNAMICFUSION_OPERATORGRAPH