Skip to content

Commit 830b562

Browse files
Merge branch 'sycl' into fixdevicekernelinfo
2 parents ad32e03 + b6af1f5 commit 830b562

File tree

10 files changed

+124
-153
lines changed

10 files changed

+124
-153
lines changed

devops/dependencies-igc-dev.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"linux": {
33
"igc_dev": {
4-
"github_tag": "igc-dev-788001e",
5-
"version": "788001e",
6-
"updated_at": "2025-09-03T22:42:39Z",
7-
"url": "https://api.github.com/repos/intel/intel-graphics-compiler/actions/artifacts/3921755581/zip",
4+
"github_tag": "igc-dev-558c584",
5+
"version": "558c584",
6+
"updated_at": "2025-09-05T22:44:40Z",
7+
"url": "https://api.github.com/repos/intel/intel-graphics-compiler/actions/artifacts/3941562792/zip",
88
"root": "{DEPS_ROOT}/opencl/runtime/linux/oclgpu"
99
}
1010
}

sycl-jit/jit-compiler/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ else()
99
set(SYCL_JIT_VIRTUAL_TOOLCHAIN_ROOT "/sycl-jit-toolchain/")
1010
endif()
1111

12-
# TODO: libdevice
13-
set(SYCL_JIT_RESOURCE_DEPS sycl-headers clang ${CMAKE_CURRENT_SOURCE_DIR}/utils/generate.py)
12+
set(SYCL_JIT_RESOURCE_DEPS
13+
sycl-headers # include/sycl
14+
clang # lib/clang/N/include
15+
${CMAKE_CURRENT_SOURCE_DIR}/utils/generate.py)
1416

1517
if ("libclc" IN_LIST LLVM_ENABLE_PROJECTS)
1618
# Somehow just "libclc" doesn't build "remangled-*" (and maybe whatever else).
17-
list(APPEND SYCL_JIT_RESOURCE_DEPS libclc libspirv-builtins)
19+
list(APPEND SYCL_JIT_RESOURCE_DEPS libclc libspirv-builtins) # lib/clc/*.bc
20+
endif()
21+
22+
if ("libdevice" IN_LIST LLVM_ENABLE_PROJECTS)
23+
list(APPEND SYCL_JIT_RESOURCE_DEPS libsycldevice) # lib/*.bc
1824
endif()
1925

2026
add_custom_command(

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

Lines changed: 38 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -64,86 +64,6 @@ using namespace llvm::util;
6464
using namespace llvm::vfs;
6565
using namespace jit_compiler;
6666

67-
#ifdef _GNU_SOURCE
68-
#include <dlfcn.h>
69-
static char X; // Dummy symbol, used as an anchor for `dlinfo` below.
70-
#endif
71-
72-
#ifdef _WIN32
73-
#include <filesystem> // For std::filesystem::path ( C++17 only )
74-
#include <shlwapi.h> // For PathRemoveFileSpec
75-
#include <windows.h> // For GetModuleFileName, HMODULE, DWORD, MAX_PATH
76-
77-
// cribbed from sycl/source/detail/os_util.cpp
78-
using OSModuleHandle = intptr_t;
79-
static constexpr OSModuleHandle ExeModuleHandle = -1;
80-
static OSModuleHandle getOSModuleHandle(const void *VirtAddr) {
81-
HMODULE PhModule;
82-
DWORD Flag = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
83-
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
84-
auto LpModuleAddr = reinterpret_cast<LPCSTR>(VirtAddr);
85-
if (!GetModuleHandleExA(Flag, LpModuleAddr, &PhModule)) {
86-
// Expect the caller to check for zero and take
87-
// necessary action
88-
return 0;
89-
}
90-
if (PhModule == GetModuleHandleA(nullptr))
91-
return ExeModuleHandle;
92-
return reinterpret_cast<OSModuleHandle>(PhModule);
93-
}
94-
95-
// cribbed from sycl/source/detail/os_util.cpp
96-
/// Returns an absolute path where the object was found.
97-
std::wstring getCurrentDSODir() {
98-
wchar_t Path[MAX_PATH];
99-
auto Handle = getOSModuleHandle(reinterpret_cast<void *>(&getCurrentDSODir));
100-
DWORD Ret = GetModuleFileName(
101-
reinterpret_cast<HMODULE>(ExeModuleHandle == Handle ? 0 : Handle), Path,
102-
MAX_PATH);
103-
assert(Ret < MAX_PATH && "Path is longer than MAX_PATH?");
104-
assert(Ret > 0 && "GetModuleFileName failed");
105-
(void)Ret;
106-
107-
BOOL RetCode = PathRemoveFileSpec(Path);
108-
assert(RetCode && "PathRemoveFileSpec failed");
109-
(void)RetCode;
110-
111-
return Path;
112-
}
113-
#endif // _WIN32
114-
115-
static constexpr auto InvalidDPCPPRoot = "<invalid>";
116-
117-
static const std::string &getDPCPPRoot() {
118-
thread_local std::string DPCPPRoot;
119-
120-
if (!DPCPPRoot.empty()) {
121-
return DPCPPRoot;
122-
}
123-
DPCPPRoot = InvalidDPCPPRoot;
124-
125-
#ifdef _GNU_SOURCE
126-
static constexpr auto JITLibraryPathSuffix = "/lib/libsycl-jit.so";
127-
Dl_info Info;
128-
if (dladdr(&X, &Info)) {
129-
std::string LoadedLibraryPath = Info.dli_fname;
130-
auto Pos = LoadedLibraryPath.rfind(JITLibraryPathSuffix);
131-
if (Pos != std::string::npos) {
132-
DPCPPRoot = LoadedLibraryPath.substr(0, Pos);
133-
}
134-
}
135-
#endif // _GNU_SOURCE
136-
137-
#ifdef _WIN32
138-
DPCPPRoot = std::filesystem::path(getCurrentDSODir()).parent_path().string();
139-
#endif // _WIN32
140-
141-
// TODO: Implemenent other means of determining the DPCPP root, e.g.
142-
// evaluating the `CMPLR_ROOT` env.
143-
144-
return DPCPPRoot;
145-
}
146-
14767
namespace {
14868

14969
class HashPreprocessedAction : public PreprocessorFrontendAction {
@@ -252,6 +172,30 @@ class SYCLToolchain {
252172
return TI.run();
253173
}
254174

175+
Expected<ModuleUPtr> loadBitcodeLibrary(StringRef LibPath,
176+
LLVMContext &Context) {
177+
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(
178+
llvm::vfs::getRealFileSystem());
179+
FS->pushOverlay(ToolchainFS);
180+
181+
auto MemBuf = FS->getBufferForFile(LibPath, /*FileSize*/ -1,
182+
/*RequiresNullTerminator*/ false);
183+
if (!MemBuf) {
184+
return createStringError("Error opening file %s: %s", LibPath.data(),
185+
MemBuf.getError().message().c_str());
186+
}
187+
188+
SMDiagnostic Diag;
189+
ModuleUPtr Lib = parseIR(*MemBuf->get(), Diag, Context);
190+
if (!Lib) {
191+
std::string DiagMsg;
192+
raw_string_ostream SOS(DiagMsg);
193+
Diag.print(/*ProgName=*/nullptr, SOS);
194+
return createStringError(DiagMsg);
195+
}
196+
return std::move(Lib);
197+
}
198+
255199
std::string_view getClangXXExe() const { return ClangXXExe; }
256200

257201
private:
@@ -516,30 +460,12 @@ static bool getDeviceLibraries(const ArgList &Args,
516460
return FoundUnknownLib;
517461
}
518462

519-
static Expected<ModuleUPtr> loadBitcodeLibrary(StringRef LibPath,
520-
LLVMContext &Context) {
521-
SMDiagnostic Diag;
522-
ModuleUPtr Lib = parseIRFile(LibPath, Diag, Context);
523-
if (!Lib) {
524-
std::string DiagMsg;
525-
raw_string_ostream SOS(DiagMsg);
526-
Diag.print(/*ProgName=*/nullptr, SOS);
527-
return createStringError(DiagMsg);
528-
}
529-
return std::move(Lib);
530-
}
531-
532463
Error jit_compiler::linkDeviceLibraries(llvm::Module &Module,
533464
const InputArgList &UserArgList,
534465
std::string &BuildLog,
535466
BinaryFormat Format) {
536467
TimeTraceScope TTS{"linkDeviceLibraries"};
537468

538-
const std::string &DPCPPRoot = getDPCPPRoot();
539-
if (DPCPPRoot == InvalidDPCPPRoot) {
540-
return createStringError("Could not locate DPCPP root directory");
541-
}
542-
543469
IntrusiveRefCntPtr<DiagnosticIDs> DiagID{new DiagnosticIDs};
544470
DiagnosticOptions DiagOpts;
545471
ClangDiagnosticWrapper Wrapper(BuildLog, &DiagOpts);
@@ -573,10 +499,13 @@ Error jit_compiler::linkDeviceLibraries(llvm::Module &Module,
573499

574500
LLVMContext &Context = Module.getContext();
575501
for (const std::string &LibName : LibNames) {
576-
std::string LibPath = DPCPPRoot + "/lib/" + LibName;
502+
std::string LibPath =
503+
(jit_compiler::ToolchainPrefix + "/lib/" + LibName).str();
577504

578505
ModuleUPtr LibModule;
579-
if (auto Error = loadBitcodeLibrary(LibPath, Context).moveInto(LibModule)) {
506+
if (auto Error = SYCLToolchain::instance()
507+
.loadBitcodeLibrary(LibPath, Context)
508+
.moveInto(LibModule)) {
580509
return Error;
581510
}
582511

@@ -590,14 +519,16 @@ Error jit_compiler::linkDeviceLibraries(llvm::Module &Module,
590519
// For GPU targets we need to link against vendor provided libdevice.
591520
if (IsCudaHIP) {
592521
Triple T{Module.getTargetTriple()};
593-
Driver D{(Twine(DPCPPRoot) + "/bin/clang++").str(), T.getTriple(), Diags};
522+
Driver D{(jit_compiler::ToolchainPrefix + "/bin/clang++").str(),
523+
T.getTriple(), Diags};
594524
auto [CPU, Features] =
595525
Translator::getTargetCPUAndFeatureAttrs(&Module, "", Format);
596526
(void)Features;
597527
// Helper lambda to link modules.
598528
auto LinkInLib = [&](const StringRef LibDevice) -> Error {
599529
ModuleUPtr LibDeviceModule;
600-
if (auto Error = loadBitcodeLibrary(LibDevice, Context)
530+
if (auto Error = SYCLToolchain::instance()
531+
.loadBitcodeLibrary(LibDevice, Context)
601532
.moveInto(LibDeviceModule)) {
602533
return Error;
603534
}
@@ -831,16 +762,14 @@ jit_compiler::performPostLink(ModuleUPtr Module,
831762
}
832763

833764
if (IsBF16DeviceLibUsed) {
834-
const std::string &DPCPPRoot = getDPCPPRoot();
835-
if (DPCPPRoot == InvalidDPCPPRoot) {
836-
return createStringError("Could not locate DPCPP root directory");
837-
}
838-
839765
auto &Ctx = Modules.front()->getContext();
840766
auto WrapLibraryInDevImg = [&](const std::string &LibName) -> Error {
841-
std::string LibPath = DPCPPRoot + "/lib/" + LibName;
767+
std::string LibPath =
768+
(jit_compiler::ToolchainPrefix + "/lib/" + LibName).str();
842769
ModuleUPtr LibModule;
843-
if (auto Error = loadBitcodeLibrary(LibPath, Ctx).moveInto(LibModule)) {
770+
if (auto Error = SYCLToolchain::instance()
771+
.loadBitcodeLibrary(LibPath, Ctx)
772+
.moveInto(LibModule)) {
844773
return Error;
845774
}
846775

sycl-jit/jit-compiler/utils/generate.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import argparse
3+
import glob
34

45

56
def main():
@@ -31,12 +32,9 @@ def main():
3132
const std::pair<std::string_view, std::string_view> ToolchainFiles[] = {"""
3233
)
3334

34-
def process_dir(dir):
35-
for root, _, files in os.walk(dir):
36-
for file in files:
37-
file_path = os.path.join(root, file)
38-
out.write(
39-
f"""
35+
def process_file(file_path):
36+
out.write(
37+
f"""
4038
{{
4139
{{"{args.prefix}{os.path.relpath(file_path, toolchain_dir).replace(os.sep, "/")}"}} ,
4240
[]() {{
@@ -46,12 +44,24 @@ def process_dir(dir):
4644
return std::string_view(data, std::size(data) - 1);
4745
}}()
4846
}},"""
49-
)
47+
)
48+
49+
def process_dir(dir):
50+
for root, _, files in os.walk(dir):
51+
for file in files:
52+
file_path = os.path.join(root, file)
53+
process_file(file_path)
5054

5155
process_dir(os.path.join(args.toolchain_dir, "include/"))
5256
process_dir(os.path.join(args.toolchain_dir, "lib/clang/"))
5357
process_dir(os.path.join(args.toolchain_dir, "lib/clc/"))
5458

59+
for file in glob.iglob(
60+
"*.bc", root_dir=os.path.join(args.toolchain_dir, "lib")
61+
):
62+
file_path = os.path.join(args.toolchain_dir, "lib", file)
63+
process_file(file_path)
64+
5565
out.write(
5666
f"""
5767
}};

sycl/include/sycl/handler.hpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -825,16 +825,24 @@ class __SYCL_EXPORT handler {
825825
#endif
826826
constexpr auto Info = detail::CompileTimeKernelInfo<KernelName>;
827827

828-
constexpr bool KernelHasName = (Info.Name != std::string_view{});
828+
// SYCL unittests are built without sycl compiler, so "host" information
829+
// about kernels isn't provided (e.g., via integration headers or compiler
830+
// builtins).
831+
//
832+
// However, some copy/fill USM operation are implemented via SYCL kernels
833+
// and are instantiated resulting in all the `static_assert` checks being
834+
// exercised. Without kernel information that would fail, so we explicitly
835+
// disable such checks when this macro is defined. Note that the unittests
836+
// don't actually execute those operation, that's why disabling
837+
// unconditional `static_asserts`s is enough for now.
838+
#ifndef __SYCL_UNITTESTS_BYPASS_KERNEL_NAME_CHECK
839+
static_assert(Info.Name != std::string_view{}, "Kernel must have a name!");
829840

830841
// Some host compilers may have different captures from Clang. Currently
831842
// there is no stable way of handling this when extracting the captures,
832843
// so a static assert is made to fail for incompatible kernel lambdas.
833-
834-
// TODO remove the ifdef once the kernel size builtin is supported.
835-
#ifdef __INTEL_SYCL_USE_INTEGRATION_HEADERS
836844
static_assert(
837-
!KernelHasName || sizeof(KernelType) == Info.KernelSize,
845+
sizeof(KernelType) == Info.KernelSize,
838846
"Unexpected kernel lambda size. This can be caused by an "
839847
"external host compiler producing a lambda with an "
840848
"unexpected layout. This is a limitation of the compiler."
@@ -846,25 +854,13 @@ class __SYCL_EXPORT handler {
846854
"-fsycl-host-compiler-options='/std:c++latest' "
847855
"might also help.");
848856
#endif
849-
// Empty name indicates that the compilation happens without integration
850-
// header, so don't perform things that require it.
851-
if constexpr (KernelHasName) {
852-
// TODO support ESIMD in no-integration-header case too.
853-
854-
// Force hasSpecialCaptures to be evaluated at compile-time.
855-
setKernelInfo((void *)MHostKernel->getPtr(), Info.NumParams,
856-
Info.ParamDescGetter, Info.IsESIMD,
857-
Info.HasSpecialCaptures);
858-
859-
MKernelName = Info.Name;
860-
setDeviceKernelInfoPtr(&detail::getDeviceKernelInfo<KernelName>());
861-
} else {
862-
// In case w/o the integration header it is necessary to process
863-
// accessors from the list(which are associated with this handler) as
864-
// arguments. We must copy the associated accessors as they are checked
865-
// later during finalize.
866-
setArgsToAssociatedAccessors();
867-
}
857+
858+
// Force hasSpecialCaptures to be evaluated at compile-time.
859+
setKernelInfo((void *)MHostKernel->getPtr(), Info.NumParams,
860+
Info.ParamDescGetter, Info.IsESIMD, Info.HasSpecialCaptures);
861+
862+
MKernelName = Info.Name;
863+
setDeviceKernelInfoPtr(&detail::getDeviceKernelInfo<KernelName>());
868864

869865
// If the kernel lambda is callable with a kernel_handler argument, manifest
870866
// the associated kernel handler.

sycl/source/detail/device_kernel_info.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ void DeviceKernelInfo::init(KernelNameStrRefT KernelName) {
3232
}
3333

3434
#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
35-
void DeviceKernelInfo::initIfNeeded(KernelNameStrRefT KernelName) {
36-
if (!MInitialized.load())
37-
init(KernelName);
35+
void DeviceKernelInfo::initIfEmpty(const CompileTimeKernelInfoTy &Info) {
36+
if (MInitialized.load())
37+
return;
38+
39+
CompileTimeKernelInfoTy::operator=(Info);
40+
Name = Info.Name.data();
41+
init(Name.data());
3842
}
3943
#endif
4044

sycl/source/detail/device_kernel_info.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ class DeviceKernelInfo : public CompileTimeKernelInfoTy {
102102

103103
void init(KernelNameStrRefT KernelName);
104104
#ifndef __INTEL_PREVIEW_BREAKING_CHANGES
105-
void initIfNeeded(KernelNameStrRefT KernelName);
105+
// Initialize default-created entry that has no data recorded:
106+
void initIfEmpty(const CompileTimeKernelInfoTy &Info);
106107
#endif
107108
void setCompileTimeInfoIfNeeded(const CompileTimeKernelInfoTy &Info);
108109

0 commit comments

Comments
 (0)