Skip to content

Commit 100ea1d

Browse files
committed
[SYCL][RTC] Experimental use of program manager to build device images
Signed-off-by: Julian Oppermann <[email protected]>
1 parent b453dcc commit 100ea1d

File tree

8 files changed

+68
-40
lines changed

8 files changed

+68
-40
lines changed

sycl/source/detail/jit_compiler.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,13 +1120,17 @@ sycl_device_binaries jit_compiler::createPIDeviceBinary(
11201120
}
11211121

11221122
sycl_device_binaries jit_compiler::createDeviceBinaryImage(
1123-
const ::jit_compiler::RTCBundleInfo &BundleInfo) {
1123+
const ::jit_compiler::RTCBundleInfo &BundleInfo,
1124+
const std::string &OffloadEntryPrefix) {
11241125
DeviceBinaryContainer Binary;
11251126
for (const auto &Symbol : BundleInfo.SymbolTable) {
1126-
// Create an offload entry for each kernel.
1127+
// Create an offload entry for each kernel. We prepend a unique prefix to
1128+
// support reusing the same name across multiple RTC requests. The actual
1129+
// entrypoints remain unchanged.
11271130
// It seems to be OK to set zero for most of the information here, at least
11281131
// that is the case for compiled SPIR-V binaries.
1129-
OffloadEntryContainer Entry{Symbol.c_str(), /*Addr=*/nullptr, /*Size=*/0,
1132+
std::string PrefixedName = OffloadEntryPrefix + Symbol.c_str();
1133+
OffloadEntryContainer Entry{PrefixedName, /*Addr=*/nullptr, /*Size=*/0,
11301134
/*Flags=*/0, /*Reserved=*/0};
11311135
Binary.addOffloadEntry(std::move(Entry));
11321136
}
@@ -1250,7 +1254,8 @@ sycl_device_binaries jit_compiler::compileSYCL(
12501254
throw sycl::exception(sycl::errc::build, Result.getBuildLog());
12511255
}
12521256

1253-
return createDeviceBinaryImage(Result.getBundleInfo());
1257+
return createDeviceBinaryImage(Result.getBundleInfo(),
1258+
/*OffloadEntryPrefix=*/Id + '$');
12541259
}
12551260

12561261
} // namespace detail

sycl/source/detail/jit_compiler.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ class jit_compiler {
7171
::jit_compiler::BinaryFormat Format);
7272

7373
sycl_device_binaries
74-
createDeviceBinaryImage(const ::jit_compiler::RTCBundleInfo &BundleInfo);
74+
createDeviceBinaryImage(const ::jit_compiler::RTCBundleInfo &BundleInfo,
75+
const std::string &OffloadEntryPrefix);
7576

7677
std::vector<uint8_t>
7778
encodeArgUsageMask(const ::jit_compiler::ArgUsageMask &Mask) const;

sycl/source/detail/kernel_bundle_impl.hpp

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,46 @@ class kernel_bundle_impl {
474474
DeviceVec.push_back(Dev);
475475
}
476476

477+
if (Language == syclex::source_language::sycl_jit) {
478+
// Experimental: Build device images via the program manager.
479+
// TODO: Support persistent caching.
480+
481+
const std::string &SourceStr = std::get<std::string>(this->Source);
482+
auto [Binaries, Id] = syclex::detail::SYCL_JIT_to_SPIRV(
483+
SourceStr, IncludePairs, BuildOptions, LogPtr, RegisteredKernelNames);
484+
485+
assert(Binaries->NumDeviceBinaries == 1);
486+
487+
auto &PM = detail::ProgramManager::getInstance();
488+
std::unordered_set<uintptr_t> ImageIds;
489+
PM.addImages(Binaries, &ImageIds);
490+
auto DevImgs = PM.getSYCLDeviceImages(
491+
MContext, MDevices,
492+
[&ImageIds](const detail::DeviceImageImplPtr &DevImgImpl) -> bool {
493+
return ImageIds.count(
494+
DevImgImpl->get_bin_image_ref()->getImageID());
495+
},
496+
bundle_state::executable);
497+
498+
PM.bringSYCLDeviceImagesToState(DevImgs, bundle_state::executable);
499+
500+
std::vector<std::string> KernelNames;
501+
std::transform(Binaries->DeviceBinaries->EntriesBegin,
502+
Binaries->DeviceBinaries->EntriesEnd,
503+
std::back_inserter(KernelNames),
504+
[PrefixLen = Id.length() + 1](auto &OffloadEntry) {
505+
// `jit_compiler::compileSYCL` uses `Id + '$'` as name
506+
// prefix; drop that here.
507+
return std::string{OffloadEntry.name + PrefixLen};
508+
});
509+
510+
assert(DevImgs.size() == 1);
511+
assert(!DevImgs.front().hasDeps());
512+
513+
return std::make_shared<kernel_bundle_impl>(
514+
MContext, MDevices, DevImgs.front().getMain(), KernelNames, Language);
515+
}
516+
477517
ur_program_handle_t UrProgram = nullptr;
478518
// SourceStrPtr will be null when source is Spir-V bytes.
479519
const std::string *SourceStrPtr = std::get_if<std::string>(&this->Source);
@@ -514,15 +554,6 @@ class kernel_bundle_impl {
514554
BuildOptions, LogPtr,
515555
RegisteredKernelNames);
516556
}
517-
if (Language == syclex::source_language::sycl_jit) {
518-
auto *Binaries = syclex::detail::SYCL_JIT_to_SPIRV(
519-
*SourceStrPtr, IncludePairs, BuildOptions, LogPtr,
520-
RegisteredKernelNames);
521-
assert(Binaries->NumDeviceBinaries == 1 &&
522-
"Device code splitting is not yet supported");
523-
return std::vector<uint8_t>(Binaries->DeviceBinaries->BinaryStart,
524-
Binaries->DeviceBinaries->BinaryEnd);
525-
}
526557
throw sycl::exception(
527558
make_error_code(errc::invalid),
528559
"SYCL C++, OpenCL C and SPIR-V are the only supported "

sycl/source/detail/kernel_compiler/kernel_compiler_sycl.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ bool SYCL_Compilation_Available() {
327327

328328
#if SYCL_EXT_JIT_ENABLE
329329
#include "../jit_compiler.hpp"
330+
#include <atomic>
330331
#endif
331332

332333
namespace sycl {
@@ -342,15 +343,20 @@ bool SYCL_JIT_Compilation_Available() {
342343
#endif
343344
}
344345

345-
sycl_device_binaries SYCL_JIT_to_SPIRV(
346+
std::pair<sycl_device_binaries, std::string> SYCL_JIT_to_SPIRV(
346347
[[maybe_unused]] const std::string &SYCLSource,
347348
[[maybe_unused]] include_pairs_t IncludePairs,
348349
[[maybe_unused]] const std::vector<std::string> &UserArgs,
349350
[[maybe_unused]] std::string *LogPtr,
350351
[[maybe_unused]] const std::vector<std::string> &RegisteredKernelNames) {
351352
#if SYCL_EXT_JIT_ENABLE
352-
return sycl::detail::jit_compiler::get_instance().compileSYCL(
353-
"rtc", SYCLSource, IncludePairs, UserArgs, LogPtr, RegisteredKernelNames);
353+
static std::atomic_uintptr_t CompilationId;
354+
std::string Id = "rtc_" + std::to_string(CompilationId++);
355+
sycl_device_binaries Binaries =
356+
sycl::detail::jit_compiler::get_instance().compileSYCL(
357+
Id, SYCLSource, IncludePairs, UserArgs, LogPtr,
358+
RegisteredKernelNames);
359+
return std::make_pair(Binaries, std::move(Id));
354360
#else
355361
throw sycl::exception(sycl::errc::build,
356362
"kernel_compiler via sycl-jit is not available");

sycl/source/detail/kernel_compiler/kernel_compiler_sycl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ bool SYCL_Compilation_Available();
3535

3636
std::string userArgsAsString(const std::vector<std::string> &UserArguments);
3737

38-
sycl_device_binaries
38+
std::pair<sycl_device_binaries, std::string>
3939
SYCL_JIT_to_SPIRV(const std::string &Source, include_pairs_t IncludePairs,
4040
const std::vector<std::string> &UserArgs, std::string *LogPtr,
4141
const std::vector<std::string> &RegisteredKernelNames);

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,8 @@ ProgramManager::kernelImplicitLocalArgPos(const std::string &KernelName) const {
18021802
return {};
18031803
}
18041804

1805-
void ProgramManager::addImages(sycl_device_binaries DeviceBinary) {
1805+
void ProgramManager::addImages(sycl_device_binaries DeviceBinary,
1806+
std::unordered_set<uintptr_t> *ImageIds) {
18061807
const bool DumpImages = std::getenv("SYCL_DUMP_IMAGES") && !m_UseSpvFile;
18071808
for (int I = 0; I < DeviceBinary->NumDeviceBinaries; I++) {
18081809
sycl_device_binary RawImg = &(DeviceBinary->DeviceBinaries[I]);
@@ -1825,6 +1826,9 @@ void ProgramManager::addImages(sycl_device_binaries DeviceBinary) {
18251826
else
18261827
Img = std::make_unique<RTDeviceBinaryImage>(RawImg);
18271828

1829+
if (ImageIds)
1830+
ImageIds->insert(Img->getImageID());
1831+
18281832
static uint32_t SequenceID = 0;
18291833

18301834
// Fill the kernel argument mask map

sycl/source/detail/program_manager/program_manager.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ class ProgramManager {
210210
ur_program_handle_t getUrProgramFromUrKernel(ur_kernel_handle_t Kernel,
211211
const ContextImplPtr Context);
212212

213-
void addImages(sycl_device_binaries DeviceImages);
213+
void addImages(sycl_device_binaries DeviceImages,
214+
std::unordered_set<uintptr_t> *ImageIds = nullptr);
214215
void debugPrintBinaryImages() const;
215216
static std::string getProgramBuildLog(const ur_program_handle_t &Program,
216217
const ContextImplPtr Context);

sycl/test-e2e/KernelCompiler/kernel_compiler_sycl_jit.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,6 @@
1313
// RUN: %{run} %t.out 1
1414
// RUN: %{l0_leak_check} %{run} %t.out 1
1515

16-
// -- Test again, with caching.
17-
18-
// DEFINE: %{cache_vars} = %{l0_leak_check} env SYCL_CACHE_PERSISTENT=1 SYCL_CACHE_TRACE=5 SYCL_CACHE_DIR=%t/cache_dir
19-
// RUN: %if run-mode %{ rm -rf %t/cache_dir %}
20-
// RUN: %{cache_vars} %{run-unfiltered-devices} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE
21-
// RUN: %{cache_vars} %{run-unfiltered-devices} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE
22-
23-
// -- Add leak check.
24-
// RUN: %if run-mode %{ rm -rf %t/cache_dir %}
25-
// RUN: %{l0_leak_check} %{cache_vars} %{run-unfiltered-devices} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE
26-
// RUN: %{l0_leak_check} %{cache_vars} %{run-unfiltered-devices} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE
27-
28-
// CHECK-WRITTEN-TO-CACHE: [Persistent Cache]: enabled
29-
// CHECK-WRITTEN-TO-CACHE-NOT: [kernel_compiler Persistent Cache]: using cached binary
30-
// CHECK-WRITTEN-TO-CACHE: [kernel_compiler Persistent Cache]: binary has been cached
31-
32-
// CHECK-READ-FROM-CACHE: [Persistent Cache]: enabled
33-
// CHECK-READ-FROM-CACHE-NOT: [kernel_compiler Persistent Cache]: binary has been cached
34-
// CHECK-READ-FROM-CACHE: [kernel_compiler Persistent Cache]: using cached binary
35-
3616
#include <sycl/detail/core.hpp>
3717
#include <sycl/kernel_bundle.hpp>
3818
#include <sycl/usm.hpp>

0 commit comments

Comments
 (0)