blob: dd094b414c28491f7d932a70345f875bcbbaa526 [file] [log] [blame]
Georgios Pinitas856f66e2021-04-22 21:13:21 +01001/*
2 * Copyright (c) 2021 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 SRC_COMMON_MEMORY_HELPERS_H
25#define SRC_COMMON_MEMORY_HELPERS_H
26
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010027#include "arm_compute/core/experimental/Types.h"
Georgios Pinitas856f66e2021-04-22 21:13:21 +010028#include "arm_compute/core/ITensorPack.h"
29#include "arm_compute/core/TensorInfo.h"
Georgios Pinitas856f66e2021-04-22 21:13:21 +010030#include "arm_compute/runtime/MemoryGroup.h"
31
32#include <memory>
33#include <utility>
34#include <vector>
35
36namespace arm_compute
37{
38inline int offset_int_vec(int offset)
39{
40 return ACL_INT_VEC + offset;
41}
42
43template <typename TensorType>
Georgios Pinitas2b147ee2021-07-08 18:14:45 +010044struct WorkspaceDataElement
45{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010046 int slot{-1};
47 experimental::MemoryLifetime lifetime{experimental::MemoryLifetime::Temporary};
48 std::unique_ptr<TensorType> tensor{nullptr};
Georgios Pinitas2b147ee2021-07-08 18:14:45 +010049};
50
51template <typename TensorType>
52using WorkspaceData = std::vector<WorkspaceDataElement<TensorType>>;
Georgios Pinitas856f66e2021-04-22 21:13:21 +010053
54template <typename TensorType>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010055WorkspaceData<TensorType>
56manage_workspace(const experimental::MemoryRequirements &mem_reqs, MemoryGroup &mgroup, ITensorPack &run_pack)
Manuel Bottini94f799e2021-06-09 16:37:32 +010057{
58 ITensorPack dummy_pack = ITensorPack();
59 return manage_workspace<TensorType>(mem_reqs, mgroup, run_pack, dummy_pack);
60}
61
62template <typename TensorType>
63WorkspaceData<TensorType> manage_workspace(const experimental::MemoryRequirements &mem_reqs,
64 MemoryGroup &mgroup,
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010065 ITensorPack &run_pack,
66 ITensorPack &prep_pack)
Georgios Pinitas856f66e2021-04-22 21:13:21 +010067{
68 WorkspaceData<TensorType> workspace_memory;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010069 for (const auto &req : mem_reqs)
Georgios Pinitas856f66e2021-04-22 21:13:21 +010070 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010071 if (req.size == 0)
Georgios Pinitas856f66e2021-04-22 21:13:21 +010072 {
73 continue;
74 }
75
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010076 const auto aux_info = TensorInfo{TensorShape(req.size), 1, DataType::U8};
77 workspace_memory.emplace_back(
78 WorkspaceDataElement<TensorType>{req.slot, req.lifetime, std::make_unique<TensorType>()});
Georgios Pinitas856f66e2021-04-22 21:13:21 +010079
Georgios Pinitas2b147ee2021-07-08 18:14:45 +010080 auto aux_tensor = workspace_memory.back().tensor.get();
Georgios Pinitas856f66e2021-04-22 21:13:21 +010081 ARM_COMPUTE_ERROR_ON_NULLPTR(aux_tensor);
Michele Di Giorgiod7316eb2021-06-16 11:14:41 +010082 aux_tensor->allocator()->init(aux_info, req.alignment);
Georgios Pinitas856f66e2021-04-22 21:13:21 +010083
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010084 if (req.lifetime == experimental::MemoryLifetime::Temporary)
Georgios Pinitas856f66e2021-04-22 21:13:21 +010085 {
86 mgroup.manage(aux_tensor);
87 }
88 else
89 {
90 prep_pack.add_tensor(req.slot, aux_tensor);
91 }
92 run_pack.add_tensor(req.slot, aux_tensor);
93 }
94
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010095 for (auto &mem : workspace_memory)
Georgios Pinitas856f66e2021-04-22 21:13:21 +010096 {
Georgios Pinitas2b147ee2021-07-08 18:14:45 +010097 auto tensor = mem.tensor.get();
Georgios Pinitas856f66e2021-04-22 21:13:21 +010098 tensor->allocator()->allocate();
99 }
100
101 return workspace_memory;
102}
Georgios Pinitas2b147ee2021-07-08 18:14:45 +0100103
104template <typename TensorType>
105void release_prepare_tensors(WorkspaceData<TensorType> &workspace, ITensorPack &prep_pack)
106{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100107 workspace.erase(std::remove_if(workspace.begin(), workspace.end(),
108 [&prep_pack](auto &wk)
109 {
110 const bool to_erase = wk.lifetime == experimental::MemoryLifetime::Prepare;
111 if (to_erase)
112 {
113 prep_pack.remove_tensor(wk.slot);
114 }
115 return to_erase;
116 }),
117 workspace.end());
Georgios Pinitas2b147ee2021-07-08 18:14:45 +0100118}
Michele Di Giorgiod9cdf142021-07-02 15:17:08 +0100119
120/** Utility function to release tensors with lifetime marked as Prepare */
121template <typename TensorType>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100122void release_temporaries(const experimental::MemoryRequirements &mem_reqs, WorkspaceData<TensorType> &workspace)
Michele Di Giorgiod9cdf142021-07-02 15:17:08 +0100123{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100124 for (auto &ws : workspace)
Michele Di Giorgiod9cdf142021-07-02 15:17:08 +0100125 {
126 const int slot = ws.slot;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100127 for (auto &m : mem_reqs)
Michele Di Giorgiod9cdf142021-07-02 15:17:08 +0100128 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100129 if (m.slot == slot && m.lifetime == experimental::MemoryLifetime::Prepare)
Michele Di Giorgiod9cdf142021-07-02 15:17:08 +0100130 {
131 auto tensor = ws.tensor.get();
132 tensor->allocator()->free();
133 break;
134 }
135 }
136 }
137}
Georgios Pinitas856f66e2021-04-22 21:13:21 +0100138} // namespace arm_compute
139#endif /* SRC_COMMON_MEMORY_HELPERS_H */