Skip to content

Commit 2cde5d0

Browse files
KerilkbashbaugMathiasMagnus
authored
Add first prototype of cllayerinfo. (#175)
* Add first prototype of cllayerinfo. * Added scheme to silence layers during loading and exit. * Added a first test of cllayerinfo. * Fix lock if no layers are found. * Improve style. * Copy layer library name as it is transient. * Add new required definitions. * Remove deprecated OPENCL_ICD_LOADER_DISABLE_OPENCLON12 CMake option. * Factor compile definitions. * Add variable to disable cllayerinfo build. * Refactor CMake test file. * Remove options for now as suggested by the working group. * Remove constants * Include share.h for mingw Co-authored-by: Ben Ashbaugh <[email protected]> * Add cllayerinfo to install and export target. * Use CMakeDependOption. Co-authored-by: Nagy-Egri Máté Ferenc <[email protected]> --------- Co-authored-by: Ben Ashbaugh <[email protected]> Co-authored-by: Nagy-Egri Máté Ferenc <[email protected]>
1 parent 217a177 commit 2cde5d0

File tree

6 files changed

+263
-20
lines changed

6 files changed

+263
-20
lines changed

CMakeLists.txt

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ endif()
5252
# It is currently needed default while the specification is being formalized,
5353
# and to study the performance impact.
5454
option (ENABLE_OPENCL_LAYERS "Enable OpenCL Layers" ON)
55+
include(CMakeDependentOption)
56+
cmake_dependent_option(ENABLE_OPENCL_LAYERINFO "Enable building cllayerinfo tool" ON ENABLE_OPENCL_LAYERS OFF)
5557

5658
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
5759
include(JoinPaths)
@@ -150,22 +152,64 @@ else ()
150152
target_link_libraries (OpenCL PUBLIC OpenCL::Headers)
151153
endif ()
152154

153-
target_compile_definitions (OpenCL
154-
PRIVATE
155+
set (OPENCL_COMPILE_DEFINITIONS
155156
CL_TARGET_OPENCL_VERSION=300
156157
OPENCL_ICD_LOADER_VERSION_MAJOR=3
157158
OPENCL_ICD_LOADER_VERSION_MINOR=0
158159
OPENCL_ICD_LOADER_VERSION_REV=5
159160
$<$<BOOL:${ENABLE_OPENCL_LAYERS}>:CL_ENABLE_LAYERS>
160161
)
161162

163+
target_compile_definitions (OpenCL
164+
PRIVATE
165+
${OPENCL_COMPILE_DEFINITIONS}
166+
)
167+
162168
target_include_directories (OpenCL
163169
PRIVATE
164170
${CMAKE_CURRENT_BINARY_DIR}
165171
loader
166172
)
167173
target_link_libraries (OpenCL PUBLIC ${CMAKE_DL_LIBS})
168174

175+
if (ENABLE_OPENCL_LAYERINFO)
176+
177+
set (OPENCL_LAYER_INFO_SOURCES
178+
loader/cllayerinfo.c
179+
${OPENCL_ICD_LOADER_SOURCES}
180+
)
181+
182+
add_executable(cllayerinfo ${OPENCL_LAYER_INFO_SOURCES})
183+
184+
add_executable(OpenCL::cllayerinfo ALIAS cllayerinfo)
185+
186+
target_compile_definitions (cllayerinfo
187+
PRIVATE
188+
CL_LAYER_INFO
189+
${OPENCL_COMPILE_DEFINITIONS}
190+
)
191+
192+
if (EXISTS ${OPENCL_ICD_LOADER_HEADERS_DIR}/CL/cl.h)
193+
target_include_directories (cllayerinfo PUBLIC $<BUILD_INTERFACE:${OPENCL_ICD_LOADER_HEADERS_DIR}>)
194+
else ()
195+
target_link_libraries (cllayerinfo PUBLIC OpenCL::Headers)
196+
endif ()
197+
198+
if (WIN32)
199+
target_link_libraries (cllayerinfo PRIVATE cfgmgr32.lib runtimeobject.lib)
200+
else ()
201+
target_link_libraries (cllayerinfo PRIVATE ${CMAKE_THREAD_LIBS_INIT})
202+
endif ()
203+
204+
target_link_libraries (cllayerinfo PUBLIC ${CMAKE_DL_LIBS})
205+
206+
target_include_directories (cllayerinfo
207+
PRIVATE
208+
${CMAKE_CURRENT_BINARY_DIR}
209+
loader
210+
)
211+
endif ()
212+
169213
option (OPENCL_ICD_LOADER_BUILD_TESTING "Enable support for OpenCL ICD Loader testing." OFF)
170214

171215
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR OPENCL_ICD_LOADER_BUILD_TESTING)
@@ -191,6 +235,15 @@ install(
191235
OPTIONAL
192236
)
193237

238+
if (ENABLE_OPENCL_LAYERINFO)
239+
install(
240+
TARGETS cllayerinfo
241+
EXPORT OpenCLICDLoaderTargets
242+
RUNTIME
243+
DESTINATION ${CMAKE_INSTALL_BINDIR}
244+
)
245+
endif()
246+
194247
export(
195248
EXPORT OpenCLICDLoaderTargets
196249
FILE ${PROJECT_BINARY_DIR}/OpenCLICDLoader/OpenCLICDLoaderTargets.cmake

loader/cllayerinfo.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (c) 2022 The Khronos Group Inc.
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+
* OpenCL is a trademark of Apple Inc. used under license by Khronos.
17+
*/
18+
19+
#include "icd.h"
20+
#include <stdio.h>
21+
#include <stdlib.h>
22+
#include <CL/cl_layer.h>
23+
#if defined(_WIN32)
24+
#include <io.h>
25+
#include <share.h>
26+
#include <sys/stat.h>
27+
#else
28+
#include <unistd.h>
29+
#endif
30+
#include <fcntl.h>
31+
32+
int stdout_bak, stderr_bak;
33+
34+
// Temporarily deactivate stdout:
35+
// https://stackoverflow.com/a/4832902
36+
37+
#if defined(_WIN32)
38+
#define SECURE 1
39+
#define OPEN _open
40+
#define OPEN_FLAGS _O_WRONLY
41+
#define CLOSE _close
42+
#define DUP _dup
43+
#define DUP2 _dup2
44+
#define NULL_STREAM "nul"
45+
#else
46+
#define OPEN open
47+
#define OPEN_FLAGS O_WRONLY
48+
#define CLOSE close
49+
#define DUP dup
50+
#define DUP2 dup2
51+
#define NULL_STREAM "/dev/null"
52+
#endif
53+
54+
static inline int
55+
silence_stream(FILE *file, int fd)
56+
{
57+
int new_fd, fd_bak;
58+
fflush(file);
59+
fd_bak = DUP(fd);
60+
#if defined(_WIN32) && SECURE
61+
_sopen_s(&new_fd, NULL_STREAM, OPEN_FLAGS, _SH_DENYNO, _S_IWRITE);
62+
#else
63+
new_fd = OPEN(NULL_STREAM, OPEN_FLAGS);
64+
#endif
65+
DUP2(new_fd, fd);
66+
CLOSE(new_fd);
67+
return fd_bak;
68+
}
69+
70+
static void silence_layers(void)
71+
{
72+
stdout_bak = silence_stream(stdout, 1);
73+
stderr_bak = silence_stream(stderr, 2);
74+
}
75+
76+
static inline void
77+
restore_stream(FILE *file, int fd, int fd_bak)
78+
{
79+
fflush(file);
80+
DUP2(fd_bak, fd);
81+
CLOSE(fd_bak);
82+
}
83+
84+
static void restore_outputs(void)
85+
{
86+
restore_stream(stdout, 1, stdout_bak);
87+
restore_stream(stderr, 2, stderr_bak);
88+
}
89+
90+
void printLayerInfo(const struct KHRLayer *layer)
91+
{
92+
cl_layer_api_version api_version = 0;
93+
pfn_clGetLayerInfo p_clGetLayerInfo = (pfn_clGetLayerInfo)(size_t)layer->p_clGetLayerInfo;
94+
cl_int result = CL_SUCCESS;
95+
size_t sz;
96+
97+
printf("%s:\n", layer->libraryName);
98+
result = p_clGetLayerInfo(CL_LAYER_API_VERSION, sizeof(api_version), &api_version, NULL);
99+
if (CL_SUCCESS == result)
100+
printf("\tCL_LAYER_API_VERSION: %d\n", (int)api_version);
101+
102+
result = p_clGetLayerInfo(CL_LAYER_NAME, 0, NULL, &sz);
103+
if (CL_SUCCESS == result)
104+
{
105+
char *name = (char *)malloc(sz);
106+
if (name)
107+
{
108+
result = p_clGetLayerInfo(CL_LAYER_NAME, sz, name, NULL);
109+
if (CL_SUCCESS == result)
110+
printf("\tCL_LAYER_NAME: %s\n", name);
111+
free(name);
112+
}
113+
}
114+
}
115+
116+
int main (int argc, char *argv[])
117+
{
118+
(void)argc;
119+
(void)argv;
120+
silence_layers();
121+
atexit(restore_outputs);
122+
khrIcdInitialize();
123+
restore_outputs();
124+
atexit(silence_layers);
125+
const struct KHRLayer *layer = khrFirstLayer;
126+
while (layer)
127+
{
128+
printLayerInfo(layer);
129+
layer = layer->next;
130+
}
131+
return 0;
132+
}

loader/icd.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,20 @@ void khrIcdLayerAdd(const char *libraryName)
285285
KHR_ICD_TRACE("failed to allocate memory\n");
286286
goto Done;
287287
}
288+
#ifdef CL_LAYER_INFO
289+
{
290+
// Not using strdup as it is not standard c
291+
size_t sz_name = strlen(libraryName) + 1;
292+
layer->libraryName = malloc(sz_name);
293+
if (!layer->libraryName)
294+
{
295+
KHR_ICD_TRACE("failed to allocate memory\n");
296+
goto Done;
297+
}
298+
memcpy(layer->libraryName, libraryName, sz_name);
299+
layer->p_clGetLayerInfo = (void *)(size_t)p_clGetLayerInfo;
300+
}
301+
#endif
288302

289303
if (khrFirstLayer) {
290304
targetDispatch = &(khrFirstLayer->dispatch);

loader/icd.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ struct KHRLayer
114114
struct _cl_icd_dispatch dispatch;
115115
// The next layer in the chain
116116
struct KHRLayer *next;
117+
#ifdef CL_LAYER_INFO
118+
// The layer library name
119+
char *libraryName;
120+
// the pointer to the clGetLayerInfo funciton
121+
void *p_clGetLayerInfo;
122+
#endif
117123
};
118124

119125
// the global layer state

test/CMakeLists.txt

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,30 @@ add_test (
1818
NAME opencl_icd_loader_test
1919
COMMAND icd_loader_test
2020
)
21-
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
22-
if(GENERATOR_IS_MULTI_CONFIG)
23-
set_tests_properties(opencl_icd_loader_test
24-
PROPERTIES
25-
ENVIRONMENT OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStub>
26-
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>"
21+
22+
if (ENABLE_OPENCL_LAYERINFO)
23+
add_test (
24+
NAME cllayerinfo_test
25+
COMMAND cllayerinfo
2726
)
28-
else()
29-
set_tests_properties(opencl_icd_loader_test
27+
endif ()
28+
29+
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
30+
if (GENERATOR_IS_MULTI_CONFIG)
31+
set (TEST_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>")
32+
else ()
33+
set (TEST_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
34+
endif()
35+
36+
set_tests_properties(opencl_icd_loader_test
37+
PROPERTIES
38+
ENVIRONMENT OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStub>
39+
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
40+
)
41+
if (ENABLE_OPENCL_LAYERINFO)
42+
set_tests_properties(cllayerinfo_test
3043
PROPERTIES
31-
ENVIRONMENT OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStub>
32-
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
44+
ENVIRONMENT OPENCL_LAYERS=$<TARGET_FILE:PrintLayer>
45+
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
3346
)
3447
endif()

test/layer/icd_print_layer.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,58 @@
1717
*/
1818

1919
#include "icd_print_layer.h"
20+
#include <stdbool.h>
21+
#include <stdlib.h>
22+
#include <string.h>
2023

2124
struct _cl_icd_dispatch dispatch;
2225

2326
const struct _cl_icd_dispatch *tdispatch;
2427

28+
static cl_layer_api_version api_version = CL_LAYER_API_VERSION_100;
29+
static const char name[] = "print_layer";
30+
31+
static inline cl_int
32+
set_param_value(
33+
size_t param_value_size,
34+
void *param_value,
35+
size_t *param_value_size_ret,
36+
size_t src_size,
37+
const void *src) {
38+
if (param_value && param_value_size < src_size)
39+
return CL_INVALID_VALUE;
40+
if (param_value)
41+
memcpy(param_value, src, src_size);
42+
if (param_value_size_ret)
43+
*param_value_size_ret = src_size;
44+
return CL_SUCCESS;
45+
}
46+
2547
CL_API_ENTRY cl_int CL_API_CALL
2648
clGetLayerInfo(
2749
cl_layer_info param_name,
2850
size_t param_value_size,
2951
void *param_value,
3052
size_t *param_value_size_ret) {
53+
size_t sz = 0;
54+
const void *src = NULL;
3155
if (param_value_size && !param_value)
3256
return CL_INVALID_VALUE;
3357
if (!param_value && !param_value_size_ret)
3458
return CL_INVALID_VALUE;
3559
switch (param_name) {
3660
case CL_LAYER_API_VERSION:
37-
if (param_value_size < sizeof(cl_layer_api_version))
38-
return CL_INVALID_VALUE;
39-
if (param_value)
40-
*((cl_layer_api_version *)param_value) = CL_LAYER_API_VERSION_100;
41-
if (param_value_size_ret)
42-
*param_value_size_ret = sizeof(cl_layer_api_version);
61+
sz = sizeof(api_version);
62+
src = &api_version;
63+
break;
64+
case CL_LAYER_NAME:
65+
sz = sizeof(name);
66+
src = name;
4367
break;
4468
default:
4569
return CL_INVALID_VALUE;
4670
}
47-
return CL_SUCCESS;
71+
return set_param_value(param_value_size, param_value, param_value_size_ret, sz, src);
4872
}
4973

5074
CL_API_ENTRY cl_int CL_API_CALL
@@ -53,14 +77,15 @@ clInitLayer(
5377
const struct _cl_icd_dispatch *target_dispatch,
5478
cl_uint *num_entries_out,
5579
const struct _cl_icd_dispatch **layer_dispatch_ret) {
56-
if (!target_dispatch || !layer_dispatch_ret ||!num_entries_out || num_entries < sizeof(dispatch)/sizeof(dispatch.clGetPlatformIDs))
80+
if (!target_dispatch || !layer_dispatch_ret || !num_entries_out || num_entries < sizeof(dispatch)/sizeof(dispatch.clGetPlatformIDs))
5781
return CL_INVALID_VALUE;
5882

5983
_init_dispatch();
6084

6185
tdispatch = target_dispatch;
6286
*layer_dispatch_ret = &dispatch;
6387
*num_entries_out = sizeof(dispatch)/sizeof(dispatch.clGetPlatformIDs);
88+
6489
return CL_SUCCESS;
6590
}
6691

0 commit comments

Comments
 (0)