diff --git a/cpp/include/cudf/detail/join/distinct_filtered_join.cuh b/cpp/include/cudf/detail/join/distinct_filtered_join.cuh deleted file mode 100644 index f05877cf264e..000000000000 --- a/cpp/include/cudf/detail/join/distinct_filtered_join.cuh +++ /dev/null @@ -1,129 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -namespace cudf::detail::row::equality { -struct preprocessed_table; -} - -namespace cudf { - -// Forward declaration -enum class join_kind : int32_t; - -namespace detail { - -/** - * @brief Implementation of filtered join using set hash tables - * - * This class extends the base filtered_join to implement join operations - * using set semantics, where duplicate keys are not allowed in the hash table. - * This implementation is more memory efficient when the same filter table (right table) - * is to be reused for multiple semi/anti join operations. - */ -class distinct_filtered_join : public filtered_join { - private: - /** - * @brief Performs either a semi or anti join based on the specified kind - * - * @param left The left table to probe the hash table with - * @param kind The kind of join to perform (SEMI or ANTI) - * @param stream CUDA stream on which to perform operations - * @param mr Memory resource for allocations - * @return Device vector of indices representing the join result - */ - std::unique_ptr> semi_anti_join( - cudf::table_view const& left, - join_kind kind, - rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr); - - // Queries the hash table for every left row and writes the matches to contains_map. - template - void query_right_table(cudf::table_view const& left, - Iterator left_iter, - Ref query_ref, - cudf::device_span contains_map, - rmm::cuda_stream_view stream); - - void query_right_table_primitive( - cudf::table_view const& left, - std::shared_ptr const& preprocessed_left, - cudf::device_span contains_map, - rmm::cuda_stream_view stream); - - void query_right_table_flat( - cudf::table_view const& left, - std::shared_ptr const& preprocessed_left, - cudf::device_span contains_map, - rmm::cuda_stream_view stream); - - void query_right_table_nested( - cudf::table_view const& left, - std::shared_ptr const& preprocessed_left, - cudf::device_span contains_map, - rmm::cuda_stream_view stream); - - public: - /** - * @brief Constructor for filtered join with set - * - * @param right The right table used to build the hash table - * @param compare_nulls How null values should be compared - * @param load_factor Target load factor for the hash table - * @param stream CUDA stream on which to perform operations - * @param mr Device memory resource used to allocate the internal hash table - */ - distinct_filtered_join(cudf::table_view const& right, - cudf::null_equality compare_nulls, - double load_factor, - rmm::cuda_stream_view stream, - cuda::mr::any_resource mr); - - /** - * @brief Implementation of semi join for set - * - * Returns indices of left table rows that have matching keys in the right table. - * - * @param left The left table to probe the hash table with - * @param stream CUDA stream on which to perform operations - * @param mr Memory resource for allocations - * @return Device vector of indices representing the join result - */ - std::unique_ptr> semi_join( - cudf::table_view const& left, - rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr) override; - - /** - * @brief Implementation of anti join for set - * - * Returns indices of left table rows that do not have matching keys in the right table. - * - * @param left The left table to probe the hash table with - * @param stream CUDA stream on which to perform operations - * @param mr Memory resource for allocations - * @return Device vector of indices representing the join result - */ - std::unique_ptr> anti_join( - cudf::table_view const& left, - rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr) override; -}; - -} // namespace detail -} // namespace cudf diff --git a/cpp/include/cudf/detail/join/filtered_join.cuh b/cpp/include/cudf/detail/join/filtered_join.cuh index e58259a39e81..1206857b684f 100644 --- a/cpp/include/cudf/detail/join/filtered_join.cuh +++ b/cpp/include/cudf/detail/join/filtered_join.cuh @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -37,10 +38,10 @@ using cudf::detail::row::lhs_index_type; using cudf::detail::row::rhs_index_type; /** - * @brief Base class providing common functionality for filtered join operations. + * @brief Implementation of filtered join using set hash tables. * - * This abstract class implements the core components needed for hash-based semi - * and anti join operations. + * Implements hash-based semi and anti joins using set semantics, where duplicate + * keys are not stored in the hash table. */ class filtered_join { public: @@ -121,7 +122,7 @@ class filtered_join { }; /** - * @brief Constructor for filtered_join base class + * @brief Constructor for filtered_join * * Initializes the hash table with the right table and prepares it for join operations. * @@ -138,27 +139,50 @@ class filtered_join { cuda::mr::any_resource mr); /** - * Virtual semi join function overridden in derived classes + * @brief Returns indices of left table rows that have matching keys in the right table */ - virtual std::unique_ptr> semi_join( - cudf::table_view const& left, - rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr) = 0; + std::unique_ptr> semi_join( + cudf::table_view const& left, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr); /** - * Virtual anti join function overridden in derived classes + * @brief Returns indices of left table rows that do not have matching keys in the right table */ - virtual std::unique_ptr> anti_join( + std::unique_ptr> anti_join( + cudf::table_view const& left, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr); + + private: + std::unique_ptr> semi_anti_join( cudf::table_view const& left, + join_kind kind, rmm::cuda_stream_view stream, - rmm::device_async_resource_ref mr) = 0; + rmm::device_async_resource_ref mr); - /** - * Virtual abstract base class destructor - */ - virtual ~filtered_join() = default; + // Queries the hash table for every left row and writes the matches to contains_map. + template + void query_right_table(cudf::table_view const& left, + Iterator left_iter, + Ref query_ref, + cudf::device_span contains_map, + rmm::cuda_stream_view stream); + + void query_right_table_primitive( + cudf::table_view const& left, + std::shared_ptr const& preprocessed_left, + cudf::device_span contains_map, + rmm::cuda_stream_view stream); + + void query_right_table_flat( + cudf::table_view const& left, + std::shared_ptr const& preprocessed_left, + cudf::device_span contains_map, + rmm::cuda_stream_view stream); + + void query_right_table_nested( + cudf::table_view const& left, + std::shared_ptr const& preprocessed_left, + cudf::device_span contains_map, + rmm::cuda_stream_view stream); - protected: enum class row_operator_mode : uint8_t { PRIMITIVE, FLAT, NESTED }; // Key type used in the hash table @@ -196,7 +220,6 @@ class filtered_join { void insert_right_table_flat(rmm::cuda_stream_view stream); void insert_right_table_nested(rmm::cuda_stream_view stream); - private: /** * @brief Calculates the required storage size for the hash table * diff --git a/cpp/src/join/filtered_join/filtered_join.cu b/cpp/src/join/filtered_join/filtered_join.cu index 9498157f052d..d1766f0ffab3 100644 --- a/cpp/src/join/filtered_join/filtered_join.cu +++ b/cpp/src/join/filtered_join/filtered_join.cu @@ -6,7 +6,6 @@ #include "join/join_common_utils.hpp" #include -#include #include #include #include @@ -110,20 +109,9 @@ filtered_join::filtered_join(cudf::table_view const& right, _nulls_equal{compare_nulls}, _preprocessed_right{cudf::detail::row::equality::preprocessed_table::create(_right, stream)} { + cudf::scoped_range range{"filtered_join::filtered_join"}; if (_right.num_rows() == 0) return; _bucket_storage.initialize(empty_sentinel_key, stream); -} - -distinct_filtered_join::distinct_filtered_join( - cudf::table_view const& right, - cudf::null_equality compare_nulls, - double load_factor, - rmm::cuda_stream_view stream, - cuda::mr::any_resource mr) - : filtered_join(right, compare_nulls, load_factor, stream, std::move(mr)) -{ - cudf::scoped_range range{"distinct_filtered_join::distinct_filtered_join"}; - if (_right.num_rows() == 0) return; if (_right_mode == row_operator_mode::PRIMITIVE) { insert_right_table_primitive(stream); } else if (_right_mode == row_operator_mode::NESTED) { @@ -133,16 +121,16 @@ distinct_filtered_join::distinct_filtered_join( } } -std::unique_ptr> distinct_filtered_join::semi_anti_join( +std::unique_ptr> filtered_join::semi_anti_join( cudf::table_view const& left, join_kind kind, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr) { - cudf::scoped_range range{"distinct_filtered_join::semi_anti_join"}; + cudf::scoped_range range{"filtered_join::semi_anti_join"}; auto const preprocessed_left = [&left, stream] { - cudf::scoped_range range{"distinct_filtered_join::semi_anti_join::preprocessed_left"}; + cudf::scoped_range range{"filtered_join::semi_anti_join::preprocessed_left"}; return cudf::detail::row::equality::preprocessed_table::create(left, stream); }(); @@ -167,7 +155,7 @@ std::unique_ptr> distinct_filtered_join::se return std::make_unique>(std::move(gather_map)); } -std::unique_ptr> distinct_filtered_join::semi_join( +std::unique_ptr> filtered_join::semi_join( cudf::table_view const& left, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr) { // Early return for empty right or left table @@ -178,7 +166,7 @@ std::unique_ptr> distinct_filtered_join::se return semi_anti_join(left, join_kind::LEFT_SEMI_JOIN, stream, mr); } -std::unique_ptr> distinct_filtered_join::anti_join( +std::unique_ptr> filtered_join::anti_join( cudf::table_view const& left, rmm::cuda_stream_view stream, rmm::device_async_resource_ref mr) { // Early return for empty left table @@ -206,7 +194,7 @@ filtered_join::filtered_join(cudf::table_view const& build, double load_factor, rmm::cuda_stream_view stream, cuda::mr::any_resource mr) - : _impl{std::make_unique( + : _impl{std::make_unique( build, compare_nulls, load_factor, stream, std::move(mr))} { } diff --git a/cpp/src/join/filtered_join/filtered_join_common.cuh b/cpp/src/join/filtered_join/filtered_join_common.cuh index 9f0ddc57862b..aa2fb3c4e2cf 100644 --- a/cpp/src/join/filtered_join/filtered_join_common.cuh +++ b/cpp/src/join/filtered_join/filtered_join_common.cuh @@ -5,7 +5,6 @@ #pragma once -#include #include #include #include @@ -59,7 +58,7 @@ void filtered_join::insert_right_table(Iterator right_iter, Ref const& insert_ref, rmm::cuda_stream_view stream) { - cudf::scoped_range range{"distinct_filtered_join::insert_right_table"}; + cudf::scoped_range range{"filtered_join::insert_right_table"}; // Insert valid rows from the right table into the hash table. auto const grid_size = cuco::detail::grid_size(_right.num_rows(), CGSize); auto const bitmask_buffer_and_ptr = make_filtered_join_row_bitmask(_right, _nulls_equal, stream); @@ -84,13 +83,13 @@ void filtered_join::insert_right_table(Iterator right_iter, } template -void distinct_filtered_join::query_right_table(cudf::table_view const& left, - Iterator left_iter, - Ref query_ref, - cudf::device_span contains_map, - rmm::cuda_stream_view stream) +void filtered_join::query_right_table(cudf::table_view const& left, + Iterator left_iter, + Ref query_ref, + cudf::device_span contains_map, + rmm::cuda_stream_view stream) { - cudf::scoped_range range{"distinct_filtered_join::query_right_table"}; + cudf::scoped_range range{"filtered_join::query_right_table"}; auto const grid_size = cuco::detail::grid_size(left.num_rows(), CGSize); auto const bitmask_buffer_and_ptr = make_filtered_join_row_bitmask(left, _nulls_equal, stream); if (bitmask_buffer_and_ptr.second != nullptr) { diff --git a/cpp/src/join/filtered_join/filtered_join_flat.cu b/cpp/src/join/filtered_join/filtered_join_flat.cu index e7e178bae9c3..5837c5aafe73 100644 --- a/cpp/src/join/filtered_join/filtered_join_flat.cu +++ b/cpp/src/join/filtered_join/filtered_join_flat.cu @@ -45,7 +45,7 @@ void filtered_join::insert_right_table_flat(rmm::cuda_stream_view stream) iter, set_ref.rebind_operators(cuco::insert), stream); } -void distinct_filtered_join::query_right_table_flat( +void filtered_join::query_right_table_flat( cudf::table_view const& left, std::shared_ptr const& preprocessed_left, cudf::device_span contains_map, diff --git a/cpp/src/join/filtered_join/filtered_join_nested_query.cu b/cpp/src/join/filtered_join/filtered_join_nested_query.cu index c684f86b51f9..c4c27dfccae1 100644 --- a/cpp/src/join/filtered_join/filtered_join_nested_query.cu +++ b/cpp/src/join/filtered_join/filtered_join_nested_query.cu @@ -26,7 +26,7 @@ namespace cudf::detail { -void distinct_filtered_join::query_right_table_nested( +void filtered_join::query_right_table_nested( cudf::table_view const& left, std::shared_ptr const& preprocessed_left, cudf::device_span contains_map, diff --git a/cpp/src/join/filtered_join/filtered_join_primitive.cu b/cpp/src/join/filtered_join/filtered_join_primitive.cu index a455d8d7cb11..2c3026b6d893 100644 --- a/cpp/src/join/filtered_join/filtered_join_primitive.cu +++ b/cpp/src/join/filtered_join/filtered_join_primitive.cu @@ -49,7 +49,7 @@ void filtered_join::insert_right_table_primitive(rmm::cuda_stream_view stream) iter, set_ref.rebind_operators(cuco::insert), stream); } -void distinct_filtered_join::query_right_table_primitive( +void filtered_join::query_right_table_primitive( cudf::table_view const& left, std::shared_ptr const& preprocessed_left, cudf::device_span contains_map,