xref: /aosp_15_r20/external/ComputeLibrary/src/c/AclTensor.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
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"
25 #include "arm_compute/AclUtils.h"
26 #include "src/common/ITensorV2.h"
27 #include "src/common/utils/Macros.h"
28 
29 namespace
30 {
31 using namespace arm_compute;
32 /**< Maximum allowed dimensions by Compute Library */
33 constexpr 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  */
is_desc_valid(const AclTensorDescriptor & desc)41 bool is_desc_valid(const AclTensorDescriptor &desc)
42 {
43     if(desc.data_type > AclFloat32 || desc.data_type <= AclDataTypeUnknown)
44     {
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 }
60 
convert_and_validate_tensor(AclTensor tensor,ITensorV2 ** internal_tensor)61 StatusCode 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 }
66 } // namespace
67 
AclCreateTensor(AclTensor * external_tensor,AclContext external_ctx,const AclTensorDescriptor * desc,bool allocate)68 extern "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 
AclMapTensor(AclTensor external_tensor,void ** handle)97 extern "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 
AclUnmapTensor(AclTensor external_tensor,void * handle)116 extern "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 
AclTensorImport(AclTensor external_tensor,void * handle,AclImportMemoryType type)130 extern "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 
AclDestroyTensor(AclTensor external_tensor)144 extern "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 }
157 
AclGetTensorSize(AclTensor tensor,uint64_t * size)158 extern "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 
AclGetTensorDescriptor(AclTensor tensor,AclTensorDescriptor * desc)175 extern "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 }