Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cpp/benchmarks/io/nvbench_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ NVBENCH_DECLARE_ENUM_TYPE_STRINGS(

enum class converts_strings : bool { YES, NO };

enum class output_dict : bool { YES, NO };

enum class uses_pandas_metadata : bool { YES, NO };

NVBENCH_DECLARE_ENUM_TYPE_STRINGS(
Expand All @@ -150,6 +152,17 @@ NVBENCH_DECLARE_ENUM_TYPE_STRINGS(
},
[](auto) { return std::string{}; })

NVBENCH_DECLARE_ENUM_TYPE_STRINGS(
output_dict,
[](auto value) {
switch (value) {
case output_dict::YES: return "YES";
case output_dict::NO: return "NO";
default: return "Unknown";
}
},
[](auto) { return std::string{}; })

NVBENCH_DECLARE_ENUM_TYPE_STRINGS(
uses_pandas_metadata,
[](auto value) {
Expand Down
60 changes: 57 additions & 3 deletions cpp/benchmarks/io/parquet/parquet_reader_options.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

Expand Down Expand Up @@ -37,18 +37,21 @@ template <column_selection ColSelection,
row_selection RowSelection,
converts_strings ConvertsStrings,
uses_pandas_metadata UsesPandasMetadata,
output_dict OutputDict,
cudf::type_id Timestamp>
void BM_parquet_read_options(nvbench::state& state,
nvbench::type_list<nvbench::enum_type<ColSelection>,
nvbench::enum_type<RowSelection>,
nvbench::enum_type<ConvertsStrings>,
nvbench::enum_type<UsesPandasMetadata>,
nvbench::enum_type<OutputDict>,
nvbench::enum_type<Timestamp>>)
{
auto const num_chunks = RowSelection == row_selection::ALL ? 1 : chunked_read_num_chunks;

auto constexpr str_to_categories = ConvertsStrings == converts_strings::YES;
auto constexpr uses_pd_metadata = UsesPandasMetadata == uses_pandas_metadata::YES;
auto constexpr str_to_categories = ConvertsStrings == converts_strings::YES;
auto constexpr output_dict_columns = OutputDict == output_dict::YES;
auto constexpr uses_pd_metadata = UsesPandasMetadata == uses_pandas_metadata::YES;

auto const ts_type = cudf::data_type{Timestamp};

Expand Down Expand Up @@ -84,6 +87,7 @@ void BM_parquet_read_options(nvbench::state& state,
cudf::io::parquet_reader_options::builder(source_sink.make_source_info())
.column_names(cols_to_read)
.convert_strings_to_categories(str_to_categories)
.output_dict_columns(output_dict_columns)
.use_pandas_metadata(uses_pd_metadata)
.timestamp_type(ts_type);

Expand All @@ -93,6 +97,26 @@ void BM_parquet_read_options(nvbench::state& state,

auto const chunk_row_cnt = cudf::util::div_rounding_up_unsafe(view.num_rows(), num_chunks);

// Non-timed preflight: confirm the reader honors `output_dict_columns` on a flat STRING column --
// YES transcodes it to DICTIONARY32, NO leaves it as STRING. Skipped when
// `convert_strings_to_categories` is set.
if constexpr (not str_to_categories) {
auto const preflight_tbl = cudf::io::read_parquet(read_options).tbl;
auto const preflight = preflight_tbl->view();
auto const has_type = [&](cudf::type_id id) {
return std::any_of(preflight.begin(), preflight.end(), [id](auto const& col) {
return col.type().id() == id;
});
};
if constexpr (output_dict_columns) {
CUDF_EXPECTS(has_type(cudf::type_id::DICTIONARY32),
"output_dict_columns=YES must produce a DICTIONARY32 column");
} else {
CUDF_EXPECTS(has_type(cudf::type_id::STRING),
"output_dict_columns=NO must produce a STRING column");
}
}

Comment on lines +100 to +119

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this check. Other options don't check if they are applied correctly.

auto mem_stats_logger = cudf::memory_stats_logger();
state.set_cuda_stream(nvbench::make_cuda_stream_view(cudf::get_default_stream().value()));
state.exec(
Expand Down Expand Up @@ -139,12 +163,14 @@ NVBENCH_BENCH_TYPES(BM_parquet_read_options,
row_selections,
nvbench::enum_type_list<converts_strings::YES>,
nvbench::enum_type_list<uses_pandas_metadata::YES>,
nvbench::enum_type_list<output_dict::NO>,
nvbench::enum_type_list<cudf::type_id::EMPTY>))
.set_name("parquet_read_row_selection")
.set_type_axes_names({"column_selection",
"row_selection",
"str_to_categories",
"uses_pandas_metadata",
"output_dict_columns",
"timestamp_type"})
.set_min_samples(4)
// NOTE: row_selection::ROW_GROUPS reads a fraction of row groups; non-zero
Expand All @@ -161,12 +187,14 @@ NVBENCH_BENCH_TYPES(BM_parquet_read_options,
nvbench::enum_type_list<row_selection::ALL>,
nvbench::enum_type_list<converts_strings::YES>,
nvbench::enum_type_list<uses_pandas_metadata::YES>,
nvbench::enum_type_list<output_dict::NO>,
nvbench::enum_type_list<cudf::type_id::EMPTY>))
.set_name("parquet_read_column_selection")
.set_type_axes_names({"column_selection",
"row_selection",
"str_to_categories",
"uses_pandas_metadata",
"output_dict_columns",
"timestamp_type"})
.set_min_samples(4)
.add_int64_axis("row_group_size_bytes", {0})
Expand All @@ -178,13 +206,39 @@ NVBENCH_BENCH_TYPES(
nvbench::enum_type_list<row_selection::ALL>,
nvbench::enum_type_list<converts_strings::YES, converts_strings::NO>,
nvbench::enum_type_list<uses_pandas_metadata::YES, uses_pandas_metadata::NO>,
nvbench::enum_type_list<output_dict::NO>,
nvbench::enum_type_list<cudf::type_id::EMPTY>))
.set_name("parquet_read_misc_options")
.set_type_axes_names({"column_selection",
"row_selection",
"str_to_categories",
"uses_pandas_metadata",
"output_dict_columns",
"timestamp_type"})
.set_min_samples(4)
.add_int64_axis("row_group_size_bytes", {0})
.add_int64_axis("row_group_size_rows", {0});

// Sweep `output_dict_columns` on/off. Only flat STRING columns are dictionary-transcoded, so this
// case reports read throughput and peak memory for both the direct transcode (YES) and the plain
// STRING materialization (NO). Varying `row_group_size_rows` exercises the single-row-group fast
// path (few, large row groups) versus the multi-row-group concatenate path (many, small ones).
NVBENCH_BENCH_TYPES(BM_parquet_read_options,
NVBENCH_TYPE_AXES(nvbench::enum_type_list<column_selection::ALL>,
nvbench::enum_type_list<row_selection::ALL>,
nvbench::enum_type_list<converts_strings::NO>,
nvbench::enum_type_list<uses_pandas_metadata::NO>,
nvbench::enum_type_list<output_dict::YES, output_dict::NO>,
nvbench::enum_type_list<cudf::type_id::EMPTY>))
.set_name("parquet_read_dict_output")
.set_type_axes_names({"column_selection",
"row_selection",
"str_to_categories",
"uses_pandas_metadata",
"output_dict_columns",
"timestamp_type"})
.set_min_samples(4)
.add_int64_axis("row_group_size_bytes", {0})
// 0 == cuDF default (1,000,000 rows/RG → few, large row groups); 100,000 forces ~10x more,
// smaller row groups, exercising the multi-row-group concatenate path.
.add_int64_axis("row_group_size_rows", {0, 100'000});
Loading