blob: c4cd08ac70aae3eacb75931e55269cae1ea9342c [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"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010027
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010028#include "src/common/ITensorV2.h"
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000029#include "src/common/utils/Macros.h"
30
31namespace
32{
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010033using namespace arm_compute;
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000034/**< Maximum allowed dimensions by Compute Library */
35constexpr int32_t max_allowed_dims = 6;
36
37/** Check if a descriptor is valid
38 *
39 * @param desc Descriptor to validate
40 *
41 * @return true in case of success else false
42 */
43bool is_desc_valid(const AclTensorDescriptor &desc)
44{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010045 if (desc.data_type > AclFloat32 || desc.data_type <= AclDataTypeUnknown)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000046 {
47 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Unknown data type!");
48 return false;
49 }
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010050 if (desc.ndims > max_allowed_dims)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000051 {
52 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions surpass the maximum allowed value!");
53 return false;
54 }
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010055 if (desc.ndims > 0 && desc.shape == nullptr)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000056 {
57 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions values are empty while dimensionality is > 0!");
58 return false;
59 }
60 return true;
61}
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010062
63StatusCode convert_and_validate_tensor(AclTensor tensor, ITensorV2 **internal_tensor)
64{
65 *internal_tensor = get_internal(tensor);
66 return detail::validate_internal_tensor(*internal_tensor);
67}
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000068} // namespace
69
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010070extern "C" AclStatus
71AclCreateTensor(AclTensor *external_tensor, AclContext external_ctx, const AclTensorDescriptor *desc, bool allocate)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000072{
73 using namespace arm_compute;
74
75 IContext *ctx = get_internal(external_ctx);
76
77 StatusCode status = detail::validate_internal_context(ctx);
78 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
79
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010080 if (desc == nullptr || !is_desc_valid(*desc))
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000081 {
82 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Descriptor is invalid!");
83 return AclInvalidArgument;
84 }
85
86 auto tensor = ctx->create_tensor(*desc, allocate);
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010087 if (tensor == nullptr)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000088 {
89 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Couldn't allocate internal resources for tensor creation!");
90 return AclOutOfMemory;
91 }
92 *external_tensor = tensor;
93
94 return AclSuccess;
95}
96
97extern "C" AclStatus AclMapTensor(AclTensor external_tensor, void **handle)
98{
99 using namespace arm_compute;
100
101 auto tensor = get_internal(external_tensor);
102 StatusCode status = detail::validate_internal_tensor(tensor);
103 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
104
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100105 if (handle == nullptr)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +0000106 {
107 ARM_COMPUTE_LOG_ERROR_ACL("[AclMapTensor]: Handle object is nullptr!");
108 return AclInvalidArgument;
109 }
110
111 *handle = tensor->map();
112
113 return AclSuccess;
114}
115
116extern "C" AclStatus AclUnmapTensor(AclTensor external_tensor, void *handle)
117{
118 ARM_COMPUTE_UNUSED(handle);
119
120 using namespace arm_compute;
121
122 auto tensor = get_internal(external_tensor);
123 StatusCode status = detail::validate_internal_tensor(tensor);
124 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
125
126 status = tensor->unmap();
127 return AclSuccess;
128}
129
130extern "C" AclStatus AclTensorImport(AclTensor external_tensor, void *handle, AclImportMemoryType type)
131{
132 using namespace arm_compute;
133
134 auto tensor = get_internal(external_tensor);
135 StatusCode status = detail::validate_internal_tensor(tensor);
136 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
137
138 status = tensor->import(handle, utils::as_enum<ImportMemoryType>(type));
139 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
140
141 return AclSuccess;
142}
143
144extern "C" AclStatus AclDestroyTensor(AclTensor external_tensor)
145{
146 using namespace arm_compute;
147
148 auto tensor = get_internal(external_tensor);
149
150 StatusCode status = detail::validate_internal_tensor(tensor);
151 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
152
153 delete tensor;
154
155 return AclSuccess;
156}
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100157
158extern "C" AclStatus AclGetTensorSize(AclTensor tensor, uint64_t *size)
159{
160 using namespace arm_compute;
161
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100162 if (size == nullptr)
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100163 {
164 return AclStatus::AclInvalidArgument;
165 }
166
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100167 ITensorV2 *internal_tensor{nullptr};
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100168 auto status = convert_and_validate_tensor(tensor, &internal_tensor);
169 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
170
171 *size = internal_tensor->get_size();
172 return utils::as_cenum<AclStatus>(status);
173}
174
175extern "C" AclStatus AclGetTensorDescriptor(AclTensor tensor, AclTensorDescriptor *desc)
176{
177 using namespace arm_compute;
178
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100179 if (desc == nullptr)
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100180 {
181 return AclStatus::AclInvalidArgument;
182 }
183
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100184 ITensorV2 *internal_tensor{nullptr};
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +0100185 const auto status = convert_and_validate_tensor(tensor, &internal_tensor);
186 ARM_COMPUTE_RETURN_CENUM_ON_FAILURE(status);
187
188 *desc = internal_tensor->get_descriptor();
189 return utils::as_cenum<AclStatus>(status);
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100190}