aboutsummaryrefslogtreecommitdiff
path: root/arm_compute/runtime/experimental/ClCompositeOperator.h
blob: 827629bd8239422fde49e18908ec42d975e415c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/*
 * 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.
 */
#ifdef ENABLE_EXPERIMENTAL_DYNAMIC_FUSION
#ifndef ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H
#define ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H

#include "arm_compute/core/CL/CLCompileContext.h"
#include "arm_compute/runtime/CL/CLTensor.h"
#include "arm_compute/runtime/IOperator.h"

#include "arm_compute/core/experimental/ClWorkload.h"

#include <memory>

namespace arm_compute
{
namespace experimental
{
namespace dynamic_fusion
{
/** Map OpTensor handles to their corresponding ITensor memory
 */
using OpTensorBinding = std::map<OpTensor, ITensor *>;

/** Map a kernel (as identified by its unit workload id) to its corresponding tensor pack
 *
 * @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
 */
class TensorPackMap
{
public:
    /** Find a tensor pack associated with the unit workload Id @p uwk_id
     *
     * @param[in] uwk_id unit workload Id associated with the tensor pack
     *
     * @return ITensorPack*
     */
    ITensorPack *find_tensor_pack(UnitWorkload::Id uwk_id);
    /** Get a tensor pack associated with @p uwk_id. Throws a exception if it cannot be found.
     *
     * @param[in] uwk_id unit workload Id associated with the tensor pack
     *
     * @return ITensorPack*
     */
    ITensorPack &get_tensor_pack(UnitWorkload::Id uwk_id);
    /** Add a tensor pack and associate it with unit workload Id @p uwk_id
     * @note Should not be used by external user
     *
     * @param[in] uwk_id      unit workload Id associated with the tensor pack
     * @param[in] tensor_pack Tensor Pack to be added
     */
    void add_tensor_pack(UnitWorkload::Id uwk_id, const ITensorPack &tensor_pack);

private:
    std::map<UnitWorkload::Id, ITensorPack> _tensor_packs{};
};

/** Holder of any auxiliary CLTensors required by a ClWorkload.
 *
 * @note The tensors are not allocated by default, and require the user to explicitly allocate them using the TensorInfo and AuxMemoryInfo
 *
 * @note This data holder must remain valid until the ClCompositeOperator that it's passed to is out of scope
 *
 * @note External user should not use the add_aux_tensor method, and should only use the data returned by @ref bind_tensors
 */
class ClAuxTensorData
{
public:
    /** A view of a single auxiliary data and the associated TensorInfo and AuxMemoryInfo
     */
    struct DataView
    {
        DataView() = default;
        DataView(CLTensor *tensor, const TensorInfo &tensor_info, const AuxMemoryInfo &memory_info)
            : tensor{ tensor }, tensor_info{ tensor_info }, memory_info{ memory_info }
        {
        }
        ~DataView()                     = default;
        DataView(const DataView &other) = default;
        DataView &operator=(const DataView &other) = default;
        DataView(DataView &&other)                 = default;
        DataView &operator=(DataView &&other) = default;
        CLTensor     *tensor{};      /**< Pointer to the auxiliary tensor */
        TensorInfo    tensor_info{}; /**< Associated TensorInfo */
        AuxMemoryInfo memory_info{}; /**< Memory requirement */
    };

    /** Add auxiliary tensor.
     *
     * @note Should not be used by external user
     *
     * @param[in] tensor_id   Any Id that can uniquely identify an auxiliary tensor. Usually ClWorkloadTensor Id
     * @param[in] tensor_info TensorInfo associated with the tensor
     * @param[in] memory_info Memory requirements
     *
     * @return CLTensor*  if successfully added, otherwise nullptr
     */
    CLTensor *add_aux_tensor(int tensor_id, const ITensorInfo &tensor_info, const AuxMemoryInfo &memory_info);

    /** Get views of all auxiliary tensors. This is mainly used for allocating the auxiliary tensors.
     *
     * @return std::vector<DataView>&
     */
    std::vector<DataView> &get_tensors();

private:
    std::map<int, std::unique_ptr<CLTensor>> _owned_tensors{};
    std::vector<DataView> _tensors{};
};

/** Bind tensor memory to packs used by prepare and run methods. Create auxiliary tensor objects and their memory requirements if needed
 *
 * @note This is the only method for external user to create ClAuxTensorData, and the prepare and run TensorPackMaps
 *
 * @param[out] aux_tensor_data  Auxiliary Tensors required by the workload
 * @param[out] prepare_pack_map TensorPackMap used by the prepare method
 * @param[out] run_pack_map     TensorPackMap used by the run method
 * @param[in]  workload         ClWorkload to bind the tensors to
 * @param[in]  op_tensors       CLTensor memory objects mapped from Core OpTensors
 *
 * @return Status
 */
Status bind_tensors(ClAuxTensorData &aux_tensor_data, TensorPackMap &prepare_pack_map, TensorPackMap &run_pack_map, const ClWorkload &workload, const OpTensorBinding &op_tensors);

/** Operator runtime to run a @ref ClWorkload
 *
 * @note User must explicitly call prepare before run otherwise run will fail.
 *
 */
class ClCompositeOperator
{
public:
    ClCompositeOperator();
    ~ClCompositeOperator();
    /** Configures a @ref ClCompositeOperator with a @ref ClWorkload
     * This includes the compilation of Cl kernels inside the @ref ClWorkload
     *
     * @param[in] ctx      CLCompileContext
     * @param[in] workload ClWorkload to configure with
     */
    void configure(const CLCompileContext &ctx, const ClWorkload &workload);
    /** Validate ClWorkload @p workload
     *
     * @param[in] workload ClWorkload to be validated
     *
     * @return Status
     */
    static Status validate(const ClWorkload &workload);
    /** Enqueue prepare workloads
     *
     * @param tensor_pack_map Tensors required by the prepare workloads
     */
    void prepare(TensorPackMap &tensor_pack_map);
    /** Enqueue run workloads
     *
     * @param tensor_pack_map Tensors required by the run workloads
     */
    void run(TensorPackMap &tensor_pack_map);

private:
    struct Implementation;
    std::unique_ptr<Implementation> _impl;
};

} // namespace dynamic_fusion
} // namespace experimental
} // namespace arm_compute
#endif //ARM_COMPUTE_EXPERIMENTAL_DYNAMIC_FUSION_CLCOMPOSITEOPERATOR_H
#endif /* ENABLE_EXPERIMENTAL_DYNAMIC_FUSION */