blob: 5b184697aa983e2dcf2e5ba16ee522e8f1804f3a [file] [log] [blame]
Georgios Pinitas3f26ef42021-02-23 10:01:33 +00001/*
Matthew Bentham1d062042023-07-06 13:13:59 +00002 * Copyright (c) 2021,2023 Arm Limited.
Georgios Pinitas3f26ef42021-02-23 10:01:33 +00003 *
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#include "arm_compute/AclEntrypoints.h"
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010025#include "arm_compute/AclUtils.h"
Matthew Bentham1d062042023-07-06 13:13:59 +000026#include "arm_compute/core/Error.h"
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010027#include "src/common/ITensorV2.h"
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000028#include "src/common/utils/Macros.h"
29
30namespace
31{
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010032using namespace arm_compute;
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000033/**< Maximum allowed dimensions by Compute Library */
34constexpr int32_t max_allowed_dims = 6;
35
36/** Check if a descriptor is valid
37 *
38 * @param desc Descriptor to validate
39 *
40 * @return true in case of success else false
41 */
42bool is_desc_valid(const AclTensorDescriptor &desc)
43{
Georgios Pinitasf4edddb2021-04-13 09:53:04 +010044 if(desc.data_type > AclFloat32 || desc.data_type <= AclDataTypeUnknown)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000045 {
46 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Unknown data type!");
47 return false;
48 }
49 if(desc.ndims > max_allowed_dims)
50 {
51 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions surpass the maximum allowed value!");
52 return false;
53 }
54 if(desc.ndims > 0 && desc.shape == nullptr)
55 {
56 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions values are empty while dimensionality is > 0!");
57 return false;
58 }
59 return true;
60}
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010061
62StatusCode convert_and_validate_tensor(AclTensor tensor, ITensorV2 **internal_tensor)
63{
64 *internal_tensor = get_internal(tensor);
65 return detail::validate_internal_tensor(*internal_tensor);
66}
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000067} // namespace
68
69extern "C" AclStatus AclCreateTensor(AclTensor *external_tensor,
70 AclContext external_ctx,
71 const AclTensorDescriptor *desc,
72 bool allocate)
73{
74 using namespace arm_compute;
75
76 IContext *ctx = get_internal(external_ctx);
77
78 StatusCode status = detail::validate_internal_context(ctx);
79 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
80
81 if(desc == nullptr || !is_desc_valid(*desc))
82 {
83 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Descriptor is invalid!");
84 return AclInvalidArgument;
85 }
86
87 auto tensor = ctx->create_tensor(*desc, allocate);
88 if(tensor == nullptr)
89 {
90 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Couldn't allocate internal resources for tensor creation!");
91 return AclOutOfMemory;
92 }
93 *external_tensor = tensor;
94
95 return AclSuccess;
96}
97
98extern "C" AclStatus AclMapTensor(AclTensor external_tensor, void **handle)
99{
100 using namespace arm_compute;
101
102 auto tensor = get_internal(external_tensor);
103 StatusCode status = detail::validate_internal_tensor(tensor);
104 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
105
106 if(handle == nullptr)
107 {
108 ARM_COMPUTE_LOG_ERROR_ACL("[AclMapTensor]: Handle object is nullptr!");
109 return AclInvalidArgument;
110 }
111
112 *handle = tensor->map();
113
114 return AclSuccess;
115}
116
117extern "C" AclStatus AclUnmapTensor(AclTensor external_tensor, void *handle)
118{
119 ARM_COMPUTE_UNUSED(handle);
120
121 using namespace arm_compute;
122
123 auto tensor = get_internal(external_tensor);
124 StatusCode status = detail::validate_internal_tensor(tensor);
125 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
126
127 status = tensor->unmap();
128 return AclSuccess;
129}
130
131extern "C" AclStatus AclTensorImport(AclTensor external_tensor, void *handle, AclImportMemoryType type)
132{
133 using namespace arm_compute;
134
135 auto tensor = get_internal(external_tensor);
136 StatusCode status = detail::validate_internal_tensor(tensor);
137 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
138
139 status = tensor->import(handle, utils::as_enum<ImportMemoryType>(type));
140 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
141
142 return AclSuccess;
143}
144
145extern "C" AclStatus AclDestroyTensor(AclTensor external_tensor)
146{
147 using namespace arm_compute;
148
149 auto tensor = get_internal(external_tensor);
150
151 StatusCode status = detail::validate_internal_tensor(tensor);
152 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
153
154 delete tensor;
155
156 return AclSuccess;
157}
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100158
159extern "C" AclStatus AclGetTensorSize(AclTensor tensor, uint64_t *size)
160{
161 using namespace arm_compute;
162
163 if(size == nullptr)
164 {
165 return AclStatus::AclInvalidArgument;
166 }
167
168 ITensorV2 *internal_tensor{ nullptr };
169 auto status = convert_and_validate_tensor(tensor, &internal_tensor);
170 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
171
172 *size = internal_tensor->get_size();
173 return utils::as_cenum<AclStatus>(status);
174}
175
176extern "C" AclStatus AclGetTensorDescriptor(AclTensor tensor, AclTensorDescriptor *desc)
177{
178 using namespace arm_compute;
179
180 if(desc == nullptr)
181 {
182 return AclStatus::AclInvalidArgument;
183 }
184
185 ITensorV2 *internal_tensor{ nullptr };
186 const auto status = convert_and_validate_tensor(tensor, &internal_tensor);
187 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
188
189 *desc = internal_tensor->get_descriptor();
190 return utils::as_cenum<AclStatus>(status);
191}