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/AclOpenClExt.h"
25
26 #include "src/common/ITensorV2.h"
27 #include "src/common/Types.h"
28 #include "src/gpu/cl/ClContext.h"
29 #include "src/gpu/cl/ClQueue.h"
30
31 #include "arm_compute/core/CL/ICLTensor.h"
32
33 #include "support/Cast.h"
34
AclGetClContext(AclContext external_ctx,cl_context * opencl_context)35 extern "C" AclStatus AclGetClContext(AclContext external_ctx, cl_context *opencl_context)
36 {
37 using namespace arm_compute;
38 IContext *ctx = get_internal(external_ctx);
39
40 if(detail::validate_internal_context(ctx) != StatusCode::Success)
41 {
42 return AclStatus::AclInvalidArgument;
43 }
44
45 if(ctx->type() != Target::GpuOcl)
46 {
47 return AclStatus::AclInvalidTarget;
48 }
49
50 if(opencl_context == nullptr)
51 {
52 return AclStatus::AclInvalidArgument;
53 }
54
55 *opencl_context = utils::cast::polymorphic_downcast<arm_compute::gpu::opencl::ClContext *>(ctx)->cl_ctx().get();
56
57 return AclStatus::AclSuccess;
58 }
59
AclSetClContext(AclContext external_ctx,cl_context opencl_context)60 extern "C" AclStatus AclSetClContext(AclContext external_ctx, cl_context opencl_context)
61 {
62 using namespace arm_compute;
63 IContext *ctx = get_internal(external_ctx);
64
65 if(detail::validate_internal_context(ctx) != StatusCode::Success)
66 {
67 return AclStatus::AclInvalidArgument;
68 }
69
70 if(ctx->type() != Target::GpuOcl)
71 {
72 return AclStatus::AclInvalidTarget;
73 }
74
75 if(ctx->refcount() != 0)
76 {
77 return AclStatus::AclUnsupportedConfig;
78 }
79
80 auto cl_ctx = utils::cast::polymorphic_downcast<arm_compute::gpu::opencl::ClContext *>(ctx);
81 if(!cl_ctx->set_cl_ctx(::cl::Context(opencl_context)))
82 {
83 return AclStatus::AclRuntimeError;
84 }
85
86 return AclStatus::AclSuccess;
87 }
88
AclGetClDevice(AclContext external_ctx,cl_device_id * opencl_device)89 extern "C" AclStatus AclGetClDevice(AclContext external_ctx, cl_device_id *opencl_device)
90 {
91 using namespace arm_compute;
92 IContext *ctx = get_internal(external_ctx);
93
94 if(detail::validate_internal_context(ctx) != StatusCode::Success)
95 {
96 return AclStatus::AclInvalidArgument;
97 }
98
99 if(ctx->type() != Target::GpuOcl)
100 {
101 return AclStatus::AclInvalidTarget;
102 }
103
104 if(opencl_device == nullptr)
105 {
106 return AclStatus::AclInvalidArgument;
107 }
108
109 *opencl_device = utils::cast::polymorphic_downcast<arm_compute::gpu::opencl::ClContext *>(ctx)->cl_dev().get();
110
111 return AclStatus::AclSuccess;
112 }
113
AclGetClQueue(AclQueue external_queue,cl_command_queue * opencl_queue)114 extern "C" AclStatus AclGetClQueue(AclQueue external_queue, cl_command_queue *opencl_queue)
115 {
116 using namespace arm_compute;
117 IQueue *queue = get_internal(external_queue);
118
119 if(detail::validate_internal_queue(queue) != StatusCode::Success)
120 {
121 return AclStatus::AclInvalidArgument;
122 }
123
124 if(queue->header.ctx->type() != Target::GpuOcl)
125 {
126 return AclStatus::AclInvalidTarget;
127 }
128
129 if(opencl_queue == nullptr)
130 {
131 return AclStatus::AclInvalidArgument;
132 }
133
134 *opencl_queue = utils::cast::polymorphic_downcast<arm_compute::gpu::opencl::ClQueue *>(queue)->cl_queue().get();
135
136 return AclStatus::AclSuccess;
137 }
138
AclSetClQueue(AclQueue external_queue,cl_command_queue opencl_queue)139 extern "C" AclStatus AclSetClQueue(AclQueue external_queue, cl_command_queue opencl_queue)
140 {
141 using namespace arm_compute;
142 IQueue *queue = get_internal(external_queue);
143
144 if(detail::validate_internal_queue(queue) != StatusCode::Success)
145 {
146 return AclStatus::AclInvalidArgument;
147 }
148
149 if(queue->header.ctx->type() != Target::GpuOcl)
150 {
151 return AclStatus::AclInvalidTarget;
152 }
153
154 auto cl_queue = utils::cast::polymorphic_downcast<arm_compute::gpu::opencl::ClQueue *>(queue);
155 if(!cl_queue->set_cl_queue(::cl::CommandQueue(opencl_queue)))
156 {
157 return AclStatus::AclRuntimeError;
158 }
159
160 return AclStatus::AclSuccess;
161 }
162
AclGetClMem(AclTensor external_tensor,cl_mem * opencl_mem)163 extern "C" AclStatus AclGetClMem(AclTensor external_tensor, cl_mem *opencl_mem)
164 {
165 using namespace arm_compute;
166 ITensorV2 *tensor = get_internal(external_tensor);
167
168 if(detail::validate_internal_tensor(tensor) != StatusCode::Success)
169 {
170 return AclStatus::AclInvalidArgument;
171 }
172
173 if(tensor->header.ctx->type() != Target::GpuOcl)
174 {
175 return AclStatus::AclInvalidTarget;
176 }
177
178 if(opencl_mem == nullptr)
179 {
180 return AclStatus::AclInvalidArgument;
181 }
182
183 auto cl_tensor = utils::cast::polymorphic_downcast<arm_compute::ICLTensor *>(tensor->tensor());
184 *opencl_mem = cl_tensor->cl_buffer().get();
185
186 return AclStatus::AclSuccess;
187 }