1 /*******************************************************************************
2 * Copyright 2019-2021 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17 #include "dnnl_test_common.hpp"
18 #include "gtest/gtest.h"
19
20 #include <memory>
21 #include "oneapi/dnnl/dnnl_ocl.h"
22 #include "oneapi/dnnl/dnnl_ocl.hpp"
23 #include <CL/cl.h>
24
25 namespace dnnl {
26 class ocl_stream_test_c_t : public ::testing::Test {
27 protected:
SetUp()28 void SetUp() override {
29 if (!find_ocl_device(CL_DEVICE_TYPE_GPU)) { return; }
30
31 DNNL_CHECK(dnnl_engine_create(&eng, dnnl_gpu, 0));
32
33 DNNL_CHECK(dnnl_ocl_interop_engine_get_context(eng, &ocl_ctx));
34 DNNL_CHECK(dnnl_ocl_interop_get_device(eng, &ocl_dev));
35 }
36
TearDown()37 void TearDown() override {
38 if (eng) { DNNL_CHECK(dnnl_engine_destroy(eng)); }
39 }
40
41 dnnl_engine_t eng = nullptr;
42 cl_context ocl_ctx = nullptr;
43 cl_device_id ocl_dev = nullptr;
44 };
45
46 class ocl_stream_test_cpp_t : public ::testing::Test {
47 protected:
SetUp()48 void SetUp() override {
49 if (!find_ocl_device(CL_DEVICE_TYPE_GPU)) { return; }
50
51 eng = engine(engine::kind::gpu, 0);
52
53 ocl_ctx = ocl_interop::get_context(eng);
54 ocl_dev = ocl_interop::get_device(eng);
55 }
56
57 engine eng;
58 cl_context ocl_ctx = nullptr;
59 cl_device_id ocl_dev = nullptr;
60 };
61
TEST_F(ocl_stream_test_c_t,CreateC)62 TEST_F(ocl_stream_test_c_t, CreateC) {
63 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
64 "OpenCL GPU devices not found.");
65
66 dnnl_stream_t stream;
67 DNNL_CHECK(dnnl_stream_create(&stream, eng, dnnl_stream_default_flags));
68
69 cl_command_queue ocl_queue;
70 DNNL_CHECK(dnnl_ocl_interop_stream_get_command_queue(stream, &ocl_queue));
71
72 cl_device_id ocl_queue_dev;
73 cl_context ocl_queue_ctx;
74 TEST_OCL_CHECK(clGetCommandQueueInfo(ocl_queue, CL_QUEUE_DEVICE,
75 sizeof(ocl_queue_dev), &ocl_queue_dev, nullptr));
76 TEST_OCL_CHECK(clGetCommandQueueInfo(ocl_queue, CL_QUEUE_CONTEXT,
77 sizeof(ocl_queue_ctx), &ocl_queue_ctx, nullptr));
78
79 ASSERT_EQ(ocl_dev, ocl_queue_dev);
80 ASSERT_EQ(ocl_ctx, ocl_queue_ctx);
81
82 DNNL_CHECK(dnnl_stream_destroy(stream));
83 }
84
TEST_F(ocl_stream_test_cpp_t,CreateCpp)85 TEST_F(ocl_stream_test_cpp_t, CreateCpp) {
86 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
87 "OpenCL GPU devices not found.");
88
89 stream s(eng);
90 cl_command_queue ocl_queue = ocl_interop::get_command_queue(s);
91
92 cl_device_id ocl_queue_dev;
93 cl_context ocl_queue_ctx;
94 TEST_OCL_CHECK(clGetCommandQueueInfo(ocl_queue, CL_QUEUE_DEVICE,
95 sizeof(ocl_queue_dev), &ocl_queue_dev, nullptr));
96 TEST_OCL_CHECK(clGetCommandQueueInfo(ocl_queue, CL_QUEUE_CONTEXT,
97 sizeof(ocl_queue_ctx), &ocl_queue_ctx, nullptr));
98
99 ASSERT_EQ(ocl_dev, ocl_queue_dev);
100 ASSERT_EQ(ocl_ctx, ocl_queue_ctx);
101 }
102
TEST_F(ocl_stream_test_c_t,BasicInteropC)103 TEST_F(ocl_stream_test_c_t, BasicInteropC) {
104 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
105 "OpenCL GPU devices not found.");
106
107 cl_int err;
108 #ifdef CL_VERSION_2_0
109 cl_command_queue interop_ocl_queue = clCreateCommandQueueWithProperties(
110 ocl_ctx, ocl_dev, nullptr, &err);
111 #else
112 cl_command_queue interop_ocl_queue
113 = clCreateCommandQueue(ocl_ctx, ocl_dev, 0, &err);
114 #endif
115 TEST_OCL_CHECK(err);
116
117 dnnl_stream_t stream;
118 DNNL_CHECK(dnnl_ocl_interop_stream_create(&stream, eng, interop_ocl_queue));
119
120 cl_command_queue ocl_queue;
121 DNNL_CHECK(dnnl_ocl_interop_stream_get_command_queue(stream, &ocl_queue));
122 ASSERT_EQ(ocl_queue, interop_ocl_queue);
123
124 cl_uint ref_count;
125 TEST_OCL_CHECK(clGetCommandQueueInfo(interop_ocl_queue,
126 CL_QUEUE_REFERENCE_COUNT, sizeof(cl_uint), &ref_count, nullptr));
127 int i_ref_count = int(ref_count);
128 ASSERT_EQ(i_ref_count, 2);
129
130 DNNL_CHECK(dnnl_stream_destroy(stream));
131
132 TEST_OCL_CHECK(clGetCommandQueueInfo(interop_ocl_queue,
133 CL_QUEUE_REFERENCE_COUNT, sizeof(cl_uint), &ref_count, nullptr));
134 i_ref_count = int(ref_count);
135 ASSERT_EQ(i_ref_count, 1);
136
137 TEST_OCL_CHECK(clReleaseCommandQueue(interop_ocl_queue));
138 }
139
TEST_F(ocl_stream_test_cpp_t,BasicInteropC)140 TEST_F(ocl_stream_test_cpp_t, BasicInteropC) {
141 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
142 "OpenCL GPU devices not found.");
143
144 cl_int err;
145 #ifdef CL_VERSION_2_0
146 cl_command_queue interop_ocl_queue = clCreateCommandQueueWithProperties(
147 ocl_ctx, ocl_dev, nullptr, &err);
148 #else
149 cl_command_queue interop_ocl_queue
150 = clCreateCommandQueue(ocl_ctx, ocl_dev, 0, &err);
151 #endif
152 TEST_OCL_CHECK(err);
153
154 {
155 auto s = ocl_interop::make_stream(eng, interop_ocl_queue);
156
157 cl_uint ref_count;
158 TEST_OCL_CHECK(clGetCommandQueueInfo(interop_ocl_queue,
159 CL_QUEUE_REFERENCE_COUNT, sizeof(cl_uint), &ref_count,
160 nullptr));
161 int i_ref_count = int(ref_count);
162 ASSERT_EQ(i_ref_count, 2);
163
164 cl_command_queue ocl_queue = ocl_interop::get_command_queue(s);
165 ASSERT_EQ(ocl_queue, interop_ocl_queue);
166 }
167
168 cl_uint ref_count;
169 TEST_OCL_CHECK(clGetCommandQueueInfo(interop_ocl_queue,
170 CL_QUEUE_REFERENCE_COUNT, sizeof(cl_uint), &ref_count, nullptr));
171 int i_ref_count = int(ref_count);
172 ASSERT_EQ(i_ref_count, 1);
173
174 TEST_OCL_CHECK(clReleaseCommandQueue(interop_ocl_queue));
175 }
176
TEST_F(ocl_stream_test_c_t,InteropIncompatibleQueueC)177 TEST_F(ocl_stream_test_c_t, InteropIncompatibleQueueC) {
178 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
179 "OpenCL GPU devices not found.");
180
181 cl_device_id cpu_ocl_dev = find_ocl_device(CL_DEVICE_TYPE_CPU);
182 SKIP_IF(!cpu_ocl_dev, "OpenCL CPU devices not found.");
183
184 cl_int err;
185 cl_context cpu_ocl_ctx
186 = clCreateContext(nullptr, 1, &cpu_ocl_dev, nullptr, nullptr, &err);
187 TEST_OCL_CHECK(err);
188
189 #ifdef CL_VERSION_2_0
190 cl_command_queue cpu_ocl_queue = clCreateCommandQueueWithProperties(
191 cpu_ocl_ctx, cpu_ocl_dev, nullptr, &err);
192 #else
193 cl_command_queue cpu_ocl_queue
194 = clCreateCommandQueue(cpu_ocl_ctx, cpu_ocl_dev, 0, &err);
195 #endif
196 TEST_OCL_CHECK(err);
197
198 dnnl_stream_t stream;
199 dnnl_status_t status
200 = dnnl_ocl_interop_stream_create(&stream, eng, cpu_ocl_queue);
201 ASSERT_EQ(status, dnnl_invalid_arguments);
202
203 TEST_OCL_CHECK(clReleaseCommandQueue(cpu_ocl_queue));
204 }
205
TEST_F(ocl_stream_test_cpp_t,InteropIncompatibleQueueCpp)206 TEST_F(ocl_stream_test_cpp_t, InteropIncompatibleQueueCpp) {
207 SKIP_IF(!find_ocl_device(CL_DEVICE_TYPE_GPU),
208 "OpenCL GPU devices not found.");
209
210 cl_device_id cpu_ocl_dev = find_ocl_device(CL_DEVICE_TYPE_CPU);
211 SKIP_IF(!cpu_ocl_dev, "OpenCL CPU devices not found.");
212
213 cl_int err;
214 cl_context cpu_ocl_ctx
215 = clCreateContext(nullptr, 1, &cpu_ocl_dev, nullptr, nullptr, &err);
216 TEST_OCL_CHECK(err);
217
218 #ifdef CL_VERSION_2_0
219 cl_command_queue cpu_ocl_queue = clCreateCommandQueueWithProperties(
220 cpu_ocl_ctx, cpu_ocl_dev, nullptr, &err);
221 #else
222 cl_command_queue cpu_ocl_queue
223 = clCreateCommandQueue(cpu_ocl_ctx, cpu_ocl_dev, 0, &err);
224 #endif
225 TEST_OCL_CHECK(err);
226
227 catch_expected_failures(
228 [&] { ocl_interop::make_stream(eng, cpu_ocl_queue); }, true,
229 dnnl_invalid_arguments);
230
231 TEST_OCL_CHECK(clReleaseCommandQueue(cpu_ocl_queue));
232 }
233
234 } // namespace dnnl
235