blob: b903bc0ee6fd3580a467b1afdf42686581e40f9f [file] [log] [blame]
SiCong Lib63b1192022-01-28 18:24:39 +00001/*
2 * Copyright (c) 2022 Arm Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ENABLE_EXPERIMENTAL_DYNAMIC_FUSION
25#error "This experimental feature must be enabled with -DENABLE_EXPERIMENTAL_DYNAMIC_FUSION"
26#endif /* ENABLE_EXPERIMENTAL_DYNAMIC_FUSION */
27#ifndef ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H
28#define ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H
29
30#include "arm_compute/core/CL/CLCompileContext.h"
31#include "arm_compute/runtime/CL/CLTensor.h"
32#include "arm_compute/runtime/IOperator.h"
33
34#include "arm_compute/core/experimental/ClWorkload.h"
35
36#include <memory>
37
38namespace arm_compute
39{
40namespace experimental
41{
42namespace dynamic_fusion
43{
44/** Map OpTensor handles to their corresponding ITensor memory
45 */
46using OpTensorBinding = std::map<OpTensor, ITensor *>;
47
48/** Map a kernel (as identified by its unit workload id) to its corresponding tensor pack
49 *
50 * @note External user should not use the add_tensor_pack method to alter this tensor pack map, and should only use the map returned by @ref bind_tensors
51 */
52class TensorPackMap
53{
54public:
55 /** Find a tensor pack associated with the unit workload Id @p uwk_id
56 *
57 * @param[in] uwk_id unit workload Id associated with the tensor pack
58 *
59 * @return ITensorPack*
60 */
61 ITensorPack *find_tensor_pack(UnitWorkload::Id uwk_id);
62 /** Get a tensor pack associated with @p uwk_id. Throws a exception if it cannot be found.
63 *
64 * @param[in] uwk_id unit workload Id associated with the tensor pack
65 *
66 * @return ITensorPack*
67 */
68 ITensorPack &get_tensor_pack(UnitWorkload::Id uwk_id);
69 /** Add a tensor pack and associate it with unit workload Id @p uwk_id
70 * @note Should not be used by external user
71 *
72 * @param[in] uwk_id unit workload Id associated with the tensor pack
73 * @param[in] tensor_pack Tensor Pack to be added
74 */
75 void add_tensor_pack(UnitWorkload::Id uwk_id, const ITensorPack &tensor_pack);
76
77private:
78 std::map<UnitWorkload::Id, ITensorPack> _tensor_packs{};
79};
80
81/** Holder of any auxiliary CLTensors required by a ClWorkload.
82 *
83 * @note The tensors are not allocated by default, and require the user to explicitly allocate them using the TensorInfo and AuxMemoryInfo
84 *
85 * @note This data holder must remain valid until the ClCompositeOperator that it's passed to is out of scope
86 *
87 * @note External user should not use the add_aux_tensor method, and should only use the data returned by @ref bind_tensors
88 */
89class ClAuxTensorData
90{
91public:
92 /** A view of a single auxiliary data and the associated TensorInfo and AuxMemoryInfo
93 */
94 struct DataView
95 {
96 DataView() = default;
97 DataView(CLTensor *tensor, const TensorInfo &tensor_info, const AuxMemoryInfo &memory_info)
98 : tensor{ tensor }, tensor_info{ tensor_info }, memory_info{ memory_info }
99 {
100 }
101 ~DataView() = default;
102 DataView(const DataView &other) = default;
103 DataView &operator=(const DataView &other) = default;
104 DataView(DataView &&other) = default;
105 DataView &operator=(DataView &&other) = default;
106 CLTensor *tensor{}; /**< Pointer to the auxiliary tensor */
107 TensorInfo tensor_info{}; /**< Associated TensorInfo */
108 AuxMemoryInfo memory_info{}; /**< Memory requirement */
109 };
110
111 /** Add auxiliary tensor.
112 *
113 * @note Should not be used by external user
114 *
115 * @param[in] tensor_id Any Id that can uniquely identify an auxiliary tensor. Usually ClWorkloadTensor Id
116 * @param[in] tensor_info TensorInfo associated with the tensor
117 * @param[in] memory_info Memory requirements
118 *
119 * @return CLTensor* if successfully added, otherwise nullptr
120 */
121 CLTensor *add_aux_tensor(int tensor_id, const ITensorInfo &tensor_info, const AuxMemoryInfo &memory_info);
122
123 /** Get views of all auxiliary tensors. This is mainly used for allocating the auxiliary tensors.
124 *
125 * @return std::vector<DataView>&
126 */
127 std::vector<DataView> &get_tensors();
128
129private:
130 std::map<int, std::unique_ptr<CLTensor>> _owned_tensors{};
131 std::vector<DataView> _tensors{};
132};
133
134/** Bind tensor memory to packs used by prepare and run methods. Create auxiliary tensor objects and their memory requirements if needed
135 *
136 * @note This is the only method for external user to create ClAuxTensorData, and the prepare and run TensorPackMaps
137 *
138 * @param[out] aux_tensor_data Auxiliary Tensors required by the workload
139 * @param[out] prepare_pack_map TensorPackMap used by the prepare method
140 * @param[out] run_pack_map TensorPackMap used by the run method
141 * @param[in] workload ClWorkload to bind the tensors to
142 * @param[in] op_tensors CLTensor memory objects mapped from Core OpTensors
143 *
144 * @return Status
145 */
146Status bind_tensors(ClAuxTensorData &aux_tensor_data, TensorPackMap &prepare_pack_map, TensorPackMap &run_pack_map, const ClWorkload &workload, const OpTensorBinding &op_tensors);
147
148/** Operator runtime to run a @ref ClWorkload
149 *
150 * @note User must explicitly call prepare before run otherwise run will fail.
151 *
152 */
153class ClCompositeOperator
154{
155public:
156 ClCompositeOperator();
157 ~ClCompositeOperator();
158 /** Configures a @ref ClCompositeOperator with a @ref ClWorkload
159 * This includes the compilation of Cl kernels inside the @ref ClWorkload
160 *
161 * @param[in] ctx CLCompileContext
162 * @param[in] workload ClWorkload to configure with
163 */
164 void configure(const CLCompileContext &ctx, const ClWorkload &workload);
165 /** Validate ClWorkload @p workload
166 *
167 * @param[in] workload ClWorkload to be validated
168 *
169 * @return Status
170 */
171 static Status validate(const ClWorkload &workload);
172 /** Enqueue prepare workloads
173 *
174 * @param tensor_pack_map Tensors required by the prepare workloads
175 */
176 void prepare(TensorPackMap &tensor_pack_map);
177 /** Enqueue run workloads
178 *
179 * @param tensor_pack_map Tensors required by the run workloads
180 */
181 void run(TensorPackMap &tensor_pack_map);
182
183private:
184 struct Implementation;
185 std::unique_ptr<Implementation> _impl;
186};
187
188} // namespace dynamic_fusion
189} // namespace experimental
190} // namespace arm_compute
191#endif //ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H