blob: 8f6ce45628f81371d7d9385967e86c1964772eea [file] [log] [blame]
Georgios Pinitas3f26ef42021-02-23 10:01:33 +00001/*
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#include "arm_compute/AclEntrypoints.h"
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010025#include "arm_compute/AclUtils.h"
26#include "src/common/ITensorV2.h"
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000027#include "src/common/utils/Macros.h"
28
29namespace
30{
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010031using namespace arm_compute;
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000032/**< Maximum allowed dimensions by Compute Library */
33constexpr int32_t max_allowed_dims = 6;
34
35/** Check if a descriptor is valid
36 *
37 * @param desc Descriptor to validate
38 *
39 * @return true in case of success else false
40 */
41bool is_desc_valid(const AclTensorDescriptor &desc)
42{
Georgios Pinitasf4edddb2021-04-13 09:53:04 +010043 if(desc.data_type > AclFloat32 || desc.data_type <= AclDataTypeUnknown)
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000044 {
45 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Unknown data type!");
46 return false;
47 }
48 if(desc.ndims > max_allowed_dims)
49 {
50 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions surpass the maximum allowed value!");
51 return false;
52 }
53 if(desc.ndims > 0 && desc.shape == nullptr)
54 {
55 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Dimensions values are empty while dimensionality is > 0!");
56 return false;
57 }
58 return true;
59}
Sang-Hoon Parkc6fcfb42021-03-31 15:18:16 +010060
61StatusCode convert_and_validate_tensor(AclTensor tensor, ITensorV2 **internal_tensor)
62{
63 *internal_tensor = get_internal(tensor);
64 return detail::validate_internal_tensor(*internal_tensor);
65}
Georgios Pinitas3f26ef42021-02-23 10:01:33 +000066} // namespace
67
68extern "C" AclStatus AclCreateTensor(AclTensor *external_tensor,
69 AclContext external_ctx,
70 const AclTensorDescriptor *desc,
71 bool allocate)
72{
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
80 if(desc == nullptr || !is_desc_valid(*desc))
81 {
82 ARM_COMPUTE_LOG_ERROR_ACL("[AclCreateTensor]: Descriptor is invalid!");
83 return AclInvalidArgument;
84 }
85
86 auto tensor = ctx->create_tensor(*desc, allocate);
87 if(tensor == nullptr)
88 {
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
105 if(handle == nullptr)
106 {
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
162 if(size == nullptr)
163 {
164 return AclStatus::AclInvalidArgument;
165 }
166
167 ITensorV2 *internal_tensor{ nullptr };
168 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
179 if(desc == nullptr)
180 {
181 return AclStatus::AclInvalidArgument;
182 }
183
184 ITensorV2 *internal_tensor{ nullptr };
185 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);
190}