Skip to content

Commit 3c8a50b

Browse files
[SYCL RTC] Workaround data race related to the VFS containing toolchain
This regressed due to intel#19924 but, apparently, we didn't have proper tests in place. I'm not sure what's causing this exactly, but having each compilation create its unique `ToolchainFS` instead of all of them using the same `llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> SYCLToolchain::ToolchainFS` somehow results in the test (added in this PR) passing consistently.
1 parent 5c5b121 commit 3c8a50b

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ using namespace jit_compiler;
6969
namespace {
7070

7171
class SYCLToolchain {
72-
SYCLToolchain() {
72+
// TODO: For some reason, moving this to a data member of the single instance
73+
// of SYCLToolchain results in some data races leading to memory corruption
74+
// (e.g., ::free() report errors).
75+
static auto getToolchainFS() {
76+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> ToolchainFS =
77+
llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
7378
using namespace jit_compiler::resource;
7479

7580
for (size_t i = 0; i < NumToolchainFiles; ++i) {
@@ -78,8 +83,11 @@ class SYCLToolchain {
7883
std::string_view Content{RF.Content.S, RF.Content.Size};
7984
ToolchainFS->addFile(Path, 0, llvm::MemoryBuffer::getMemBuffer(Content));
8085
}
86+
return ToolchainFS;
8187
}
8288

89+
SYCLToolchain() = default;
90+
8391
struct PrecompiledPreambles {
8492
using key = std::pair<std::string /*Opts*/, std::string /*Preamble*/>;
8593
std::mutex Mutex;
@@ -260,7 +268,7 @@ class SYCLToolchain {
260268

261269
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(
262270
llvm::vfs::getRealFileSystem());
263-
FS->pushOverlay(ToolchainFS);
271+
FS->pushOverlay(getToolchainFS());
264272
if (FSOverlay)
265273
FS->pushOverlay(std::move(FSOverlay));
266274

@@ -291,7 +299,7 @@ class SYCLToolchain {
291299
LLVMContext &Context) {
292300
auto FS = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(
293301
llvm::vfs::getRealFileSystem());
294-
FS->pushOverlay(ToolchainFS);
302+
FS->pushOverlay(getToolchainFS());
295303

296304
auto MemBuf = FS->getBufferForFile(LibPath, /*FileSize*/ -1,
297305
/*RequiresNullTerminator*/ false);
@@ -319,8 +327,6 @@ class SYCLToolchain {
319327
std::string_view Prefix{jit_compiler::resource::ToolchainPrefix.S,
320328
jit_compiler::resource::ToolchainPrefix.Size};
321329
std::string ClangXXExe = (Prefix + "/bin/clang++").str();
322-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> ToolchainFS =
323-
llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
324330

325331
PrecompiledPreambles Preambles;
326332
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %{build} -o %t.out
2+
// RUN: %if hip %{ env SYCL_JIT_AMDGCN_PTX_TARGET_CPU=%{amd_arch} %} %{run} %t.out
3+
4+
// UNSUPPORTED: target-native_cpu
5+
// UNSUPPORTED-TRACKER: https://github.com/intel/llvm/issues/20142
6+
7+
// Verify that parallel compilations work.
8+
9+
#include <sycl/detail/core.hpp>
10+
#include <sycl/kernel_bundle.hpp>
11+
12+
#include <thread>
13+
14+
namespace syclexp = sycl::ext::oneapi::experimental;
15+
int main() {
16+
sycl::queue q;
17+
constexpr int N = 16;
18+
std::string src_str = R"""(
19+
#include <sycl/ext/oneapi/free_function_queries.hpp>
20+
#include <sycl/ext/oneapi/kernel_properties/properties.hpp>
21+
namespace syclext = sycl::ext::oneapi;
22+
namespace syclexp = sycl::ext::oneapi::experimental;
23+
24+
extern "C"
25+
SYCL_EXT_ONEAPI_FUNCTION_PROPERTY((syclexp::single_task_kernel))
26+
void foo(int *p) {
27+
*p = 42;
28+
}
29+
)""";
30+
31+
auto Run = [&](auto... args) {
32+
auto kb_src = syclexp::create_kernel_bundle_from_source(
33+
q.get_context(), syclexp::source_language::sycl, src_str);
34+
auto kb_exe = syclexp::build(kb_src, args...);
35+
};
36+
37+
std::thread threads[N];
38+
39+
for (auto &t : threads)
40+
t = std::thread{Run};
41+
for (auto &t : threads)
42+
t.join();
43+
44+
auto auto_pch = syclexp::properties{
45+
syclexp::build_options{std::vector<std::string>{"--auto-pch"}}};
46+
47+
for (auto &t : threads)
48+
t = std::thread{Run, auto_pch};
49+
for (auto &t : threads)
50+
t.join();
51+
}

0 commit comments

Comments
 (0)