Skip to content

Commit 491ec6d

Browse files
[SYCL] Cache kernel_id and implement sycl::get_kernel_ids (#4379)
These changes implement the sycl::get_kernel_ids free function and introduces caching of kernel identifiers in the program manager. The caching of kernel identifiers is intended to ensure that each identifier is only created once and copies of the identifier is passed around, as to ensure equality in accordance with the SYCL 2020 specification. NOTE: This is a non-breaking ABI change. Signed-off-by: Steffen Larsen <[email protected]>
1 parent c357af1 commit 491ec6d

File tree

9 files changed

+383
-26
lines changed

9 files changed

+383
-26
lines changed

sycl/include/CL/sycl/kernel_bundle.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ class __SYCL_EXPORT kernel_id {
5757

5858
template <class T>
5959
friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
60-
61-
template <typename KernelName> friend kernel_id get_kernel_id();
6260
};
6361

6462
namespace detail {
@@ -343,14 +341,20 @@ class kernel_bundle : public detail::kernel_bundle_plain {
343341
// get_kernel_id API
344342
/////////////////////////
345343

344+
namespace detail {
345+
// Internal non-template versions of get_kernel_id API which is used by public
346+
// onces
347+
__SYCL_EXPORT kernel_id get_kernel_id_impl(std::string KernelName);
348+
} // namespace detail
349+
346350
/// \returns the kernel_id associated with the KernelName
347351
template <typename KernelName> kernel_id get_kernel_id() {
348352
using KI = sycl::detail::KernelInfo<KernelName>;
349-
return sycl::kernel_id(KI::getName());
353+
return detail::get_kernel_id_impl(KI::getName());
350354
}
351355

352356
/// \returns a vector with all kernel_id's defined in the application
353-
std::vector<kernel_id> get_kernel_ids();
357+
__SYCL_EXPORT std::vector<kernel_id> get_kernel_ids();
354358

355359
/////////////////////////
356360
// get_kernel_bundle API

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,11 +1037,21 @@ void ProgramManager::addImages(pi_device_binaries DeviceBinary) {
10371037
}
10381038
// ... or create the set first if it hasn't been
10391039
KernelSetId KSId = getNextKernelSetId();
1040-
for (_pi_offload_entry EntriesIt = EntriesB; EntriesIt != EntriesE;
1041-
++EntriesIt) {
1042-
auto Result = KSIdMap.insert(std::make_pair(EntriesIt->name, KSId));
1043-
(void)Result;
1044-
assert(Result.second && "Kernel sets are not disjoint");
1040+
{
1041+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
1042+
for (_pi_offload_entry EntriesIt = EntriesB; EntriesIt != EntriesE;
1043+
++EntriesIt) {
1044+
auto Result = KSIdMap.insert(std::make_pair(EntriesIt->name, KSId));
1045+
(void)Result;
1046+
assert(Result.second && "Kernel sets are not disjoint");
1047+
// ... and create a unique kernel ID for the entry
1048+
std::shared_ptr<detail::kernel_id_impl> KernelIDImpl =
1049+
std::make_shared<detail::kernel_id_impl>(EntriesIt->name);
1050+
sycl::kernel_id KernelID =
1051+
detail::createSyclObjFromImpl<sycl::kernel_id>(KernelIDImpl);
1052+
m_KernelIDs.insert(
1053+
std::make_pair(EntriesIt->name, std::move(KernelID)));
1054+
}
10451055
}
10461056
m_DeviceImages[KSId].reset(new std::vector<RTDeviceBinaryImageUPtr>());
10471057
m_DeviceImages[KSId]->push_back(std::move(Img));
@@ -1266,6 +1276,25 @@ static bool compatibleWithDevice(RTDeviceBinaryImage *BinImage,
12661276
return (0 == SuitableImageID);
12671277
}
12681278

1279+
kernel_id ProgramManager::getSYCLKernelID(const std::string &KernelName) {
1280+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
1281+
1282+
auto KernelID = m_KernelIDs.find(KernelName);
1283+
assert(KernelID != m_KernelIDs.end() && "Kernel ID missing");
1284+
return KernelID->second;
1285+
}
1286+
1287+
std::vector<kernel_id> ProgramManager::getAllSYCLKernelIDs() {
1288+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
1289+
1290+
std::vector<sycl::kernel_id> AllKernelIDs;
1291+
AllKernelIDs.reserve(m_KernelIDs.size());
1292+
for (std::pair<std::string, kernel_id> KernelID : m_KernelIDs) {
1293+
AllKernelIDs.push_back(KernelID.second);
1294+
}
1295+
return AllKernelIDs;
1296+
}
1297+
12691298
std::vector<device_image_plain>
12701299
ProgramManager::getSYCLDeviceImagesWithCompatibleState(
12711300
const context &Ctx, const std::vector<device> &Devs,
@@ -1317,14 +1346,15 @@ ProgramManager::getSYCLDeviceImagesWithCompatibleState(
13171346
// Collect kernel names for the image
13181347
pi_device_binary DevBin =
13191348
const_cast<pi_device_binary>(&BinImage->getRawData());
1320-
for (_pi_offload_entry EntriesIt = DevBin->EntriesBegin;
1321-
EntriesIt != DevBin->EntriesEnd; ++EntriesIt) {
1322-
1323-
std::shared_ptr<detail::kernel_id_impl> KernelIDImpl =
1324-
std::make_shared<detail::kernel_id_impl>(EntriesIt->name);
1325-
1326-
KernelIDs.push_back(
1327-
detail::createSyclObjFromImpl<sycl::kernel_id>(KernelIDImpl));
1349+
{
1350+
std::lock_guard<std::mutex> KernelIDsGuard(m_KernelIDsMutex);
1351+
for (_pi_offload_entry EntriesIt = DevBin->EntriesBegin;
1352+
EntriesIt != DevBin->EntriesEnd; ++EntriesIt) {
1353+
auto KernelID = m_KernelIDs.find(EntriesIt->name);
1354+
assert(KernelID != m_KernelIDs.end() &&
1355+
"Kernel ID in device binary missing from cache");
1356+
KernelIDs.push_back(KernelID->second);
1357+
}
13281358
}
13291359
// device_image_impl expects kernel ids to be sorted for fast search
13301360
std::sort(KernelIDs.begin(), KernelIDs.end(), LessByNameComp{});

sycl/source/detail/program_manager/program_manager.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ class ProgramManager {
153153
const std::string &KernelName,
154154
bool KnownProgram);
155155

156+
// The function returns the unique SYCL kernel identifier associated with a
157+
// kernel name.
158+
kernel_id getSYCLKernelID(const std::string &KernelName);
159+
160+
// The function returns a vector containing all unique SYCL kernel identifiers
161+
// in SYCL device images.
162+
std::vector<kernel_id> getAllSYCLKernelIDs();
163+
156164
// The function returns a vector of SYCL device images that are compiled with
157165
// the required state and at least one device from the passed list of devices.
158166
std::vector<device_image_plain>
@@ -272,6 +280,18 @@ class ProgramManager {
272280
/// Access must be guarded by the \ref Sync::getGlobalLock()
273281
std::unordered_map<OSModuleHandle, KernelSetId> m_OSModuleKernelSets;
274282

283+
/// Maps names of kernels to their unique kernel IDs.
284+
/// TODO: Use std::unordered_set with transparent hash and equality functions
285+
/// when C++20 is enabled for the runtime library.
286+
/// Access must be guarded by the m_KernelIDsMutex mutex
287+
std::unordered_map<std::string, kernel_id> m_KernelIDs;
288+
289+
/// Protects kernel ID cache.
290+
/// NOTE: This may be acquired while \ref Sync::getGlobalLock() is held so to
291+
/// avoid deadlocks care must be taken not to acquire
292+
/// \ref Sync::getGlobalLock() while holding this mutex.
293+
std::mutex m_KernelIDsMutex;
294+
275295
// Keeps track of pi_program to image correspondence. Needed for:
276296
// - knowing which specialization constants are used in the program and
277297
// injecting their current values before compiling the SPIR-V; the binary

sycl/source/kernel_bundle.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,13 @@ bool kernel_bundle_plain::is_specialization_constant_set(
110110
return impl->is_specialization_constant_set(SpecName);
111111
}
112112

113-
////////////////////////////
114-
///// free functions
115-
///////////////////////////
113+
//////////////////////////////////
114+
///// sycl::detail free functions
115+
//////////////////////////////////
116+
117+
kernel_id get_kernel_id_impl(std::string KernelName) {
118+
return detail::ProgramManager::getInstance().getSYCLKernelID(KernelName);
119+
}
116120

117121
detail::KernelBundleImplPtr
118122
get_kernel_bundle_impl(const context &Ctx, const std::vector<device> &Devs,
@@ -263,5 +267,13 @@ std::vector<sycl::device> find_device_intersection(
263267

264268
} // namespace detail
265269

270+
//////////////////////////
271+
///// sycl free functions
272+
//////////////////////////
273+
274+
std::vector<kernel_id> get_kernel_ids() {
275+
return detail::ProgramManager::getInstance().getAllSYCLKernelIDs();
276+
}
277+
266278
} // namespace sycl
267279
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3618,6 +3618,7 @@ _ZN2cl4sycl13sycl_categoryEv
36183618
_ZN2cl4sycl14exception_list5ClearEv
36193619
_ZN2cl4sycl14exception_list8PushBackEONSt15__exception_ptr13exception_ptrE
36203620
_ZN2cl4sycl14exception_list8PushBackERKNSt15__exception_ptr13exception_ptrE
3621+
_ZN2cl4sycl14get_kernel_idsEv
36213622
_ZN2cl4sycl15make_error_codeENS0_4errcE
36223623
_ZN2cl4sycl16get_pointer_typeEPKvRKNS0_7contextE
36233624
_ZN2cl4sycl18aligned_alloc_hostEmmRKNS0_5queueE
@@ -3818,6 +3819,7 @@ _ZN2cl4sycl6detail17HostProfilingInfo3endEv
38183819
_ZN2cl4sycl6detail17HostProfilingInfo5startEv
38193820
_ZN2cl4sycl6detail18convertChannelTypeE22_pi_image_channel_type
38203821
_ZN2cl4sycl6detail18convertChannelTypeENS0_18image_channel_typeE
3822+
_ZN2cl4sycl6detail18get_kernel_id_implENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
38213823
_ZN2cl4sycl6detail18make_kernel_bundleEmRKNS0_7contextENS0_12bundle_stateENS0_7backendE
38223824
_ZN2cl4sycl6detail18stringifyErrorCodeEi
38233825
_ZN2cl4sycl6detail19convertChannelOrderE23_pi_image_channel_order

sycl/test/abi/sycl_symbols_windows.dump

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,7 +2133,9 @@
21332133
?get_kernel_bundle_impl@detail@sycl@cl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@sycl@cl@@@std@@AEBVcontext@23@AEBV?$vector@Vdevice@sycl@cl@@V?$allocator@Vdevice@sycl@cl@@@std@@@5@AEBV?$vector@Vkernel_id@sycl@cl@@V?$allocator@Vkernel_id@sycl@cl@@@std@@@5@W4bundle_state@23@@Z
21342134
?get_kernel_bundle_impl@detail@sycl@cl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@sycl@cl@@@std@@AEBVcontext@23@AEBV?$vector@Vdevice@sycl@cl@@V?$allocator@Vdevice@sycl@cl@@@std@@@5@W4bundle_state@23@@Z
21352135
?get_kernel_bundle_impl@detail@sycl@cl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@sycl@cl@@@std@@AEBVcontext@23@AEBV?$vector@Vdevice@sycl@cl@@V?$allocator@Vdevice@sycl@cl@@@std@@@5@W4bundle_state@23@AEBV?$function@$$A6A_NAEBV?$shared_ptr@Vdevice_image_impl@detail@sycl@cl@@@std@@@Z@5@@Z
2136+
?get_kernel_id_impl@detail@sycl@cl@@YA?AVkernel_id@23@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z
21362137
?get_kernel_ids@kernel_bundle_plain@detail@sycl@cl@@QEBA?AV?$vector@Vkernel_id@sycl@cl@@V?$allocator@Vkernel_id@sycl@cl@@@std@@@std@@XZ
2138+
?get_kernel_ids@sycl@cl@@YA?AV?$vector@Vkernel_id@sycl@cl@@V?$allocator@Vkernel_id@sycl@cl@@@std@@@std@@XZ
21372139
?get_link_options@program@sycl@cl@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ
21382140
?get_max_statement_size@stream@sycl@cl@@QEBA_KXZ
21392141
?get_max_statement_size@stream_impl@detail@sycl@cl@@QEBA_KXZ

sycl/unittests/SYCL2020/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ add_sycl_unittest(SYCL2020Tests OBJECT
66
GetNativeOpenCL.cpp
77
SpecConstDefaultValues.cpp
88
KernelBundle.cpp
9+
KernelID.cpp
910
)
1011

0 commit comments

Comments
 (0)