Skip to content

Commit aabbbe8

Browse files
authored
[SYCL][RTC] Propagate -Xs options along in-memory pipeline (#17329)
Ensures that `-Xs` option arguments are baked into the device image(s), from which they are picked up by the progam manager. Signed-off-by: Julian Oppermann <julian.oppermann@codeplay.com>
1 parent 0904348 commit aabbbe8

File tree

9 files changed

+79
-16
lines changed

9 files changed

+79
-16
lines changed

sycl-jit/common/include/Kernel.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,14 @@ struct RTCDevImgInfo {
409409
RTCDevImgInfo &operator=(RTCDevImgInfo &&) = default;
410410
};
411411

412-
using RTCBundleInfo = DynArray<RTCDevImgInfo>;
412+
struct RTCBundleInfo {
413+
DynArray<RTCDevImgInfo> DevImgInfos;
414+
sycl::detail::string CompileOptions;
415+
416+
RTCBundleInfo() = default;
417+
RTCBundleInfo(RTCBundleInfo &&) = default;
418+
RTCBundleInfo &operator=(RTCBundleInfo &&) = default;
419+
};
413420

414421
// LLVM's APIs prefer `char *` for byte buffers.
415422
using RTCDeviceCodeIR = DynArray<char>;

sycl-jit/jit-compiler/lib/KernelFusion.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@ compileSYCL(InMemoryFile SourceFile, View<InMemoryFile> IncludeFiles,
361361
}
362362
auto [BundleInfo, Modules] = std::move(*PostLinkResultOrError);
363363

364-
for (auto [DevImgInfo, Module] : llvm::zip_equal(BundleInfo, Modules)) {
364+
for (auto [DevImgInfo, Module] :
365+
llvm::zip_equal(BundleInfo.DevImgInfos, Modules)) {
365366
auto BinaryInfoOrError =
366367
translation::KernelTranslator::translateDevImgToSPIRV(
367368
*Module, JITContext::getInstance());
@@ -372,6 +373,8 @@ compileSYCL(InMemoryFile SourceFile, View<InMemoryFile> IncludeFiles,
372373
DevImgInfo.BinaryInfo = std::move(*BinaryInfoOrError);
373374
}
374375

376+
encodeBuildOptions(BundleInfo, UserArgList);
377+
375378
if (llvm::timeTraceProfilerEnabled()) {
376379
auto Error = llvm::timeTraceProfilerWrite(
377380
TraceFileName, /*FallbackFileName=*/"trace.json");

sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -661,12 +661,13 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
661661

662662
// TODO: This allocation assumes that there are no further splits required,
663663
// i.e. there are no mixed SYCL/ESIMD modules.
664-
RTCBundleInfo BundleInfo{Splitter->remainingSplits()};
664+
RTCBundleInfo BundleInfo;
665+
BundleInfo.DevImgInfos = DynArray<RTCDevImgInfo>{Splitter->remainingSplits()};
665666
SmallVector<std::unique_ptr<llvm::Module>> Modules;
666667

667-
auto *DevImgInfoIt = BundleInfo.begin();
668+
auto *DevImgInfoIt = BundleInfo.DevImgInfos.begin();
668669
while (Splitter->hasMoreSplits()) {
669-
assert(DevImgInfoIt != BundleInfo.end());
670+
assert(DevImgInfoIt != BundleInfo.DevImgInfos.end());
670671

671672
ModuleDesc MDesc = Splitter->nextSplit();
672673
RTCDevImgInfo &DevImgInfo = *DevImgInfoIt++;
@@ -796,6 +797,32 @@ jit_compiler::parseUserArgs(View<const char *> UserArgs) {
796797
return std::move(AL);
797798
}
798799

800+
void jit_compiler::encodeBuildOptions(RTCBundleInfo &BundleInfo,
801+
const InputArgList &UserArgList) {
802+
std::string CompileOptions;
803+
raw_string_ostream COSOS{CompileOptions};
804+
805+
for (Arg *A : UserArgList.getArgs()) {
806+
if (!(A->getOption().matches(OPT_Xs) ||
807+
A->getOption().matches(OPT_Xs_separate))) {
808+
continue;
809+
}
810+
811+
// Trim first and last quote if they exist, but no others.
812+
StringRef AV{A->getValue()};
813+
AV = AV.trim();
814+
if (AV.front() == AV.back() && (AV.front() == '\'' || AV.front() == '"')) {
815+
AV = AV.drop_front().drop_back();
816+
}
817+
818+
COSOS << (CompileOptions.empty() ? "" : " ") << AV;
819+
}
820+
821+
if (!CompileOptions.empty()) {
822+
BundleInfo.CompileOptions = CompileOptions;
823+
}
824+
}
825+
799826
void jit_compiler::configureDiagnostics(LLVMContext &Context,
800827
std::string &BuildLog) {
801828
Context.setDiagnosticHandler(

sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ performPostLink(std::unique_ptr<llvm::Module> Module,
4444
llvm::Expected<llvm::opt::InputArgList>
4545
parseUserArgs(View<const char *> UserArgs);
4646

47+
void encodeBuildOptions(RTCBundleInfo &BundleInfo,
48+
const llvm::opt::InputArgList &UserArgList);
49+
4750
void configureDiagnostics(llvm::LLVMContext &Context, std::string &BuildLog);
4851

4952
} // namespace jit_compiler

sycl/source/detail/jit_compiler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ sycl_device_binaries jit_compiler::createDeviceBinaries(
11551155
const std::string &Prefix) {
11561156
auto Collection = std::make_unique<DeviceBinariesCollection>();
11571157

1158-
for (const auto &DevImgInfo : BundleInfo) {
1158+
for (const auto &DevImgInfo : BundleInfo.DevImgInfos) {
11591159
DeviceBinaryContainer Binary;
11601160
for (const auto &Symbol : DevImgInfo.SymbolTable) {
11611161
// Create an offload entry for each kernel. We prepend a unique prefix to
@@ -1182,6 +1182,8 @@ sycl_device_binaries jit_compiler::createDeviceBinaries(
11821182
}
11831183
}
11841184
Binary.addProperty(std::move(PropSet));
1185+
1186+
Binary.setCompileOptions(BundleInfo.CompileOptions.c_str());
11851187
}
11861188

11871189
Collection->addDeviceBinary(std::move(Binary),

sycl/source/detail/jit_compiler.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ class JITContext;
2727
struct SYCLKernelInfo;
2828
struct SYCLKernelAttribute;
2929
struct RTCDevImgInfo;
30+
struct RTCBundleInfo;
3031
template <typename T> class DynArray;
3132
using ArgUsageMask = DynArray<uint8_t>;
3233
using JITEnvVar = DynArray<char>;
33-
using RTCBundleInfo = DynArray<RTCDevImgInfo>;
3434
} // namespace jit_compiler
3535

3636
namespace sycl {

sycl/source/detail/jit_device_binaries.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,26 @@ void DeviceBinaryContainer::addProperty(PropertySetContainer &&Cont) {
8989
PropertySets.push_back(std::move(Cont));
9090
}
9191

92+
void DeviceBinaryContainer::setCompileOptions(std::string_view CompileOpts) {
93+
// Forbid calls to this method after the first PI struct has been created.
94+
assert(Fused && "Reallocating string would invalidate existing UR structs");
95+
if (CompileOpts.empty()) {
96+
CompileOptions.reset();
97+
return;
98+
}
99+
CompileOptions.reset(new char[CompileOpts.length() + 1]);
100+
std::memcpy(CompileOptions.get(), CompileOpts.data(),
101+
CompileOpts.length() + 1);
102+
}
103+
92104
sycl_device_binary_struct DeviceBinaryContainer::getPIDeviceBinary(
93105
const unsigned char *BinaryStart, size_t BinarySize, const char *TargetSpec,
94106
sycl_device_binary_type Format) {
95107
sycl_device_binary_struct DeviceBinary;
96108
DeviceBinary.Version = SYCL_DEVICE_BINARY_VERSION;
97109
DeviceBinary.Kind = SYCL_DEVICE_BINARY_OFFLOAD_KIND_SYCL;
98110
DeviceBinary.Format = Format;
99-
DeviceBinary.CompileOptions = "";
111+
DeviceBinary.CompileOptions = CompileOptions ? CompileOptions.get() : "";
100112
DeviceBinary.LinkOptions = "";
101113
DeviceBinary.ManifestStart = nullptr;
102114
DeviceBinary.ManifestEnd = nullptr;

sycl/source/detail/jit_device_binaries.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <cstring>
1515
#include <memory>
16+
#include <string_view>
1617

1718
namespace sycl {
1819
inline namespace _V1 {
@@ -113,6 +114,8 @@ class DeviceBinaryContainer {
113114

114115
void addProperty(PropertySetContainer &&Cont);
115116

117+
void setCompileOptions(std::string_view CompileOpts);
118+
116119
sycl_device_binary_struct getPIDeviceBinary(const unsigned char *BinaryStart,
117120
size_t BinarySize,
118121
const char *TargetSpec,
@@ -124,6 +127,7 @@ class DeviceBinaryContainer {
124127
std::vector<_sycl_offload_entry_struct> PIOffloadEntries;
125128
std::vector<PropertySetContainer> PropertySets;
126129
std::vector<_sycl_device_binary_property_set_struct> PIPropertySets;
130+
std::unique_ptr<char[]> CompileOptions;
127131
};
128132

129133
/// Representation of sycl_device_binaries_struct for creation of JIT device

sycl/test-e2e/KernelCompiler/sycl_device_flags.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
// UNSUPPORTED-INTENDED: IGC shader dump not available on Windows.
1414

1515
// RUN: %{build} -o %t.out
16-
// RUN: env IGC_DumpToCustomDir=%T.dump IGC_ShaderDumpEnable=1 NEO_CACHE_PERSISTENT=0 %{run} %t.out %T.dump/
16+
// RUN: env IGC_DumpToCustomDir=%T.dump_0 IGC_ShaderDumpEnable=1 NEO_CACHE_PERSISTENT=0 %{run} %t.out sycl %T.dump_0/
17+
// RUN: env IGC_DumpToCustomDir=%T.dump_1 IGC_ShaderDumpEnable=1 NEO_CACHE_PERSISTENT=0 %{run} %t.out sycl_jit %T.dump_1/
1718

1819
// clang-format off
1920
/*
@@ -105,28 +106,32 @@ int test_dump(std::string &dump_dir) {
105106

106107
int main(int argc, char *argv[]) {
107108

108-
if (argc != 2) {
109-
std::cerr << "Usage: " << argv[0] << " <dump_directory>" << std::endl;
109+
if (argc != 3) {
110+
std::cerr << "Usage: " << argv[0] << " <lang> <dump_directory>"
111+
<< std::endl;
110112
return 1;
111113
}
112-
std::string dump_dir = argv[1];
113114

114115
namespace syclex = sycl::ext::oneapi::experimental;
115116
using source_kb = sycl::kernel_bundle<sycl::bundle_state::ext_oneapi_source>;
116117
using exe_kb = sycl::kernel_bundle<sycl::bundle_state::executable>;
117118

119+
syclex::source_language lang = std::strcmp(argv[1], "sycl_jit") == 0
120+
? syclex::source_language::sycl_jit
121+
: syclex::source_language::sycl;
122+
std::string dump_dir = argv[2];
123+
118124
sycl::queue q;
119125
sycl::context ctx = q.get_context();
120126

121-
bool ok =
122-
q.get_device().ext_oneapi_can_compile(syclex::source_language::sycl);
127+
bool ok = q.get_device().ext_oneapi_can_compile(lang);
123128
if (!ok) {
124129
std::cout << "compiling from SYCL source not supported" << std::endl;
125130
return 0; // if kernel compilation is not supported, do nothing.
126131
}
127132

128-
source_kb kbSrc = syclex::create_kernel_bundle_from_source(
129-
ctx, syclex::source_language::sycl, SYCLSource);
133+
source_kb kbSrc =
134+
syclex::create_kernel_bundle_from_source(ctx, lang, SYCLSource);
130135

131136
// Flags with and without space, inner quotes.
132137
std::vector<std::string> flags{"-Xs '-doubleGRF'",

0 commit comments

Comments
 (0)