Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / runtime / onert / core / include / exec / FunctionSequence.h
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef __ONERT_EXEC_FUNCTION_SEQUENCE_H__
18 #define __ONERT_EXEC_FUNCTION_SEQUENCE_H__
19
20 #include <memory>
21 #include <cassert>
22 #include <vector>
23 #include <functional>
24
25 #include "exec/IFunction.h"
26 #include "exec/DynamicShapeInferer.h"
27 #include "ir/Operations.h"
28 #include "backend/ITensorRegistry.h"
29
30 namespace onert
31 {
32 namespace exec
33 {
34
35 class FunctionSequence : public IFunction
36 {
37 public:
38   template <typename... Args> FunctionSequence(Args &&... args) { initialize(std::move(args)...); }
39
40 private:
41   void initialize()
42   {
43     // Template base case : do nothing
44   }
45
46   template <typename T, typename... Args> void initialize(std::unique_ptr<T> &&fn, Args &&... args)
47   {
48     _functions.emplace_back(std::move(fn));
49     initialize(std::move(args)...);
50   }
51
52 public:
53   virtual ~FunctionSequence() = default;
54
55   void run() override;
56   void prepare() override;
57
58   /**
59    * @brief Appends an IFunction object to the function sequence
60    *
61    * @param function IFunction object to be appended
62    */
63   void append(std::unique_ptr<IFunction> &&function);
64
65   void iterate(const std::function<void(IFunction &)> &fn);
66
67   template <typename T, typename... Args> void wrap(Args &&... args)
68   {
69     for (auto &&function : _functions)
70     {
71       function = std::make_unique<T>(std::move(function), args...);
72     }
73   }
74
75 public: // methods related to dynamic tensor
76   struct DynamicTensorCtx
77   {
78     const ir::IOperation *op = nullptr;
79     std::shared_ptr<exec::DynamicShapeInferer> dynamic_shape_inferer = nullptr;
80   };
81
82   /**
83    * @brief Prepare to run FunctionSequence which "might" handle dynamic tensor
84    * @note  Calling this does not mean that run() will handle dynamic tensor.
85    *        enableDynamicShapeInferer(true) will make run() will handle dynamic tensor.
86    */
87   void dynamic_tensor_ctx(std::shared_ptr<DynamicTensorCtx> &dynamic_tensor_ctx)
88   {
89     _dynamic_tensor_ctx = dynamic_tensor_ctx;
90   }
91
92   std::shared_ptr<DynamicTensorCtx> &dynamic_tensor_ctx() { return _dynamic_tensor_ctx; }
93
94   /**
95    * @brief Call this function by passing @c true if this FunctionSequence handles dynamic tensors
96    *        and should run DynamicShapeInferer. This function can be called multiple times and
97    *        if @c false is passed during multiple calls, DynamicShapeInfere will not be run.
98    * @note This must be called before run(). If not called, run() assumes that all tensors are
99    *       dynamic and DynamicShapeInferer will be run.
100    */
101   void enableDynamicShapeInferer(bool enable)
102   {
103     _enable_dynamic_shape_inferer = _enable_dynamic_shape_inferer || enable;
104   }
105
106   /**
107    * @brief Call this function to initialize vars before running
108    * @note When we run a model with static tensor input and then run with dynamic tensor input,
109    *       _enable_dynamic_shape_inferer is set to @c false at first run.
110    *       Once _enable_dynamic_shape_inferer is set to @c true it cannot be changed to @c false
111    *       only with calling enableDynamicShapeInferer(). So initializing it to @c false is
112    *       necessary.
113    * @todo This is a quick fix. Adding this will increase time for run(). Find way to optimize.
114    */
115   void initRunning() { _enable_dynamic_shape_inferer = false; }
116
117 protected:
118   std::vector<std::unique_ptr<IFunction>> _functions;
119
120 protected:
121   bool _enable_dynamic_shape_inferer = false;
122
123   std::shared_ptr<DynamicTensorCtx> _dynamic_tensor_ctx = nullptr;
124 };
125
126 } // namespace exec
127 } // namespace onert
128
129 #endif // __ONERT_EXEC_FUNCTION_SEQUENCE_H__