9
9
#include " kernel_compiler_sycl.hpp"
10
10
#include < sycl/exception.hpp> // make_error_code
11
11
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
-
55
12
#include < sycl/detail/os_util.hpp>
56
13
57
14
#include < ctime>
58
- #include < filesystem>
59
15
#include < fstream>
60
16
#include < random>
61
17
#include < regex>
62
18
#include < sstream>
63
19
#include < stdio.h>
64
20
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
+
65
32
namespace sycl {
66
33
inline namespace _V1 {
67
34
namespace ext ::oneapi::experimental {
@@ -80,14 +47,12 @@ std::string generateSemiUniqueId() {
80
47
81
48
// Combine time and random number into a string.
82
49
std::stringstream Ss;
83
- Ss << Milliseconds.count () << " _" << std::setfill (' 0' ) << std::setw (5 )
84
- << RandomNumber;
50
+ Ss << Milliseconds.count () << " _" << RandomNumber;
85
51
86
52
return Ss.str ();
87
53
}
88
54
89
- std::filesystem::path prepareWS (const std::string &Id) {
90
- namespace fs = std::filesystem;
55
+ fs::path prepareWS (const std::string &Id) {
91
56
const fs::path TmpDirectoryPath = fs::temp_directory_path ();
92
57
fs::path NewDirectoryPath = TmpDirectoryPath / Id;
93
58
@@ -104,10 +69,10 @@ std::filesystem::path prepareWS(const std::string &Id) {
104
69
return NewDirectoryPath;
105
70
}
106
71
107
- void deleteWS (const std::filesystem ::path &ParentDir) {
72
+ void deleteWS (const fs ::path &ParentDir) {
108
73
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) {
111
76
// We could simply suppress this, since deleting the directory afterwards
112
77
// is not critical. But if there are problems, seems good to know.
113
78
throw sycl::exception (sycl::errc::build, E.what ());
@@ -122,8 +87,7 @@ std::string userArgsAsString(const std::vector<std::string> &UserArguments) {
122
87
});
123
88
}
124
89
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,
127
91
const std::vector<std::string> &UserArgs) {
128
92
129
93
Os << " /*\n " ;
@@ -133,15 +97,15 @@ void outputPreamble(std::ofstream &Os, const std::filesystem::path &FilePath,
133
97
Os << " .cpp \n */" << std::endl;
134
98
}
135
99
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" );
141
105
std::ofstream Outfile (FilePath, std::ios::out | std::ios::trunc );
142
106
143
107
if (Outfile.is_open ()) {
144
- outputPreamble (Outfile, FilePath, Id, UserArgs);
108
+ outputPreamble (Outfile, Id, UserArgs);
145
109
Outfile << RawCodeString << std::endl;
146
110
147
111
// Temporarily needed until -c works with -fsycl-dump-spirv.
@@ -161,12 +125,11 @@ outputCpp(const std::filesystem::path &ParentDir, const std::string &Id,
161
125
return FilePath;
162
126
}
163
127
164
- void outputIncludeFiles (const std::filesystem::path &Dirpath,
165
- include_pairs_t IncludePairs) {
128
+ void outputIncludeFiles (const fs::path &Dirpath, include_pairs_t IncludePairs) {
166
129
using pairStrings = std::pair<std::string, std::string>;
167
130
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 ());
170
133
std::ofstream outfile (FilePath, std::ios::out | std::ios::trunc );
171
134
if (outfile.is_open ()) {
172
135
outfile << p.second << std::endl;
@@ -191,11 +154,10 @@ std::string getCompilerName() {
191
154
192
155
// We are assuming that the compiler is in /bin and the shared lib in
193
156
// the adjacent /lib.
194
- std::filesystem ::path getCompilerPath () {
157
+ fs ::path getCompilerPath () {
195
158
std::string Compiler = getCompilerName ();
196
159
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;
199
161
return CompilerPath;
200
162
}
201
163
@@ -225,16 +187,15 @@ int invokeCommand(const std::string &command, std::string &output) {
225
187
return 0 ;
226
188
}
227
189
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,
230
191
const std::string &Id,
231
192
const std::vector<std::string> &UserArgs,
232
193
std::string *LogPtr) {
233
194
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" ;
238
199
std::string Compiler = getCompilerPath ().make_preferred ().string ();
239
200
240
201
std::string Command =
@@ -262,13 +223,13 @@ std::string invokeCompiler(const std::filesystem::path &FPath,
262
223
return CompileLog;
263
224
}
264
225
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) {
267
228
std::regex PatternRegex (Id + R"( .*\.spv)" );
268
229
269
230
// 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 () ) &&
272
233
std::regex_match (Entry.path ().filename ().string (), PatternRegex)) {
273
234
return Entry.path (); // Return the path if it matches the SPV pattern.
274
235
}
@@ -278,7 +239,7 @@ std::filesystem::path findSpv(const std::filesystem::path &ParentDir,
278
239
throw sycl::exception (sycl::errc::build, " Compile failure: " + CompileLog);
279
240
}
280
241
281
- spirv_vec_t loadSpvFromFile (const std::filesystem ::path &FileName) {
242
+ spirv_vec_t loadSpvFromFile (const fs ::path &FileName) {
282
243
std::ifstream SpvStream (FileName, std::ios::binary);
283
244
SpvStream.seekg (0 , std::ios::end);
284
245
size_t Size = SpvStream.tellg ();
@@ -294,23 +255,23 @@ SYCL_to_SPIRV(const std::string &SYCLSource, include_pairs_t IncludePairs,
294
255
const std::vector<std::string> &UserArgs, std::string *LogPtr,
295
256
const std::vector<std::string> &RegisteredKernelNames) {
296
257
// 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;
306
267
// clang-format on
307
268
}
308
269
309
270
bool SYCL_Compilation_Available () {
310
271
// Is compiler on $PATH ? We try to invoke it.
311
272
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" );
314
275
std::string Compiler = getCompilerPath ().make_preferred ().string ();
315
276
std::string TestCommand =
316
277
Compiler + " --version > " + DumpPath.make_preferred ().string ();
@@ -323,7 +284,6 @@ bool SYCL_Compilation_Available() {
323
284
} // namespace ext::oneapi::experimental
324
285
} // namespace _V1
325
286
} // namespace sycl
326
- #endif
327
287
328
288
#if SYCL_EXT_JIT_ENABLE
329
289
#include " ../jit_compiler.hpp"
0 commit comments