Skip to content

Commit dc82826

Browse files
author
vzakhari
authored
Add ITT stubs and wrappers for SPIR-V devices (#3279)
The patch adds definitions of ITT related APIs into SPIR-V libdevice. The APIs may be used in user device code, and also the compiler may use them for automatic instrumentation of the device code. Tools like Intel Inspector should be able to recognize the calls in the device code by their names. Signed-off-by: Vyacheslav Zakharin [email protected]
1 parent c0c3c80 commit dc82826

File tree

8 files changed

+394
-4
lines changed

8 files changed

+394
-4
lines changed

libdevice/cmake/modules/SYCLLibdevice.cmake

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,46 @@ add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-fallback-cmath-fp64.${lib-su
167167
DEPENDS device_math.h device.h clang clang-offload-bundler
168168
VERBATIM)
169169

170+
add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-itt-stubs.${lib-suffix}
171+
COMMAND ${clang} -fsycl -c
172+
${compile_opts} ${sycl_targets_opt}
173+
${CMAKE_CURRENT_SOURCE_DIR}/itt_stubs.cpp
174+
-o ${obj_binary_dir}/libsycl-itt-stubs.${lib-suffix}
175+
MAIN_DEPENDENCY itt_stubs.cpp
176+
DEPENDS device_itt.h spirv_vars.h device.h clang clang-offload-bundler
177+
VERBATIM)
178+
179+
add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-itt-compiler-wrappers.${lib-suffix}
180+
COMMAND ${clang} -fsycl -c
181+
${compile_opts} ${sycl_targets_opt}
182+
${CMAKE_CURRENT_SOURCE_DIR}/itt_compiler_wrappers.cpp
183+
-o ${obj_binary_dir}/libsycl-itt-compiler-wrappers.${lib-suffix}
184+
MAIN_DEPENDENCY itt_compiler_wrappers.cpp
185+
DEPENDS device_itt.h spirv_vars.h device.h clang clang-offload-bundler
186+
VERBATIM)
187+
188+
add_custom_command(OUTPUT ${obj_binary_dir}/libsycl-itt-user-wrappers.${lib-suffix}
189+
COMMAND ${clang} -fsycl -c
190+
${compile_opts} ${sycl_targets_opt}
191+
${CMAKE_CURRENT_SOURCE_DIR}/itt_user_wrappers.cpp
192+
-o ${obj_binary_dir}/libsycl-itt-user-wrappers.${lib-suffix}
193+
MAIN_DEPENDENCY itt_user_wrappers.cpp
194+
DEPENDS device_itt.h spirv_vars.h device.h clang clang-offload-bundler
195+
VERBATIM)
196+
197+
set(devicelib-obj-itt-files
198+
${obj_binary_dir}/libsycl-itt-stubs.${lib-suffix}
199+
${obj_binary_dir}/libsycl-itt-compiler-wrappers.${lib-suffix}
200+
${obj_binary_dir}/libsycl-itt-user-wrappers.${lib-suffix}
201+
)
202+
170203
add_custom_target(libsycldevice-obj DEPENDS
171204
${devicelib-obj-file}
172205
${devicelib-obj-complex}
173206
${devicelib-obj-complex-fp64}
174207
${devicelib-obj-cmath}
175208
${devicelib-obj-cmath-fp64}
209+
${devicelib-obj-itt-files}
176210
)
177211
add_custom_target(libsycldevice-spv DEPENDS
178212
${spv_binary_dir}/libsycl-fallback-cassert.spv
@@ -212,7 +246,8 @@ install(FILES ${devicelib-obj-file}
212246
${devicelib-obj-cmath}
213247
${obj_binary_dir}/libsycl-fallback-cmath.${lib-suffix}
214248
${devicelib-obj-cmath-fp64}
215-
${obj_binary_dir}/libsycl-fallback-cmath-fp64.${lib-suffix}
249+
${obj_binary_dir}/libsycl-fallback-cmath-fp64.${lib-suffix}
250+
${devicelib-obj-itt-files}
216251
DESTINATION ${install_dest_lib}
217252
COMPONENT libsycldevice)
218253

libdevice/device_itt.h

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//==------- device_itt.h - ITT devicelib functions declarations ------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//==------------------------------------------------------------------------==//
8+
9+
#ifndef __LIBDEVICE_DEVICE_ITT_H__
10+
#define __LIBDEVICE_DEVICE_ITT_H__
11+
12+
#include "device.h"
13+
14+
#ifdef __SPIR__
15+
#include "spirv_vars.h"
16+
17+
#define ITT_STUB_ATTRIBUTES __attribute__((noinline, optnone))
18+
19+
/// Atomic operation type
20+
enum __itt_atomic_mem_op_t {
21+
__itt_mem_load = 0,
22+
__itt_mem_store = 1,
23+
__itt_mem_update = 2
24+
};
25+
26+
/// Memory operation ordering semantic type
27+
enum __itt_atomic_mem_order_t {
28+
__itt_mem_order_relaxed = 0,
29+
__itt_mem_order_acquire = 1,
30+
__itt_mem_order_release = 2,
31+
__itt_mem_order_acquire_release = 3
32+
};
33+
34+
// FIXME: must be enabled via -fdeclare-spirv-builtins
35+
DEVICE_EXTERN_C char __spirv_SpecConstant(int, char);
36+
37+
#define ITT_SPEC_CONSTANT 0xFF747469
38+
39+
static inline bool isITTEnabled() {
40+
return __spirv_SpecConstant(ITT_SPEC_CONSTANT, 0) != 0;
41+
}
42+
43+
// Wrapper APIs that may be called by compiler-generated code.
44+
// These are just parameterless helper APIs that call the corresponding
45+
// stub APIs after preparing the arguments for them.
46+
//
47+
// Note that we do not provide compiler wrappers for all stub APIs.
48+
// For example, there is no compiler wrapper for
49+
// __itt_offload_sync_acquired_stub, since the API's parameter cannot
50+
// be computed in the wrapper itself and has to be passed from outside.
51+
// If a compiler needs to invoke such an API, it has to use the user
52+
// visible API directly (i.e. __itt_offload_sync_acquired).
53+
DEVICE_EXTERN_C
54+
void __itt_offload_wi_start_wrapper();
55+
DEVICE_EXTERN_C
56+
void __itt_offload_wi_finish_wrapper();
57+
DEVICE_EXTERN_C
58+
void __itt_offload_wg_barrier_wrapper();
59+
DEVICE_EXTERN_C
60+
void __itt_offload_wi_resume_wrapper();
61+
62+
// Non-inlinable and non-optimizable APIs that are recognized
63+
// by profiling tools.
64+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
65+
__itt_offload_wi_start_stub(size_t *group_id, size_t wi_id, uint32_t wg_size);
66+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
67+
__itt_offload_wi_finish_stub(size_t *group_id, size_t wi_id);
68+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
69+
__itt_offload_wg_barrier_stub(uintptr_t barrier_id);
70+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
71+
__itt_offload_wi_resume_stub(size_t *group_id, size_t wi_id);
72+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
73+
__itt_offload_sync_acquired_stub(uintptr_t sync_id);
74+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
75+
__itt_offload_sync_releasing_stub(uintptr_t sync_id);
76+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
77+
__itt_offload_wg_local_range_stub(void *ptr, size_t size);
78+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
79+
__itt_offload_atomic_op_start_stub(void *object, __itt_atomic_mem_op_t op_type,
80+
__itt_atomic_mem_order_t mem_order);
81+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
82+
__itt_offload_atomic_op_finish_stub(void *object, __itt_atomic_mem_op_t op_type,
83+
__itt_atomic_mem_order_t mem_order);
84+
85+
// User visible APIs. These may called both from user code and from
86+
// compiler generated code.
87+
DEVICE_EXTERN_C void __itt_offload_wi_start(size_t *group_id, size_t wi_id,
88+
uint32_t wg_size);
89+
DEVICE_EXTERN_C void __itt_offload_wi_finish(size_t *group_id, size_t wi_id);
90+
DEVICE_EXTERN_C void __itt_offload_wg_barrier(uintptr_t barrier_id);
91+
DEVICE_EXTERN_C void __itt_offload_wi_resume(size_t *group_id, size_t wi_id);
92+
DEVICE_EXTERN_C void __itt_offload_sync_acquired(uintptr_t sync_id);
93+
DEVICE_EXTERN_C void __itt_offload_sync_releasing(uintptr_t sync_id);
94+
DEVICE_EXTERN_C void __itt_offload_wg_local_range(void *ptr, size_t size);
95+
DEVICE_EXTERN_C void
96+
__itt_offload_atomic_op_start(void *object, __itt_atomic_mem_op_t op_type,
97+
__itt_atomic_mem_order_t mem_order);
98+
DEVICE_EXTERN_C void
99+
__itt_offload_atomic_op_finish(void *object, __itt_atomic_mem_op_t op_type,
100+
__itt_atomic_mem_order_t mem_order);
101+
102+
#endif // __SPIR__
103+
#endif // __LIBDEVICE_DEVICE_ITT_H__

libdevice/itt_compiler_wrappers.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//==--- itt_compiler_wrappers.cpp - compiler wrappers for ITT --------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "device_itt.h"
10+
11+
#ifdef __SPIR__
12+
13+
DEVICE_EXTERN_C
14+
void __itt_offload_wi_start_wrapper() {
15+
if (!isITTEnabled())
16+
return;
17+
18+
size_t GroupID[3] = {__spirv_BuiltInWorkgroupId.x,
19+
__spirv_BuiltInWorkgroupId.y,
20+
__spirv_BuiltInWorkgroupId.z};
21+
size_t WIID = __spirv_BuiltInGlobalLinearId;
22+
uint32_t WGSize = static_cast<uint32_t>(__spirv_BuiltInWorkgroupSize.x *
23+
__spirv_BuiltInWorkgroupSize.y *
24+
__spirv_BuiltInWorkgroupSize.z);
25+
__itt_offload_wi_start_stub(GroupID, WIID, WGSize);
26+
}
27+
28+
DEVICE_EXTERN_C
29+
void __itt_offload_wi_finish_wrapper() {
30+
if (!isITTEnabled())
31+
return;
32+
33+
size_t GroupID[3] = {__spirv_BuiltInWorkgroupId.x,
34+
__spirv_BuiltInWorkgroupId.y,
35+
__spirv_BuiltInWorkgroupId.z};
36+
size_t WIID = __spirv_BuiltInGlobalLinearId;
37+
__itt_offload_wi_finish_stub(GroupID, WIID);
38+
}
39+
40+
DEVICE_EXTERN_C
41+
void __itt_offload_wg_barrier_wrapper() {
42+
if (!isITTEnabled())
43+
return;
44+
45+
__itt_offload_wg_barrier_stub(0);
46+
}
47+
48+
DEVICE_EXTERN_C
49+
void __itt_offload_wi_resume_wrapper() {
50+
if (!isITTEnabled())
51+
return;
52+
53+
size_t GroupID[3] = {__spirv_BuiltInWorkgroupId.x,
54+
__spirv_BuiltInWorkgroupId.y,
55+
__spirv_BuiltInWorkgroupId.z};
56+
size_t WIID = __spirv_BuiltInGlobalLinearId;
57+
__itt_offload_wi_resume_stub(GroupID, WIID);
58+
}
59+
60+
#endif // __SPIR__

libdevice/itt_stubs.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//==--- itt_stubs.cpp - stub functions for ITT ----------------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "device_itt.h"
10+
11+
#ifdef __SPIR__
12+
13+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
14+
__itt_offload_wi_start_stub(size_t *group_id, size_t wi_id, uint32_t wg_size) {}
15+
16+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
17+
__itt_offload_wi_finish_stub(size_t *group_id, size_t wi_id) {}
18+
19+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
20+
__itt_offload_wg_barrier_stub(uintptr_t barrier_id) {}
21+
22+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
23+
__itt_offload_wi_resume_stub(size_t *group_id, size_t wi_id) {}
24+
25+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
26+
__itt_offload_sync_acquired_stub(uintptr_t sync_id) {}
27+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
28+
__itt_offload_sync_releasing_stub(uintptr_t sync_id) {}
29+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
30+
__itt_offload_wg_local_range_stub(void *ptr, size_t size) {}
31+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
32+
__itt_offload_atomic_op_start_stub(void *object, __itt_atomic_mem_op_t op_type,
33+
__itt_atomic_mem_order_t mem_order) {}
34+
DEVICE_EXTERN_C ITT_STUB_ATTRIBUTES void
35+
__itt_offload_atomic_op_finish_stub(void *object, __itt_atomic_mem_op_t op_type,
36+
__itt_atomic_mem_order_t mem_order) {}
37+
38+
#endif // __SPIR__

libdevice/itt_user_wrappers.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//==--- itt_user_wrappers.cpp - user visible functions for ITT ------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "device_itt.h"
10+
11+
#ifdef __SPIR__
12+
13+
DEVICE_EXTERN_C void __itt_offload_wi_start(size_t *group_id, size_t wi_id,
14+
uint32_t wg_size) {
15+
if (isITTEnabled())
16+
__itt_offload_wi_start_stub(group_id, wi_id, wg_size);
17+
}
18+
19+
DEVICE_EXTERN_C void __itt_offload_wi_finish(size_t *group_id, size_t wi_id) {
20+
if (isITTEnabled())
21+
__itt_offload_wi_finish_stub(group_id, wi_id);
22+
}
23+
24+
DEVICE_EXTERN_C void __itt_offload_wg_barrier(uintptr_t barrier_id) {
25+
if (isITTEnabled())
26+
__itt_offload_wg_barrier_stub(barrier_id);
27+
}
28+
29+
DEVICE_EXTERN_C void __itt_offload_wi_resume(size_t *group_id, size_t wi_id) {
30+
if (isITTEnabled())
31+
__itt_offload_wi_resume_stub(group_id, wi_id);
32+
}
33+
34+
DEVICE_EXTERN_C void __itt_offload_sync_acquired(uintptr_t sync_id) {
35+
if (isITTEnabled())
36+
__itt_offload_sync_acquired_stub(sync_id);
37+
}
38+
39+
DEVICE_EXTERN_C void __itt_offload_sync_releasing(uintptr_t sync_id) {
40+
if (isITTEnabled())
41+
__itt_offload_sync_releasing_stub(sync_id);
42+
}
43+
44+
DEVICE_EXTERN_C void __itt_offload_wg_local_range(void *ptr, size_t size) {
45+
if (isITTEnabled())
46+
__itt_offload_wg_local_range_stub(ptr, size);
47+
}
48+
49+
DEVICE_EXTERN_C void
50+
__itt_offload_atomic_op_start(void *object, __itt_atomic_mem_op_t op_type,
51+
__itt_atomic_mem_order_t mem_order) {
52+
if (isITTEnabled())
53+
__itt_offload_atomic_op_start_stub(object, op_type, mem_order);
54+
}
55+
56+
DEVICE_EXTERN_C void
57+
__itt_offload_atomic_op_finish(void *object, __itt_atomic_mem_op_t op_type,
58+
__itt_atomic_mem_order_t mem_order) {
59+
if (isITTEnabled())
60+
__itt_offload_atomic_op_finish_stub(object, op_type, mem_order);
61+
}
62+
63+
#endif // __SPIR__

libdevice/spirv_vars.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,21 @@
1616
#include <cstddef>
1717
#include <cstdint>
1818

19+
#define __SPIRV_VAR_QUALIFIERS EXTERN_C const
1920
typedef size_t size_t_vec __attribute__((ext_vector_type(3)));
20-
extern "C" const size_t_vec __spirv_BuiltInGlobalInvocationId;
21-
extern "C" const size_t_vec __spirv_BuiltInLocalInvocationId;
22-
21+
__SPIRV_VAR_QUALIFIERS size_t_vec __spirv_BuiltInGlobalInvocationId;
22+
__SPIRV_VAR_QUALIFIERS size_t __spirv_BuiltInGlobalLinearId;
23+
__SPIRV_VAR_QUALIFIERS size_t_vec __spirv_BuiltInLocalInvocationId;
24+
__SPIRV_VAR_QUALIFIERS size_t_vec __spirv_BuiltInWorkgroupId;
25+
__SPIRV_VAR_QUALIFIERS size_t_vec __spirv_BuiltInWorkgroupSize;
26+
27+
// FIXME: change DEVICE_EXTERNAL to static and rename the functions,
28+
// when #3311 is fixed.
29+
// These are just internal functions used within libdevice.
30+
// We must not intrude the __spirv "namespace", so we'd better
31+
// use names like getGlobalInvocationIdX.
32+
// Libdevice must not export these APIs either, but it currently
33+
// exports them due to DEVICE_EXTERNAL.
2334
DEVICE_EXTERNAL inline size_t __spirv_GlobalInvocationId_x() {
2435
return __spirv_BuiltInGlobalInvocationId.x;
2536
}

0 commit comments

Comments
 (0)