From 310fe9f5ca62c895f9ec9c7c5cb02673210ceffa Mon Sep 17 00:00:00 2001 From: Vukasin Milovanovic Date: Mon, 24 Apr 2023 10:53:13 -0700 Subject: [PATCH] Add log messages about cuIO's nvCOMP and cuFile use (#13132) Issue #7861 Added the following log messages: - Info message about nvCOMP use for a given compression type (once per type). - Error message when a file cannot be read/written with cuFile, and fallback is disabled (per file). - Info messages about GDS use vs. bounce buffer (per file). Authors: - Vukasin Milovanovic (https://github.com/vuule) Approvers: - Nghia Truong (https://github.com/ttnghia) - Karthikeyan (https://github.com/karthikeyann) URL: https://github.com/rapidsai/cudf/pull/13132 --- cpp/src/io/comp/nvcomp_adapter.cpp | 81 ++++++++++++++++++++-- cpp/src/io/comp/nvcomp_adapter.hpp | 15 +++- cpp/src/io/utilities/file_io_utilities.cpp | 26 +++++-- 3 files changed, 113 insertions(+), 9 deletions(-) diff --git a/cpp/src/io/comp/nvcomp_adapter.cpp b/cpp/src/io/comp/nvcomp_adapter.cpp index 363ae6af1ad..68831ce1e83 100644 --- a/cpp/src/io/comp/nvcomp_adapter.cpp +++ b/cpp/src/io/comp/nvcomp_adapter.cpp @@ -125,6 +125,16 @@ auto batched_decompress_async(compression_type compression, Args&&... args) } } +std::string compression_type_name(compression_type compression) +{ + switch (compression) { + case compression_type::SNAPPY: return "Snappy"; + case compression_type::ZSTD: return "Zstandard"; + case compression_type::DEFLATE: return "Deflate"; + } + return "compression_type(" + std::to_string(static_cast(compression)) + ")"; +} + size_t batched_decompress_temp_size(compression_type compression, size_t num_chunks, size_t max_uncomp_chunk_size, @@ -439,8 +449,23 @@ feature_status_parameters::feature_status_parameters() cudaDeviceGetAttribute(&compute_capability_major, cudaDevAttrComputeCapabilityMajor, device)); } -std::optional is_compression_disabled(compression_type compression, - feature_status_parameters params) +// Represents all parameters required to determine status of a compression/decompression feature +using feature_status_inputs = std::pair; +struct hash_feature_status_inputs { + size_t operator()(feature_status_inputs const& fsi) const + { + // Outside of unit tests, the same `feature_status_parameters` value will always be passed + // within a run; for simplicity, only use `compression_type` for the hash + return std::hash{}(fsi.first); + } +}; + +// Hash map type that stores feature status for different combinations of input parameters +using feature_status_memo_map = + std::unordered_map, hash_feature_status_inputs>; + +std::optional is_compression_disabled_impl(compression_type compression, + feature_status_parameters params) { switch (compression) { case compression_type::DEFLATE: { @@ -477,6 +502,30 @@ std::optional is_compression_disabled(compression_type compression, return "Unsupported compression type"; } +std::optional is_compression_disabled(compression_type compression, + feature_status_parameters params) +{ + static feature_status_memo_map comp_status_reason; + if (auto mem_res_it = comp_status_reason.find(feature_status_inputs{compression, params}); + mem_res_it != comp_status_reason.end()) { + return mem_res_it->second; + } + + // The rest of the function will execute only once per run, the memoized result will be returned + // in all subsequent calls with the same compression type + auto const reason = is_compression_disabled_impl(compression, params); + comp_status_reason[{compression, params}] = reason; + if (reason.has_value()) { + CUDF_LOG_INFO("nvCOMP is disabled for {} compression; reason: {}", + compression_type_name(compression), + reason.value()); + } else { + CUDF_LOG_INFO("nvCOMP is enabled for {} compression", compression_type_name(compression)); + } + + return reason; +} + std::optional is_zstd_decomp_disabled(feature_status_parameters const& params) { if (not NVCOMP_HAS_ZSTD_DECOMP( @@ -503,8 +552,8 @@ std::optional is_zstd_decomp_disabled(feature_status_parameters con return std::nullopt; } -std::optional is_decompression_disabled(compression_type compression, - feature_status_parameters params) +std::optional is_decompression_disabled_impl(compression_type compression, + feature_status_parameters params) { switch (compression) { case compression_type::DEFLATE: { @@ -531,6 +580,30 @@ std::optional is_decompression_disabled(compression_type compressio return "Unsupported compression type"; } +std::optional is_decompression_disabled(compression_type compression, + feature_status_parameters params) +{ + static feature_status_memo_map decomp_status_reason; + if (auto mem_res_it = decomp_status_reason.find(feature_status_inputs{compression, params}); + mem_res_it != decomp_status_reason.end()) { + return mem_res_it->second; + } + + // The rest of the function will execute only once per run, the memoized result will be returned + // in all subsequent calls with the same compression type + auto const reason = is_decompression_disabled_impl(compression, params); + decomp_status_reason[{compression, params}] = reason; + if (reason.has_value()) { + CUDF_LOG_INFO("nvCOMP is disabled for {} decompression; reason: {}", + compression_type_name(compression), + reason.value()); + } else { + CUDF_LOG_INFO("nvCOMP is enabled for {} decompression", compression_type_name(compression)); + } + + return reason; +} + size_t compress_input_alignment_bits(compression_type compression) { switch (compression) { diff --git a/cpp/src/io/comp/nvcomp_adapter.hpp b/cpp/src/io/comp/nvcomp_adapter.hpp index a6bde7957c7..1393b70f058 100644 --- a/cpp/src/io/comp/nvcomp_adapter.hpp +++ b/cpp/src/io/comp/nvcomp_adapter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, NVIDIA CORPORATION. + * Copyright (c) 2022-2023, NVIDIA CORPORATION. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,19 @@ struct feature_status_parameters { } }; +/** + * @brief Equality operator overload. Required to use `feature_status_parameters` as a map key. + */ +inline bool operator==(feature_status_parameters const& lhs, feature_status_parameters const& rhs) +{ + return lhs.lib_major_version == rhs.lib_major_version and + lhs.lib_minor_version == rhs.lib_minor_version and + lhs.lib_patch_version == rhs.lib_patch_version and + lhs.are_all_integrations_enabled == rhs.are_all_integrations_enabled and + lhs.are_stable_integrations_enabled == rhs.are_stable_integrations_enabled and + lhs.compute_capability_major == rhs.compute_capability_major; +} + /** * @brief If a compression type is disabled through nvCOMP, returns the reason as a string. * diff --git a/cpp/src/io/utilities/file_io_utilities.cpp b/cpp/src/io/utilities/file_io_utilities.cpp index da24770661c..6f4f481de36 100644 --- a/cpp/src/io/utilities/file_io_utilities.cpp +++ b/cpp/src/io/utilities/file_io_utilities.cpp @@ -273,9 +273,18 @@ std::unique_ptr make_cufile_input(std::string const& filepath { if (cufile_integration::is_gds_enabled()) { try { - return std::make_unique(filepath); + auto const cufile_in = std::make_unique(filepath); + CUDF_LOG_INFO("File successfully opened for reading with GDS."); } catch (...) { - if (cufile_integration::is_always_enabled()) throw; + if (cufile_integration::is_always_enabled()) { + CUDF_LOG_ERROR( + "Failed to open file for reading with GDS. Enable bounce buffer fallback to read this " + "file."); + throw; + } + CUDF_LOG_INFO( + "Failed to open file for reading with GDS. Data will be read from the file using a bounce " + "buffer (possible performance impact)."); } } return nullptr; @@ -285,9 +294,18 @@ std::unique_ptr make_cufile_output(std::string const& filepa { if (cufile_integration::is_gds_enabled()) { try { - return std::make_unique(filepath); + auto const cufile_out = std::make_unique(filepath); + CUDF_LOG_INFO("File successfully opened for writing with GDS."); } catch (...) { - if (cufile_integration::is_always_enabled()) throw; + if (cufile_integration::is_always_enabled()) { + CUDF_LOG_ERROR( + "Failed to open file for writing with GDS. Enable bounce buffer fallback to write to " + "this file."); + throw; + } + CUDF_LOG_INFO( + "Failed to open file for writing with GDS. Data will be written to the file using a bounce " + "buffer (possible performance impact)."); } } return nullptr;