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+
6532namespace sycl {
6633inline namespace _V1 {
6734namespace 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
309270bool 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"
0 commit comments