From: Joel Rosdahl Date: Sun, 25 May 2025 17:53:25 +0000 (+0200) Subject: chore: Tweak Clang CUDA code slightly X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=2499167eb41ccf770113af066f945f464d1187ae;p=thirdparty%2Fccache.git chore: Tweak Clang CUDA code slightly --- diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index dce33220..8c0bce3b 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -1335,9 +1335,8 @@ process_cuda_chunk(Context& ctx, const std::string& chunk, size_t index) { - // 1. Create a temp file for this CUDA chunk auto tmp_result = util::TemporaryFile::create( - FMT("{}/cuda_tmp_{}.i", ctx.config.temporary_dir(), index), + FMT("{}/cuda_tmp_{}", ctx.config.temporary_dir(), index), FMT(".{}", ctx.config.cpp_extension())); if (!tmp_result) { return tl::unexpected(Statistic::internal_error); @@ -1346,24 +1345,18 @@ process_cuda_chunk(Context& ctx, const auto& chunk_path = tmp_result->path; tmp_result->fd.close(); // we only need the path, not the open fd - // 2. Write the chunk contents into the temp file if (!util::write_file(chunk_path, chunk)) { return tl::unexpected(Statistic::internal_error); } - // 3. Register the file so it gets cleaned up later ctx.register_pending_tmp_file(chunk_path); - - // 4. Add a unique hash delimiter for this chunk hash.hash_delimiter(FMT("cu_{}", index)); - - // 5. Process the chunk just like a normal preprocessed file TRY(process_preprocessed_file(ctx, hash, chunk_path)); return {}; } static bool -get_clang_cu_enable_verbose_mode(Args& args) +get_clang_cu_enable_verbose_mode(const Args& args) { for (size_t i = 1; i < args.size(); i++) { if (args[i] == "-v") { @@ -1384,9 +1377,8 @@ get_result_key_from_cpp(Context& ctx, Args& args, Hash& hash) util::Bytes cpp_stdout_data; // When Clang runs in verbose mode, it outputs command details to stdout, - // which can corrupt the output of precompiled CUDA files. - // Therefore, caching is disabled in this scenario. - // (Is there a better approach to handle this?) + // which can corrupt the output of precompiled CUDA files. Therefore, caching + // is disabled in this scenario. (Is there a better approach to handle this?) const bool is_clang_cu = ctx.config.is_compiler_group_clang() && (ctx.args_info.actual_language == "cu" || ctx.args_info.actual_language == "cuda") @@ -1452,10 +1444,8 @@ get_result_key_from_cpp(Context& ctx, Args& args, Hash& hash) if (is_clang_cu) { util::write_file(preprocessed_path, cpp_stdout_data); - auto chunks = - util::split_preprocess_file_in_clang_cuda(preprocessed_path.string()); - + util::split_preprocessed_file_from_clang_cuda(preprocessed_path); for (size_t i = 0; i < chunks.size(); ++i) { TRY(process_cuda_chunk(ctx, hash, chunks[i], i)); } diff --git a/src/ccache/util/CMakeLists.txt b/src/ccache/util/CMakeLists.txt index e6d19195..87a0722f 100644 --- a/src/ccache/util/CMakeLists.txt +++ b/src/ccache/util/CMakeLists.txt @@ -2,6 +2,7 @@ set( sources assertions.cpp bytes.cpp + clang.cpp cpu.cpp direntry.cpp environment.cpp @@ -24,7 +25,6 @@ set( tokenizer.cpp umaskscope.cpp zstd.cpp - clang.cpp ) file(GLOB headers *.hpp) diff --git a/src/ccache/util/clang.cpp b/src/ccache/util/clang.cpp index 4e3a2869..713daeb2 100644 --- a/src/ccache/util/clang.cpp +++ b/src/ccache/util/clang.cpp @@ -18,48 +18,51 @@ #include "clang.hpp" +#include +#include #include +#include #include #include -#include -#include + +namespace fs = util::filesystem; namespace util { std::vector -split_preprocess_file_in_clang_cuda(const std::string& mixed_preprocessed_path) +split_preprocessed_file_from_clang_cuda(const fs::path& path) { - std::ifstream infile(mixed_preprocessed_path); - std::vector split_preprocess_file_list; + std::ifstream infile(path); + std::vector chunks; if (!infile) { - LOG("Can't open file {}", mixed_preprocessed_path); - return split_preprocess_file_list; + LOG("Failed to open {}: {}", path, strerror(errno)); + return chunks; } std::string delimiter; if (!std::getline(infile, delimiter)) { - return split_preprocess_file_list; + return chunks; } - std::string currentPart = delimiter + "\n"; + std::string current_part = delimiter + "\n"; std::string line; while (std::getline(infile, line)) { if (line == delimiter) { - split_preprocess_file_list.push_back(currentPart); - currentPart = delimiter + "\n"; + chunks.push_back(current_part); + current_part = delimiter + "\n"; } else { - currentPart += line + "\n"; + current_part += line + "\n"; } } - if (!currentPart.empty()) { - split_preprocess_file_list.push_back(currentPart); + if (!current_part.empty()) { + chunks.push_back(current_part); } - return split_preprocess_file_list; + return chunks; } } // namespace util diff --git a/src/ccache/util/clang.hpp b/src/ccache/util/clang.hpp index 4c7a262d..32e4861a 100644 --- a/src/ccache/util/clang.hpp +++ b/src/ccache/util/clang.hpp @@ -18,12 +18,13 @@ #pragma once +#include #include #include namespace util { std::vector -split_preprocess_file_in_clang_cuda(const std::string& mixed_preprocessed_path); +split_preprocessed_file_from_clang_cuda(const std::filesystem::path& path); } // namespace util diff --git a/test/suites/clang_cu.bash b/test/suites/clang_cu.bash index a6b35025..57dbec4e 100644 --- a/test/suites/clang_cu.bash +++ b/test/suites/clang_cu.bash @@ -1,4 +1,4 @@ -setup_clang() { +set_up_clang() { local CUDA_PATH="--cuda-path=/usr/local/cuda" if [ ! -z "$CUDA_HOME" ]; then local CUDA_PATH="--cuda-path=$CUDA_HOME" @@ -23,11 +23,11 @@ clang_cu_PROBE() { return fi - setup_clang + set_up_clang touch test.cu if ! $REAL_CLANG -c -x cu test.cu >/dev/null 2>&1; then - echo "Clang's CUDA support is not compatible." + echo "Clang's CUDA support is not compatible" fi } @@ -44,7 +44,6 @@ void caller() { } EOF - # Test code using cuda. cat <test_cuda.cu #ifndef NUM @@ -66,7 +65,7 @@ EOF } clang_cu_tests() { - setup_clang + set_up_clang clang_opts_cpp="-c -x c++" clang_opts_cuda="-c -x $CLANG_CU_LANG_TYPE" diff --git a/test/suites/clang_cu_direct.bash b/test/suites/clang_cu_direct.bash index 4f98303e..31d55d6d 100644 --- a/test/suites/clang_cu_direct.bash +++ b/test/suites/clang_cu_direct.bash @@ -9,7 +9,7 @@ SUITE_clang_cu_direct_SETUP() { } SUITE_clang_cu_direct() { - setup_clang + set_up_clang clang_opts_cpp="-c -x c++" clang_opts_cuda="-c -x $CLANG_CU_LANG_TYPE" diff --git a/unittest/test_util_clang.cpp b/unittest/test_util_clang.cpp index 522630df..afded55f 100644 --- a/unittest/test_util_clang.cpp +++ b/unittest/test_util_clang.cpp @@ -16,65 +16,30 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include "testutil.hpp" + #include +#include +#include #include -#include -#include -#include -#include // https://github.com/doctest/doctest/issues/618 #include -#include - -TEST_SUITE_BEGIN("util"); - -// RAII helper class for test file management -class TestFileGuard -{ -private: - std::string filename_; -public: - explicit TestFileGuard(const std::string& filename) : filename_(filename) - { - } - - ~TestFileGuard() - { - try { - if (std::filesystem::exists(filename_)) { - std::filesystem::remove(filename_); - } - } catch (...) { - // Ignore cleanup errors in destructor - } - } +namespace fs = util::filesystem; - void - create_file(const std::string& content) - { - std::ofstream outfile; - outfile.open(filename_); - if (outfile.is_open()) { - outfile << content; - outfile.close(); - } - } +using TestUtil::TestContext; - const std::string& - filename() const - { - return filename_; - } -}; +TEST_SUITE_BEGIN("util"); -TEST_CASE("util::split_preprocess_file_in_clang_cuda") +TEST_CASE("util::split_preprocessed_file_from_clang_cuda") { + TestContext test_context; + SUBCASE("normal") { - TestFileGuard guard("test_normal.txt"); - std::string content = R"(# 1 "test_cuda.cu" + fs::path filename = "test_normal.txt"; + util::write_file(filename, R"(# 1 "test_cuda.cu" # 1 "" 1 # 1 "" 3 void caller() { @@ -83,10 +48,9 @@ void caller() { # 1 "test_cuda.cu" # 1 "" 1 # 1 "" 3 -)"; - guard.create_file(content); +)"); - auto result = util::split_preprocess_file_in_clang_cuda(guard.filename()); + auto result = util::split_preprocessed_file_from_clang_cuda(filename); REQUIRE(result.size() == 2); CHECK(result[0] == R"(# 1 "test_cuda.cu" @@ -104,21 +68,16 @@ void caller() { SUBCASE("non-existent file") { - std::string nonexistent_file = "nonexistent_file_12345.txt"; - - auto result = util::split_preprocess_file_in_clang_cuda(nonexistent_file); - - CHECK(result.empty()); + fs::path filename = "nonexistent_file.txt"; + CHECK(util::split_preprocessed_file_from_clang_cuda(filename).empty()); } SUBCASE("empty file") { - TestFileGuard guard("test_empty.txt"); - guard.create_file(""); - - auto result = util::split_preprocess_file_in_clang_cuda(guard.filename()); + fs::path filename = "test_empty.txt"; + util::write_file(filename, ""); - CHECK(result.empty()); + CHECK(util::split_preprocessed_file_from_clang_cuda(filename).empty()); } }