Skip to content

Commit f3563e9

Browse files
cperkinsintelKornevNikita
authored andcommitted
[SYCL] kernel_compiler remove GCC < 8 workarounds. (#16550)
We can use experimental filesystem when compiling SYCL with GCC 7, which means we can remove the #ifdef hacks from the kernel_compiler.
1 parent 48f478e commit f3563e9

File tree

2 files changed

+55
-98
lines changed

2 files changed

+55
-98
lines changed

sycl/source/detail/kernel_compiler/kernel_compiler_sycl.cpp

+49-89
Original file line numberDiff line numberDiff line change
@@ -9,59 +9,26 @@
99
#include "kernel_compiler_sycl.hpp"
1010
#include <sycl/exception.hpp> // make_error_code
1111

12-
#if __GNUC__ && __GNUC__ < 8
13-
14-
// std::filesystem is not availalbe for GCC < 8
15-
// and much of the cross-platform file handling code depends upon it.
16-
// Given that this extension is experimental and that the file
17-
// handling aspects are most likely temporary, it makes sense to
18-
// simply not support GCC<8.
19-
20-
namespace sycl {
21-
inline namespace _V1 {
22-
namespace ext::oneapi::experimental {
23-
namespace detail {
24-
25-
bool SYCL_Compilation_Available() { return false; }
26-
27-
spirv_vec_t
28-
SYCL_to_SPIRV(const std::string &SYCLSource, include_pairs_t IncludePairs,
29-
const std::vector<std::string> &UserArgs, std::string *LogPtr,
30-
const std::vector<std::string> &RegisteredKernelNames) {
31-
(void)SYCLSource;
32-
(void)IncludePairs;
33-
(void)UserArgs;
34-
(void)LogPtr;
35-
(void)RegisteredKernelNames;
36-
throw sycl::exception(sycl::errc::build,
37-
"kernel_compiler does not support GCC<8");
38-
}
39-
40-
std::string userArgsAsString(const std::vector<std::string> &UserArguments) {
41-
return std::accumulate(UserArguments.begin(), UserArguments.end(),
42-
std::string(""),
43-
[](const std::string &A, const std::string &B) {
44-
return A.empty() ? B : A + " " + B;
45-
});
46-
}
47-
48-
} // namespace detail
49-
} // namespace ext::oneapi::experimental
50-
} // namespace _V1
51-
} // namespace sycl
52-
53-
#else
54-
5512
#include <sycl/detail/os_util.hpp>
5613

5714
#include <ctime>
58-
#include <filesystem>
5915
#include <fstream>
6016
#include <random>
6117
#include <regex>
6218
#include <sstream>
6319
#include <stdio.h>
6420

21+
// For GCC versions less than 8, use experimental/filesystem.
22+
#if defined(__has_include) && __has_include(<filesystem>)
23+
#include <filesystem>
24+
namespace fs = std::filesystem;
25+
#elif defined(__has_include) && __has_include(<experimental/filesystem>)
26+
#include <experimental/filesystem>
27+
namespace fs = std::experimental::filesystem;
28+
#else
29+
#error "kernel_compiler sycl requires C++ filesystem support"
30+
#endif
31+
6532
namespace sycl {
6633
inline namespace _V1 {
6734
namespace ext::oneapi::experimental {
@@ -80,14 +47,12 @@ std::string generateSemiUniqueId() {
8047

8148
// Combine time and random number into a string.
8249
std::stringstream Ss;
83-
Ss << Milliseconds.count() << "_" << std::setfill('0') << std::setw(5)
84-
<< RandomNumber;
50+
Ss << Milliseconds.count() << "_" << RandomNumber;
8551

8652
return Ss.str();
8753
}
8854

89-
std::filesystem::path prepareWS(const std::string &Id) {
90-
namespace fs = std::filesystem;
55+
fs::path prepareWS(const std::string &Id) {
9156
const fs::path TmpDirectoryPath = fs::temp_directory_path();
9257
fs::path NewDirectoryPath = TmpDirectoryPath / Id;
9358

@@ -104,10 +69,10 @@ std::filesystem::path prepareWS(const std::string &Id) {
10469
return NewDirectoryPath;
10570
}
10671

107-
void deleteWS(const std::filesystem::path &ParentDir) {
72+
void deleteWS(const fs::path &ParentDir) {
10873
try {
109-
std::filesystem::remove_all(ParentDir);
110-
} catch (const std::filesystem::filesystem_error &E) {
74+
fs::remove_all(ParentDir);
75+
} catch (const fs::filesystem_error &E) {
11176
// We could simply suppress this, since deleting the directory afterwards
11277
// is not critical. But if there are problems, seems good to know.
11378
throw sycl::exception(sycl::errc::build, E.what());
@@ -122,8 +87,7 @@ std::string userArgsAsString(const std::vector<std::string> &UserArguments) {
12287
});
12388
}
12489

125-
void outputPreamble(std::ofstream &Os, const std::filesystem::path &FilePath,
126-
const std::string &Id,
90+
void outputPreamble(std::ofstream &Os, const std::string &Id,
12791
const std::vector<std::string> &UserArgs) {
12892

12993
Os << "/*\n";
@@ -133,15 +97,15 @@ void outputPreamble(std::ofstream &Os, const std::filesystem::path &FilePath,
13397
Os << ".cpp \n */" << std::endl;
13498
}
13599

136-
std::filesystem::path
137-
outputCpp(const std::filesystem::path &ParentDir, const std::string &Id,
138-
std::string RawCodeString, const std::vector<std::string> &UserArgs,
139-
const std::vector<std::string> &RegisteredKernelNames) {
140-
std::filesystem::path FilePath = ParentDir / (Id + ".cpp");
100+
fs::path outputCpp(const fs::path &ParentDir, const std::string &Id,
101+
std::string RawCodeString,
102+
const std::vector<std::string> &UserArgs,
103+
const std::vector<std::string> &RegisteredKernelNames) {
104+
fs::path FilePath = ParentDir / (Id + ".cpp");
141105
std::ofstream Outfile(FilePath, std::ios::out | std::ios::trunc);
142106

143107
if (Outfile.is_open()) {
144-
outputPreamble(Outfile, FilePath, Id, UserArgs);
108+
outputPreamble(Outfile, Id, UserArgs);
145109
Outfile << RawCodeString << std::endl;
146110

147111
// Temporarily needed until -c works with -fsycl-dump-spirv.
@@ -161,12 +125,11 @@ outputCpp(const std::filesystem::path &ParentDir, const std::string &Id,
161125
return FilePath;
162126
}
163127

164-
void outputIncludeFiles(const std::filesystem::path &Dirpath,
165-
include_pairs_t IncludePairs) {
128+
void outputIncludeFiles(const fs::path &Dirpath, include_pairs_t IncludePairs) {
166129
using pairStrings = std::pair<std::string, std::string>;
167130
for (pairStrings p : IncludePairs) {
168-
std::filesystem::path FilePath = Dirpath / p.first;
169-
std::filesystem::create_directories(FilePath.parent_path());
131+
fs::path FilePath = Dirpath / p.first;
132+
fs::create_directories(FilePath.parent_path());
170133
std::ofstream outfile(FilePath, std::ios::out | std::ios::trunc);
171134
if (outfile.is_open()) {
172135
outfile << p.second << std::endl;
@@ -191,11 +154,10 @@ std::string getCompilerName() {
191154

192155
// We are assuming that the compiler is in /bin and the shared lib in
193156
// the adjacent /lib.
194-
std::filesystem::path getCompilerPath() {
157+
fs::path getCompilerPath() {
195158
std::string Compiler = getCompilerName();
196159
const std::string LibSYCLDir = sycl::detail::OSUtil::getCurrentDSODir();
197-
std::filesystem::path CompilerPath =
198-
std::filesystem::path(LibSYCLDir) / ".." / "bin" / Compiler;
160+
fs::path CompilerPath = fs::path(LibSYCLDir) / ".." / "bin" / Compiler;
199161
return CompilerPath;
200162
}
201163

@@ -225,16 +187,15 @@ int invokeCommand(const std::string &command, std::string &output) {
225187
return 0;
226188
}
227189

228-
std::string invokeCompiler(const std::filesystem::path &FPath,
229-
const std::filesystem::path &DPath,
190+
std::string invokeCompiler(const fs::path &FPath, const fs::path &DPath,
230191
const std::string &Id,
231192
const std::vector<std::string> &UserArgs,
232193
std::string *LogPtr) {
233194

234-
std::filesystem::path FilePath(FPath);
235-
std::filesystem::path ParentDir(DPath);
236-
std::filesystem::path TargetPath = ParentDir / (Id + ".bin");
237-
std::filesystem::path LogPath = ParentDir / "compilation_log.txt";
195+
fs::path FilePath(FPath);
196+
fs::path ParentDir(DPath);
197+
fs::path TargetPath = ParentDir / (Id + ".bin");
198+
fs::path LogPath = ParentDir / "compilation_log.txt";
238199
std::string Compiler = getCompilerPath().make_preferred().string();
239200

240201
std::string Command =
@@ -262,13 +223,13 @@ std::string invokeCompiler(const std::filesystem::path &FPath,
262223
return CompileLog;
263224
}
264225

265-
std::filesystem::path findSpv(const std::filesystem::path &ParentDir,
266-
const std::string &Id, std::string &CompileLog) {
226+
fs::path findSpv(const fs::path &ParentDir, const std::string &Id,
227+
std::string &CompileLog) {
267228
std::regex PatternRegex(Id + R"(.*\.spv)");
268229

269230
// Iterate through all files in the directory matching the pattern.
270-
for (const auto &Entry : std::filesystem::directory_iterator(ParentDir)) {
271-
if (Entry.is_regular_file() &&
231+
for (const auto &Entry : fs::directory_iterator(ParentDir)) {
232+
if (fs::is_regular_file(Entry.path()) &&
272233
std::regex_match(Entry.path().filename().string(), PatternRegex)) {
273234
return Entry.path(); // Return the path if it matches the SPV pattern.
274235
}
@@ -278,7 +239,7 @@ std::filesystem::path findSpv(const std::filesystem::path &ParentDir,
278239
throw sycl::exception(sycl::errc::build, "Compile failure: " + CompileLog);
279240
}
280241

281-
spirv_vec_t loadSpvFromFile(const std::filesystem::path &FileName) {
242+
spirv_vec_t loadSpvFromFile(const fs::path &FileName) {
282243
std::ifstream SpvStream(FileName, std::ios::binary);
283244
SpvStream.seekg(0, std::ios::end);
284245
size_t Size = SpvStream.tellg();
@@ -294,23 +255,23 @@ SYCL_to_SPIRV(const std::string &SYCLSource, include_pairs_t IncludePairs,
294255
const std::vector<std::string> &UserArgs, std::string *LogPtr,
295256
const std::vector<std::string> &RegisteredKernelNames) {
296257
// clang-format off
297-
const std::string id = generateSemiUniqueId();
298-
const std::filesystem::path ParentDir = prepareWS(id);
299-
std::filesystem::path FilePath = outputCpp(ParentDir, id, SYCLSource, UserArgs, RegisteredKernelNames);
300-
outputIncludeFiles(ParentDir, IncludePairs);
301-
std::string CompileLog = invokeCompiler(FilePath, ParentDir, id, UserArgs, LogPtr);
302-
std::filesystem::path SpvPath = findSpv(ParentDir, id, CompileLog);
303-
spirv_vec_t Spv = loadSpvFromFile(SpvPath);
304-
deleteWS(ParentDir);
305-
return Spv;
258+
const std::string id = generateSemiUniqueId();
259+
const fs::path ParentDir = prepareWS(id);
260+
fs::path FilePath = outputCpp(ParentDir, id, SYCLSource, UserArgs, RegisteredKernelNames);
261+
outputIncludeFiles(ParentDir, IncludePairs);
262+
std::string CompileLog = invokeCompiler(FilePath, ParentDir, id, UserArgs, LogPtr);
263+
fs::path SpvPath = findSpv(ParentDir, id, CompileLog);
264+
spirv_vec_t Spv = loadSpvFromFile(SpvPath);
265+
deleteWS(ParentDir);
266+
return Spv;
306267
// clang-format on
307268
}
308269

309270
bool SYCL_Compilation_Available() {
310271
// Is compiler on $PATH ? We try to invoke it.
311272
std::string id = generateSemiUniqueId();
312-
const std::filesystem::path tmp = std::filesystem::temp_directory_path();
313-
std::filesystem::path DumpPath = tmp / (id + "_version.txt");
273+
const fs::path tmp = fs::temp_directory_path();
274+
fs::path DumpPath = tmp / (id + "_version.txt");
314275
std::string Compiler = getCompilerPath().make_preferred().string();
315276
std::string TestCommand =
316277
Compiler + " --version > " + DumpPath.make_preferred().string();
@@ -323,7 +284,6 @@ bool SYCL_Compilation_Available() {
323284
} // namespace ext::oneapi::experimental
324285
} // namespace _V1
325286
} // namespace sycl
326-
#endif
327287

328288
#if SYCL_EXT_JIT_ENABLE
329289
#include "../jit_compiler.hpp"

sycl/test-e2e/KernelCompiler/kernel_compiler_sycl.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,25 @@
1212
// -- Test the kernel_compiler with SYCL source.
1313
// RUN: %{build} -o %t.out
1414

15-
// If clang++ is not on the PATH, or if sycl was compiled with GCC < 8, then
16-
// the kernel_compiler is not available for SYCL language.
1715
// Note: this 'invoking clang++' version for SYCL language support is temporary,
1816
// and will be replaced by the SYCL_JIT version soon.
19-
// DEFINE: %{available} = %t.out available
2017

21-
// RUN: %if available %{ %{run} %t.out %}
22-
// RUN: %if available %{ %{l0_leak_check} %{run} %t.out %}
18+
// RUN: %{run} %t.out
19+
// RUN: %{l0_leak_check} %{run} %t.out
2320

2421
// -- Test again, with caching.
2522
// 'reading-from-cache' is just a string we pass to differentiate between the
2623
// two runs.
2724

2825
// DEFINE: %{cache_vars} = %{l0_leak_check} env SYCL_CACHE_PERSISTENT=1 SYCL_CACHE_TRACE=5 SYCL_CACHE_DIR=%t/cache_dir
2926
// RUN: rm -rf %t/cache_dir
30-
// RUN: %if available %{ %{cache_vars} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE %}
31-
// RUN: %if available %{ %{cache_vars} %t.out reading-from-cache 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE %}
27+
// RUN: %{cache_vars} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE
28+
// RUN: %{cache_vars} %t.out reading-from-cache 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE
3229

3330
// -- Add leak check.
3431
// RUN: rm -rf %t/cache_dir
35-
// RUN: %if available %{ %{l0_leak_check} %{cache_vars} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE %}
36-
// RUN: %if available %{ %{l0_leak_check} %{cache_vars} %t.out reading-from-cache 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE %}
32+
// RUN: %{l0_leak_check} %{cache_vars} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-WRITTEN-TO-CACHE
33+
// RUN: %{l0_leak_check} %{cache_vars} %t.out reading-from-cache 2>&1 | FileCheck %s --check-prefixes=CHECK-READ-FROM-CACHE
3734

3835
// CHECK-WRITTEN-TO-CACHE: [Persistent Cache]: enabled
3936
// CHECK-WRITTEN-TO-CACHE-NOT: [kernel_compiler Persistent Cache]: using cached binary

0 commit comments

Comments
 (0)