From c4c4405db19052e4d9cfb337258b0ec221861592 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 13:40:38 +0000 Subject: [PATCH 01/15] Add relational helpers for NDS-H benchmarks --- .../ndsh_data_generator/table_helpers.cpp | 12 +- .../ndsh_data_generator/table_helpers.hpp | 6 +- cpp/benchmarks/ndsh/utilities.cpp | 159 +++++++++++++++++- cpp/benchmarks/ndsh/utilities.hpp | 81 ++++++++- 4 files changed, 246 insertions(+), 12 deletions(-) diff --git a/cpp/benchmarks/common/ndsh_data_generator/table_helpers.cpp b/cpp/benchmarks/common/ndsh_data_generator/table_helpers.cpp index 8510e9d6c623..a40de2d52c2f 100644 --- a/cpp/benchmarks/common/ndsh_data_generator/table_helpers.cpp +++ b/cpp/benchmarks/common/ndsh_data_generator/table_helpers.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -145,13 +145,14 @@ std::unique_ptr perform_left_join(cudf::table_view const& left_inpu * @param mr Device memory resource used to allocate the returned column's device memory */ [[nodiscard]] std::unique_ptr calculate_l_suppkey(cudf::column_view const& l_partkey, - cudf::size_type scale_factor, + double scale_factor, cudf::size_type num_rows, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr) { CUDF_BENCHMARK_RANGE(); // Expression: (l_partkey + (i * (s/4 + (int)(l_partkey - 1)/s))) % s + 1 + auto const supplier_count = static_cast(scale_factor * 10'000); // Generate the `s` col auto s_empty = cudf::make_numeric_column( @@ -160,7 +161,7 @@ std::unique_ptr perform_left_join(cudf::table_view const& left_inpu auto s = cudf::fill(s_empty->view(), 0, num_rows, - cudf::numeric_scalar(scale_factor * 10'000), + cudf::numeric_scalar(supplier_count), stream, mr); @@ -217,13 +218,14 @@ std::unique_ptr perform_left_join(cudf::table_view const& left_inpu */ [[nodiscard]] std::unique_ptr calculate_ps_suppkey( cudf::column_view const& ps_partkey, - cudf::size_type scale_factor, + double scale_factor, cudf::size_type num_rows, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr) { CUDF_BENCHMARK_RANGE(); // Expression: ps_suppkey = (ps_partkey + (i * (s/4 + (int)(ps_partkey - 1)/s))) % s + 1 + auto const supplier_count = static_cast(scale_factor * 10'000); // Generate the `s` col auto s_empty = cudf::make_numeric_column( @@ -232,7 +234,7 @@ std::unique_ptr perform_left_join(cudf::table_view const& left_inpu auto s = cudf::fill(s_empty->view(), 0, num_rows, - cudf::numeric_scalar(scale_factor * 10'000), + cudf::numeric_scalar(supplier_count), stream, mr); diff --git a/cpp/benchmarks/common/ndsh_data_generator/table_helpers.hpp b/cpp/benchmarks/common/ndsh_data_generator/table_helpers.hpp index 055d1c915718..7b6572372e0b 100644 --- a/cpp/benchmarks/common/ndsh_data_generator/table_helpers.hpp +++ b/cpp/benchmarks/common/ndsh_data_generator/table_helpers.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -72,7 +72,7 @@ std::unique_ptr perform_left_join( */ [[nodiscard]] std::unique_ptr calculate_l_suppkey( cudf::column_view const& l_partkey, - cudf::size_type scale_factor, + double scale_factor, cudf::size_type num_rows, rmm::cuda_stream_view stream = cudf::get_default_stream(), rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref()); @@ -88,7 +88,7 @@ std::unique_ptr perform_left_join( */ [[nodiscard]] std::unique_ptr calculate_ps_suppkey( cudf::column_view const& ps_partkey, - cudf::size_type scale_factor, + double scale_factor, cudf::size_type num_rows, rmm::cuda_stream_view stream = cudf::get_default_stream(), rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref()); diff --git a/cpp/benchmarks/ndsh/utilities.cpp b/cpp/benchmarks/ndsh/utilities.cpp index 324ce8e9a88f..82a1580d90a3 100644 --- a/cpp/benchmarks/ndsh/utilities.cpp +++ b/cpp/benchmarks/ndsh/utilities.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include namespace { @@ -91,8 +93,50 @@ std::unordered_map const> const SCHEMAS = {"customer", CUSTOMER_SCHEMA}, {"nation", NATION_SCHEMA}, {"region", REGION_SCHEMA}}; + +std::vector column_ids(std::unique_ptr const& table, + std::vector const& columns) +{ + std::vector result; + std::transform( + columns.begin(), columns.end(), std::back_inserter(result), [&](auto const& column) { + return table->column_id(column); + }); + return result; +} + +std::unique_ptr apply_left_filter_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls, + bool semi_join) +{ + auto const stream = cudf::get_default_stream(); + auto const left_selected = left_input->table().select(column_ids(left_input, left_on)); + auto const right_selected = right_input->table().select(column_ids(right_input, right_on)); + cudf::filtered_join join{ + right_selected, compare_nulls, stream, cudf::get_current_device_resource_ref()}; + auto indices = semi_join ? join.semi_join(left_selected) : join.anti_join(left_selected); + auto const indices_view = cudf::column_view{cudf::device_span{*indices}}; + auto result = + cudf::gather(left_input->table(), indices_view, cudf::out_of_bounds_policy::DONT_CHECK); + return std::make_unique(std::move(result), left_input->column_names()); +} } // namespace +query_mode query_mode_from_string(std::string const& str) +{ + if (str == "end_to_end") { + return query_mode::END_TO_END; + } else if (str == "compute_only") { + return query_mode::COMPUTE_ONLY; + } else { + CUDF_FAIL("unrecognized query mode: " + str); + } +} + cudf::table_view table_with_names::table() const { return tbl->view(); } cudf::column_view table_with_names::column(std::string const& col_name) const @@ -146,6 +190,14 @@ void table_with_names::to_parquet(std::string const& filepath) const cudf::io::write_parquet(options); } +std::unique_ptr apply_projection(std::unique_ptr const& table, + std::vector const& columns) +{ + CUDF_BENCHMARK_RANGE(); + auto result = std::make_unique(table->select(columns)); + return std::make_unique(std::move(result), columns); +} + std::unique_ptr join_and_gather(cudf::table_view const& left_input, cudf::table_view const& right_input, std::vector const& left_on, @@ -213,6 +265,60 @@ std::unique_ptr apply_inner_join( return std::make_unique(std::move(table), merged_column_names); } +std::unique_ptr apply_left_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls) +{ + CUDF_BENCHMARK_RANGE(); + auto const left_selected = left_input->table().select(column_ids(left_input, left_on)); + auto const right_selected = right_input->table().select(column_ids(right_input, right_on)); + auto const [left_indices, right_indices] = + cudf::left_join(left_selected, right_selected, compare_nulls); + auto const left_indices_view = + cudf::column_view{cudf::device_span{*left_indices}}; + auto const right_indices_view = + cudf::column_view{cudf::device_span{*right_indices}}; + auto left_result = + cudf::gather(left_input->table(), left_indices_view, cudf::out_of_bounds_policy::DONT_CHECK); + auto right_result = + cudf::gather(right_input->table(), right_indices_view, cudf::out_of_bounds_policy::NULLIFY); + auto joined_columns = left_result->release(); + auto right_columns = right_result->release(); + joined_columns.insert(joined_columns.end(), + std::make_move_iterator(right_columns.begin()), + std::make_move_iterator(right_columns.end())); + std::vector column_names = left_input->column_names(); + column_names.insert( + column_names.end(), right_input->column_names().begin(), right_input->column_names().end()); + return std::make_unique( + std::make_unique(std::move(joined_columns)), std::move(column_names)); +} + +std::unique_ptr apply_left_semi_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls) +{ + CUDF_BENCHMARK_RANGE(); + return apply_left_filter_join(left_input, right_input, left_on, right_on, compare_nulls, true); +} + +std::unique_ptr apply_left_anti_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls) +{ + CUDF_BENCHMARK_RANGE(); + return apply_left_filter_join(left_input, right_input, left_on, right_on, compare_nulls, false); +} + std::unique_ptr apply_filter(std::unique_ptr const& table, cudf::ast::operation const& predicate) { @@ -230,6 +336,28 @@ std::unique_ptr apply_mask(std::unique_ptr c return std::make_unique(std::move(result_table), table->column_names()); } +std::unique_ptr apply_distinct(std::unique_ptr const& table) +{ + CUDF_BENCHMARK_RANGE(); + std::vector keys(table->table().num_columns()); + std::iota(keys.begin(), keys.end(), 0); + auto result = cudf::distinct(table->table(), keys); + return std::make_unique(std::move(result), table->column_names()); +} + +std::unique_ptr apply_slice(std::unique_ptr const& table, + cudf::size_type begin, + cudf::size_type end) +{ + CUDF_BENCHMARK_RANGE(); + auto const num_rows = table->table().num_rows(); + begin = std::clamp(begin, cudf::size_type{0}, num_rows); + end = std::clamp(end, begin, num_rows); + auto const view = cudf::slice(table->table(), {begin, end}).front(); + auto result = std::make_unique(view); + return std::make_unique(std::move(result), table->column_names()); +} + std::unique_ptr apply_groupby(std::unique_ptr const& table, groupby_context_t const& ctx) { @@ -245,12 +373,21 @@ std::unique_ptr apply_groupby(std::unique_ptr()); + } else if (agg.first == cudf::aggregation::Kind::MIN) { + requests.back().aggregations.push_back( + cudf::make_min_aggregation()); + } else if (agg.first == cudf::aggregation::Kind::MAX) { + requests.back().aggregations.push_back( + cudf::make_max_aggregation()); } else if (agg.first == cudf::aggregation::Kind::MEAN) { requests.back().aggregations.push_back( cudf::make_mean_aggregation()); } else if (agg.first == cudf::aggregation::Kind::COUNT_ALL) { requests.back().aggregations.push_back( - cudf::make_count_aggregation()); + cudf::make_count_aggregation(cudf::null_policy::INCLUDE)); + } else if (agg.first == cudf::aggregation::Kind::NUNIQUE) { + requests.back().aggregations.push_back( + cudf::make_nunique_aggregation()); } else { throw std::runtime_error("Unsupported aggregation"); } @@ -292,8 +429,24 @@ std::unique_ptr apply_reduction(cudf::column_view const& colum std::string const& col_name) { CUDF_BENCHMARK_RANGE(); - auto const agg = cudf::make_sum_aggregation(); - auto const result = cudf::reduce(column, *agg, column.type()); + std::unique_ptr agg; + auto output_type = column.type(); + if (agg_kind == cudf::aggregation::Kind::SUM) { + agg = cudf::make_sum_aggregation(); + } else if (agg_kind == cudf::aggregation::Kind::MIN) { + agg = cudf::make_min_aggregation(); + } else if (agg_kind == cudf::aggregation::Kind::MAX) { + agg = cudf::make_max_aggregation(); + } else if (agg_kind == cudf::aggregation::Kind::MEAN) { + agg = cudf::make_mean_aggregation(); + output_type = cudf::data_type{cudf::type_id::FLOAT64}; + } else if (agg_kind == cudf::aggregation::Kind::COUNT_ALL) { + agg = cudf::make_count_aggregation(cudf::null_policy::INCLUDE); + output_type = cudf::data_type{cudf::type_id::INT32}; + } else { + throw std::runtime_error("Unsupported aggregation"); + } + auto const result = cudf::reduce(column, *agg, output_type); cudf::size_type const len = 1; auto col = cudf::make_column_from_scalar(*result, len); std::vector> columns; diff --git a/cpp/benchmarks/ndsh/utilities.hpp b/cpp/benchmarks/ndsh/utilities.hpp index 7864e547b225..5773bc546b14 100644 --- a/cpp/benchmarks/ndsh/utilities.hpp +++ b/cpp/benchmarks/ndsh/utilities.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -64,6 +64,19 @@ class table_with_names { std::vector col_names; }; +enum class query_mode : int32_t { END_TO_END = 0, COMPUTE_ONLY = 1 }; + +[[nodiscard]] query_mode query_mode_from_string(std::string const& str); + +/** + * @brief Select and copy named columns from a table + * + * @param table The input table + * @param columns The columns to copy + */ +[[nodiscard]] std::unique_ptr apply_projection( + std::unique_ptr const& table, std::vector const& columns); + /** * @brief Inner join two tables and gather the result * @@ -96,6 +109,54 @@ class table_with_names { std::vector const& right_on, cudf::null_equality compare_nulls = cudf::null_equality::EQUAL); +/** + * @brief Apply a left join operation to two tables + * + * @param left_input The left input table + * @param right_input The right input table + * @param left_on The columns to join on in the left table + * @param right_on The columns to join on in the right table + * @param compare_nulls The null equality policy + */ +[[nodiscard]] std::unique_ptr apply_left_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls = cudf::null_equality::EQUAL); + +/** + * @brief Apply a left semi join operation to two tables + * + * @param left_input The left input table + * @param right_input The right input table + * @param left_on The columns to join on in the left table + * @param right_on The columns to join on in the right table + * @param compare_nulls The null equality policy + */ +[[nodiscard]] std::unique_ptr apply_left_semi_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls = cudf::null_equality::EQUAL); + +/** + * @brief Apply a left anti join operation to two tables + * + * @param left_input The left input table + * @param right_input The right input table + * @param left_on The columns to join on in the left table + * @param right_on The columns to join on in the right table + * @param compare_nulls The null equality policy + */ +[[nodiscard]] std::unique_ptr apply_left_anti_join( + std::unique_ptr const& left_input, + std::unique_ptr const& right_input, + std::vector const& left_on, + std::vector const& right_on, + cudf::null_equality compare_nulls = cudf::null_equality::EQUAL); + /** * @brief Apply a filter predicate to a table * @@ -114,6 +175,24 @@ class table_with_names { [[nodiscard]] std::unique_ptr apply_mask( std::unique_ptr const& table, std::unique_ptr const& mask); +/** + * @brief Remove duplicate rows from a table + * + * @param table The input table + */ +[[nodiscard]] std::unique_ptr apply_distinct( + std::unique_ptr const& table); + +/** + * @brief Copy a range of rows from a table + * + * @param table The input table + * @param begin The first row to copy + * @param end One past the last row to copy + */ +[[nodiscard]] std::unique_ptr apply_slice( + std::unique_ptr const& table, cudf::size_type begin, cudf::size_type end); + /** * Struct representing group by key columns, value columns, and the type of aggregations to perform * on the value columns From 26f61ae98481858439e217e365cc3500d1940c68 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 14:01:32 +0000 Subject: [PATCH 02/15] Add standard modes to NDS-H queries --- cpp/benchmarks/ndsh/q01.cpp | 35 ++++++++++++----- cpp/benchmarks/ndsh/q05.cpp | 75 +++++++++++++++++++++++++------------ cpp/benchmarks/ndsh/q06.cpp | 38 +++++++++++++------ cpp/benchmarks/ndsh/q10.cpp | 68 ++++++++++++++++++++++----------- 4 files changed, 150 insertions(+), 66 deletions(-) diff --git a/cpp/benchmarks/ndsh/q01.cpp b/cpp/benchmarks/ndsh/q01.cpp index 0a17d91d0c29..53ca1faa4abf 100644 --- a/cpp/benchmarks/ndsh/q01.cpp +++ b/cpp/benchmarks/ndsh/q01.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -95,7 +95,7 @@ disc_price, one_plus_tax->view(), cudf::binary_operator::MUL, tax.type(), stream, mr); } -void run_ndsh_q1(nvbench::state& state, cudf::io::source_info const& source) +std::unique_ptr load_ndsh_q1(cudf::io::source_info const& source) { // Define the column projections and filter predicate for `lineitem` table std::vector const lineitem_cols = {"l_returnflag", @@ -115,7 +115,13 @@ void run_ndsh_q1(nvbench::state& state, cudf::io::source_info const& source) cudf::ast::ast_operator::LESS_EQUAL, shipdate_ref, shipdate_upper_literal); // Read out the `lineitem` table from parquet file - auto lineitem = read_parquet(source, lineitem_cols, std::move(lineitem_pred)); + return read_parquet(source, lineitem_cols, std::move(lineitem_pred)); +} + +std::unique_ptr execute_ndsh_q1(std::unique_ptr const& input) +{ + auto lineitem = std::make_unique(std::make_unique(input->table()), + input->column_names()); // Calculate the discount price and charge columns and append to lineitem table auto disc_price = @@ -148,12 +154,9 @@ void run_ndsh_q1(nvbench::state& state, cudf::io::source_info const& source) }}); // Perform the order by operation - auto const orderedby_table = apply_orderby(groupedby_table, - {"l_returnflag", "l_linestatus"}, - {cudf::order::ASCENDING, cudf::order::ASCENDING}); - - // Write query result to a parquet file - orderedby_table->to_parquet("q1.parquet"); + return apply_orderby(groupedby_table, + {"l_returnflag", "l_linestatus"}, + {cudf::order::ASCENDING, cudf::order::ASCENDING}); } void ndsh_q1(nvbench::state& state) @@ -161,6 +164,7 @@ void ndsh_q1(nvbench::state& state) // Generate the required parquet files in device buffers auto const scale_factor = state.get_float64("scale_factor"); auto const filename = state.get_string("filename"); + auto const mode = query_mode_from_string(state.get_string("mode")); if (!filename.empty() && scale_factor != 1.0) { state.skip("Only scale_factor=1 supported with filename input"); return; @@ -177,7 +181,17 @@ void ndsh_q1(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); auto const mem_stats_logger = cudf::memory_stats_logger(); - state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { run_ndsh_q1(state, source); }); + auto lineitem = mode == query_mode::COMPUTE_ONLY ? load_ndsh_q1(source) : nullptr; + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q1(source); + result = execute_ndsh_q1(input); + } else { + result = execute_ndsh_q1(lineitem); + } + }); + result->to_parquet("q1.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); } @@ -185,4 +199,5 @@ void ndsh_q1(nvbench::state& state) NVBENCH_BENCH(ndsh_q1) .set_name("ndsh_q1") .add_string_axis("filename", {""}) + .add_string_axis("mode", {"end_to_end", "compute_only"}) .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q05.cpp b/cpp/benchmarks/ndsh/q05.cpp index 482390a7bc18..3f69c3f17e98 100644 --- a/cpp/benchmarks/ndsh/q05.cpp +++ b/cpp/benchmarks/ndsh/q05.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -79,8 +79,8 @@ return revenue; } -void run_ndsh_q5(nvbench::state& state, - std::unordered_map& sources) +std::unordered_map> load_ndsh_q5( + std::unordered_map& sources) { // Define the column projection and filter predicate for the `orders` table std::vector const orders_cols = {"o_custkey", "o_orderkey", "o_orderdate"}; @@ -110,18 +110,37 @@ void run_ndsh_q5(nvbench::state& state, // Read out the tables from parquet files // while pushing down the column projections and filter predicates - auto const customer = - read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_nationkey"}); - auto const orders = - read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred)); - auto const lineitem = read_parquet(sources.at("lineitem").make_source_info(), - {"l_orderkey", "l_suppkey", "l_extendedprice", "l_discount"}); - auto const supplier = - read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_nationkey"}); - auto const nation = - read_parquet(sources.at("nation").make_source_info(), {"n_nationkey", "n_regionkey", "n_name"}); - auto const region = - read_parquet(sources.at("region").make_source_info(), region_cols, std::move(region_pred)); + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_nationkey"})); + tables.emplace( + "orders", + read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred))); + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_orderkey", "l_suppkey", "l_extendedprice", "l_discount"})); + tables.emplace( + "supplier", + read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_nationkey"})); + tables.emplace("nation", + read_parquet(sources.at("nation").make_source_info(), + {"n_nationkey", "n_regionkey", "n_name"})); + tables.emplace( + "region", + read_parquet(sources.at("region").make_source_info(), region_cols, std::move(region_pred))); + return tables; +} + +std::unique_ptr execute_ndsh_q5( + std::unordered_map> const& tables) +{ + auto const& customer = tables.at("customer"); + auto const& orders = tables.at("orders"); + auto const& lineitem = tables.at("lineitem"); + auto const& supplier = tables.at("supplier"); + auto const& nation = tables.at("nation"); + auto const& region = tables.at("region"); // Perform the joins auto const join_a = apply_inner_join(region, nation, {"r_regionkey"}, {"n_regionkey"}); @@ -145,17 +164,14 @@ void run_ndsh_q5(nvbench::state& state, }}); // Perform the order by operation - auto const orderedby_table = - apply_orderby(groupedby_table, {"revenue"}, {cudf::order::DESCENDING}); - - // Write query result to a parquet file - orderedby_table->to_parquet("q5.parquet"); + return apply_orderby(groupedby_table, {"revenue"}, {cudf::order::DESCENDING}); } void ndsh_q5(nvbench::state& state) { // Generate the required parquet files in device buffers double const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); std::unordered_map sources; generate_parquet_data_sources( scale_factor, {"customer", "orders", "lineitem", "supplier", "nation", "region"}, sources); @@ -163,10 +179,23 @@ void ndsh_q5(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); auto const mem_stats_logger = cudf::memory_stats_logger(); - state.exec(nvbench::exec_tag::sync, - [&](nvbench::launch& launch) { run_ndsh_q5(state, sources); }); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q5(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q5(sources); + result = execute_ndsh_q5(input); + } else { + result = execute_ndsh_q5(tables); + } + }); + result->to_parquet("q5.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); } -NVBENCH_BENCH(ndsh_q5).set_name("ndsh_q5").add_float64_axis("scale_factor", {0.01, 0.1, 1}); +NVBENCH_BENCH(ndsh_q5) + .set_name("ndsh_q5") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q06.cpp b/cpp/benchmarks/ndsh/q06.cpp index 35a7a3727faf..7c3a5056721d 100644 --- a/cpp/benchmarks/ndsh/q06.cpp +++ b/cpp/benchmarks/ndsh/q06.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -54,8 +54,8 @@ return revenue; } -void run_ndsh_q6(nvbench::state& state, - std::unordered_map& sources) +std::unique_ptr load_ndsh_q6( + std::unordered_map& sources) { // Read out the `lineitem` table from parquet file std::vector const lineitem_cols = { @@ -74,8 +74,14 @@ void run_ndsh_q6(nvbench::state& state, cudf::ast::operation(cudf::ast::ast_operator::LESS, shipdate_ref, shipdate_upper_literal); auto const lineitem_pred = std::make_unique( cudf::ast::ast_operator::LOGICAL_AND, shipdate_pred_a, shipdate_pred_b); - auto lineitem = read_parquet( + return read_parquet( sources.at("lineitem").make_source_info(), lineitem_cols, std::move(lineitem_pred)); +} + +std::unique_ptr execute_ndsh_q6(std::unique_ptr const& input) +{ + auto lineitem = std::make_unique(std::make_unique(input->table()), + input->column_names()); // Cast the discount and quantity columns to float32 and append to lineitem table auto discout_float = @@ -115,26 +121,36 @@ void run_ndsh_q6(nvbench::state& state, // Sum the `revenue` column auto const revenue_view = revenue->view(); - auto const result_table = apply_reduction(revenue_view, cudf::aggregation::Kind::SUM, "revenue"); - - // Write query result to a parquet file - result_table->to_parquet("q6.parquet"); + return apply_reduction(revenue_view, cudf::aggregation::Kind::SUM, "revenue"); } void ndsh_q6(nvbench::state& state) { // Generate the required parquet files in device buffers double const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); std::unordered_map sources; generate_parquet_data_sources(scale_factor, {"lineitem"}, sources); auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); auto const mem_stats_logger = cudf::memory_stats_logger(); - state.exec(nvbench::exec_tag::sync, - [&](nvbench::launch& launch) { run_ndsh_q6(state, sources); }); + auto lineitem = mode == query_mode::COMPUTE_ONLY ? load_ndsh_q6(sources) : nullptr; + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q6(sources); + result = execute_ndsh_q6(input); + } else { + result = execute_ndsh_q6(lineitem); + } + }); + result->to_parquet("q6.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); } -NVBENCH_BENCH(ndsh_q6).set_name("ndsh_q6").add_float64_axis("scale_factor", {0.01, 0.1, 1}); +NVBENCH_BENCH(ndsh_q6) + .set_name("ndsh_q6") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q10.cpp b/cpp/benchmarks/ndsh/q10.cpp index 567b6a0df884..bdc7331a8cd4 100644 --- a/cpp/benchmarks/ndsh/q10.cpp +++ b/cpp/benchmarks/ndsh/q10.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -84,8 +84,8 @@ return revenue; } -void run_ndsh_q10(nvbench::state& state, - std::unordered_map& sources) +std::unordered_map> load_ndsh_q10( + std::unordered_map& sources) { // Define the column projection and filter predicate for the `orders` table std::vector const orders_cols = {"o_custkey", "o_orderkey", "o_orderdate"}; @@ -112,17 +112,31 @@ void run_ndsh_q10(nvbench::state& state, // Read out the tables from parquet files // while pushing down the column projections and filter predicates - auto const customer = read_parquet( - sources.at("customer").make_source_info(), - {"c_custkey", "c_name", "c_nationkey", "c_acctbal", "c_address", "c_phone", "c_comment"}); - auto const orders = - read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred)); - auto const lineitem = - read_parquet(sources.at("lineitem").make_source_info(), - {"l_extendedprice", "l_discount", "l_orderkey", "l_returnflag"}, - std::move(lineitem_pred)); - auto const nation = - read_parquet(sources.at("nation").make_source_info(), {"n_name", "n_nationkey"}); + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet( + sources.at("customer").make_source_info(), + {"c_custkey", "c_name", "c_nationkey", "c_acctbal", "c_address", "c_phone", "c_comment"})); + tables.emplace( + "orders", + read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred))); + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_extendedprice", "l_discount", "l_orderkey", "l_returnflag"}, + std::move(lineitem_pred))); + tables.emplace("nation", + read_parquet(sources.at("nation").make_source_info(), {"n_name", "n_nationkey"})); + return tables; +} + +std::unique_ptr execute_ndsh_q10( + std::unordered_map> const& tables) +{ + auto const& customer = tables.at("customer"); + auto const& orders = tables.at("orders"); + auto const& lineitem = tables.at("lineitem"); + auto const& nation = tables.at("nation"); // Perform the joins auto const join_a = apply_inner_join(customer, nation, {"c_nationkey"}, {"n_nationkey"}); @@ -144,17 +158,14 @@ void run_ndsh_q10(nvbench::state& state, }}); // Perform the order by operation - auto const orderedby_table = - apply_orderby(groupedby_table, {"revenue"}, {cudf::order::DESCENDING}); - - // Write query result to a parquet file - orderedby_table->to_parquet("q10.parquet"); + return apply_orderby(groupedby_table, {"revenue"}, {cudf::order::DESCENDING}); } void ndsh_q10(nvbench::state& state) { // Generate the required parquet files in device buffers double const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); std::unordered_map sources; generate_parquet_data_sources( scale_factor, {"customer", "orders", "lineitem", "nation"}, sources); @@ -162,10 +173,23 @@ void ndsh_q10(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); auto const mem_stats_logger = cudf::memory_stats_logger(); - state.exec(nvbench::exec_tag::sync, - [&](nvbench::launch& launch) { run_ndsh_q10(state, sources); }); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q10(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q10(sources); + result = execute_ndsh_q10(input); + } else { + result = execute_ndsh_q10(tables); + } + }); + result->to_parquet("q10.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); } -NVBENCH_BENCH(ndsh_q10).set_name("ndsh_q10").add_float64_axis("scale_factor", {0.01, 0.1, 1}); +NVBENCH_BENCH(ndsh_q10) + .set_name("ndsh_q10") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); From c351c0e95638910de346591ff8cdb4a3371ababa Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 15:03:41 +0000 Subject: [PATCH 03/15] Add remaining NDS-H query benchmarks --- cpp/benchmarks/CMakeLists.txt | 17 ++++ cpp/benchmarks/ndsh/q02.cpp | 115 +++++++++++++++++++++ cpp/benchmarks/ndsh/q03.cpp | 128 +++++++++++++++++++++++ cpp/benchmarks/ndsh/q04.cpp | 90 +++++++++++++++++ cpp/benchmarks/ndsh/q07.cpp | 174 ++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q08.cpp | 172 +++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q11.cpp | 120 ++++++++++++++++++++++ cpp/benchmarks/ndsh/q12.cpp | 154 ++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q13.cpp | 114 +++++++++++++++++++++ cpp/benchmarks/ndsh/q14.cpp | 122 ++++++++++++++++++++++ cpp/benchmarks/ndsh/q15.cpp | 107 ++++++++++++++++++++ cpp/benchmarks/ndsh/q16.cpp | 136 +++++++++++++++++++++++++ cpp/benchmarks/ndsh/q17.cpp | 114 +++++++++++++++++++++ cpp/benchmarks/ndsh/q18.cpp | 88 ++++++++++++++++ cpp/benchmarks/ndsh/q19.cpp | 184 ++++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q20.cpp | 131 ++++++++++++++++++++++++ cpp/benchmarks/ndsh/q21.cpp | 141 ++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q22.cpp | 105 +++++++++++++++++++ 18 files changed, 2212 insertions(+) create mode 100644 cpp/benchmarks/ndsh/q02.cpp create mode 100644 cpp/benchmarks/ndsh/q03.cpp create mode 100644 cpp/benchmarks/ndsh/q04.cpp create mode 100644 cpp/benchmarks/ndsh/q07.cpp create mode 100644 cpp/benchmarks/ndsh/q08.cpp create mode 100644 cpp/benchmarks/ndsh/q11.cpp create mode 100644 cpp/benchmarks/ndsh/q12.cpp create mode 100644 cpp/benchmarks/ndsh/q13.cpp create mode 100644 cpp/benchmarks/ndsh/q14.cpp create mode 100644 cpp/benchmarks/ndsh/q15.cpp create mode 100644 cpp/benchmarks/ndsh/q16.cpp create mode 100644 cpp/benchmarks/ndsh/q17.cpp create mode 100644 cpp/benchmarks/ndsh/q18.cpp create mode 100644 cpp/benchmarks/ndsh/q19.cpp create mode 100644 cpp/benchmarks/ndsh/q20.cpp create mode 100644 cpp/benchmarks/ndsh/q21.cpp create mode 100644 cpp/benchmarks/ndsh/q22.cpp diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index d03bf72ee9e8..7e8623543048 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -125,10 +125,27 @@ ConfigureNVBench(TRANSPOSE_NVBENCH transpose/transpose.cpp) # ################################################################################################## # * nds-h benchmark -------------------------------------------------------------------------------- ConfigureNVBench(NDSH_Q01_NVBENCH ndsh/q01.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q02_NVBENCH ndsh/q02.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q03_NVBENCH ndsh/q03.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q04_NVBENCH ndsh/q04.cpp ndsh/utilities.cpp) ConfigureNVBench(NDSH_Q05_NVBENCH ndsh/q05.cpp ndsh/utilities.cpp) ConfigureNVBench(NDSH_Q06_NVBENCH ndsh/q06.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q07_NVBENCH ndsh/q07.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q08_NVBENCH ndsh/q08.cpp ndsh/utilities.cpp) ConfigureNVBench(NDSH_Q09_NVBENCH ndsh/q09.cpp ndsh/utilities.cpp) ConfigureNVBench(NDSH_Q10_NVBENCH ndsh/q10.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q11_NVBENCH ndsh/q11.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q12_NVBENCH ndsh/q12.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q13_NVBENCH ndsh/q13.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q14_NVBENCH ndsh/q14.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q15_NVBENCH ndsh/q15.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q16_NVBENCH ndsh/q16.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q17_NVBENCH ndsh/q17.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q18_NVBENCH ndsh/q18.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q19_NVBENCH ndsh/q19.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q20_NVBENCH ndsh/q20.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q21_NVBENCH ndsh/q21.cpp ndsh/utilities.cpp) +ConfigureNVBench(NDSH_Q22_NVBENCH ndsh/q22.cpp ndsh/utilities.cpp) # ################################################################################################## # * filter benchmark ------------------------------------------------------------------- diff --git a/cpp/benchmarks/ndsh/q02.cpp b/cpp/benchmarks/ndsh/q02.cpp new file mode 100644 index 000000000000..e18a14be6a97 --- /dev/null +++ b/cpp/benchmarks/ndsh/q02.cpp @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include + +#include + +#include + +struct q2_data { + std::unique_ptr nation; + std::unique_ptr part; + std::unique_ptr partsupp; + std::unique_ptr region; + std::unique_ptr supplier; +}; + +q2_data load_ndsh_q2(std::unordered_map& sources) +{ + std::vector const part_columns = {"p_partkey", "p_size", "p_type", "p_mfgr"}; + auto const p_size_ref = cudf::ast::column_reference{1}; + auto p_size = cudf::numeric_scalar{15}; + auto const p_size_literal = cudf::ast::literal{p_size}; + auto part_predicate = std::make_unique( + cudf::ast::ast_operator::EQUAL, p_size_ref, p_size_literal); + + std::vector const region_columns = {"r_regionkey", "r_name"}; + auto const r_name_ref = cudf::ast::column_reference{1}; + auto r_name = cudf::string_scalar{"EUROPE"}; + auto const r_name_literal = cudf::ast::literal{r_name}; + auto region_predicate = std::make_unique( + cudf::ast::ast_operator::EQUAL, r_name_ref, r_name_literal); + + return q2_data{ + read_parquet(sources.at("nation").make_source_info(), {"n_nationkey", "n_regionkey", "n_name"}), + read_parquet(sources.at("part").make_source_info(), part_columns, std::move(part_predicate)), + read_parquet(sources.at("partsupp").make_source_info(), + {"ps_partkey", "ps_suppkey", "ps_supplycost"}), + read_parquet( + sources.at("region").make_source_info(), region_columns, std::move(region_predicate)), + read_parquet( + sources.at("supplier").make_source_info(), + {"s_suppkey", "s_name", "s_address", "s_nationkey", "s_phone", "s_acctbal", "s_comment"})}; +} + +std::unique_ptr execute_ndsh_q2(q2_data const& data) +{ + auto const brass = cudf::string_scalar{"BRASS"}; + auto const mask = + cudf::strings::ends_with(cudf::strings_column_view{data.part->column("p_type")}, brass); + auto const part = apply_mask(data.part, mask); + + auto const join_a = apply_inner_join(part, data.partsupp, {"p_partkey"}, {"ps_partkey"}); + auto const join_b = apply_inner_join(join_a, data.supplier, {"ps_suppkey"}, {"s_suppkey"}); + auto const join_c = apply_inner_join(join_b, data.nation, {"s_nationkey"}, {"n_nationkey"}); + auto const joined = apply_inner_join(join_c, data.region, {"n_regionkey"}, {"r_regionkey"}); + + auto const minimum_cost = apply_groupby( + joined, + groupby_context_t{{"p_partkey"}, + {{"ps_supplycost", {{cudf::aggregation::Kind::MIN, "ps_supplycost"}}}}}); + auto const minimum_suppliers = apply_inner_join( + minimum_cost, joined, {"p_partkey", "ps_supplycost"}, {"p_partkey", "ps_supplycost"}); + auto const selected = apply_projection( + minimum_suppliers, + {"s_acctbal", "s_name", "n_name", "p_partkey", "p_mfgr", "s_address", "s_phone", "s_comment"}); + auto const ordered = apply_orderby(selected, + {"s_acctbal", "n_name", "s_name", "p_partkey"}, + {cudf::order::DESCENDING, + cudf::order::ASCENDING, + cudf::order::ASCENDING, + cudf::order::ASCENDING}); + return apply_slice(ordered, 0, 100); +} + +void ndsh_q2(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources( + scale_factor, {"nation", "part", "partsupp", "region", "supplier"}, sources); + + auto const stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + auto data = + mode == query_mode::COMPUTE_ONLY ? std::optional{load_ndsh_q2(sources)} : std::nullopt; + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q2(sources); + result = execute_ndsh_q2(input); + } else { + result = execute_ndsh_q2(*data); + } + }); + result->to_parquet("q2.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q2) + .set_name("ndsh_q2") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q03.cpp b/cpp/benchmarks/ndsh/q03.cpp new file mode 100644 index 000000000000..4b208402f12f --- /dev/null +++ b/cpp/benchmarks/ndsh/q03.cpp @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include + +#include + +[[nodiscard]] std::unique_ptr calculate_revenue( + cudf::column_view const& extendedprice, + cudf::column_view const& discount, + rmm::cuda_stream_view stream = cudf::get_default_stream(), + rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref()) +{ + auto const one = cudf::numeric_scalar(1); + auto const one_minus_discount = + cudf::binary_operation(one, discount, cudf::binary_operator::SUB, discount.type(), stream, mr); + return cudf::binary_operation(extendedprice, + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}, + stream, + mr); +} + +std::unordered_map> load_ndsh_q3( + std::unordered_map& sources) +{ + std::vector const customer_cols = {"c_custkey", "c_mktsegment"}; + auto const c_mktsegment_ref = cudf::ast::column_reference(1); + auto building = cudf::string_scalar("BUILDING"); + auto const building_literal = cudf::ast::literal(building); + auto const customer_pred = std::make_unique( + cudf::ast::ast_operator::EQUAL, c_mktsegment_ref, building_literal); + + std::vector const orders_cols = { + "o_custkey", "o_orderkey", "o_orderdate", "o_shippriority"}; + auto const o_orderdate_ref = cudf::ast::column_reference(2); + auto orderdate_limit = + cudf::timestamp_scalar(days_since_epoch(1995, 3, 15), true); + auto const orderdate_literal = cudf::ast::literal(orderdate_limit); + auto const orders_pred = std::make_unique( + cudf::ast::ast_operator::LESS, o_orderdate_ref, orderdate_literal); + + std::vector const lineitem_cols = { + "l_orderkey", "l_extendedprice", "l_discount", "l_shipdate"}; + auto const l_shipdate_ref = cudf::ast::column_reference(3); + auto shipdate_limit = + cudf::timestamp_scalar(days_since_epoch(1995, 3, 15), true); + auto const shipdate_literal = cudf::ast::literal(shipdate_limit); + auto const lineitem_pred = std::make_unique( + cudf::ast::ast_operator::GREATER, l_shipdate_ref, shipdate_literal); + + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet( + sources.at("customer").make_source_info(), customer_cols, std::move(customer_pred))); + tables.emplace( + "orders", + read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred))); + tables.emplace( + "lineitem", + read_parquet( + sources.at("lineitem").make_source_info(), lineitem_cols, std::move(lineitem_pred))); + return tables; +} + +std::unique_ptr execute_ndsh_q3( + std::unordered_map> const& tables) +{ + auto const customer_orders = + apply_inner_join(tables.at("customer"), tables.at("orders"), {"c_custkey"}, {"o_custkey"}); + auto joined = + apply_inner_join(customer_orders, tables.at("lineitem"), {"o_orderkey"}, {"l_orderkey"}); + + auto revenue = calculate_revenue(joined->column("l_extendedprice"), joined->column("l_discount")); + joined->append(revenue, "revenue"); + + auto const grouped = + apply_groupby(joined, + groupby_context_t{{"l_orderkey", "o_orderdate", "o_shippriority"}, + {{"revenue", {{cudf::aggregation::Kind::SUM, "revenue"}}}}}); + auto const ordered = apply_orderby( + grouped, {"revenue", "o_orderdate"}, {cudf::order::DESCENDING, cudf::order::ASCENDING}); + auto const top_ten = apply_slice(ordered, 0, 10); + return apply_projection(top_ten, {"l_orderkey", "revenue", "o_orderdate", "o_shippriority"}); +} + +void ndsh_q3(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"customer", "orders", "lineitem"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q3(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q3(sources); + result = execute_ndsh_q3(input); + } else { + result = execute_ndsh_q3(tables); + } + }); + result->to_parquet("q3.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q3) + .set_name("ndsh_q3") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q04.cpp b/cpp/benchmarks/ndsh/q04.cpp new file mode 100644 index 000000000000..1dc8b7e194a2 --- /dev/null +++ b/cpp/benchmarks/ndsh/q04.cpp @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include + +#include + +struct q4_data { + std::unique_ptr lineitem; + std::unique_ptr orders; +}; + +q4_data load_ndsh_q4(std::unordered_map& sources) +{ + std::vector const lineitem_cols = {"l_orderkey", "l_commitdate", "l_receiptdate"}; + + std::vector const orders_cols = {"o_orderkey", "o_orderdate", "o_orderpriority"}; + auto const orderdate_ref = cudf::ast::column_reference(1); + auto orderdate_lower = + cudf::timestamp_scalar(days_since_epoch(1993, 7, 1), true); + auto orderdate_upper = + cudf::timestamp_scalar(days_since_epoch(1993, 10, 1), true); + auto const orderdate_lower_literal = cudf::ast::literal(orderdate_lower); + auto const orderdate_upper_literal = cudf::ast::literal(orderdate_upper); + auto const orderdate_lower_pred = cudf::ast::operation( + cudf::ast::ast_operator::GREATER_EQUAL, orderdate_ref, orderdate_lower_literal); + auto const orderdate_upper_pred = + cudf::ast::operation(cudf::ast::ast_operator::LESS, orderdate_ref, orderdate_upper_literal); + auto const orders_pred = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, orderdate_lower_pred, orderdate_upper_pred); + + return q4_data{ + read_parquet(sources.at("lineitem").make_source_info(), lineitem_cols), + read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred))}; +} + +std::unique_ptr execute_ndsh_q4(q4_data const& data) +{ + auto const commitdate_ref = cudf::ast::column_reference(data.lineitem->column_id("l_commitdate")); + auto const receiptdate_ref = + cudf::ast::column_reference(data.lineitem->column_id("l_receiptdate")); + auto const lineitem_pred = + cudf::ast::operation(cudf::ast::ast_operator::LESS, commitdate_ref, receiptdate_ref); + auto const lineitem = apply_filter(data.lineitem, lineitem_pred); + auto const qualifying_orders = + apply_left_semi_join(data.orders, lineitem, {"o_orderkey"}, {"l_orderkey"}); + auto const grouped_orders = apply_groupby( + qualifying_orders, + groupby_context_t{{"o_orderpriority"}, + {{"o_orderkey", {{cudf::aggregation::Kind::COUNT_ALL, "order_count"}}}}}); + return apply_orderby(grouped_orders, {"o_orderpriority"}, {cudf::order::ASCENDING}); +} + +void ndsh_q4(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "orders"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + q4_data data; + if (mode == query_mode::COMPUTE_ONLY) { data = load_ndsh_q4(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q4(sources); + result = execute_ndsh_q4(input); + } else { + result = execute_ndsh_q4(data); + } + }); + result->to_parquet("q4.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q4) + .set_name("ndsh_q4") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q07.cpp b/cpp/benchmarks/ndsh/q07.cpp new file mode 100644 index 000000000000..bf24ddd62483 --- /dev/null +++ b/cpp/benchmarks/ndsh/q07.cpp @@ -0,0 +1,174 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +[[nodiscard]] std::unique_ptr calculate_revenue( + cudf::column_view const& extendedprice, + cudf::column_view const& discount, + rmm::cuda_stream_view stream = cudf::get_default_stream(), + rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref()) +{ + auto const one = cudf::numeric_scalar(1); + auto const one_minus_discount = + cudf::binary_operation(one, discount, cudf::binary_operator::SUB, discount.type(), stream, mr); + return cudf::binary_operation(extendedprice, + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}, + stream, + mr); +} + +std::unordered_map> load_ndsh_q7( + std::unordered_map& sources) +{ + std::vector const lineitem_cols = { + "l_orderkey", "l_suppkey", "l_extendedprice", "l_discount", "l_shipdate"}; + auto const l_shipdate_ref = cudf::ast::column_reference(4); + auto l_shipdate_lower = + cudf::timestamp_scalar(days_since_epoch(1995, 1, 1), true); + auto const l_shipdate_lower_limit = cudf::ast::literal(l_shipdate_lower); + auto const l_shipdate_pred_lower = cudf::ast::operation( + cudf::ast::ast_operator::GREATER_EQUAL, l_shipdate_ref, l_shipdate_lower_limit); + auto l_shipdate_upper = + cudf::timestamp_scalar(days_since_epoch(1996, 12, 31), true); + auto const l_shipdate_upper_limit = cudf::ast::literal(l_shipdate_upper); + auto const l_shipdate_pred_upper = cudf::ast::operation( + cudf::ast::ast_operator::LESS_EQUAL, l_shipdate_ref, l_shipdate_upper_limit); + auto const lineitem_pred = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, l_shipdate_pred_lower, l_shipdate_pred_upper); + + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_nationkey"})); + tables.emplace( + "lineitem", + read_parquet( + sources.at("lineitem").make_source_info(), lineitem_cols, std::move(lineitem_pred))); + tables.emplace("nation", + read_parquet(sources.at("nation").make_source_info(), {"n_nationkey", "n_name"})); + tables.emplace( + "orders", read_parquet(sources.at("orders").make_source_info(), {"o_custkey", "o_orderkey"})); + tables.emplace( + "supplier", + read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_nationkey"})); + return tables; +} + +std::unique_ptr filter_nation(std::unique_ptr const& nation, + std::string const& name, + std::string const& name_column) +{ + auto name_value = cudf::string_scalar(name); + auto const name_ref = cudf::ast::column_reference(nation->column_id("n_name")); + auto const name_literal = cudf::ast::literal(name_value); + auto const predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, name_ref, name_literal); + auto const boolean_mask = cudf::compute_column(nation->table(), predicate); + auto filtered = cudf::apply_boolean_mask(nation->table(), boolean_mask->view()); + return std::make_unique(std::move(filtered), + std::vector{"n_nationkey", name_column}); +} + +std::unique_ptr make_shipping( + std::unordered_map> const& tables, + std::string const& customer_nation_name, + std::string const& supplier_nation_name) +{ + auto const& customer = tables.at("customer"); + auto const& lineitem = tables.at("lineitem"); + auto const& nation = tables.at("nation"); + auto const& orders = tables.at("orders"); + auto const& supplier = tables.at("supplier"); + + auto const customer_nation = filter_nation(nation, customer_nation_name, "cust_nation"); + auto const supplier_nation = filter_nation(nation, supplier_nation_name, "supp_nation"); + auto const customers = + apply_inner_join(customer, customer_nation, {"c_nationkey"}, {"n_nationkey"}); + auto const suppliers = + apply_inner_join(supplier, supplier_nation, {"s_nationkey"}, {"n_nationkey"}); + auto const items = apply_inner_join(orders, lineitem, {"o_orderkey"}, {"l_orderkey"}); + auto const customer_items = apply_inner_join(customers, items, {"c_custkey"}, {"o_custkey"}); + auto const joined = apply_inner_join(customer_items, suppliers, {"l_suppkey"}, {"s_suppkey"}); + + std::vector> columns; + columns.push_back(std::make_unique(joined->column("supp_nation"))); + columns.push_back(std::make_unique(joined->column("cust_nation"))); + columns.push_back(cudf::datetime::extract_datetime_component( + joined->column("l_shipdate"), cudf::datetime::datetime_component::YEAR)); + columns.push_back( + calculate_revenue(joined->column("l_extendedprice"), joined->column("l_discount"))); + return std::make_unique( + std::make_unique(std::move(columns)), + std::vector{"supp_nation", "cust_nation", "l_year", "volume"}); +} + +std::unique_ptr execute_ndsh_q7( + std::unordered_map> const& tables) +{ + auto const france_to_germany = make_shipping(tables, "GERMANY", "FRANCE"); + auto const germany_to_france = make_shipping(tables, "FRANCE", "GERMANY"); + std::array const shipping_views = {france_to_germany->table(), + germany_to_france->table()}; + auto shipping = std::make_unique(cudf::concatenate(shipping_views), + france_to_germany->column_names()); + auto const grouped = + apply_groupby(shipping, + groupby_context_t{{"supp_nation", "cust_nation", "l_year"}, + {{"volume", {{cudf::aggregation::Kind::SUM, "revenue"}}}}}); + return apply_orderby(grouped, + {"supp_nation", "cust_nation", "l_year"}, + {cudf::order::ASCENDING, cudf::order::ASCENDING, cudf::order::ASCENDING}); +} + +void ndsh_q7(nvbench::state& state) +{ + double const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources( + scale_factor, {"customer", "lineitem", "nation", "orders", "supplier"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q7(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q7(sources); + result = execute_ndsh_q7(input); + } else { + result = execute_ndsh_q7(tables); + } + }); + result->to_parquet("q7.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q7) + .set_name("ndsh_q7") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q08.cpp b/cpp/benchmarks/ndsh/q08.cpp new file mode 100644 index 000000000000..b35d4c93afec --- /dev/null +++ b/cpp/benchmarks/ndsh/q08.cpp @@ -0,0 +1,172 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q8( + std::unordered_map& sources) +{ + std::vector const orders_cols = {"o_orderkey", "o_custkey", "o_orderdate"}; + auto const orderdate_ref = cudf::ast::column_reference(2); + auto orderdate_lower = + cudf::timestamp_scalar(days_since_epoch(1995, 1, 1), true); + auto const orderdate_lower_literal = cudf::ast::literal(orderdate_lower); + auto orderdate_upper = + cudf::timestamp_scalar(days_since_epoch(1996, 12, 31), true); + auto const orderdate_upper_literal = cudf::ast::literal(orderdate_upper); + auto const orderdate_pred_lower = cudf::ast::operation( + cudf::ast::ast_operator::GREATER_EQUAL, orderdate_ref, orderdate_lower_literal); + auto const orderdate_pred_upper = cudf::ast::operation( + cudf::ast::ast_operator::LESS_EQUAL, orderdate_ref, orderdate_upper_literal); + auto const orders_pred = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, orderdate_pred_lower, orderdate_pred_upper); + + std::vector const part_cols = {"p_partkey", "p_type"}; + auto const part_type_ref = cudf::ast::column_reference(1); + auto part_type = cudf::string_scalar("ECONOMY ANODIZED STEEL"); + auto const part_type_literal = cudf::ast::literal(part_type); + auto const part_pred = std::make_unique( + cudf::ast::ast_operator::EQUAL, part_type_ref, part_type_literal); + + std::vector const region_cols = {"r_regionkey", "r_name"}; + auto const region_name_ref = cudf::ast::column_reference(1); + auto region_name = cudf::string_scalar("AMERICA"); + auto const region_name_literal = cudf::ast::literal(region_name); + auto const region_pred = std::make_unique( + cudf::ast::ast_operator::EQUAL, region_name_ref, region_name_literal); + + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_nationkey"})); + tables.emplace( + "lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_partkey", "l_suppkey", "l_orderkey", "l_extendedprice", "l_discount"})); + tables.emplace("nation", + read_parquet(sources.at("nation").make_source_info(), + {"n_nationkey", "n_regionkey", "n_name"})); + tables.emplace( + "orders", + read_parquet(sources.at("orders").make_source_info(), orders_cols, std::move(orders_pred))); + tables.emplace( + "part", read_parquet(sources.at("part").make_source_info(), part_cols, std::move(part_pred))); + tables.emplace( + "region", + read_parquet(sources.at("region").make_source_info(), region_cols, std::move(region_pred))); + tables.emplace( + "supplier", + read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_nationkey"})); + return tables; +} + +std::unique_ptr execute_ndsh_q8( + std::unordered_map> const& tables) +{ + auto const customer_nation = + apply_projection(tables.at("nation"), {"n_nationkey", "n_regionkey"}); + auto const supplier_nation = apply_projection(tables.at("nation"), {"n_nationkey", "n_name"}); + auto const america_nations = + apply_inner_join(customer_nation, tables.at("region"), {"n_regionkey"}, {"r_regionkey"}); + + auto const join_a = + apply_inner_join(tables.at("part"), tables.at("lineitem"), {"p_partkey"}, {"l_partkey"}); + auto const join_b = apply_inner_join(join_a, tables.at("supplier"), {"l_suppkey"}, {"s_suppkey"}); + auto const join_c = apply_inner_join(join_b, tables.at("orders"), {"l_orderkey"}, {"o_orderkey"}); + auto const join_d = apply_inner_join(join_c, tables.at("customer"), {"o_custkey"}, {"c_custkey"}); + auto const join_e = apply_inner_join(join_d, america_nations, {"c_nationkey"}, {"n_nationkey"}); + auto joined = apply_inner_join(join_e, supplier_nation, {"s_nationkey"}, {"n_nationkey"}); + + auto o_year = cudf::datetime::extract_datetime_component( + joined->column("o_orderdate"), cudf::datetime::datetime_component::YEAR); + auto const one = cudf::numeric_scalar(1); + auto const one_minus_discount = cudf::binary_operation(one, + joined->column("l_discount"), + cudf::binary_operator::SUB, + cudf::data_type{cudf::type_id::FLOAT64}); + auto volume = cudf::binary_operation(joined->column("l_extendedprice"), + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + + auto const nation_ref = cudf::ast::column_reference(joined->column_id("n_name")); + auto brazil = cudf::string_scalar("BRAZIL"); + auto const brazil_literal = cudf::ast::literal(brazil); + auto const brazil_pred = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, nation_ref, brazil_literal); + auto const brazil_mask = cudf::compute_column(joined->table(), brazil_pred); + auto const zero = cudf::numeric_scalar(0); + auto brazil_volume = cudf::copy_if_else(volume->view(), zero, brazil_mask->view()); + + joined->append(o_year, "o_year").append(volume, "volume").append(brazil_volume, "brazil_volume"); + auto const grouped = apply_groupby( + joined, + groupby_context_t{{"o_year"}, + {{"volume", {{cudf::aggregation::Kind::SUM, "volume"}}}, + {"brazil_volume", {{cudf::aggregation::Kind::SUM, "brazil_volume"}}}}}); + auto market_share = cudf::binary_operation(grouped->column("brazil_volume"), + grouped->column("volume"), + cudf::binary_operator::DIV, + cudf::data_type{cudf::type_id::FLOAT64}); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + auto rounded_market_share = cudf::round(market_share->view(), 2, cudf::rounding_method::HALF_UP); +#pragma GCC diagnostic pop + + std::vector> result_columns; + result_columns.push_back(std::make_unique(grouped->column("o_year"))); + result_columns.push_back(std::move(rounded_market_share)); + auto result = + std::make_unique(std::make_unique(std::move(result_columns)), + std::vector{"o_year", "mkt_share"}); + return apply_orderby(result, {"o_year"}, {cudf::order::ASCENDING}); +} + +void ndsh_q8(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources( + scale_factor, + {"customer", "lineitem", "nation", "orders", "part", "region", "supplier"}, + sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q8(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q8(sources); + result = execute_ndsh_q8(input); + } else { + result = execute_ndsh_q8(tables); + } + }); + result->to_parquet("q8.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q8) + .set_name("ndsh_q8") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q11.cpp b/cpp/benchmarks/ndsh/q11.cpp new file mode 100644 index 000000000000..f678eab0d6b7 --- /dev/null +++ b/cpp/benchmarks/ndsh/q11.cpp @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q11( + std::unordered_map& sources) +{ + std::vector const nation_columns = {"n_nationkey", "n_name"}; + auto const nation_name = cudf::ast::column_reference{1}; + auto germany = cudf::string_scalar{"GERMANY"}; + auto const germany_literal = cudf::ast::literal{germany}; + auto nation_filter = std::make_unique( + cudf::ast::ast_operator::EQUAL, nation_name, germany_literal); + + std::unordered_map> tables; + tables.emplace( + "nation", + read_parquet( + sources.at("nation").make_source_info(), nation_columns, std::move(nation_filter))); + tables.emplace("partsupp", + read_parquet(sources.at("partsupp").make_source_info(), + {"ps_suppkey", "ps_supplycost", "ps_availqty", "ps_partkey"})); + tables.emplace( + "supplier", + read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_nationkey"})); + return tables; +} + +std::unique_ptr execute_ndsh_q11( + std::unordered_map> const& tables, + double scale_factor) +{ + auto const partsupp_supplier = + apply_inner_join(tables.at("partsupp"), tables.at("supplier"), {"ps_suppkey"}, {"s_suppkey"}); + auto joined = + apply_inner_join(partsupp_supplier, tables.at("nation"), {"s_nationkey"}, {"n_nationkey"}); + + auto value = cudf::binary_operation(joined->column("ps_supplycost"), + joined->column("ps_availqty"), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + joined->append(value, "value"); + + auto const sum_aggregation = cudf::make_sum_aggregation(); + auto total = cudf::reduce( + joined->column("value"), *sum_aggregation, cudf::data_type{cudf::type_id::FLOAT64}); + auto total_column = cudf::make_column_from_scalar(*total, 1); + auto const threshold_factor = cudf::numeric_scalar{0.0001 / scale_factor}; + auto threshold_column = cudf::binary_operation(total_column->view(), + threshold_factor, + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + auto threshold = cudf::get_element(threshold_column->view(), 0); + + auto grouped = apply_groupby( + joined, + groupby_context_t{{"ps_partkey"}, {{"value", {{cudf::aggregation::Kind::SUM, "value"}}}}}); + auto mask = cudf::binary_operation(grouped->column("value"), + *threshold, + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto filtered = apply_mask(grouped, mask); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + auto rounded = cudf::round(filtered->column("value"), 2, cudf::rounding_method::HALF_UP); +#pragma GCC diagnostic pop + std::vector> columns; + columns.push_back(std::make_unique(filtered->column("ps_partkey"))); + columns.push_back(std::move(rounded)); + auto result = + std::make_unique(std::make_unique(std::move(columns)), + std::vector{"ps_partkey", "value"}); + return apply_orderby(result, {"value"}, {cudf::order::DESCENDING}); +} + +void ndsh_q11(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"nation", "partsupp", "supplier"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q11(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q11(sources); + result = execute_ndsh_q11(input, scale_factor); + } else { + result = execute_ndsh_q11(tables, scale_factor); + } + }); + result->to_parquet("q11.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q11) + .set_name("ndsh_q11") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q12.cpp b/cpp/benchmarks/ndsh/q12.cpp new file mode 100644 index 000000000000..54b444dc3dba --- /dev/null +++ b/cpp/benchmarks/ndsh/q12.cpp @@ -0,0 +1,154 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * @file q12.cpp + * @brief Implement query 12 of the NDS-H benchmark. + */ + +std::unordered_map> load_ndsh_q12( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace( + "lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_orderkey", "l_shipmode", "l_commitdate", "l_receiptdate", "l_shipdate"})); + tables.emplace( + "orders", + read_parquet(sources.at("orders").make_source_info(), {"o_orderkey", "o_orderpriority"})); + return tables; +} + +std::unique_ptr execute_ndsh_q12( + std::unordered_map> const& tables) +{ + auto const& lineitem = tables.at("lineitem"); + auto const& orders = tables.at("orders"); + + auto const shipmode_ref = cudf::ast::column_reference(lineitem->column_id("l_shipmode")); + auto const commit_ref = cudf::ast::column_reference(lineitem->column_id("l_commitdate")); + auto const receipt_ref = cudf::ast::column_reference(lineitem->column_id("l_receiptdate")); + auto const ship_ref = cudf::ast::column_reference(lineitem->column_id("l_shipdate")); + + auto mail = cudf::string_scalar("MAIL"); + auto ship = cudf::string_scalar("SHIP"); + auto const mail_literal = cudf::ast::literal(mail); + auto const ship_literal = cudf::ast::literal(ship); + auto const mail_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, shipmode_ref, mail_literal); + auto const ship_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, shipmode_ref, ship_literal); + auto const shipmode_predicate = + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, mail_predicate, ship_predicate); + + auto const commit_before_receipt = + cudf::ast::operation(cudf::ast::ast_operator::LESS, commit_ref, receipt_ref); + auto const ship_before_commit = + cudf::ast::operation(cudf::ast::ast_operator::LESS, ship_ref, commit_ref); + + auto receipt_lower = + cudf::timestamp_scalar(days_since_epoch(1994, 1, 1), true); + auto receipt_upper = + cudf::timestamp_scalar(days_since_epoch(1995, 1, 1), true); + auto const receipt_lower_literal = cudf::ast::literal(receipt_lower); + auto const receipt_upper_literal = cudf::ast::literal(receipt_upper); + auto const receipt_after_lower = cudf::ast::operation( + cudf::ast::ast_operator::GREATER_EQUAL, receipt_ref, receipt_lower_literal); + auto const receipt_before_upper = + cudf::ast::operation(cudf::ast::ast_operator::LESS, receipt_ref, receipt_upper_literal); + + auto const date_order_predicate = cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, commit_before_receipt, ship_before_commit); + auto const receipt_predicate = cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, receipt_after_lower, receipt_before_upper); + auto const date_predicate = cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, date_order_predicate, receipt_predicate); + auto const lineitem_predicate = + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_AND, shipmode_predicate, date_predicate); + auto const filtered_lineitem = apply_filter(lineitem, lineitem_predicate); + + auto joined = apply_inner_join(orders, filtered_lineitem, {"o_orderkey"}, {"l_orderkey"}); + auto const priority_ref = cudf::ast::column_reference(joined->column_id("o_orderpriority")); + auto urgent = cudf::string_scalar("1-URGENT"); + auto high = cudf::string_scalar("2-HIGH"); + auto const urgent_literal = cudf::ast::literal(urgent); + auto const high_literal = cudf::ast::literal(high); + auto const urgent_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, priority_ref, urgent_literal); + auto const high_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, priority_ref, high_literal); + auto const high_priority_predicate = + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, urgent_predicate, high_predicate); + auto const high_priority = cudf::compute_column(joined->table(), high_priority_predicate); + + auto const false_scalar = cudf::numeric_scalar{false}; + auto normalized_priority = cudf::replace_nulls(high_priority->view(), false_scalar); + auto not_high_priority = + cudf::unary_operation(normalized_priority->view(), cudf::unary_operator::NOT); + auto valid_priority = cudf::is_valid(joined->column("o_orderpriority")); + auto low_priority = cudf::binary_operation(not_high_priority->view(), + valid_priority->view(), + cudf::binary_operator::LOGICAL_AND, + cudf::data_type{cudf::type_id::BOOL8}); + auto const one = cudf::numeric_scalar(1); + auto const zero = cudf::numeric_scalar(0); + auto high_line_count = cudf::copy_if_else(one, zero, normalized_priority->view()); + auto low_line_count = cudf::copy_if_else(one, zero, low_priority->view()); + joined->append(high_line_count, "high_line_count").append(low_line_count, "low_line_count"); + + auto grouped = apply_groupby( + joined, + groupby_context_t{{"l_shipmode"}, + {{"high_line_count", {{cudf::aggregation::Kind::SUM, "high_line_count"}}}, + {"low_line_count", {{cudf::aggregation::Kind::SUM, "low_line_count"}}}}}); + auto projected = apply_projection(grouped, {"l_shipmode", "high_line_count", "low_line_count"}); + return apply_orderby(projected, {"l_shipmode"}, {cudf::order::ASCENDING}); +} + +void ndsh_q12(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "orders"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q12(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q12(sources); + result = execute_ndsh_q12(input); + } else { + result = execute_ndsh_q12(tables); + } + }); + result->to_parquet("q12.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q12) + .set_name("ndsh_q12") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q13.cpp b/cpp/benchmarks/ndsh/q13.cpp new file mode 100644 index 000000000000..a1852834142f --- /dev/null +++ b/cpp/benchmarks/ndsh/q13.cpp @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/** + * @file q13.cpp + * @brief Implement query 13 of the NDS-H benchmark. + * + * select + * c_count, + * count(*) as custdist + * from ( + * select + * c_custkey, + * count(o_orderkey) as c_count + * from customer left outer join orders on + * c_custkey = o_custkey + * and o_comment not like '%special%requests%' + * group by c_custkey + * ) as c_orders + * group by c_count + * order by custdist desc, c_count desc; + */ + +std::unordered_map> load_ndsh_q13( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace("customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey"})); + tables.emplace("orders", + read_parquet(sources.at("orders").make_source_info(), + {"o_custkey", "o_orderkey", "o_comment"})); + return tables; +} + +std::unique_ptr execute_ndsh_q13( + std::unordered_map> const& tables) +{ + auto const& customer = tables.at("customer"); + auto const& orders = tables.at("orders"); + + auto const program = cudf::strings::regex_program::create("special.*requests"); + auto matches = + cudf::strings::contains_re(cudf::strings_column_view{orders->column("o_comment")}, *program); + auto keep_orders = cudf::unary_operation(matches->view(), cudf::unary_operator::NOT); + auto const filtered_orders = apply_mask(orders, keep_orders); + + auto const joined = apply_left_join(customer, filtered_orders, {"c_custkey"}, {"o_custkey"}); + + cudf::groupby::groupby customer_groups(joined->select({"c_custkey"})); + std::vector requests(1); + requests[0].values = joined->column("o_orderkey"); + requests[0].aggregations.push_back( + cudf::make_count_aggregation(cudf::null_policy::EXCLUDE)); + auto [customer_keys, customer_counts] = customer_groups.aggregate(requests); + auto count_columns = customer_keys->release(); + count_columns.push_back(std::move(customer_counts[0].results[0])); + auto counts = + std::make_unique(std::make_unique(std::move(count_columns)), + std::vector{"c_custkey", "c_count"}); + + auto const distribution = apply_groupby( + counts, + groupby_context_t{{"c_count"}, + {{"c_custkey", {{cudf::aggregation::Kind::COUNT_ALL, "custdist"}}}}}); + return apply_orderby( + distribution, {"custdist", "c_count"}, {cudf::order::DESCENDING, cudf::order::DESCENDING}); +} + +void ndsh_q13(nvbench::state& state) +{ + double const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"customer", "orders"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q13(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q13(sources); + result = execute_ndsh_q13(input); + } else { + result = execute_ndsh_q13(tables); + } + }); + result->to_parquet("q13.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q13) + .set_name("ndsh_q13") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q14.cpp b/cpp/benchmarks/ndsh/q14.cpp new file mode 100644 index 000000000000..ad9c0f004564 --- /dev/null +++ b/cpp/benchmarks/ndsh/q14.cpp @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q14( + std::unordered_map& sources) +{ + std::vector const lineitem_columns = { + "l_partkey", "l_shipdate", "l_extendedprice", "l_discount"}; + auto const shipdate_ref = cudf::ast::column_reference{1}; + auto lower = cudf::timestamp_scalar(days_since_epoch(1995, 9, 1), true); + auto upper = cudf::timestamp_scalar(days_since_epoch(1995, 10, 1), true); + auto const lower_literal = cudf::ast::literal{lower}; + auto const upper_literal = cudf::ast::literal{upper}; + auto const after_lower = + cudf::ast::operation{cudf::ast::ast_operator::GREATER_EQUAL, shipdate_ref, lower_literal}; + auto const before_upper = + cudf::ast::operation{cudf::ast::ast_operator::LESS, shipdate_ref, upper_literal}; + auto shipdate_filter = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, after_lower, before_upper); + + std::unordered_map> tables; + tables.emplace( + "lineitem", + read_parquet( + sources.at("lineitem").make_source_info(), lineitem_columns, std::move(shipdate_filter))); + tables.emplace("part", + read_parquet(sources.at("part").make_source_info(), {"p_partkey", "p_type"})); + return tables; +} + +std::unique_ptr execute_ndsh_q14( + std::unordered_map> const& tables) +{ + auto const joined = + apply_inner_join(tables.at("lineitem"), tables.at("part"), {"l_partkey"}, {"p_partkey"}); + + auto const one = cudf::numeric_scalar{1}; + auto one_minus_discount = cudf::binary_operation(one, + joined->column("l_discount"), + cudf::binary_operator::SUB, + cudf::data_type{cudf::type_id::FLOAT64}); + auto revenue = cudf::binary_operation(joined->column("l_extendedprice"), + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + + auto promo = cudf::strings::starts_with(cudf::strings_column_view{joined->column("p_type")}, + cudf::string_scalar{"PROMO"}); + auto const zero = cudf::numeric_scalar{0}; + auto promo_revenue = cudf::copy_if_else(revenue->view(), zero, promo->view()); + auto const promo_total = + apply_reduction(promo_revenue->view(), cudf::aggregation::Kind::SUM, "promo_total"); + auto const revenue_total = + apply_reduction(revenue->view(), cudf::aggregation::Kind::SUM, "revenue_total"); + + auto const hundred = cudf::numeric_scalar{100}; + auto scaled_promo = cudf::binary_operation(promo_total->column("promo_total"), + hundred, + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + auto percentage = cudf::binary_operation(scaled_promo->view(), + revenue_total->column("revenue_total"), + cudf::binary_operator::DIV, + cudf::data_type{cudf::type_id::FLOAT64}); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + auto rounded = cudf::round(percentage->view(), 2, cudf::rounding_method::HALF_UP); +#pragma GCC diagnostic pop + + std::vector> result_columns; + result_columns.push_back(std::move(rounded)); + return std::make_unique( + std::make_unique(std::move(result_columns)), + std::vector{"promo_revenue"}); +} + +void ndsh_q14(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "part"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q14(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q14(sources); + result = execute_ndsh_q14(input); + } else { + result = execute_ndsh_q14(tables); + } + }); + result->to_parquet("q14.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q14) + .set_name("ndsh_q14") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q15.cpp b/cpp/benchmarks/ndsh/q15.cpp new file mode 100644 index 000000000000..2897501bb57a --- /dev/null +++ b/cpp/benchmarks/ndsh/q15.cpp @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q15( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_suppkey", "l_shipdate", "l_extendedprice", "l_discount"})); + tables.emplace("supplier", + read_parquet(sources.at("supplier").make_source_info(), + {"s_suppkey", "s_name", "s_address", "s_phone"})); + return tables; +} + +std::unique_ptr execute_ndsh_q15( + std::unordered_map> const& tables) +{ + auto const& lineitem = tables.at("lineitem"); + + auto const shipdate_ref = cudf::ast::column_reference(lineitem->column_id("l_shipdate")); + auto lower = cudf::timestamp_scalar(days_since_epoch(1996, 1, 1), true); + auto upper = cudf::timestamp_scalar(days_since_epoch(1996, 4, 1), true); + auto const lower_literal = cudf::ast::literal(lower); + auto const upper_literal = cudf::ast::literal(upper); + auto const after_lower = + cudf::ast::operation(cudf::ast::ast_operator::GREATER_EQUAL, shipdate_ref, lower_literal); + auto const before_upper = + cudf::ast::operation(cudf::ast::ast_operator::LESS, shipdate_ref, upper_literal); + auto const date_predicate = + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_AND, after_lower, before_upper); + auto filtered_lineitem = apply_filter(lineitem, date_predicate); + + auto const one = cudf::numeric_scalar(1); + auto one_minus_discount = cudf::binary_operation(one, + filtered_lineitem->column("l_discount"), + cudf::binary_operator::SUB, + cudf::data_type{cudf::type_id::FLOAT64}); + auto revenue = cudf::binary_operation(filtered_lineitem->column("l_extendedprice"), + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + filtered_lineitem->append(revenue, "revenue"); + auto const grouped = apply_groupby( + filtered_lineitem, + groupby_context_t{{"l_suppkey"}, + {{"revenue", {{cudf::aggregation::Kind::SUM, "total_revenue"}}}}}); + + auto const max_aggregation = cudf::make_max_aggregation(); + auto max_revenue = cudf::reduce( + grouped->column("total_revenue"), *max_aggregation, cudf::data_type{cudf::type_id::FLOAT64}); + auto max_mask = cudf::binary_operation(grouped->column("total_revenue"), + *max_revenue, + cudf::binary_operator::EQUAL, + cudf::data_type{cudf::type_id::BOOL8}); + auto const maximum_suppliers = apply_mask(grouped, max_mask); + auto const joined = + apply_inner_join(tables.at("supplier"), maximum_suppliers, {"s_suppkey"}, {"l_suppkey"}); + auto const selected = + apply_projection(joined, {"s_suppkey", "s_name", "s_address", "s_phone", "total_revenue"}); + return apply_orderby(selected, {"s_suppkey"}, {cudf::order::ASCENDING}); +} + +void ndsh_q15(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "supplier"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q15(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q15(sources); + result = execute_ndsh_q15(input); + } else { + result = execute_ndsh_q15(tables); + } + }); + result->to_parquet("q15.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q15) + .set_name("ndsh_q15") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q16.cpp b/cpp/benchmarks/ndsh/q16.cpp new file mode 100644 index 000000000000..51946aabfc54 --- /dev/null +++ b/cpp/benchmarks/ndsh/q16.cpp @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q16( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace("part", + read_parquet(sources.at("part").make_source_info(), + {"p_partkey", "p_brand", "p_type", "p_size"})); + tables.emplace( + "partsupp", + read_parquet(sources.at("partsupp").make_source_info(), {"ps_partkey", "ps_suppkey"})); + tables.emplace( + "supplier", + read_parquet(sources.at("supplier").make_source_info(), {"s_suppkey", "s_comment"})); + return tables; +} + +std::unique_ptr execute_ndsh_q16( + std::unordered_map> const& tables) +{ + auto const& part = tables.at("part"); + + auto const excluded_brand = cudf::string_scalar{"Brand#45"}; + auto brand_mask = cudf::binary_operation(part->column("p_brand"), + excluded_brand, + cudf::binary_operator::NOT_EQUAL, + cudf::data_type{cudf::type_id::BOOL8}); + + auto const excluded_type = cudf::string_scalar{"MEDIUM POLISHED"}; + auto excluded_type_mask = + cudf::strings::starts_with(cudf::strings_column_view{part->column("p_type")}, excluded_type); + auto type_mask = cudf::unary_operation(excluded_type_mask->view(), cudf::unary_operator::NOT); + + std::unique_ptr size_mask; + for (auto const size : {int8_t{49}, + int8_t{14}, + int8_t{23}, + int8_t{45}, + int8_t{19}, + int8_t{3}, + int8_t{36}, + int8_t{9}}) { + auto const value = cudf::numeric_scalar{size}; + auto match = cudf::binary_operation(part->column("p_size"), + value, + cudf::binary_operator::EQUAL, + cudf::data_type{cudf::type_id::BOOL8}); + if (size_mask) { + size_mask = cudf::binary_operation(size_mask->view(), + match->view(), + cudf::binary_operator::LOGICAL_OR, + cudf::data_type{cudf::type_id::BOOL8}); + } else { + size_mask = std::move(match); + } + } + + auto part_mask = cudf::binary_operation(brand_mask->view(), + type_mask->view(), + cudf::binary_operator::LOGICAL_AND, + cudf::data_type{cudf::type_id::BOOL8}); + part_mask = cudf::binary_operation(part_mask->view(), + size_mask->view(), + cudf::binary_operator::LOGICAL_AND, + cudf::data_type{cudf::type_id::BOOL8}); + auto const filtered_part = apply_mask(part, part_mask); + + auto const program = cudf::strings::regex_program::create("Customer.*Complaints"); + auto complaint_mask = cudf::strings::contains_re( + cudf::strings_column_view{tables.at("supplier")->column("s_comment")}, *program); + auto const complaint_suppliers = apply_mask(tables.at("supplier"), complaint_mask); + + auto const joined = + apply_inner_join(filtered_part, tables.at("partsupp"), {"p_partkey"}, {"ps_partkey"}); + auto const eligible = + apply_left_anti_join(joined, complaint_suppliers, {"ps_suppkey"}, {"s_suppkey"}); + auto const grouped = apply_groupby( + eligible, + groupby_context_t{{"p_brand", "p_type", "p_size"}, + {{"ps_suppkey", {{cudf::aggregation::Kind::NUNIQUE, "supplier_cnt"}}}}}); + return apply_orderby(grouped, + {"supplier_cnt", "p_brand", "p_type", "p_size"}, + {cudf::order::DESCENDING, + cudf::order::ASCENDING, + cudf::order::ASCENDING, + cudf::order::ASCENDING}); +} + +void ndsh_q16(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"part", "partsupp", "supplier"}, sources); + + auto const stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q16(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q16(sources); + result = execute_ndsh_q16(input); + } else { + result = execute_ndsh_q16(tables); + } + }); + result->to_parquet("q16.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q16) + .set_name("ndsh_q16") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q17.cpp b/cpp/benchmarks/ndsh/q17.cpp new file mode 100644 index 000000000000..a5ab7a0839eb --- /dev/null +++ b/cpp/benchmarks/ndsh/q17.cpp @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q17( + std::unordered_map& sources) +{ + std::vector const part_columns = {"p_partkey", "p_brand", "p_container"}; + auto const brand_ref = cudf::ast::column_reference{1}; + auto const container_ref = cudf::ast::column_reference{2}; + auto brand = cudf::string_scalar{"Brand#23"}; + auto container = cudf::string_scalar{"MED BOX"}; + auto const brand_literal = cudf::ast::literal{brand}; + auto const container_literal = cudf::ast::literal{container}; + auto const brand_predicate = + cudf::ast::operation{cudf::ast::ast_operator::EQUAL, brand_ref, brand_literal}; + auto const container_predicate = + cudf::ast::operation{cudf::ast::ast_operator::EQUAL, container_ref, container_literal}; + auto part_predicate = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, brand_predicate, container_predicate); + + std::unordered_map> tables; + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_partkey", "l_quantity", "l_extendedprice"})); + tables.emplace( + "part", + read_parquet(sources.at("part").make_source_info(), part_columns, std::move(part_predicate))); + return tables; +} + +std::unique_ptr execute_ndsh_q17( + std::unordered_map> const& tables) +{ + auto const joined = + apply_inner_join(tables.at("part"), tables.at("lineitem"), {"p_partkey"}, {"l_partkey"}); + auto grouped = apply_groupby( + joined, + groupby_context_t{{"p_partkey"}, + {{"l_quantity", {{cudf::aggregation::Kind::MEAN, "avg_quantity"}}}}}); + + auto const threshold_factor = cudf::numeric_scalar{0.2}; + auto threshold = cudf::binary_operation(grouped->column("avg_quantity"), + threshold_factor, + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + grouped->append(threshold, "quantity_threshold"); + auto const with_threshold = apply_inner_join(joined, grouped, {"p_partkey"}, {"p_partkey"}); + + auto mask = cudf::binary_operation(with_threshold->column("l_quantity"), + with_threshold->column("quantity_threshold"), + cudf::binary_operator::LESS, + cudf::data_type{cudf::type_id::BOOL8}); + auto const filtered = apply_mask(with_threshold, mask); + auto const total = + apply_reduction(filtered->column("l_extendedprice"), cudf::aggregation::Kind::SUM, "total"); + auto const seven = cudf::numeric_scalar{7.0}; + auto avg_yearly = cudf::binary_operation(total->column("total"), + seven, + cudf::binary_operator::DIV, + cudf::data_type{cudf::type_id::FLOAT64}); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + auto rounded = cudf::round(avg_yearly->view(), 2, cudf::rounding_method::HALF_UP); +#pragma GCC diagnostic pop + + std::vector> columns; + columns.push_back(std::move(rounded)); + return std::make_unique(std::make_unique(std::move(columns)), + std::vector{"avg_yearly"}); +} + +void ndsh_q17(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "part"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q17(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q17(sources); + result = execute_ndsh_q17(input); + } else { + result = execute_ndsh_q17(tables); + } + }); + result->to_parquet("q17.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q17) + .set_name("ndsh_q17") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q18.cpp b/cpp/benchmarks/ndsh/q18.cpp new file mode 100644 index 000000000000..c5cf77ecc5e3 --- /dev/null +++ b/cpp/benchmarks/ndsh/q18.cpp @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include + +#include + +std::unordered_map> load_ndsh_q18( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace("customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_name"})); + tables.emplace( + "lineitem", + read_parquet(sources.at("lineitem").make_source_info(), {"l_orderkey", "l_quantity"})); + tables.emplace("orders", + read_parquet(sources.at("orders").make_source_info(), + {"o_orderkey", "o_custkey", "o_orderdate", "o_totalprice"})); + return tables; +} + +std::unique_ptr execute_ndsh_q18( + std::unordered_map> const& tables) +{ + auto const quantity_by_order = apply_groupby( + tables.at("lineitem"), + groupby_context_t{{"l_orderkey"}, + {{"l_quantity", {{cudf::aggregation::Kind::SUM, "sum_quantity"}}}}}); + auto const threshold = cudf::numeric_scalar{300}; + auto mask = cudf::binary_operation(quantity_by_order->column("sum_quantity"), + threshold, + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const large_orders = apply_mask(quantity_by_order, mask); + + auto const qualifying_orders = + apply_left_semi_join(tables.at("orders"), large_orders, {"o_orderkey"}, {"l_orderkey"}); + auto const orders_lineitem = + apply_inner_join(qualifying_orders, tables.at("lineitem"), {"o_orderkey"}, {"l_orderkey"}); + auto const joined = + apply_inner_join(tables.at("customer"), orders_lineitem, {"c_custkey"}, {"o_custkey"}); + auto const grouped = apply_groupby( + joined, + groupby_context_t{{"c_name", "c_custkey", "o_orderkey", "o_orderdate", "o_totalprice"}, + {{"l_quantity", {{cudf::aggregation::Kind::SUM, "sum(l_quantity)"}}}}}); + auto const ordered = apply_orderby( + grouped, {"o_totalprice", "o_orderdate"}, {cudf::order::DESCENDING, cudf::order::ASCENDING}); + return apply_slice(ordered, 0, 100); +} + +void ndsh_q18(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"customer", "orders", "lineitem"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q18(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q18(sources); + result = execute_ndsh_q18(input); + } else { + result = execute_ndsh_q18(tables); + } + }); + result->to_parquet("q18.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q18) + .set_name("ndsh_q18") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q19.cpp b/cpp/benchmarks/ndsh/q19.cpp new file mode 100644 index 000000000000..5d8e05614090 --- /dev/null +++ b/cpp/benchmarks/ndsh/q19.cpp @@ -0,0 +1,184 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +/** + * @file q19.cpp + * @brief Implement query 19 of the NDS-H benchmark. + */ + +std::unordered_map> load_ndsh_q19( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_partkey", + "l_shipmode", + "l_shipinstruct", + "l_quantity", + "l_extendedprice", + "l_discount"})); + tables.emplace("part", + read_parquet(sources.at("part").make_source_info(), + {"p_partkey", "p_brand", "p_container", "p_size"})); + return tables; +} + +std::unique_ptr execute_ndsh_q19( + std::unordered_map> const& tables) +{ + auto const& lineitem = tables.at("lineitem"); + auto const& part = tables.at("part"); + + auto const shipmode_ref = cudf::ast::column_reference(lineitem->column_id("l_shipmode")); + auto const shipinstruct_ref = cudf::ast::column_reference(lineitem->column_id("l_shipinstruct")); + auto air = cudf::string_scalar("AIR"); + auto air_reg = cudf::string_scalar("AIR REG"); + auto deliver_in_person = cudf::string_scalar("DELIVER IN PERSON"); + auto const air_literal = cudf::ast::literal(air); + auto const air_reg_literal = cudf::ast::literal(air_reg); + auto const instruct_literal = cudf::ast::literal(deliver_in_person); + auto const air_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, shipmode_ref, air_literal); + auto const air_reg_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, shipmode_ref, air_reg_literal); + auto const shipmode_predicate = + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, air_predicate, air_reg_predicate); + auto const instruct_predicate = + cudf::ast::operation(cudf::ast::ast_operator::EQUAL, shipinstruct_ref, instruct_literal); + auto const shipping_predicate = cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, shipmode_predicate, instruct_predicate); + auto filtered_lineitem = apply_filter(lineitem, shipping_predicate); + + auto joined = apply_inner_join(part, filtered_lineitem, {"p_partkey"}, {"l_partkey"}); + auto const brand_ref = cudf::ast::column_reference(joined->column_id("p_brand")); + auto const container_ref = cudf::ast::column_reference(joined->column_id("p_container")); + auto const quantity_ref = cudf::ast::column_reference(joined->column_id("l_quantity")); + auto const size_ref = cudf::ast::column_reference(joined->column_id("p_size")); + + cudf::ast::tree tree; + std::vector> strings; + std::vector>> numbers; + auto equals = [&](cudf::ast::column_reference const& column, + std::string_view value) -> cudf::ast::expression const& { + strings.push_back(std::make_unique(value)); + auto& literal = tree.push(cudf::ast::literal(*strings.back())); + return tree.push(cudf::ast::operation(cudf::ast::ast_operator::EQUAL, column, literal)); + }; + auto between = [&](cudf::ast::column_reference const& column, + int8_t lower, + int8_t upper) -> cudf::ast::expression const& { + numbers.push_back(std::make_unique>(lower)); + auto& lower_literal = tree.push(cudf::ast::literal(*numbers.back())); + numbers.push_back(std::make_unique>(upper)); + auto& upper_literal = tree.push(cudf::ast::literal(*numbers.back())); + auto& lower_predicate = tree.push( + cudf::ast::operation(cudf::ast::ast_operator::GREATER_EQUAL, column, lower_literal)); + auto& upper_predicate = + tree.push(cudf::ast::operation(cudf::ast::ast_operator::LESS_EQUAL, column, upper_literal)); + return tree.push( + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_AND, lower_predicate, upper_predicate)); + }; + auto branch = [&](std::string_view brand, + std::array const& containers, + int8_t quantity_lower, + int8_t quantity_upper, + int8_t size_upper) -> cudf::ast::expression const& { + auto& brand_predicate = equals(brand_ref, brand); + auto& container0 = equals(container_ref, containers[0]); + auto& container1 = equals(container_ref, containers[1]); + auto& container2 = equals(container_ref, containers[2]); + auto& container3 = equals(container_ref, containers[3]); + auto& containers01 = + tree.push(cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, container0, container1)); + auto& containers23 = + tree.push(cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, container2, container3)); + auto& container_predicate = tree.push( + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, containers01, containers23)); + auto& quantity_predicate = between(quantity_ref, quantity_lower, quantity_upper); + auto& size_predicate = between(size_ref, int8_t{1}, size_upper); + auto& brand_container = tree.push(cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, brand_predicate, container_predicate)); + auto& quantity_size = tree.push(cudf::ast::operation( + cudf::ast::ast_operator::LOGICAL_AND, quantity_predicate, size_predicate)); + return tree.push( + cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_AND, brand_container, quantity_size)); + }; + + auto& branch1 = branch("Brand#12", {"SM CASE", "SM BOX", "SM PACK", "SM PKG"}, 1, 11, 5); + auto& branch2 = branch("Brand#23", {"MED BAG", "MED BOX", "MED PKG", "MED PACK"}, 10, 20, 10); + auto& branch3 = branch("Brand#34", {"LG CASE", "LG BOX", "LG PACK", "LG PKG"}, 20, 30, 15); + auto& branches12 = + tree.push(cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, branch1, branch2)); + auto& branches = + tree.push(cudf::ast::operation(cudf::ast::ast_operator::LOGICAL_OR, branches12, branch3)); + auto filtered = apply_filter(joined, branches); + + auto const one = cudf::numeric_scalar(1); + auto one_minus_discount = cudf::binary_operation(one, + filtered->column("l_discount"), + cudf::binary_operator::SUB, + cudf::data_type{cudf::type_id::FLOAT64}); + auto revenue = cudf::binary_operation(filtered->column("l_extendedprice"), + one_minus_discount->view(), + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + auto reduced = apply_reduction(revenue->view(), cudf::aggregation::Kind::SUM, "revenue"); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + auto rounded = cudf::round(reduced->column("revenue"), 2, cudf::rounding_method::HALF_UP); +#pragma GCC diagnostic pop + std::vector> result_columns; + result_columns.push_back(std::move(rounded)); + return std::make_unique( + std::make_unique(std::move(result_columns)), std::vector{"revenue"}); +} + +void ndsh_q19(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"lineitem", "part"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q19(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q19(sources); + result = execute_ndsh_q19(input); + } else { + result = execute_ndsh_q19(tables); + } + }); + result->to_parquet("q19.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q19) + .set_name("ndsh_q19") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q20.cpp b/cpp/benchmarks/ndsh/q20.cpp new file mode 100644 index 000000000000..0596dcc4d2a5 --- /dev/null +++ b/cpp/benchmarks/ndsh/q20.cpp @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q20( + std::unordered_map& sources) +{ + std::vector const lineitem_columns = { + "l_partkey", "l_suppkey", "l_quantity", "l_shipdate"}; + auto const shipdate = cudf::ast::column_reference{3}; + auto start = cudf::timestamp_scalar{days_since_epoch(1994, 1, 1), true}; + auto end = cudf::timestamp_scalar{days_since_epoch(1995, 1, 1), true}; + auto const start_literal = cudf::ast::literal{start}; + auto const end_literal = cudf::ast::literal{end}; + auto const after_start = + cudf::ast::operation{cudf::ast::ast_operator::GREATER_EQUAL, shipdate, start_literal}; + auto const before_end = + cudf::ast::operation{cudf::ast::ast_operator::LESS, shipdate, end_literal}; + auto lineitem_filter = std::make_unique( + cudf::ast::ast_operator::LOGICAL_AND, after_start, before_end); + + std::vector const nation_columns = {"n_nationkey", "n_name"}; + auto const nation_name = cudf::ast::column_reference{1}; + auto canada = cudf::string_scalar{"CANADA"}; + auto const canada_literal = cudf::ast::literal{canada}; + auto nation_filter = std::make_unique( + cudf::ast::ast_operator::EQUAL, nation_name, canada_literal); + + std::unordered_map> tables; + tables.emplace( + "lineitem", + read_parquet( + sources.at("lineitem").make_source_info(), lineitem_columns, std::move(lineitem_filter))); + tables.emplace( + "nation", + read_parquet( + sources.at("nation").make_source_info(), nation_columns, std::move(nation_filter))); + tables.emplace("part", + read_parquet(sources.at("part").make_source_info(), {"p_partkey", "p_name"})); + tables.emplace("partsupp", + read_parquet(sources.at("partsupp").make_source_info(), + {"ps_partkey", "ps_suppkey", "ps_availqty"})); + tables.emplace("supplier", + read_parquet(sources.at("supplier").make_source_info(), + {"s_suppkey", "s_nationkey", "s_name", "s_address"})); + return tables; +} + +std::unique_ptr execute_ndsh_q20( + std::unordered_map> const& tables) +{ + auto quantities = apply_groupby( + tables.at("lineitem"), + groupby_context_t{{"l_partkey", "l_suppkey"}, + {{"l_quantity", {{cudf::aggregation::Kind::SUM, "sum_quantity"}}}}}); + auto const half = cudf::numeric_scalar{0.5}; + auto threshold = cudf::binary_operation(quantities->column("sum_quantity"), + half, + cudf::binary_operator::MUL, + cudf::data_type{cudf::type_id::FLOAT64}); + quantities->append(threshold, "threshold"); + + auto const forest = cudf::string_scalar{"forest"}; + auto forest_mask = cudf::strings::starts_with( + cudf::strings_column_view{tables.at("part")->column("p_name")}, forest); + auto const forest_parts = + apply_distinct(apply_projection(apply_mask(tables.at("part"), forest_mask), {"p_partkey"})); + + auto const inventory = + apply_inner_join(forest_parts, tables.at("partsupp"), {"p_partkey"}, {"ps_partkey"}); + auto const inventory_quantity = apply_inner_join( + inventory, quantities, {"ps_suppkey", "p_partkey"}, {"l_suppkey", "l_partkey"}); + auto available = cudf::binary_operation(inventory_quantity->column("ps_availqty"), + inventory_quantity->column("threshold"), + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const eligible_suppliers = + apply_distinct(apply_projection(apply_mask(inventory_quantity, available), {"ps_suppkey"})); + + auto const canadian_suppliers = + apply_inner_join(tables.at("supplier"), tables.at("nation"), {"s_nationkey"}, {"n_nationkey"}); + auto const result = + apply_inner_join(eligible_suppliers, canadian_suppliers, {"ps_suppkey"}, {"s_suppkey"}); + return apply_orderby( + apply_projection(result, {"s_name", "s_address"}), {"s_name"}, {cudf::order::ASCENDING}); +} + +void ndsh_q20(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources( + scale_factor, {"lineitem", "nation", "part", "partsupp", "supplier"}, sources); + + auto stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q20(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q20(sources); + result = execute_ndsh_q20(input); + } else { + result = execute_ndsh_q20(tables); + } + }); + result->to_parquet("q20.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q20) + .set_name("ndsh_q20") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q21.cpp b/cpp/benchmarks/ndsh/q21.cpp new file mode 100644 index 000000000000..e6943421c682 --- /dev/null +++ b/cpp/benchmarks/ndsh/q21.cpp @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include + +#include + +std::unordered_map> load_ndsh_q21( + std::unordered_map& sources) +{ + std::vector const nation_columns = {"n_nationkey", "n_name"}; + auto const n_name_ref = cudf::ast::column_reference{1}; + auto saudi_arabia = cudf::string_scalar{"SAUDI ARABIA"}; + auto const saudi_arabia_literal = cudf::ast::literal{saudi_arabia}; + auto nation_predicate = std::make_unique( + cudf::ast::ast_operator::EQUAL, n_name_ref, saudi_arabia_literal); + + std::vector const orders_columns = {"o_orderkey", "o_orderstatus"}; + auto const o_orderstatus_ref = cudf::ast::column_reference{1}; + auto final_status = cudf::string_scalar{"F"}; + auto const final_status_literal = cudf::ast::literal{final_status}; + auto orders_predicate = std::make_unique( + cudf::ast::ast_operator::EQUAL, o_orderstatus_ref, final_status_literal); + + std::unordered_map> tables; + tables.emplace("lineitem", + read_parquet(sources.at("lineitem").make_source_info(), + {"l_orderkey", "l_suppkey", "l_receiptdate", "l_commitdate"})); + tables.emplace( + "nation", + read_parquet( + sources.at("nation").make_source_info(), nation_columns, std::move(nation_predicate))); + tables.emplace( + "orders", + read_parquet( + sources.at("orders").make_source_info(), orders_columns, std::move(orders_predicate))); + tables.emplace("supplier", + read_parquet(sources.at("supplier").make_source_info(), + {"s_suppkey", "s_nationkey", "s_name"})); + return tables; +} + +std::unique_ptr execute_ndsh_q21( + std::unordered_map> const& tables) +{ + auto const& lineitem = tables.at("lineitem"); + + auto const late_mask = cudf::binary_operation(lineitem->column("l_receiptdate"), + lineitem->column("l_commitdate"), + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const late_lineitem = apply_mask(lineitem, late_mask); + + auto const supplier_pairs = + apply_distinct(apply_projection(lineitem, {"l_orderkey", "l_suppkey"})); + auto const suppliers_per_order = apply_groupby( + supplier_pairs, + groupby_context_t{{"l_orderkey"}, + {{"l_suppkey", {{cudf::aggregation::Kind::COUNT_ALL, "supplier_count"}}}}}); + auto const one = cudf::numeric_scalar{1}; + auto const multiple_mask = cudf::binary_operation(suppliers_per_order->column("supplier_count"), + one, + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const multiple_orders = + apply_projection(apply_mask(suppliers_per_order, multiple_mask), {"l_orderkey"}); + + auto const late_supplier_pairs = + apply_distinct(apply_projection(late_lineitem, {"l_orderkey", "l_suppkey"})); + auto const late_suppliers_per_order = apply_groupby( + late_supplier_pairs, + groupby_context_t{{"l_orderkey"}, + {{"l_suppkey", {{cudf::aggregation::Kind::COUNT_ALL, "supplier_count"}}}}}); + auto const single_late_mask = + cudf::binary_operation(late_suppliers_per_order->column("supplier_count"), + one, + cudf::binary_operator::EQUAL, + cudf::data_type{cudf::type_id::BOOL8}); + auto const single_late_orders = + apply_projection(apply_mask(late_suppliers_per_order, single_late_mask), {"l_orderkey"}); + + auto const qualifying_late = + apply_left_semi_join(late_lineitem, multiple_orders, {"l_orderkey"}, {"l_orderkey"}); + auto const qualifying_lineitem = + apply_left_semi_join(qualifying_late, single_late_orders, {"l_orderkey"}, {"l_orderkey"}); + + auto const saudi_suppliers = + apply_inner_join(tables.at("supplier"), tables.at("nation"), {"s_nationkey"}, {"n_nationkey"}); + auto const supplier_lineitem = + apply_inner_join(qualifying_lineitem, saudi_suppliers, {"l_suppkey"}, {"s_suppkey"}); + auto const joined = + apply_inner_join(supplier_lineitem, tables.at("orders"), {"l_orderkey"}, {"o_orderkey"}); + + auto const grouped = apply_groupby( + joined, + groupby_context_t{{"s_name"}, + {{"l_orderkey", {{cudf::aggregation::Kind::COUNT_ALL, "numwait"}}}}}); + auto const ordered = apply_orderby( + grouped, {"numwait", "s_name"}, {cudf::order::DESCENDING, cudf::order::ASCENDING}); + return apply_slice(ordered, 0, 100); +} + +void ndsh_q21(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources( + scale_factor, {"lineitem", "nation", "orders", "supplier"}, sources); + + auto const stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q21(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q21(sources); + result = execute_ndsh_q21(input); + } else { + result = execute_ndsh_q21(tables); + } + }); + result->to_parquet("q21.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q21) + .set_name("ndsh_q21") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); diff --git a/cpp/benchmarks/ndsh/q22.cpp b/cpp/benchmarks/ndsh/q22.cpp new file mode 100644 index 000000000000..460e4de7544c --- /dev/null +++ b/cpp/benchmarks/ndsh/q22.cpp @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "utilities.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +std::unordered_map> load_ndsh_q22( + std::unordered_map& sources) +{ + std::unordered_map> tables; + tables.emplace( + "customer", + read_parquet(sources.at("customer").make_source_info(), {"c_custkey", "c_phone", "c_acctbal"})); + tables.emplace("orders", read_parquet(sources.at("orders").make_source_info(), {"o_custkey"})); + return tables; +} + +std::unique_ptr execute_ndsh_q22( + std::unordered_map> const& tables) +{ + auto customer = apply_projection(tables.at("customer"), {"c_custkey", "c_phone", "c_acctbal"}); + auto country_code = + cudf::strings::slice_strings(cudf::strings_column_view{customer->column("c_phone")}, + std::optional{0}, + std::optional{2}); + customer->append(country_code, "cntrycode"); + + auto const country_pattern = cudf::strings::regex_program::create("^(13|31|23|29|30|18|17)$"); + auto country_mask = cudf::strings::contains_re( + cudf::strings_column_view{customer->column("cntrycode")}, *country_pattern); + auto selected = apply_mask(customer, country_mask); + selected = apply_projection(selected, {"c_acctbal", "c_custkey", "cntrycode"}); + + auto const zero = cudf::numeric_scalar{0.0}; + auto positive_mask = cudf::binary_operation(selected->column("c_acctbal"), + zero, + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const positive = apply_mask(selected, positive_mask); + auto const mean = cudf::make_mean_aggregation(); + auto average = + cudf::reduce(positive->column("c_acctbal"), *mean, cudf::data_type{cudf::type_id::FLOAT64}); + + auto const without_orders = + apply_left_anti_join(selected, tables.at("orders"), {"c_custkey"}, {"o_custkey"}); + auto above_average_mask = cudf::binary_operation(without_orders->column("c_acctbal"), + *average, + cudf::binary_operator::GREATER, + cudf::data_type{cudf::type_id::BOOL8}); + auto const above_average = apply_mask(without_orders, above_average_mask); + + auto const grouped = + apply_groupby(above_average, + groupby_context_t{{"cntrycode"}, + {{"c_acctbal", + {{cudf::aggregation::Kind::COUNT_ALL, "numcust"}, + {cudf::aggregation::Kind::SUM, "totacctbal"}}}}}); + return apply_orderby(grouped, {"cntrycode"}, {cudf::order::ASCENDING}); +} + +void ndsh_q22(nvbench::state& state) +{ + auto const scale_factor = state.get_float64("scale_factor"); + auto const mode = query_mode_from_string(state.get_string("mode")); + std::unordered_map sources; + generate_parquet_data_sources(scale_factor, {"customer", "orders"}, sources); + + auto const stream = cudf::get_default_stream(); + state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); + auto const mem_stats_logger = cudf::memory_stats_logger(); + std::unordered_map> tables; + if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q22(sources); } + std::unique_ptr result; + state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q22(sources); + result = execute_ndsh_q22(input); + } else { + result = execute_ndsh_q22(tables); + } + }); + result->to_parquet("q22.parquet"); + state.add_buffer_size( + mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); +} + +NVBENCH_BENCH(ndsh_q22) + .set_name("ndsh_q22") + .add_string_axis("mode", {"end_to_end", "compute_only"}) + .add_float64_axis("scale_factor", {0.01, 0.1, 1}); From e6e50e4c5bb9d574088746343dc87b351c5533b3 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 18:54:36 +0000 Subject: [PATCH 04/15] Add smoke coverage for NDS-H benchmarks --- ci/run_cudf_benchmark_smoketests.sh | 8 ++- cpp/benchmarks/CMakeLists.txt | 23 ++++++++ .../ndsh_data_generator_test.cpp | 57 +++++++++++++++++++ cpp/benchmarks/ndsh/README.md | 6 +- 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 cpp/benchmarks/common/ndsh_data_generator/ndsh_data_generator_test.cpp diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index c9e9873a6f3d..7bc09a0b2e60 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -1,5 +1,5 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -euo pipefail @@ -27,7 +27,11 @@ for bench in *_NVBENCH; do if [[ -x "$bench" && -f "$bench" ]]; then start_time=$(date +%s) echo "Running $bench with --profile..." - "./$bench" --profile --devices 0 -q --rmm_mode cuda + args=(--profile --devices 0 -q --rmm_mode cuda) + if [[ "$bench" == NDSH_* ]]; then + args+=(--axis scale_factor=0.01) + fi + "./$bench" "${args[@]}" SUITEERROR=$? end_time=$(date +%s) duration=$((end_time - start_time)) diff --git a/cpp/benchmarks/CMakeLists.txt b/cpp/benchmarks/CMakeLists.txt index 7e8623543048..76c99b075ff7 100644 --- a/cpp/benchmarks/CMakeLists.txt +++ b/cpp/benchmarks/CMakeLists.txt @@ -55,6 +55,29 @@ target_include_directories( "$" ) +if(CUDF_BUILD_TESTS) + add_executable(NDSH_DATA_GENERATOR_TEST common/ndsh_data_generator/ndsh_data_generator_test.cpp) + set_target_properties( + NDSH_DATA_GENERATOR_TEST + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$" + INSTALL_RPATH "\$ORIGIN/../../../lib" + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED ON + ) + target_link_libraries( + NDSH_DATA_GENERATOR_TEST PRIVATE ndsh_data_generator cudf::cudftestutil_objects + $ + ) + rapids_cuda_set_runtime(NDSH_DATA_GENERATOR_TEST USE_STATIC ON) + rapids_test_add( + NAME NDSH_DATA_GENERATOR_TEST + COMMAND NDSH_DATA_GENERATOR_TEST + GPUS 1 + PERCENT 15 + INSTALL_COMPONENT_SET testing + ) +endif() + # ################################################################################################## # * compiler function ----------------------------------------------------------------------------- diff --git a/cpp/benchmarks/common/ndsh_data_generator/ndsh_data_generator_test.cpp b/cpp/benchmarks/common/ndsh_data_generator/ndsh_data_generator_test.cpp new file mode 100644 index 000000000000..932c39a20539 --- /dev/null +++ b/cpp/benchmarks/common/ndsh_data_generator/ndsh_data_generator_test.cpp @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ndsh_data_generator.hpp" + +#include + +#include +#include + +#include + +struct NDSHDataGeneratorTest : public cudf::test::BaseFixture {}; + +TEST_F(NDSHDataGeneratorTest, ScaleFactorPointZeroOne) +{ + constexpr double scale_factor = 0.01; + + auto [orders, lineitem, part] = cudf::datagen::generate_orders_lineitem_part(scale_factor); + auto partsupp = cudf::datagen::generate_partsupp(scale_factor); + auto supplier = cudf::datagen::generate_supplier(scale_factor); + auto customer = cudf::datagen::generate_customer(scale_factor); + auto nation = cudf::datagen::generate_nation(); + auto region = cudf::datagen::generate_region(); + + auto const expect_cardinality = + [](cudf::table const& table, cudf::size_type rows, cudf::size_type columns) { + EXPECT_EQ(table.num_rows(), rows); + EXPECT_EQ(table.num_columns(), columns); + }; + + expect_cardinality(*orders, 15'000, 9); + EXPECT_GE(lineitem->num_rows(), 15'000); + EXPECT_LE(lineitem->num_rows(), 105'000); + EXPECT_EQ(lineitem->num_columns(), 16); + expect_cardinality(*part, 2'000, 9); + expect_cardinality(*partsupp, 8'000, 5); + expect_cardinality(*supplier, 100, 7); + expect_cardinality(*customer, 1'500, 8); + expect_cardinality(*nation, 25, 4); + expect_cardinality(*region, 5, 3); + + auto const expect_supplier_key_range = [](cudf::column_view const& keys, + cudf::size_type supplier_rows) { + EXPECT_EQ(keys.null_count(), 0); + auto const [minimum, maximum] = cudf::minmax(keys); + auto const min_key = static_cast const*>(minimum.get()); + auto const max_key = static_cast const*>(maximum.get()); + EXPECT_GE(min_key->value(), 1); + EXPECT_LE(max_key->value(), supplier_rows); + }; + + expect_supplier_key_range(lineitem->view().column(2), supplier->num_rows()); + expect_supplier_key_range(partsupp->view().column(1), supplier->num_rows()); +} diff --git a/cpp/benchmarks/ndsh/README.md b/cpp/benchmarks/ndsh/README.md index 0a462e1684e5..25c92d5339e7 100644 --- a/cpp/benchmarks/ndsh/README.md +++ b/cpp/benchmarks/ndsh/README.md @@ -8,4 +8,8 @@ comply with the TPC-H Benchmarks. ## Current Status -For now, only Q1, Q5, Q6, Q9, and Q10 have been implemented +All 22 NDS-H queries are implemented. + +The standard benchmark modes are `end_to_end`, which includes Parquet reads and query execution, +and `compute_only`, which measures query execution using preloaded data. Q9 retains its additional +engine and expression variants. From 93dedb36e6d849aaeadbf2e954f7cdfff69feea9 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 19:17:44 +0000 Subject: [PATCH 05/15] Fix NDS-H benchmark iteration metrics --- cpp/benchmarks/ndsh/q01.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q02.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q03.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q04.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q05.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q06.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q07.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q08.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q10.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q11.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q12.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q13.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q14.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q15.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q16.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q17.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q18.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q19.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q20.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q21.cpp | 13 ++++++++++--- cpp/benchmarks/ndsh/q22.cpp | 13 ++++++++++--- 21 files changed, 210 insertions(+), 63 deletions(-) diff --git a/cpp/benchmarks/ndsh/q01.cpp b/cpp/benchmarks/ndsh/q01.cpp index 53ca1faa4abf..a97d32fe888a 100644 --- a/cpp/benchmarks/ndsh/q01.cpp +++ b/cpp/benchmarks/ndsh/q01.cpp @@ -180,10 +180,10 @@ void ndsh_q1(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); auto lineitem = mode == query_mode::COMPUTE_ONLY ? load_ndsh_q1(source) : nullptr; - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q1(source); result = execute_ndsh_q1(input); @@ -191,9 +191,16 @@ void ndsh_q1(nvbench::state& state) result = execute_ndsh_q1(lineitem); } }); - result->to_parquet("q1.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q1(source); + result = execute_ndsh_q1(input); + } else { + result = execute_ndsh_q1(lineitem); + } + result->to_parquet("q1.parquet"); } NVBENCH_BENCH(ndsh_q1) diff --git a/cpp/benchmarks/ndsh/q02.cpp b/cpp/benchmarks/ndsh/q02.cpp index e18a14be6a97..1187b3bb1ee7 100644 --- a/cpp/benchmarks/ndsh/q02.cpp +++ b/cpp/benchmarks/ndsh/q02.cpp @@ -92,11 +92,11 @@ void ndsh_q2(nvbench::state& state) auto const stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); auto data = mode == query_mode::COMPUTE_ONLY ? std::optional{load_ndsh_q2(sources)} : std::nullopt; - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q2(sources); result = execute_ndsh_q2(input); @@ -104,9 +104,16 @@ void ndsh_q2(nvbench::state& state) result = execute_ndsh_q2(*data); } }); - result->to_parquet("q2.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q2(sources); + result = execute_ndsh_q2(input); + } else { + result = execute_ndsh_q2(*data); + } + result->to_parquet("q2.parquet"); } NVBENCH_BENCH(ndsh_q2) diff --git a/cpp/benchmarks/ndsh/q03.cpp b/cpp/benchmarks/ndsh/q03.cpp index 4b208402f12f..50a3e063fe78 100644 --- a/cpp/benchmarks/ndsh/q03.cpp +++ b/cpp/benchmarks/ndsh/q03.cpp @@ -105,11 +105,11 @@ void ndsh_q3(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q3(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q3(sources); result = execute_ndsh_q3(input); @@ -117,9 +117,16 @@ void ndsh_q3(nvbench::state& state) result = execute_ndsh_q3(tables); } }); - result->to_parquet("q3.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q3(sources); + result = execute_ndsh_q3(input); + } else { + result = execute_ndsh_q3(tables); + } + result->to_parquet("q3.parquet"); } NVBENCH_BENCH(ndsh_q3) diff --git a/cpp/benchmarks/ndsh/q04.cpp b/cpp/benchmarks/ndsh/q04.cpp index 1dc8b7e194a2..b5414591f276 100644 --- a/cpp/benchmarks/ndsh/q04.cpp +++ b/cpp/benchmarks/ndsh/q04.cpp @@ -67,11 +67,11 @@ void ndsh_q4(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); q4_data data; if (mode == query_mode::COMPUTE_ONLY) { data = load_ndsh_q4(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q4(sources); result = execute_ndsh_q4(input); @@ -79,9 +79,16 @@ void ndsh_q4(nvbench::state& state) result = execute_ndsh_q4(data); } }); - result->to_parquet("q4.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q4(sources); + result = execute_ndsh_q4(input); + } else { + result = execute_ndsh_q4(data); + } + result->to_parquet("q4.parquet"); } NVBENCH_BENCH(ndsh_q4) diff --git a/cpp/benchmarks/ndsh/q05.cpp b/cpp/benchmarks/ndsh/q05.cpp index 3f69c3f17e98..4f04c81d62c6 100644 --- a/cpp/benchmarks/ndsh/q05.cpp +++ b/cpp/benchmarks/ndsh/q05.cpp @@ -178,11 +178,11 @@ void ndsh_q5(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q5(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q5(sources); result = execute_ndsh_q5(input); @@ -190,9 +190,16 @@ void ndsh_q5(nvbench::state& state) result = execute_ndsh_q5(tables); } }); - result->to_parquet("q5.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q5(sources); + result = execute_ndsh_q5(input); + } else { + result = execute_ndsh_q5(tables); + } + result->to_parquet("q5.parquet"); } NVBENCH_BENCH(ndsh_q5) diff --git a/cpp/benchmarks/ndsh/q06.cpp b/cpp/benchmarks/ndsh/q06.cpp index 7c3a5056721d..1509a554d864 100644 --- a/cpp/benchmarks/ndsh/q06.cpp +++ b/cpp/benchmarks/ndsh/q06.cpp @@ -134,10 +134,10 @@ void ndsh_q6(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); auto lineitem = mode == query_mode::COMPUTE_ONLY ? load_ndsh_q6(sources) : nullptr; - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q6(sources); result = execute_ndsh_q6(input); @@ -145,9 +145,16 @@ void ndsh_q6(nvbench::state& state) result = execute_ndsh_q6(lineitem); } }); - result->to_parquet("q6.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q6(sources); + result = execute_ndsh_q6(input); + } else { + result = execute_ndsh_q6(lineitem); + } + result->to_parquet("q6.parquet"); } NVBENCH_BENCH(ndsh_q6) diff --git a/cpp/benchmarks/ndsh/q07.cpp b/cpp/benchmarks/ndsh/q07.cpp index bf24ddd62483..c0ff022fe7cb 100644 --- a/cpp/benchmarks/ndsh/q07.cpp +++ b/cpp/benchmarks/ndsh/q07.cpp @@ -151,11 +151,11 @@ void ndsh_q7(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q7(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q7(sources); result = execute_ndsh_q7(input); @@ -163,9 +163,16 @@ void ndsh_q7(nvbench::state& state) result = execute_ndsh_q7(tables); } }); - result->to_parquet("q7.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q7(sources); + result = execute_ndsh_q7(input); + } else { + result = execute_ndsh_q7(tables); + } + result->to_parquet("q7.parquet"); } NVBENCH_BENCH(ndsh_q7) diff --git a/cpp/benchmarks/ndsh/q08.cpp b/cpp/benchmarks/ndsh/q08.cpp index b35d4c93afec..20f50c4d1d28 100644 --- a/cpp/benchmarks/ndsh/q08.cpp +++ b/cpp/benchmarks/ndsh/q08.cpp @@ -149,11 +149,11 @@ void ndsh_q8(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q8(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q8(sources); result = execute_ndsh_q8(input); @@ -161,9 +161,16 @@ void ndsh_q8(nvbench::state& state) result = execute_ndsh_q8(tables); } }); - result->to_parquet("q8.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q8(sources); + result = execute_ndsh_q8(input); + } else { + result = execute_ndsh_q8(tables); + } + result->to_parquet("q8.parquet"); } NVBENCH_BENCH(ndsh_q8) diff --git a/cpp/benchmarks/ndsh/q10.cpp b/cpp/benchmarks/ndsh/q10.cpp index bdc7331a8cd4..9b6cf03ca70f 100644 --- a/cpp/benchmarks/ndsh/q10.cpp +++ b/cpp/benchmarks/ndsh/q10.cpp @@ -172,11 +172,11 @@ void ndsh_q10(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q10(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q10(sources); result = execute_ndsh_q10(input); @@ -184,9 +184,16 @@ void ndsh_q10(nvbench::state& state) result = execute_ndsh_q10(tables); } }); - result->to_parquet("q10.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q10(sources); + result = execute_ndsh_q10(input); + } else { + result = execute_ndsh_q10(tables); + } + result->to_parquet("q10.parquet"); } NVBENCH_BENCH(ndsh_q10) diff --git a/cpp/benchmarks/ndsh/q11.cpp b/cpp/benchmarks/ndsh/q11.cpp index f678eab0d6b7..c993aec4f0a9 100644 --- a/cpp/benchmarks/ndsh/q11.cpp +++ b/cpp/benchmarks/ndsh/q11.cpp @@ -97,11 +97,11 @@ void ndsh_q11(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q11(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q11(sources); result = execute_ndsh_q11(input, scale_factor); @@ -109,9 +109,16 @@ void ndsh_q11(nvbench::state& state) result = execute_ndsh_q11(tables, scale_factor); } }); - result->to_parquet("q11.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q11(sources); + result = execute_ndsh_q11(input, scale_factor); + } else { + result = execute_ndsh_q11(tables, scale_factor); + } + result->to_parquet("q11.parquet"); } NVBENCH_BENCH(ndsh_q11) diff --git a/cpp/benchmarks/ndsh/q12.cpp b/cpp/benchmarks/ndsh/q12.cpp index 54b444dc3dba..0470d84dc054 100644 --- a/cpp/benchmarks/ndsh/q12.cpp +++ b/cpp/benchmarks/ndsh/q12.cpp @@ -131,11 +131,11 @@ void ndsh_q12(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q12(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q12(sources); result = execute_ndsh_q12(input); @@ -143,9 +143,16 @@ void ndsh_q12(nvbench::state& state) result = execute_ndsh_q12(tables); } }); - result->to_parquet("q12.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q12(sources); + result = execute_ndsh_q12(input); + } else { + result = execute_ndsh_q12(tables); + } + result->to_parquet("q12.parquet"); } NVBENCH_BENCH(ndsh_q12) diff --git a/cpp/benchmarks/ndsh/q13.cpp b/cpp/benchmarks/ndsh/q13.cpp index a1852834142f..feea1f4789ea 100644 --- a/cpp/benchmarks/ndsh/q13.cpp +++ b/cpp/benchmarks/ndsh/q13.cpp @@ -91,11 +91,11 @@ void ndsh_q13(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q13(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q13(sources); result = execute_ndsh_q13(input); @@ -103,9 +103,16 @@ void ndsh_q13(nvbench::state& state) result = execute_ndsh_q13(tables); } }); - result->to_parquet("q13.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q13(sources); + result = execute_ndsh_q13(input); + } else { + result = execute_ndsh_q13(tables); + } + result->to_parquet("q13.parquet"); } NVBENCH_BENCH(ndsh_q13) diff --git a/cpp/benchmarks/ndsh/q14.cpp b/cpp/benchmarks/ndsh/q14.cpp index ad9c0f004564..0ad2aa30a68a 100644 --- a/cpp/benchmarks/ndsh/q14.cpp +++ b/cpp/benchmarks/ndsh/q14.cpp @@ -99,11 +99,11 @@ void ndsh_q14(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q14(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q14(sources); result = execute_ndsh_q14(input); @@ -111,9 +111,16 @@ void ndsh_q14(nvbench::state& state) result = execute_ndsh_q14(tables); } }); - result->to_parquet("q14.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q14(sources); + result = execute_ndsh_q14(input); + } else { + result = execute_ndsh_q14(tables); + } + result->to_parquet("q14.parquet"); } NVBENCH_BENCH(ndsh_q14) diff --git a/cpp/benchmarks/ndsh/q15.cpp b/cpp/benchmarks/ndsh/q15.cpp index 2897501bb57a..b93af966d25a 100644 --- a/cpp/benchmarks/ndsh/q15.cpp +++ b/cpp/benchmarks/ndsh/q15.cpp @@ -84,11 +84,11 @@ void ndsh_q15(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q15(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q15(sources); result = execute_ndsh_q15(input); @@ -96,9 +96,16 @@ void ndsh_q15(nvbench::state& state) result = execute_ndsh_q15(tables); } }); - result->to_parquet("q15.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q15(sources); + result = execute_ndsh_q15(input); + } else { + result = execute_ndsh_q15(tables); + } + result->to_parquet("q15.parquet"); } NVBENCH_BENCH(ndsh_q15) diff --git a/cpp/benchmarks/ndsh/q16.cpp b/cpp/benchmarks/ndsh/q16.cpp index 51946aabfc54..0c2e3eaee2f1 100644 --- a/cpp/benchmarks/ndsh/q16.cpp +++ b/cpp/benchmarks/ndsh/q16.cpp @@ -113,11 +113,11 @@ void ndsh_q16(nvbench::state& state) auto const stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q16(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q16(sources); result = execute_ndsh_q16(input); @@ -125,9 +125,16 @@ void ndsh_q16(nvbench::state& state) result = execute_ndsh_q16(tables); } }); - result->to_parquet("q16.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q16(sources); + result = execute_ndsh_q16(input); + } else { + result = execute_ndsh_q16(tables); + } + result->to_parquet("q16.parquet"); } NVBENCH_BENCH(ndsh_q16) diff --git a/cpp/benchmarks/ndsh/q17.cpp b/cpp/benchmarks/ndsh/q17.cpp index a5ab7a0839eb..b97901b1ae29 100644 --- a/cpp/benchmarks/ndsh/q17.cpp +++ b/cpp/benchmarks/ndsh/q17.cpp @@ -91,11 +91,11 @@ void ndsh_q17(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q17(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q17(sources); result = execute_ndsh_q17(input); @@ -103,9 +103,16 @@ void ndsh_q17(nvbench::state& state) result = execute_ndsh_q17(tables); } }); - result->to_parquet("q17.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q17(sources); + result = execute_ndsh_q17(input); + } else { + result = execute_ndsh_q17(tables); + } + result->to_parquet("q17.parquet"); } NVBENCH_BENCH(ndsh_q17) diff --git a/cpp/benchmarks/ndsh/q18.cpp b/cpp/benchmarks/ndsh/q18.cpp index c5cf77ecc5e3..0f7997439169 100644 --- a/cpp/benchmarks/ndsh/q18.cpp +++ b/cpp/benchmarks/ndsh/q18.cpp @@ -65,11 +65,11 @@ void ndsh_q18(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q18(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q18(sources); result = execute_ndsh_q18(input); @@ -77,9 +77,16 @@ void ndsh_q18(nvbench::state& state) result = execute_ndsh_q18(tables); } }); - result->to_parquet("q18.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q18(sources); + result = execute_ndsh_q18(input); + } else { + result = execute_ndsh_q18(tables); + } + result->to_parquet("q18.parquet"); } NVBENCH_BENCH(ndsh_q18) diff --git a/cpp/benchmarks/ndsh/q19.cpp b/cpp/benchmarks/ndsh/q19.cpp index 5d8e05614090..d81164283fcc 100644 --- a/cpp/benchmarks/ndsh/q19.cpp +++ b/cpp/benchmarks/ndsh/q19.cpp @@ -161,11 +161,11 @@ void ndsh_q19(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q19(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q19(sources); result = execute_ndsh_q19(input); @@ -173,9 +173,16 @@ void ndsh_q19(nvbench::state& state) result = execute_ndsh_q19(tables); } }); - result->to_parquet("q19.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q19(sources); + result = execute_ndsh_q19(input); + } else { + result = execute_ndsh_q19(tables); + } + result->to_parquet("q19.parquet"); } NVBENCH_BENCH(ndsh_q19) diff --git a/cpp/benchmarks/ndsh/q20.cpp b/cpp/benchmarks/ndsh/q20.cpp index 0596dcc4d2a5..af07817e708e 100644 --- a/cpp/benchmarks/ndsh/q20.cpp +++ b/cpp/benchmarks/ndsh/q20.cpp @@ -108,11 +108,11 @@ void ndsh_q20(nvbench::state& state) auto stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q20(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q20(sources); result = execute_ndsh_q20(input); @@ -120,9 +120,16 @@ void ndsh_q20(nvbench::state& state) result = execute_ndsh_q20(tables); } }); - result->to_parquet("q20.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q20(sources); + result = execute_ndsh_q20(input); + } else { + result = execute_ndsh_q20(tables); + } + result->to_parquet("q20.parquet"); } NVBENCH_BENCH(ndsh_q20) diff --git a/cpp/benchmarks/ndsh/q21.cpp b/cpp/benchmarks/ndsh/q21.cpp index e6943421c682..f5a7e78fd4a8 100644 --- a/cpp/benchmarks/ndsh/q21.cpp +++ b/cpp/benchmarks/ndsh/q21.cpp @@ -118,11 +118,11 @@ void ndsh_q21(nvbench::state& state) auto const stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q21(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q21(sources); result = execute_ndsh_q21(input); @@ -130,9 +130,16 @@ void ndsh_q21(nvbench::state& state) result = execute_ndsh_q21(tables); } }); - result->to_parquet("q21.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q21(sources); + result = execute_ndsh_q21(input); + } else { + result = execute_ndsh_q21(tables); + } + result->to_parquet("q21.parquet"); } NVBENCH_BENCH(ndsh_q21) diff --git a/cpp/benchmarks/ndsh/q22.cpp b/cpp/benchmarks/ndsh/q22.cpp index 460e4de7544c..7c6ba7705b8f 100644 --- a/cpp/benchmarks/ndsh/q22.cpp +++ b/cpp/benchmarks/ndsh/q22.cpp @@ -82,11 +82,11 @@ void ndsh_q22(nvbench::state& state) auto const stream = cudf::get_default_stream(); state.set_cuda_stream(nvbench::make_cuda_stream_view(stream.value())); - auto const mem_stats_logger = cudf::memory_stats_logger(); std::unordered_map> tables; if (mode == query_mode::COMPUTE_ONLY) { tables = load_ndsh_q22(sources); } - std::unique_ptr result; + auto const mem_stats_logger = cudf::memory_stats_logger(); state.exec(nvbench::exec_tag::sync, [&](nvbench::launch&) { + std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q22(sources); result = execute_ndsh_q22(input); @@ -94,9 +94,16 @@ void ndsh_q22(nvbench::state& state) result = execute_ndsh_q22(tables); } }); - result->to_parquet("q22.parquet"); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + std::unique_ptr result; + if (mode == query_mode::END_TO_END) { + auto input = load_ndsh_q22(sources); + result = execute_ndsh_q22(input); + } else { + result = execute_ndsh_q22(tables); + } + result->to_parquet("q22.parquet"); } NVBENCH_BENCH(ndsh_q22) From 061caf4ac3e9cbc0056299de168c451d21fd3cca Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Tue, 11 Aug 2026 19:18:08 +0000 Subject: [PATCH 06/15] Install NDS-H generator test --- cpp/CMakeLists.txt | 4 ++++ cpp/tests/CMakeLists.txt | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 3066fdf32e77..719f83997d48 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1600,6 +1600,10 @@ if(CUDF_BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif() +if(CUDF_BUILD_TESTS) + rapids_test_install_relocatable(INSTALL_COMPONENT_SET testing DESTINATION bin/gtests/libcudf) +endif() + # ################################################################################################## # * install targets ------------------------------------------------------------------------------- rapids_cmake_install_lib_dir(lib_dir) diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 06c0462ebed9..c637b4a1aa98 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -863,8 +863,3 @@ ConfigureTest( ROARING_DISABLE_AVX=1 CROARING_COMPILER_SUPPORTS_AVX512=0 ) - -# ################################################################################################## -# Install tests #################################################################################### -# ################################################################################################## -rapids_test_install_relocatable(INSTALL_COMPONENT_SET testing DESTINATION bin/gtests/libcudf) From 499038769a73266aab7ec5d3f2e51dffb15c2f7c Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 02:21:37 +0000 Subject: [PATCH 07/15] Document NDS-H benchmark queries --- cpp/benchmarks/ndsh/q02.cpp | 50 +++++++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q03.cpp | 29 +++++++++++++++++++++ cpp/benchmarks/ndsh/q04.cpp | 27 ++++++++++++++++++++ cpp/benchmarks/ndsh/q07.cpp | 45 +++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q08.cpp | 45 +++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q11.cpp | 30 ++++++++++++++++++++++ cpp/benchmarks/ndsh/q12.cpp | 29 +++++++++++++++++++++ cpp/benchmarks/ndsh/q14.cpp | 19 ++++++++++++++ cpp/benchmarks/ndsh/q15.cpp | 37 +++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q16.cpp | 36 ++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q17.cpp | 23 +++++++++++++++++ cpp/benchmarks/ndsh/q18.cpp | 39 +++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q19.cpp | 36 ++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q20.cpp | 43 +++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q21.cpp | 46 ++++++++++++++++++++++++++++++++++ cpp/benchmarks/ndsh/q22.cpp | 42 +++++++++++++++++++++++++++++++ 16 files changed, 576 insertions(+) diff --git a/cpp/benchmarks/ndsh/q02.cpp b/cpp/benchmarks/ndsh/q02.cpp index 1187b3bb1ee7..3c1aabd118e5 100644 --- a/cpp/benchmarks/ndsh/q02.cpp +++ b/cpp/benchmarks/ndsh/q02.cpp @@ -16,6 +16,56 @@ #include +/** + * @file q02.cpp + * @brief Implement query 2 of the NDS-H benchmark. + * + * select + * s_acctbal, + * s_name, + * n_name, + * p_partkey, + * p_mfgr, + * s_address, + * s_phone, + * s_comment + * from + * part, + * supplier, + * partsupp, + * nation, + * region + * where + * p_partkey = ps_partkey + * and s_suppkey = ps_suppkey + * and p_size = 15 + * and p_type like '%BRASS' + * and s_nationkey = n_nationkey + * and n_regionkey = r_regionkey + * and r_name = 'EUROPE' + * and ps_supplycost = ( + * select + * min(ps_supplycost) + * from + * partsupp, + * supplier, + * nation, + * region + * where + * p_partkey = ps_partkey + * and s_suppkey = ps_suppkey + * and s_nationkey = n_nationkey + * and n_regionkey = r_regionkey + * and r_name = 'EUROPE' + * ) + * order by + * s_acctbal desc, + * n_name, + * s_name, + * p_partkey + * limit 100; + */ + struct q2_data { std::unique_ptr nation; std::unique_ptr part; diff --git a/cpp/benchmarks/ndsh/q03.cpp b/cpp/benchmarks/ndsh/q03.cpp index 50a3e063fe78..f1bf8302bd02 100644 --- a/cpp/benchmarks/ndsh/q03.cpp +++ b/cpp/benchmarks/ndsh/q03.cpp @@ -15,6 +15,35 @@ #include +/** + * @file q03.cpp + * @brief Implement query 3 of the NDS-H benchmark. + * + * select + * l_orderkey, + * sum(l_extendedprice * (1 - l_discount)) as revenue, + * o_orderdate, + * o_shippriority + * from + * customer, + * orders, + * lineitem + * where + * c_mktsegment = 'BUILDING' + * and c_custkey = o_custkey + * and l_orderkey = o_orderkey + * and o_orderdate < '1995-03-15' + * and l_shipdate > '1995-03-15' + * group by + * l_orderkey, + * o_orderdate, + * o_shippriority + * order by + * revenue desc, + * o_orderdate + * limit 10; + */ + [[nodiscard]] std::unique_ptr calculate_revenue( cudf::column_view const& extendedprice, cudf::column_view const& discount, diff --git a/cpp/benchmarks/ndsh/q04.cpp b/cpp/benchmarks/ndsh/q04.cpp index b5414591f276..ba10c83e556b 100644 --- a/cpp/benchmarks/ndsh/q04.cpp +++ b/cpp/benchmarks/ndsh/q04.cpp @@ -12,6 +12,33 @@ #include +/** + * @file q04.cpp + * @brief Implement query 4 of the NDS-H benchmark. + * + * select + * o_orderpriority, + * count(*) as order_count + * from + * orders + * where + * o_orderdate >= timestamp '1993-07-01' + * and o_orderdate < timestamp '1993-07-01' + interval '3' month + * and exists ( + * select + * * + * from + * lineitem + * where + * l_orderkey = o_orderkey + * and l_commitdate < l_receiptdate + * ) + * group by + * o_orderpriority + * order by + * o_orderpriority; + */ + struct q4_data { std::unique_ptr lineitem; std::unique_ptr orders; diff --git a/cpp/benchmarks/ndsh/q07.cpp b/cpp/benchmarks/ndsh/q07.cpp index c0ff022fe7cb..4301a4b37f9c 100644 --- a/cpp/benchmarks/ndsh/q07.cpp +++ b/cpp/benchmarks/ndsh/q07.cpp @@ -21,6 +21,51 @@ #include +/** + * @file q07.cpp + * @brief Implement query 7 of the NDS-H benchmark. + * + * select + * supp_nation, + * cust_nation, + * l_year, + * sum(volume) as revenue + * from + * ( + * select + * n1.n_name as supp_nation, + * n2.n_name as cust_nation, + * year(l_shipdate) as l_year, + * l_extendedprice * (1 - l_discount) as volume + * from + * supplier, + * lineitem, + * orders, + * customer, + * nation n1, + * nation n2 + * where + * s_suppkey = l_suppkey + * and o_orderkey = l_orderkey + * and c_custkey = o_custkey + * and s_nationkey = n1.n_nationkey + * and c_nationkey = n2.n_nationkey + * and ( + * (n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') + * or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE') + * ) + * and l_shipdate between timestamp '1995-01-01' and timestamp '1996-12-31' + * ) as shipping + * group by + * supp_nation, + * cust_nation, + * l_year + * order by + * supp_nation, + * cust_nation, + * l_year; + */ + [[nodiscard]] std::unique_ptr calculate_revenue( cudf::column_view const& extendedprice, cudf::column_view const& discount, diff --git a/cpp/benchmarks/ndsh/q08.cpp b/cpp/benchmarks/ndsh/q08.cpp index 20f50c4d1d28..ddf16ce6fa8b 100644 --- a/cpp/benchmarks/ndsh/q08.cpp +++ b/cpp/benchmarks/ndsh/q08.cpp @@ -18,6 +18,51 @@ #include +/** + * @file q08.cpp + * @brief Implement query 8 of the NDS-H benchmark. + * + * select + * o_year, + * round( + * sum(case + * when nation = 'BRAZIL' then volume + * else 0 + * end) / sum(volume) + * , 2) as mkt_share + * from + * ( + * select + * extract(year from o_orderdate) as o_year, + * l_extendedprice * (1 - l_discount) as volume, + * n2.n_name as nation + * from + * part, + * supplier, + * lineitem, + * orders, + * customer, + * nation n1, + * nation n2, + * region + * where + * p_partkey = l_partkey + * and s_suppkey = l_suppkey + * and l_orderkey = o_orderkey + * and o_custkey = c_custkey + * and c_nationkey = n1.n_nationkey + * and n1.n_regionkey = r_regionkey + * and r_name = 'AMERICA' + * and s_nationkey = n2.n_nationkey + * and o_orderdate between timestamp '1995-01-01' and timestamp '1996-12-31' + * and p_type = 'ECONOMY ANODIZED STEEL' + * ) as all_nations + * group by + * o_year + * order by + * o_year; + */ + std::unordered_map> load_ndsh_q8( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q11.cpp b/cpp/benchmarks/ndsh/q11.cpp index c993aec4f0a9..9bbcbda7544f 100644 --- a/cpp/benchmarks/ndsh/q11.cpp +++ b/cpp/benchmarks/ndsh/q11.cpp @@ -17,6 +17,36 @@ #include +/** + * @file q11.cpp + * @brief Implement query 11 of the NDS-H benchmark. + * + * select + * ps_partkey, + * round(sum(ps_supplycost * ps_availqty), 2) as value + * from + * partsupp, supplier, nation + * where + * ps_suppkey = s_suppkey + * and s_nationkey = n_nationkey + * and n_name = 'GERMANY' + * group by + * ps_partkey + * having + * sum(ps_supplycost * ps_availqty) > ( + * select + * sum(ps_supplycost * ps_availqty) * (0.0001 / scale_factor) + * from + * partsupp, supplier, nation + * where + * ps_suppkey = s_suppkey + * and s_nationkey = n_nationkey + * and n_name = 'GERMANY' + * ) + * order by + * value desc; + */ + std::unordered_map> load_ndsh_q11( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q12.cpp b/cpp/benchmarks/ndsh/q12.cpp index 0470d84dc054..f3d4936e3c0b 100644 --- a/cpp/benchmarks/ndsh/q12.cpp +++ b/cpp/benchmarks/ndsh/q12.cpp @@ -20,6 +20,35 @@ /** * @file q12.cpp * @brief Implement query 12 of the NDS-H benchmark. + * + * select + * l_shipmode, + * sum(case + * when o_orderpriority = '1-URGENT' + * or o_orderpriority = '2-HIGH' + * then 1 + * else 0 + * end) as high_line_count, + * sum(case + * when o_orderpriority <> '1-URGENT' + * and o_orderpriority <> '2-HIGH' + * then 1 + * else 0 + * end) as low_line_count + * from + * orders, + * lineitem + * where + * o_orderkey = l_orderkey + * and l_shipmode in ('MAIL', 'SHIP') + * and l_commitdate < l_receiptdate + * and l_shipdate < l_commitdate + * and l_receiptdate >= date '1994-01-01' + * and l_receiptdate < date '1994-01-01' + interval '1' year + * group by + * l_shipmode + * order by + * l_shipmode; */ std::unordered_map> load_ndsh_q12( diff --git a/cpp/benchmarks/ndsh/q14.cpp b/cpp/benchmarks/ndsh/q14.cpp index 0ad2aa30a68a..4ca72ebf9e79 100644 --- a/cpp/benchmarks/ndsh/q14.cpp +++ b/cpp/benchmarks/ndsh/q14.cpp @@ -17,6 +17,25 @@ #include +/** + * @file q14.cpp + * @brief Implement query 14 of the NDS-H benchmark. + * + * select + * round(100.00 * sum(case + * when p_type like 'PROMO%' + * then l_extendedprice * (1 - l_discount) + * else 0 + * end) / sum(l_extendedprice * (1 - l_discount)), 2) as promo_revenue + * from + * lineitem, + * part + * where + * l_partkey = p_partkey + * and l_shipdate >= date '1995-09-01' + * and l_shipdate < date '1995-09-01' + interval '1' month; + */ + std::unordered_map> load_ndsh_q14( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q15.cpp b/cpp/benchmarks/ndsh/q15.cpp index b93af966d25a..5764793d9507 100644 --- a/cpp/benchmarks/ndsh/q15.cpp +++ b/cpp/benchmarks/ndsh/q15.cpp @@ -14,6 +14,43 @@ #include +/** + * @file q15.cpp + * @brief Implement query 15 of the NDS-H benchmark. + * + * with revenue (supplier_no, total_revenue) as ( + * select + * l_suppkey, + * sum(l_extendedprice * (1 - l_discount)) + * from + * lineitem + * where + * l_shipdate >= date '1996-01-01' + * and l_shipdate < date '1996-01-01' + interval '3' month + * group by + * l_suppkey + * ) + * select + * s_suppkey, + * s_name, + * s_address, + * s_phone, + * total_revenue + * from + * supplier, + * revenue + * where + * s_suppkey = supplier_no + * and total_revenue = ( + * select + * max(total_revenue) + * from + * revenue + * ) + * order by + * s_suppkey; + */ + std::unordered_map> load_ndsh_q15( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q16.cpp b/cpp/benchmarks/ndsh/q16.cpp index 0c2e3eaee2f1..dfb47834acde 100644 --- a/cpp/benchmarks/ndsh/q16.cpp +++ b/cpp/benchmarks/ndsh/q16.cpp @@ -17,6 +17,42 @@ #include +/** + * @file q16.cpp + * @brief Implement query 16 of the NDS-H benchmark. + * + * select + * p_brand, + * p_type, + * p_size, + * count(distinct ps_suppkey) as supplier_cnt + * from + * partsupp, + * part + * where + * p_partkey = ps_partkey + * and p_brand <> 'Brand#45' + * and p_type not like 'MEDIUM POLISHED%' + * and p_size in (49, 14, 23, 45, 19, 3, 36, 9) + * and ps_suppkey not in ( + * select + * s_suppkey + * from + * supplier + * where + * s_comment like '%Customer%Complaints%' + * ) + * group by + * p_brand, + * p_type, + * p_size + * order by + * supplier_cnt desc, + * p_brand, + * p_type, + * p_size; + */ + std::unordered_map> load_ndsh_q16( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q17.cpp b/cpp/benchmarks/ndsh/q17.cpp index b97901b1ae29..2f34dae4cec4 100644 --- a/cpp/benchmarks/ndsh/q17.cpp +++ b/cpp/benchmarks/ndsh/q17.cpp @@ -14,6 +14,29 @@ #include +/** + * @file q17.cpp + * @brief Implement query 17 of the NDS-H benchmark. + * + * select + * round(sum(l_extendedprice) / 7.0, 2) as avg_yearly + * from + * lineitem, + * part + * where + * p_partkey = l_partkey + * and p_brand = 'Brand#23' + * and p_container = 'MED BOX' + * and l_quantity < ( + * select + * 0.2 * avg(l_quantity) + * from + * lineitem + * where + * l_partkey = p_partkey + * ); + */ + std::unordered_map> load_ndsh_q17( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q18.cpp b/cpp/benchmarks/ndsh/q18.cpp index 0f7997439169..6c9b3ec31778 100644 --- a/cpp/benchmarks/ndsh/q18.cpp +++ b/cpp/benchmarks/ndsh/q18.cpp @@ -12,6 +12,45 @@ #include +/** + * @file q18.cpp + * @brief Implement query 18 of the NDS-H benchmark. + * + * select + * c_name, + * c_custkey, + * o_orderkey, + * o_orderdate, + * o_totalprice, + * sum(l_quantity) + * from + * customer, + * orders, + * lineitem + * where + * o_orderkey in ( + * select + * l_orderkey + * from + * lineitem + * group by + * l_orderkey having + * sum(l_quantity) > 300 + * ) + * and c_custkey = o_custkey + * and o_orderkey = l_orderkey + * group by + * c_name, + * c_custkey, + * o_orderkey, + * o_orderdate, + * o_totalprice + * order by + * o_totalprice desc, + * o_orderdate + * limit 100; + */ + std::unordered_map> load_ndsh_q18( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q19.cpp b/cpp/benchmarks/ndsh/q19.cpp index d81164283fcc..00c4ee6f29dd 100644 --- a/cpp/benchmarks/ndsh/q19.cpp +++ b/cpp/benchmarks/ndsh/q19.cpp @@ -22,6 +22,42 @@ /** * @file q19.cpp * @brief Implement query 19 of the NDS-H benchmark. + * + * select + * round(sum(l_extendedprice* (1 - l_discount)), 2) as revenue + * from + * lineitem, + * part + * where + * ( + * p_partkey = l_partkey + * and p_brand = 'Brand#12' + * and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') + * and l_quantity >= 1 and l_quantity <= 1 + 10 + * and p_size between 1 and 5 + * and l_shipmode in ('AIR', 'AIR REG') + * and l_shipinstruct = 'DELIVER IN PERSON' + * ) + * or + * ( + * p_partkey = l_partkey + * and p_brand = 'Brand#23' + * and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') + * and l_quantity >= 10 and l_quantity <= 20 + * and p_size between 1 and 10 + * and l_shipmode in ('AIR', 'AIR REG') + * and l_shipinstruct = 'DELIVER IN PERSON' + * ); + * or + * ( + * p_partkey = l_partkey + * and p_brand = 'Brand#34' + * and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') + * and l_quantity >= 20 and l_quantity <= 30 + * and p_size between 1 and 15 + * and l_shipmode in ('AIR', 'AIR REG') + * and l_shipinstruct = 'DELIVER IN PERSON' + * ) */ std::unordered_map> load_ndsh_q19( diff --git a/cpp/benchmarks/ndsh/q20.cpp b/cpp/benchmarks/ndsh/q20.cpp index af07817e708e..e1687786e5e3 100644 --- a/cpp/benchmarks/ndsh/q20.cpp +++ b/cpp/benchmarks/ndsh/q20.cpp @@ -15,6 +15,49 @@ #include +/** + * @file q20.cpp + * @brief Implement query 20 of the NDS-H benchmark. + * + * select + * s_name, + * s_address + * from + * supplier, + * nation + * where + * s_suppkey in ( + * select + * ps_suppkey + * from + * partsupp + * where + * ps_partkey in ( + * select + * p_partkey + * from + * part + * where + * p_name like 'forest%' + * ) + * and ps_availqty > ( + * select + * 0.5 * sum(l_quantity) + * from + * lineitem + * where + * l_partkey = ps_partkey + * and l_suppkey = ps_suppkey + * and l_shipdate >= date '1994-01-01' + * and l_shipdate < date '1994-01-01' + interval '1' year + * ) + * ) + * and s_nationkey = n_nationkey + * and n_name = 'CANADA' + * order by + * s_name; + */ + std::unordered_map> load_ndsh_q20( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q21.cpp b/cpp/benchmarks/ndsh/q21.cpp index f5a7e78fd4a8..43d969b9c660 100644 --- a/cpp/benchmarks/ndsh/q21.cpp +++ b/cpp/benchmarks/ndsh/q21.cpp @@ -13,6 +13,52 @@ #include +/** + * @file q21.cpp + * @brief Implement query 21 of the NDS-H benchmark. + * + * select + * s_name, + * count(*) as numwait + * from + * supplier, + * lineitem l1, + * orders, + * nation + * where + * s_suppkey = l1.l_suppkey + * and o_orderkey = l1.l_orderkey + * and o_orderstatus = 'F' + * and l1.l_receiptdate > l1.l_commitdate + * and exists ( + * select + * * + * from + * lineitem l2 + * where + * l2.l_orderkey = l1.l_orderkey + * and l2.l_suppkey <> l1.l_suppkey + * ) + * and not exists ( + * select + * * + * from + * lineitem l3 + * where + * l3.l_orderkey = l1.l_orderkey + * and l3.l_suppkey <> l1.l_suppkey + * and l3.l_receiptdate > l3.l_commitdate + * ) + * and s_nationkey = n_nationkey + * and n_name = 'SAUDI ARABIA' + * group by + * s_name + * order by + * numwait desc, + * s_name + * limit 100; + */ + std::unordered_map> load_ndsh_q21( std::unordered_map& sources) { diff --git a/cpp/benchmarks/ndsh/q22.cpp b/cpp/benchmarks/ndsh/q22.cpp index 7c6ba7705b8f..878f71010bdb 100644 --- a/cpp/benchmarks/ndsh/q22.cpp +++ b/cpp/benchmarks/ndsh/q22.cpp @@ -19,6 +19,48 @@ #include +/** + * @file q22.cpp + * @brief Implement query 22 of the NDS-H benchmark. + * + * select + * cntrycode, + * count(*) as numcust, + * sum(c_acctbal) as totacctbal + * from ( + * select + * substring(c_phone from 1 for 2) as cntrycode, + * c_acctbal + * from + * customer + * where + * substring(c_phone from 1 for 2) in + * (13, 31, 23, 29, 30, 18, 17) + * and c_acctbal > ( + * select + * avg(c_acctbal) + * from + * customer + * where + * c_acctbal > 0.00 + * and substring (c_phone from 1 for 2) in + * (13, 31, 23, 29, 30, 18, 17) + * ) + * and not exists ( + * select + * * + * from + * orders + * where + * o_custkey = c_custkey + * ) + * ) as custsale + * group by + * cntrycode + * order by + * cntrycode; + */ + std::unordered_map> load_ndsh_q22( std::unordered_map& sources) { From dc8bbca7f254c3aa7dc08a3a72d455d92eac85b9 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 02:54:02 +0000 Subject: [PATCH 08/15] Fix NDS-H query result semantics --- cpp/benchmarks/ndsh/q01.cpp | 17 ++++++++++++++--- cpp/benchmarks/ndsh/q06.cpp | 19 +++++-------------- cpp/benchmarks/ndsh/q10.cpp | 9 +++++++-- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/cpp/benchmarks/ndsh/q01.cpp b/cpp/benchmarks/ndsh/q01.cpp index a97d32fe888a..08213eeb5527 100644 --- a/cpp/benchmarks/ndsh/q01.cpp +++ b/cpp/benchmarks/ndsh/q01.cpp @@ -153,10 +153,21 @@ std::unique_ptr execute_ndsh_q1(std::unique_ptr #include #include -#include #include #include @@ -83,23 +82,15 @@ std::unique_ptr execute_ndsh_q6(std::unique_ptr(std::make_unique(input->table()), input->column_names()); - // Cast the discount and quantity columns to float32 and append to lineitem table - auto discout_float = - cudf::cast(lineitem->column("l_discount"), cudf::data_type{cudf::type_id::FLOAT32}); - auto quantity_float = - cudf::cast(lineitem->column("l_quantity"), cudf::data_type{cudf::type_id::FLOAT32}); - - (*lineitem).append(discout_float, "l_discount_float").append(quantity_float, "l_quantity_float"); - // Apply the filters - auto const discount_ref = cudf::ast::column_reference(lineitem->column_id("l_discount_float")); - auto const quantity_ref = cudf::ast::column_reference(lineitem->column_id("l_quantity_float")); + auto const discount_ref = cudf::ast::column_reference(lineitem->column_id("l_discount")); + auto const quantity_ref = cudf::ast::column_reference(lineitem->column_id("l_quantity")); - auto discount_lower = cudf::numeric_scalar(0.05); + auto discount_lower = cudf::numeric_scalar(0.05); auto const discount_lower_literal = cudf::ast::literal(discount_lower); - auto discount_upper = cudf::numeric_scalar(0.07); + auto discount_upper = cudf::numeric_scalar(0.07); auto const discount_upper_literal = cudf::ast::literal(discount_upper); - auto quantity_upper = cudf::numeric_scalar(24); + auto quantity_upper = cudf::numeric_scalar(24); auto const quantity_upper_literal = cudf::ast::literal(quantity_upper); auto const discount_pred_a = cudf::ast::operation( diff --git a/cpp/benchmarks/ndsh/q10.cpp b/cpp/benchmarks/ndsh/q10.cpp index 9b6cf03ca70f..ba568028df53 100644 --- a/cpp/benchmarks/ndsh/q10.cpp +++ b/cpp/benchmarks/ndsh/q10.cpp @@ -54,7 +54,8 @@ * c_address, * c_comment * order by - * revenue desc; + * revenue desc + * limit 20; */ /** @@ -156,9 +157,13 @@ std::unique_ptr execute_ndsh_q10( { {"revenue", {{cudf::aggregation::Kind::SUM, "revenue"}}}, }}); + auto const projected = apply_projection( + groupedby_table, + {"c_custkey", "c_name", "revenue", "c_acctbal", "n_name", "c_address", "c_phone", "c_comment"}); // Perform the order by operation - return apply_orderby(groupedby_table, {"revenue"}, {cudf::order::DESCENDING}); + auto const ordered = apply_orderby(projected, {"revenue"}, {cudf::order::DESCENDING}); + return apply_slice(ordered, 0, 20); } void ndsh_q10(nvbench::state& state) From cab2af8ba55dfd86eeeb3bfe2dbbc314cc915552 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:20:52 +0000 Subject: [PATCH 09/15] Validate NDS-H benchmark results with DuckDB --- ci/run_cudf_benchmark_smoketests.sh | 11 +++ ci/validate_ndsh_benchmarks.py | 99 +++++++++++++++++++ .../all_cuda-129_arch-aarch64.yaml | 1 + .../all_cuda-129_arch-x86_64.yaml | 1 + .../all_cuda-133_arch-aarch64.yaml | 1 + .../all_cuda-133_arch-x86_64.yaml | 1 + cpp/benchmarks/fixture/nvbench_fixture.hpp | 10 +- cpp/benchmarks/fixture/nvbench_main.cpp | 7 +- cpp/benchmarks/ndsh/README.md | 4 + cpp/benchmarks/ndsh/q01.cpp | 3 +- cpp/benchmarks/ndsh/q02.cpp | 3 +- cpp/benchmarks/ndsh/q03.cpp | 3 +- cpp/benchmarks/ndsh/q04.cpp | 3 +- cpp/benchmarks/ndsh/q05.cpp | 3 +- cpp/benchmarks/ndsh/q06.cpp | 3 +- cpp/benchmarks/ndsh/q07.cpp | 3 +- cpp/benchmarks/ndsh/q08.cpp | 3 +- cpp/benchmarks/ndsh/q09.cpp | 7 +- cpp/benchmarks/ndsh/q10.cpp | 3 +- cpp/benchmarks/ndsh/q11.cpp | 3 +- cpp/benchmarks/ndsh/q12.cpp | 3 +- cpp/benchmarks/ndsh/q13.cpp | 3 +- cpp/benchmarks/ndsh/q14.cpp | 3 +- cpp/benchmarks/ndsh/q15.cpp | 3 +- cpp/benchmarks/ndsh/q16.cpp | 3 +- cpp/benchmarks/ndsh/q17.cpp | 3 +- cpp/benchmarks/ndsh/q18.cpp | 3 +- cpp/benchmarks/ndsh/q19.cpp | 3 +- cpp/benchmarks/ndsh/q20.cpp | 3 +- cpp/benchmarks/ndsh/q21.cpp | 3 +- cpp/benchmarks/ndsh/q22.cpp | 3 +- cpp/benchmarks/ndsh/utilities.cpp | 26 +++++ cpp/benchmarks/ndsh/utilities.hpp | 4 + dependencies.yaml | 1 + 34 files changed, 208 insertions(+), 28 deletions(-) create mode 100644 ci/validate_ndsh_benchmarks.py diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index 7bc09a0b2e60..fa6045b708b8 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -4,6 +4,8 @@ set -euo pipefail +repo_root="$(dirname "$(realpath "${BASH_SOURCE[0]}")")/.." + # Support customizing the benchmarks' install location # First, try the installed location (CI/conda environments) installed_benchmark_location="${INSTALL_PREFIX:-${CONDA_PREFIX:-/usr}}/bin/benchmarks/libcudf/" @@ -22,6 +24,8 @@ else fi EXITCODE=0 +validation_dir="$(mktemp -d)" +trap 'rm -rf "${validation_dir}"' EXIT # Run all nvbench benchmarks with --profile and rmm_mode=cuda for bench in *_NVBENCH; do if [[ -x "$bench" && -f "$bench" ]]; then @@ -30,6 +34,9 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) + if [[ "$bench" =~ ^NDSH_Q(01|03|04|09|17|18|21)_NVBENCH$ ]]; then + args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") + fi fi "./$bench" "${args[@]}" SUITEERROR=$? @@ -44,5 +51,9 @@ for bench in *_NVBENCH; do fi done +python "${repo_root}/ci/validate_ndsh_benchmarks.py" \ + --output-dir "${validation_dir}" \ + --sql-dir "${repo_root}/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql" + echo "Test script exiting with value: $EXITCODE" exit ${EXITCODE} diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py new file mode 100644 index 000000000000..236a40fd9840 --- /dev/null +++ b/ci/validate_ndsh_benchmarks.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import math +import numbers +from pathlib import Path + +import duckdb + +QUERIES = ("q01", "q03", "q04", "q09", "q17", "q18", "q21") +EXPECTED_NAMES = { + "q18": [ + "c_name", + "c_custkey", + "o_orderkey", + "o_orderdate", + "o_totalprice", + "sum(l_quantity)", + ] +} + + +def values_equal(actual, expected): + if actual is None or expected is None: + return actual is expected + if isinstance(actual, numbers.Number) and isinstance( + expected, numbers.Number + ): + return math.isclose( + float(actual), float(expected), rel_tol=0.0, abs_tol=0.01 + ) + return actual == expected + + +def validate_query(query_name, sql_dir, output_dir): + connection = duckdb.connect() + for path in (output_dir / query_name / "input").glob("*.parquet"): + table_name = path.stem.replace('"', '""') + parquet_path = str(path).replace("'", "''") + connection.execute( + f'CREATE VIEW "{table_name}" AS ' + f"SELECT * FROM read_parquet('{parquet_path}')" + ) + + expected = connection.execute((sql_dir / f"{query_name}.sql").read_text()) + expected_names = [column[0] for column in expected.description] + expected_rows = expected.fetchall() + + result_path = output_dir / query_name / "results" / f"{query_name}.parquet" + actual = connection.execute( + "SELECT * FROM read_parquet(?)", [str(result_path)] + ) + actual_names = [column[0] for column in actual.description] + actual_rows = actual.fetchall() + + expected_names = EXPECTED_NAMES.get(query_name, expected_names) + if actual_names != expected_names: + return f"column names differ: {actual_names} != {expected_names}" + if len(actual_rows) != len(expected_rows): + return f"row counts differ: {len(actual_rows)} != {len(expected_rows)}" + + for row_index, (actual_row, expected_row) in enumerate( + zip(actual_rows, expected_rows, strict=True) + ): + for column_name, actual_value, expected_value in zip( + actual_names, actual_row, expected_row, strict=True + ): + if not values_equal(actual_value, expected_value): + return ( + f"row {row_index}, column {column_name} differs: " + f"{actual_value!r} != {expected_value!r}" + ) + return None + + +def main(): + parser = argparse.ArgumentParser( + description="Validate NDS-H benchmark Parquet results against DuckDB" + ) + parser.add_argument("--output-dir", type=Path, required=True) + parser.add_argument("--sql-dir", type=Path, required=True) + args = parser.parse_args() + + failed = False + for query_name in QUERIES: + error = validate_query(query_name, args.sql_dir, args.output_dir) + if error is None: + print(f"{query_name}: PASSED") + else: + failed = True + print(f"{query_name}: FAILED: {error}") + + raise SystemExit(failed) + + +if __name__ == "__main__": + main() diff --git a/conda/environments/all_cuda-129_arch-aarch64.yaml b/conda/environments/all_cuda-129_arch-aarch64.yaml index 1a7cdc48ac7f..c9c0bab99d6e 100644 --- a/conda/environments/all_cuda-129_arch-aarch64.yaml +++ b/conda/environments/all_cuda-129_arch-aarch64.yaml @@ -32,6 +32,7 @@ dependencies: - dask-cuda==26.10.*,>=0.0.0a0 - dlpack>=0.8,<1.0 - doxygen=1.9.1 +- duckdb - fastavro>=0.22.9 - flatbuffers==24.3.25 - fsspec>=0.6.0 diff --git a/conda/environments/all_cuda-129_arch-x86_64.yaml b/conda/environments/all_cuda-129_arch-x86_64.yaml index a25e0dc81637..56b4907bbccd 100644 --- a/conda/environments/all_cuda-129_arch-x86_64.yaml +++ b/conda/environments/all_cuda-129_arch-x86_64.yaml @@ -32,6 +32,7 @@ dependencies: - dask-cuda==26.10.*,>=0.0.0a0 - dlpack>=0.8,<1.0 - doxygen=1.9.1 +- duckdb - fastavro>=0.22.9 - flatbuffers==24.3.25 - fsspec>=0.6.0 diff --git a/conda/environments/all_cuda-133_arch-aarch64.yaml b/conda/environments/all_cuda-133_arch-aarch64.yaml index 875088c05499..21cd169f820f 100644 --- a/conda/environments/all_cuda-133_arch-aarch64.yaml +++ b/conda/environments/all_cuda-133_arch-aarch64.yaml @@ -32,6 +32,7 @@ dependencies: - dask-cuda==26.10.*,>=0.0.0a0 - dlpack>=0.8,<1.0 - doxygen=1.9.1 +- duckdb - fastavro>=0.22.9 - flatbuffers==24.3.25 - fsspec>=0.6.0 diff --git a/conda/environments/all_cuda-133_arch-x86_64.yaml b/conda/environments/all_cuda-133_arch-x86_64.yaml index fcb76af8b6b2..dc365673eea5 100644 --- a/conda/environments/all_cuda-133_arch-x86_64.yaml +++ b/conda/environments/all_cuda-133_arch-x86_64.yaml @@ -32,6 +32,7 @@ dependencies: - dask-cuda==26.10.*,>=0.0.0a0 - dlpack>=0.8,<1.0 - doxygen=1.9.1 +- duckdb - fastavro>=0.22.9 - flatbuffers==24.3.25 - fsspec>=0.6.0 diff --git a/cpp/benchmarks/fixture/nvbench_fixture.hpp b/cpp/benchmarks/fixture/nvbench_fixture.hpp index ad938a358290..d6ed6c788bc4 100644 --- a/cpp/benchmarks/fixture/nvbench_fixture.hpp +++ b/cpp/benchmarks/fixture/nvbench_fixture.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ #pragma once @@ -27,8 +27,13 @@ namespace detail { static std::string rmm_mode_param{"--rmm_mode"}; ///< RMM mode command-line parameter name static std::string cuio_host_mem_param{ "--cuio_host_mem"}; ///< cuio host memory mode parameter name +static std::string output_directory_param{ + "--output_directory"}; ///< Benchmark output directory parameter name +inline std::string output_directory; } // namespace detail +inline std::string const& benchmark_output_directory() { return detail::output_directory; } + /** * Base fixture for cudf benchmarks using nvbench. * @@ -93,6 +98,9 @@ struct nvbench_base_fixture { } else if (arg == detail::cuio_host_mem_param) { i++; cuio_host_mode = argv[i]; + } else if (arg == detail::output_directory_param) { + i++; + detail::output_directory = argv[i]; } } diff --git a/cpp/benchmarks/fixture/nvbench_main.cpp b/cpp/benchmarks/fixture/nvbench_main.cpp index 7277e1869980..ee51703a6444 100644 --- a/cpp/benchmarks/fixture/nvbench_main.cpp +++ b/cpp/benchmarks/fixture/nvbench_main.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2023-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -12,8 +12,7 @@ namespace cudf { -// strip off the rmm_mode and cuio_host_mem parameters before passing the -// remaining arguments to nvbench::option_parser +// Strip cudf-specific parameters before passing the remaining arguments to nvbench::option_parser. void benchmark_arg_handler(std::vector& args) { std::vector _cudf_tmp_args; @@ -24,6 +23,8 @@ void benchmark_arg_handler(std::vector& args) i++; // skip the next argument } else if (arg == cudf::detail::cuio_host_mem_param) { i++; // skip the next argument + } else if (arg == cudf::detail::output_directory_param) { + i++; // skip the next argument } else { _cudf_tmp_args.push_back(arg); } diff --git a/cpp/benchmarks/ndsh/README.md b/cpp/benchmarks/ndsh/README.md index 25c92d5339e7..99700ade2f7f 100644 --- a/cpp/benchmarks/ndsh/README.md +++ b/cpp/benchmarks/ndsh/README.md @@ -13,3 +13,7 @@ All 22 NDS-H queries are implemented. The standard benchmark modes are `end_to_end`, which includes Parquet reads and query execution, and `compute_only`, which measures query execution using preloaded data. Q9 retains its additional engine and expression variants. + +Pass `--output_directory ` to write the generated input tables and one query result to +Parquet for validation. Input export, the validation query execution, and result output are not +timed. diff --git a/cpp/benchmarks/ndsh/q01.cpp b/cpp/benchmarks/ndsh/q01.cpp index 08213eeb5527..4cf2d4d7b46f 100644 --- a/cpp/benchmarks/ndsh/q01.cpp +++ b/cpp/benchmarks/ndsh/q01.cpp @@ -204,6 +204,7 @@ void ndsh_q1(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q1(source); @@ -211,7 +212,7 @@ void ndsh_q1(nvbench::state& state) } else { result = execute_ndsh_q1(lineitem); } - result->to_parquet("q1.parquet"); + write_ndsh_result(*result, "q01"); } NVBENCH_BENCH(ndsh_q1) diff --git a/cpp/benchmarks/ndsh/q02.cpp b/cpp/benchmarks/ndsh/q02.cpp index 3c1aabd118e5..a6d856ce64f0 100644 --- a/cpp/benchmarks/ndsh/q02.cpp +++ b/cpp/benchmarks/ndsh/q02.cpp @@ -156,6 +156,7 @@ void ndsh_q2(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q2(sources); @@ -163,7 +164,7 @@ void ndsh_q2(nvbench::state& state) } else { result = execute_ndsh_q2(*data); } - result->to_parquet("q2.parquet"); + write_ndsh_result(*result, "q02"); } NVBENCH_BENCH(ndsh_q2) diff --git a/cpp/benchmarks/ndsh/q03.cpp b/cpp/benchmarks/ndsh/q03.cpp index f1bf8302bd02..e1f8437bae77 100644 --- a/cpp/benchmarks/ndsh/q03.cpp +++ b/cpp/benchmarks/ndsh/q03.cpp @@ -148,6 +148,7 @@ void ndsh_q3(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q3(sources); @@ -155,7 +156,7 @@ void ndsh_q3(nvbench::state& state) } else { result = execute_ndsh_q3(tables); } - result->to_parquet("q3.parquet"); + write_ndsh_result(*result, "q03"); } NVBENCH_BENCH(ndsh_q3) diff --git a/cpp/benchmarks/ndsh/q04.cpp b/cpp/benchmarks/ndsh/q04.cpp index ba10c83e556b..cf98238e0785 100644 --- a/cpp/benchmarks/ndsh/q04.cpp +++ b/cpp/benchmarks/ndsh/q04.cpp @@ -108,6 +108,7 @@ void ndsh_q4(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q4(sources); @@ -115,7 +116,7 @@ void ndsh_q4(nvbench::state& state) } else { result = execute_ndsh_q4(data); } - result->to_parquet("q4.parquet"); + write_ndsh_result(*result, "q04"); } NVBENCH_BENCH(ndsh_q4) diff --git a/cpp/benchmarks/ndsh/q05.cpp b/cpp/benchmarks/ndsh/q05.cpp index 4f04c81d62c6..048b3007dce1 100644 --- a/cpp/benchmarks/ndsh/q05.cpp +++ b/cpp/benchmarks/ndsh/q05.cpp @@ -192,6 +192,7 @@ void ndsh_q5(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q5(sources); @@ -199,7 +200,7 @@ void ndsh_q5(nvbench::state& state) } else { result = execute_ndsh_q5(tables); } - result->to_parquet("q5.parquet"); + write_ndsh_result(*result, "q05"); } NVBENCH_BENCH(ndsh_q5) diff --git a/cpp/benchmarks/ndsh/q06.cpp b/cpp/benchmarks/ndsh/q06.cpp index 934bd80410ee..791389e62599 100644 --- a/cpp/benchmarks/ndsh/q06.cpp +++ b/cpp/benchmarks/ndsh/q06.cpp @@ -138,6 +138,7 @@ void ndsh_q6(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q6(sources); @@ -145,7 +146,7 @@ void ndsh_q6(nvbench::state& state) } else { result = execute_ndsh_q6(lineitem); } - result->to_parquet("q6.parquet"); + write_ndsh_result(*result, "q06"); } NVBENCH_BENCH(ndsh_q6) diff --git a/cpp/benchmarks/ndsh/q07.cpp b/cpp/benchmarks/ndsh/q07.cpp index 4301a4b37f9c..e56b07c267ef 100644 --- a/cpp/benchmarks/ndsh/q07.cpp +++ b/cpp/benchmarks/ndsh/q07.cpp @@ -210,6 +210,7 @@ void ndsh_q7(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q7(sources); @@ -217,7 +218,7 @@ void ndsh_q7(nvbench::state& state) } else { result = execute_ndsh_q7(tables); } - result->to_parquet("q7.parquet"); + write_ndsh_result(*result, "q07"); } NVBENCH_BENCH(ndsh_q7) diff --git a/cpp/benchmarks/ndsh/q08.cpp b/cpp/benchmarks/ndsh/q08.cpp index ddf16ce6fa8b..3a79d6285f1e 100644 --- a/cpp/benchmarks/ndsh/q08.cpp +++ b/cpp/benchmarks/ndsh/q08.cpp @@ -208,6 +208,7 @@ void ndsh_q8(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q8(sources); @@ -215,7 +216,7 @@ void ndsh_q8(nvbench::state& state) } else { result = execute_ndsh_q8(tables); } - result->to_parquet("q8.parquet"); + write_ndsh_result(*result, "q08"); } NVBENCH_BENCH(ndsh_q8) diff --git a/cpp/benchmarks/ndsh/q09.cpp b/cpp/benchmarks/ndsh/q09.cpp index 1f90a307fdb9..004ef5747370 100644 --- a/cpp/benchmarks/ndsh/q09.cpp +++ b/cpp/benchmarks/ndsh/q09.cpp @@ -324,10 +324,13 @@ void ndsh_q9(nvbench::state& state) data, launch.get_stream().get_stream(), cudf::get_current_device_resource_ref()); - result->to_parquet("q9.parquet"); }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } + q9_data const data = load_data(sources); + auto const result = compute_profit(state, engine, data); + write_ndsh_result(*result, "q09"); } void ndsh_q9_noio(nvbench::state& state) @@ -353,8 +356,6 @@ void ndsh_q9_noio(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); - - if (result) { result->to_parquet("q9_noio.parquet"); } } // unlike `ndsh_q9`, `ndsh_q9_amount` benchmarks only the amount calculation part of the benchmark diff --git a/cpp/benchmarks/ndsh/q10.cpp b/cpp/benchmarks/ndsh/q10.cpp index ba568028df53..9d014439c61b 100644 --- a/cpp/benchmarks/ndsh/q10.cpp +++ b/cpp/benchmarks/ndsh/q10.cpp @@ -191,6 +191,7 @@ void ndsh_q10(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q10(sources); @@ -198,7 +199,7 @@ void ndsh_q10(nvbench::state& state) } else { result = execute_ndsh_q10(tables); } - result->to_parquet("q10.parquet"); + write_ndsh_result(*result, "q10"); } NVBENCH_BENCH(ndsh_q10) diff --git a/cpp/benchmarks/ndsh/q11.cpp b/cpp/benchmarks/ndsh/q11.cpp index 9bbcbda7544f..5a4bcc809be0 100644 --- a/cpp/benchmarks/ndsh/q11.cpp +++ b/cpp/benchmarks/ndsh/q11.cpp @@ -141,6 +141,7 @@ void ndsh_q11(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q11(sources); @@ -148,7 +149,7 @@ void ndsh_q11(nvbench::state& state) } else { result = execute_ndsh_q11(tables, scale_factor); } - result->to_parquet("q11.parquet"); + write_ndsh_result(*result, "q11"); } NVBENCH_BENCH(ndsh_q11) diff --git a/cpp/benchmarks/ndsh/q12.cpp b/cpp/benchmarks/ndsh/q12.cpp index f3d4936e3c0b..42653b7e1aba 100644 --- a/cpp/benchmarks/ndsh/q12.cpp +++ b/cpp/benchmarks/ndsh/q12.cpp @@ -174,6 +174,7 @@ void ndsh_q12(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q12(sources); @@ -181,7 +182,7 @@ void ndsh_q12(nvbench::state& state) } else { result = execute_ndsh_q12(tables); } - result->to_parquet("q12.parquet"); + write_ndsh_result(*result, "q12"); } NVBENCH_BENCH(ndsh_q12) diff --git a/cpp/benchmarks/ndsh/q13.cpp b/cpp/benchmarks/ndsh/q13.cpp index feea1f4789ea..fc9f9d3b4389 100644 --- a/cpp/benchmarks/ndsh/q13.cpp +++ b/cpp/benchmarks/ndsh/q13.cpp @@ -105,6 +105,7 @@ void ndsh_q13(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q13(sources); @@ -112,7 +113,7 @@ void ndsh_q13(nvbench::state& state) } else { result = execute_ndsh_q13(tables); } - result->to_parquet("q13.parquet"); + write_ndsh_result(*result, "q13"); } NVBENCH_BENCH(ndsh_q13) diff --git a/cpp/benchmarks/ndsh/q14.cpp b/cpp/benchmarks/ndsh/q14.cpp index 4ca72ebf9e79..360b3f38bdf9 100644 --- a/cpp/benchmarks/ndsh/q14.cpp +++ b/cpp/benchmarks/ndsh/q14.cpp @@ -132,6 +132,7 @@ void ndsh_q14(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q14(sources); @@ -139,7 +140,7 @@ void ndsh_q14(nvbench::state& state) } else { result = execute_ndsh_q14(tables); } - result->to_parquet("q14.parquet"); + write_ndsh_result(*result, "q14"); } NVBENCH_BENCH(ndsh_q14) diff --git a/cpp/benchmarks/ndsh/q15.cpp b/cpp/benchmarks/ndsh/q15.cpp index 5764793d9507..4b76855d50c6 100644 --- a/cpp/benchmarks/ndsh/q15.cpp +++ b/cpp/benchmarks/ndsh/q15.cpp @@ -135,6 +135,7 @@ void ndsh_q15(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q15(sources); @@ -142,7 +143,7 @@ void ndsh_q15(nvbench::state& state) } else { result = execute_ndsh_q15(tables); } - result->to_parquet("q15.parquet"); + write_ndsh_result(*result, "q15"); } NVBENCH_BENCH(ndsh_q15) diff --git a/cpp/benchmarks/ndsh/q16.cpp b/cpp/benchmarks/ndsh/q16.cpp index dfb47834acde..db7d128285ad 100644 --- a/cpp/benchmarks/ndsh/q16.cpp +++ b/cpp/benchmarks/ndsh/q16.cpp @@ -163,6 +163,7 @@ void ndsh_q16(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q16(sources); @@ -170,7 +171,7 @@ void ndsh_q16(nvbench::state& state) } else { result = execute_ndsh_q16(tables); } - result->to_parquet("q16.parquet"); + write_ndsh_result(*result, "q16"); } NVBENCH_BENCH(ndsh_q16) diff --git a/cpp/benchmarks/ndsh/q17.cpp b/cpp/benchmarks/ndsh/q17.cpp index 2f34dae4cec4..7ed685ba3250 100644 --- a/cpp/benchmarks/ndsh/q17.cpp +++ b/cpp/benchmarks/ndsh/q17.cpp @@ -128,6 +128,7 @@ void ndsh_q17(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q17(sources); @@ -135,7 +136,7 @@ void ndsh_q17(nvbench::state& state) } else { result = execute_ndsh_q17(tables); } - result->to_parquet("q17.parquet"); + write_ndsh_result(*result, "q17"); } NVBENCH_BENCH(ndsh_q17) diff --git a/cpp/benchmarks/ndsh/q18.cpp b/cpp/benchmarks/ndsh/q18.cpp index 6c9b3ec31778..0fc0a7baf768 100644 --- a/cpp/benchmarks/ndsh/q18.cpp +++ b/cpp/benchmarks/ndsh/q18.cpp @@ -118,6 +118,7 @@ void ndsh_q18(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q18(sources); @@ -125,7 +126,7 @@ void ndsh_q18(nvbench::state& state) } else { result = execute_ndsh_q18(tables); } - result->to_parquet("q18.parquet"); + write_ndsh_result(*result, "q18"); } NVBENCH_BENCH(ndsh_q18) diff --git a/cpp/benchmarks/ndsh/q19.cpp b/cpp/benchmarks/ndsh/q19.cpp index 00c4ee6f29dd..4ada57338e8b 100644 --- a/cpp/benchmarks/ndsh/q19.cpp +++ b/cpp/benchmarks/ndsh/q19.cpp @@ -211,6 +211,7 @@ void ndsh_q19(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q19(sources); @@ -218,7 +219,7 @@ void ndsh_q19(nvbench::state& state) } else { result = execute_ndsh_q19(tables); } - result->to_parquet("q19.parquet"); + write_ndsh_result(*result, "q19"); } NVBENCH_BENCH(ndsh_q19) diff --git a/cpp/benchmarks/ndsh/q20.cpp b/cpp/benchmarks/ndsh/q20.cpp index e1687786e5e3..5b1efb8b194b 100644 --- a/cpp/benchmarks/ndsh/q20.cpp +++ b/cpp/benchmarks/ndsh/q20.cpp @@ -165,6 +165,7 @@ void ndsh_q20(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q20(sources); @@ -172,7 +173,7 @@ void ndsh_q20(nvbench::state& state) } else { result = execute_ndsh_q20(tables); } - result->to_parquet("q20.parquet"); + write_ndsh_result(*result, "q20"); } NVBENCH_BENCH(ndsh_q20) diff --git a/cpp/benchmarks/ndsh/q21.cpp b/cpp/benchmarks/ndsh/q21.cpp index 43d969b9c660..ba05e553ce26 100644 --- a/cpp/benchmarks/ndsh/q21.cpp +++ b/cpp/benchmarks/ndsh/q21.cpp @@ -178,6 +178,7 @@ void ndsh_q21(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q21(sources); @@ -185,7 +186,7 @@ void ndsh_q21(nvbench::state& state) } else { result = execute_ndsh_q21(tables); } - result->to_parquet("q21.parquet"); + write_ndsh_result(*result, "q21"); } NVBENCH_BENCH(ndsh_q21) diff --git a/cpp/benchmarks/ndsh/q22.cpp b/cpp/benchmarks/ndsh/q22.cpp index 878f71010bdb..4cf5aa8cf8c7 100644 --- a/cpp/benchmarks/ndsh/q22.cpp +++ b/cpp/benchmarks/ndsh/q22.cpp @@ -138,6 +138,7 @@ void ndsh_q22(nvbench::state& state) }); state.add_buffer_size( mem_stats_logger.peak_memory_usage(), "peak_memory_usage", "peak_memory_usage"); + if (not write_ndsh_results()) { return; } std::unique_ptr result; if (mode == query_mode::END_TO_END) { auto input = load_ndsh_q22(sources); @@ -145,7 +146,7 @@ void ndsh_q22(nvbench::state& state) } else { result = execute_ndsh_q22(tables); } - result->to_parquet("q22.parquet"); + write_ndsh_result(*result, "q22"); } NVBENCH_BENCH(ndsh_q22) diff --git a/cpp/benchmarks/ndsh/utilities.cpp b/cpp/benchmarks/ndsh/utilities.cpp index 82a1580d90a3..2a7f09fe944b 100644 --- a/cpp/benchmarks/ndsh/utilities.cpp +++ b/cpp/benchmarks/ndsh/utilities.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -605,4 +607,28 @@ void generate_parquet_data_sources(double scale_factor, auto region = cudf::datagen::generate_region(stream, managed_pool_mr); write_to_parquet_device_buffer(region, SCHEMAS.at("region"), sources.at("region")); } + + if (write_ndsh_results()) { + auto const input_directory = + std::filesystem::path{cudf::benchmark_output_directory()} / "input"; + std::filesystem::create_directories(input_directory); + for (auto& [name, source] : sources) { + auto const path = input_directory / (name + ".parquet"); + if (not std::filesystem::exists(path)) { + read_parquet(source.make_source_info())->to_parquet(path.string()); + } + } + } +} + +bool write_ndsh_results() { return not cudf::benchmark_output_directory().empty(); } + +void write_ndsh_result(table_with_names const& result, std::string const& query_name) +{ + static std::unordered_set written_results; + if (not written_results.insert(query_name).second) { return; } + auto const result_directory = + std::filesystem::path{cudf::benchmark_output_directory()} / "results"; + std::filesystem::create_directories(result_directory); + result.to_parquet((result_directory / (query_name + ".parquet")).string()); } diff --git a/cpp/benchmarks/ndsh/utilities.hpp b/cpp/benchmarks/ndsh/utilities.hpp index 5773bc546b14..19ab34739ef1 100644 --- a/cpp/benchmarks/ndsh/utilities.hpp +++ b/cpp/benchmarks/ndsh/utilities.hpp @@ -287,3 +287,7 @@ void write_to_parquet_device_buffer(std::unique_ptr const& table, void generate_parquet_data_sources(double scale_factor, std::vector const& table_names, std::unordered_map& sources); + +[[nodiscard]] bool write_ndsh_results(); + +void write_ndsh_result(table_with_names const& result, std::string const& query_name); diff --git a/dependencies.yaml b/dependencies.yaml index 35044134c583..37933f6f6ed2 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1152,6 +1152,7 @@ dependencies: packages: - *cmake_ver - cuda-sanitizer-api + - duckdb # packages we want in the 'test_cpp' group in 'files', for CI, but which # shouldn't be added to 'all' for building a development environment test_cpp_cudf: From 31c04a18965b1ffaa498862418f7e0e898baaa78 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:27:31 +0000 Subject: [PATCH 10/15] Validate NDS-H queries 2, 5, and 6 --- ci/run_cudf_benchmark_smoketests.sh | 2 +- ci/validate_ndsh_benchmarks.py | 13 +++++- .../benchmarks/streaming/ndsh/sql/q02.sql | 44 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q05.sql | 24 ++++++++++ .../benchmarks/streaming/ndsh/sql/q06.sql | 10 +++++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q02.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q05.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q06.sql diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index fa6045b708b8..85518f3f3f4c 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -34,7 +34,7 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|03|04|09|17|18|21)_NVBENCH$ ]]; then + if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|09|17|18|21)_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index 236a40fd9840..9125523c14e5 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -9,7 +9,18 @@ import duckdb -QUERIES = ("q01", "q03", "q04", "q09", "q17", "q18", "q21") +QUERIES = ( + "q01", + "q02", + "q03", + "q04", + "q05", + "q06", + "q09", + "q17", + "q18", + "q21", +) EXPECTED_NAMES = { "q18": [ "c_name", diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q02.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q02.sql new file mode 100644 index 000000000000..56aee8e414c9 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q02.sql @@ -0,0 +1,44 @@ +select + s_acctbal, + s_name, + n_name, + p_partkey, + p_mfgr, + s_address, + s_phone, + s_comment +from + part, + supplier, + partsupp, + nation, + region +where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and p_size = 15 + and p_type like '%BRASS' + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'EUROPE' + and ps_supplycost = ( + select + min(ps_supplycost) + from + partsupp, + supplier, + nation, + region + where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'EUROPE' + ) +order by + s_acctbal desc, + n_name, + s_name, + p_partkey +limit 100 diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q05.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q05.sql new file mode 100644 index 000000000000..3250d55f7503 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q05.sql @@ -0,0 +1,24 @@ +select + n_name, + sum(l_extendedprice * (1 - l_discount)) as revenue +from + customer, + orders, + lineitem, + supplier, + nation, + region +where + c_custkey = o_custkey + and l_orderkey = o_orderkey + and l_suppkey = s_suppkey + and c_nationkey = s_nationkey + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'ASIA' + and o_orderdate >= date '1994-01-01' + and o_orderdate < date '1995-01-01' +group by + n_name +order by + revenue desc diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q06.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q06.sql new file mode 100644 index 000000000000..4db3531e9c40 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q06.sql @@ -0,0 +1,10 @@ +select + sum(l_extendedprice * l_discount) as revenue +from + lineitem +where + l_shipdate >= date '1994-01-01' + and l_shipdate < date '1995-01-01' + and l_discount >= 0.05 + and l_discount <= 0.07 + and l_quantity < 24 From 0806f0bb99ce74bf40ee5020b06f0822c33f0768 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:29:04 +0000 Subject: [PATCH 11/15] Validate NDS-H queries 7, 8, and 10 --- ci/run_cudf_benchmark_smoketests.sh | 2 +- ci/validate_ndsh_benchmarks.py | 3 ++ .../benchmarks/streaming/ndsh/sql/q07.sql | 39 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q08.sql | 39 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q10.sql | 32 +++++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q07.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q08.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q10.sql diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index 85518f3f3f4c..cb3b0bf85b7f 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -34,7 +34,7 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|09|17|18|21)_NVBENCH$ ]]; then + if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|17|18|21)_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index 9125523c14e5..e72313a1eee5 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -16,7 +16,10 @@ "q04", "q05", "q06", + "q07", + "q08", "q09", + "q10", "q17", "q18", "q21", diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q07.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q07.sql new file mode 100644 index 000000000000..280bc51f7640 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q07.sql @@ -0,0 +1,39 @@ +select + supp_nation, + cust_nation, + l_year, + sum(volume) as revenue +from + ( + select + n1.n_name as supp_nation, + n2.n_name as cust_nation, + year(l_shipdate)::INT16 as l_year, + l_extendedprice * (1 - l_discount) as volume + from + supplier, + lineitem, + orders, + customer, + nation n1, + nation n2 + where + s_suppkey = l_suppkey + and o_orderkey = l_orderkey + and c_custkey = o_custkey + and s_nationkey = n1.n_nationkey + and c_nationkey = n2.n_nationkey + and ( + (n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') + or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE') + ) + and l_shipdate between date '1995-01-01' and date '1996-12-31' + ) as shipping +group by + supp_nation, + cust_nation, + l_year +order by + supp_nation, + cust_nation, + l_year diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q08.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q08.sql new file mode 100644 index 000000000000..6b675ebb4389 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q08.sql @@ -0,0 +1,39 @@ +select + o_year, + round( + sum(case + when nation = 'BRAZIL' then volume + else 0 + end) / sum(volume) + , 2) as mkt_share +from + ( + select + year(o_orderdate)::INT16 as o_year, + l_extendedprice * (1 - l_discount) as volume, + n2.n_name as nation + from + part, + supplier, + lineitem, + orders, + customer, + nation n1, + nation n2, + region + where + p_partkey = l_partkey + and s_suppkey = l_suppkey + and l_orderkey = o_orderkey + and o_custkey = c_custkey + and c_nationkey = n1.n_nationkey + and n1.n_regionkey = r_regionkey + and r_name = 'AMERICA' + and s_nationkey = n2.n_nationkey + and o_orderdate between date '1995-01-01' and date '1996-12-31' + and p_type = 'ECONOMY ANODIZED STEEL' + ) as all_nations +group by + o_year +order by + o_year diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q10.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q10.sql new file mode 100644 index 000000000000..39c16df8c8f2 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q10.sql @@ -0,0 +1,32 @@ +select + c_custkey, + c_name, + sum(l_extendedprice * (1 - l_discount)) as revenue, + c_acctbal, + n_name, + c_address, + c_phone, + c_comment +from + customer, + orders, + lineitem, + nation +where + c_custkey = o_custkey + and l_orderkey = o_orderkey + and o_orderdate >= date '1993-10-01' + and o_orderdate < date '1994-01-01' + and l_returnflag = 'R' + and c_nationkey = n_nationkey +group by + c_custkey, + c_name, + c_acctbal, + c_phone, + n_name, + c_address, + c_comment +order by + revenue desc +limit 20 From 7e7cd372d85280d94818a97314f741082a5db149 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:29:59 +0000 Subject: [PATCH 12/15] Validate NDS-H queries 11, 12, and 13 --- ci/run_cudf_benchmark_smoketests.sh | 2 +- ci/validate_ndsh_benchmarks.py | 3 ++ .../benchmarks/streaming/ndsh/sql/q11.sql | 28 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q12.sql | 28 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q13.sql | 20 +++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q12.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q13.sql diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index cb3b0bf85b7f..1baaef1528d0 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -34,7 +34,7 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|17|18|21)_NVBENCH$ ]]; then + if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|17|18|21)_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index e72313a1eee5..2108aee19c7a 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -20,6 +20,9 @@ "q08", "q09", "q10", + "q11", + "q12", + "q13", "q17", "q18", "q21", diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql new file mode 100644 index 000000000000..94b3a8806c72 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql @@ -0,0 +1,28 @@ +select + ps_partkey, + round(sum(ps_supplycost * ps_availqty), 2) as value +from + partsupp, + supplier, + nation +where + ps_suppkey = s_suppkey + and s_nationkey = n_nationkey + and n_name = 'GERMANY' +group by + ps_partkey +having + sum(ps_supplycost * ps_availqty) > ( + select + sum(ps_supplycost * ps_availqty) * 0.01 + from + partsupp, + supplier, + nation + where + ps_suppkey = s_suppkey + and s_nationkey = n_nationkey + and n_name = 'GERMANY' + ) +order by + value desc diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q12.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q12.sql new file mode 100644 index 000000000000..b1ac775cb673 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q12.sql @@ -0,0 +1,28 @@ +select + l_shipmode, + sum(case + when o_orderpriority = '1-URGENT' + or o_orderpriority = '2-HIGH' + then 1 + else 0 + end) as high_line_count, + sum(case + when o_orderpriority <> '1-URGENT' + and o_orderpriority <> '2-HIGH' + then 1 + else 0 + end) as low_line_count +from + orders, + lineitem +where + o_orderkey = l_orderkey + and l_shipmode in ('MAIL', 'SHIP') + and l_commitdate < l_receiptdate + and l_shipdate < l_commitdate + and l_receiptdate >= date '1994-01-01' + and l_receiptdate < date '1995-01-01' +group by + l_shipmode +order by + l_shipmode diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q13.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q13.sql new file mode 100644 index 000000000000..785a1588240b --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q13.sql @@ -0,0 +1,20 @@ +select + c_count, + count(*) as custdist +from + ( + select + c_custkey, + count(o_orderkey) as c_count + from + customer left outer join orders on + c_custkey = o_custkey + and o_comment not like '%special%requests%' + group by + c_custkey + ) as c_orders +group by + c_count +order by + custdist desc, + c_count desc From 0f8d927e481d13ebdc71edf423ab18b5c669e14a Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:31:32 +0000 Subject: [PATCH 13/15] Validate NDS-H queries 14, 15, and 16 --- ci/run_cudf_benchmark_smoketests.sh | 2 +- ci/validate_ndsh_benchmarks.py | 3 ++ .../benchmarks/streaming/ndsh/sql/q14.sql | 13 ++++++++ .../benchmarks/streaming/ndsh/sql/q15.sql | 31 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q16.sql | 30 ++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q14.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q15.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q16.sql diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index 1baaef1528d0..082bd5fbbce7 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -34,7 +34,7 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|17|18|21)_NVBENCH$ ]]; then + if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|21)_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index 2108aee19c7a..3ff7f55faae5 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -23,6 +23,9 @@ "q11", "q12", "q13", + "q14", + "q15", + "q16", "q17", "q18", "q21", diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q14.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q14.sql new file mode 100644 index 000000000000..4ec565533069 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q14.sql @@ -0,0 +1,13 @@ +select + round(100.00 * sum(case + when p_type like 'PROMO%' + then l_extendedprice * (1 - l_discount) + else 0 + end) / sum(l_extendedprice * (1 - l_discount)), 2) as promo_revenue +from + lineitem, + part +where + l_partkey = p_partkey + and l_shipdate >= date '1995-09-01' + and l_shipdate < date '1995-10-01' diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q15.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q15.sql new file mode 100644 index 000000000000..cc1253fe67d7 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q15.sql @@ -0,0 +1,31 @@ +with revenue (supplier_no, total_revenue) as ( + select + l_suppkey, + sum(l_extendedprice * (1 - l_discount)) + from + lineitem + where + l_shipdate >= date '1996-01-01' + and l_shipdate < date '1996-04-01' + group by + l_suppkey +) +select + s_suppkey, + s_name, + s_address, + s_phone, + total_revenue +from + supplier, + revenue +where + s_suppkey = supplier_no + and total_revenue = ( + select + max(total_revenue) + from + revenue + ) +order by + s_suppkey diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q16.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q16.sql new file mode 100644 index 000000000000..aa736b2c2062 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q16.sql @@ -0,0 +1,30 @@ +select + p_brand, + p_type, + p_size, + count(distinct ps_suppkey) as supplier_cnt +from + partsupp, + part +where + p_partkey = ps_partkey + and p_brand <> 'Brand#45' + and p_type not like 'MEDIUM POLISHED%' + and p_size in (49, 14, 23, 45, 19, 3, 36, 9) + and ps_suppkey not in ( + select + s_suppkey + from + supplier + where + s_comment like '%Customer%Complaints%' + ) +group by + p_brand, + p_type, + p_size +order by + supplier_cnt desc, + p_brand, + p_type, + p_size From 1ceb155eacb07ce4baead5a2a9d8970bcd1b7f19 Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:32:53 +0000 Subject: [PATCH 14/15] Validate NDS-H queries 19, 20, and 22 --- ci/run_cudf_benchmark_smoketests.sh | 2 +- ci/validate_ndsh_benchmarks.py | 3 ++ .../benchmarks/streaming/ndsh/sql/q19.sql | 35 ++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q20.sql | 37 +++++++++++++++++++ .../benchmarks/streaming/ndsh/sql/q22.sql | 37 +++++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q19.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q20.sql create mode 100644 cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q22.sql diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index 082bd5fbbce7..0b697e74acdc 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -34,7 +34,7 @@ for bench in *_NVBENCH; do args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|21)_NVBENCH$ ]]; then + if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22)_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index 3ff7f55faae5..02a3d8b21dbf 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -28,7 +28,10 @@ "q16", "q17", "q18", + "q19", + "q20", "q21", + "q22", ) EXPECTED_NAMES = { "q18": [ diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q19.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q19.sql new file mode 100644 index 000000000000..21e8e49c55b6 --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q19.sql @@ -0,0 +1,35 @@ +select + round(sum(l_extendedprice * (1 - l_discount)), 2) as revenue +from + lineitem, + part +where + ( + p_partkey = l_partkey + and p_brand = 'Brand#12' + and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') + and l_quantity between 1 and 11 + and p_size between 1 and 5 + and l_shipmode in ('AIR', 'AIR REG') + and l_shipinstruct = 'DELIVER IN PERSON' + ) + or + ( + p_partkey = l_partkey + and p_brand = 'Brand#23' + and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') + and l_quantity between 10 and 20 + and p_size between 1 and 10 + and l_shipmode in ('AIR', 'AIR REG') + and l_shipinstruct = 'DELIVER IN PERSON' + ) + or + ( + p_partkey = l_partkey + and p_brand = 'Brand#34' + and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') + and l_quantity between 20 and 30 + and p_size between 1 and 15 + and l_shipmode in ('AIR', 'AIR REG') + and l_shipinstruct = 'DELIVER IN PERSON' + ) diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q20.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q20.sql new file mode 100644 index 000000000000..9a6081f08f5e --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q20.sql @@ -0,0 +1,37 @@ +select + s_name, + s_address +from + supplier, + nation +where + s_suppkey in ( + select + ps_suppkey + from + partsupp + where + ps_partkey in ( + select + p_partkey + from + part + where + p_name like 'forest%' + ) + and ps_availqty > ( + select + 0.5 * sum(l_quantity) + from + lineitem + where + l_partkey = ps_partkey + and l_suppkey = ps_suppkey + and l_shipdate >= date '1994-01-01' + and l_shipdate < date '1995-01-01' + ) + ) + and s_nationkey = n_nationkey + and n_name = 'CANADA' +order by + s_name diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q22.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q22.sql new file mode 100644 index 000000000000..0bc6725fa5fb --- /dev/null +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q22.sql @@ -0,0 +1,37 @@ +select + cntrycode, + count(*) as numcust, + sum(c_acctbal) as totacctbal +from + ( + select + substring(c_phone from 1 for 2) as cntrycode, + c_acctbal + from + customer + where + substring(c_phone from 1 for 2) in + ('13', '31', '23', '29', '30', '18', '17') + and c_acctbal > ( + select + avg(c_acctbal) + from + customer + where + c_acctbal > 0.00 + and substring(c_phone from 1 for 2) in + ('13', '31', '23', '29', '30', '18', '17') + ) + and not exists ( + select + * + from + orders + where + o_custkey = c_custkey + ) + ) as custsale +group by + cntrycode +order by + cntrycode From a089808706aef37fb66ba33d2a153221b247c4ad Mon Sep 17 00:00:00 2001 From: Bradley Dice Date: Wed, 12 Aug 2026 03:51:29 +0000 Subject: [PATCH 15/15] Validate NDS-H smoke tests at scale factor 1 --- ci/run_cudf_benchmark_smoketests.sh | 8 +++++--- ci/validate_ndsh_benchmarks.py | 14 +++++++++++--- .../benchmarks/streaming/ndsh/sql/q11.sql | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ci/run_cudf_benchmark_smoketests.sh b/ci/run_cudf_benchmark_smoketests.sh index 0b697e74acdc..959003aec68f 100755 --- a/ci/run_cudf_benchmark_smoketests.sh +++ b/ci/run_cudf_benchmark_smoketests.sh @@ -25,6 +25,7 @@ fi EXITCODE=0 validation_dir="$(mktemp -d)" +ndsh_scale_factor=1 trap 'rm -rf "${validation_dir}"' EXIT # Run all nvbench benchmarks with --profile and rmm_mode=cuda for bench in *_NVBENCH; do @@ -33,8 +34,8 @@ for bench in *_NVBENCH; do echo "Running $bench with --profile..." args=(--profile --devices 0 -q --rmm_mode cuda) if [[ "$bench" == NDSH_* ]]; then - args+=(--axis scale_factor=0.01) - if [[ "$bench" =~ ^NDSH_Q(01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22)_NVBENCH$ ]]; then + args+=(--axis "scale_factor=${ndsh_scale_factor}") + if [[ "$bench" =~ ^NDSH_Q([0-9]{2})_NVBENCH$ ]]; then args+=(--output_directory "${validation_dir}/q${BASH_REMATCH[1]}") fi fi @@ -53,7 +54,8 @@ done python "${repo_root}/ci/validate_ndsh_benchmarks.py" \ --output-dir "${validation_dir}" \ - --sql-dir "${repo_root}/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql" + --sql-dir "${repo_root}/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql" \ + --scale-factor "${ndsh_scale_factor}" echo "Test script exiting with value: $EXITCODE" exit ${EXITCODE} diff --git a/ci/validate_ndsh_benchmarks.py b/ci/validate_ndsh_benchmarks.py index 02a3d8b21dbf..f0ec0c722943 100644 --- a/ci/validate_ndsh_benchmarks.py +++ b/ci/validate_ndsh_benchmarks.py @@ -57,7 +57,7 @@ def values_equal(actual, expected): return actual == expected -def validate_query(query_name, sql_dir, output_dir): +def validate_query(query_name, sql_dir, output_dir, scale_factor=0.01): connection = duckdb.connect() for path in (output_dir / query_name / "input").glob("*.parquet"): table_name = path.stem.replace('"', '""') @@ -67,7 +67,12 @@ def validate_query(query_name, sql_dir, output_dir): f"SELECT * FROM read_parquet('{parquet_path}')" ) - expected = connection.execute((sql_dir / f"{query_name}.sql").read_text()) + parameters = ( + {"scale_factor": scale_factor} if query_name == "q11" else None + ) + expected = connection.execute( + (sql_dir / f"{query_name}.sql").read_text(), parameters + ) expected_names = [column[0] for column in expected.description] expected_rows = expected.fetchall() @@ -104,11 +109,14 @@ def main(): ) parser.add_argument("--output-dir", type=Path, required=True) parser.add_argument("--sql-dir", type=Path, required=True) + parser.add_argument("--scale-factor", type=float, default=0.01) args = parser.parse_args() failed = False for query_name in QUERIES: - error = validate_query(query_name, args.sql_dir, args.output_dir) + error = validate_query( + query_name, args.sql_dir, args.output_dir, args.scale_factor + ) if error is None: print(f"{query_name}: PASSED") else: diff --git a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql index 94b3a8806c72..8e2f9699ae91 100644 --- a/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql +++ b/cpp/libcudf_streaming/benchmarks/streaming/ndsh/sql/q11.sql @@ -14,7 +14,7 @@ group by having sum(ps_supplycost * ps_availqty) > ( select - sum(ps_supplycost * ps_availqty) * 0.01 + sum(ps_supplycost * ps_availqty) * (0.0001 / $scale_factor) from partsupp, supplier,