|
1 | 1 | /* |
2 | | - * SPDX-FileCopyrightText: Copyright (c) 2021-2025, NVIDIA CORPORATION. |
| 2 | + * SPDX-FileCopyrightText: Copyright (c) 2021-2026, NVIDIA CORPORATION. |
3 | 3 | * SPDX-License-Identifier: Apache-2.0 |
4 | 4 | */ |
5 | 5 | #pragma once |
|
11 | 11 | #include <cudf/detail/row_operator/equality.cuh> |
12 | 12 | #include <cudf/detail/row_operator/hashing.cuh> |
13 | 13 | #include <cudf/detail/utilities/cuda.cuh> |
14 | | -#include <cudf/hashing/detail/murmurhash3_x86_32.cuh> |
15 | | -#include <cudf/utilities/memory_resource.hpp> |
16 | 14 |
|
17 | 15 | #include <rmm/cuda_stream_view.hpp> |
18 | | -#include <rmm/device_uvector.hpp> |
19 | 16 |
|
20 | 17 | #include <thrust/iterator/counting_iterator.h> |
21 | 18 |
|
22 | 19 | #include <memory> |
23 | | -#include <utility> |
24 | 20 |
|
25 | 21 | namespace cudf::detail { |
26 | 22 | template <typename Hasher> |
@@ -52,169 +48,6 @@ class row_is_valid { |
52 | 48 | bitmask_type const* _row_bitmask; |
53 | 49 | }; |
54 | 50 |
|
55 | | -/** |
56 | | - * @brief Device functor to determine if two pairs are identical. |
57 | | - * |
58 | | - * This equality comparator is designed for use with cuco::static_multimap's |
59 | | - * pair* APIs, which will compare equality based on comparing (key, value) |
60 | | - * pairs. In the context of joins, these pairs are of the form |
61 | | - * (row_hash, row_id). A hash probe hit indicates that hash of a probe row's hash is |
62 | | - * equal to the hash of the hash of some row in the multimap, at which point we need an |
63 | | - * equality comparator that will check whether the contents of the rows are |
64 | | - * identical. This comparator does so by verifying key equality (i.e. that |
65 | | - * probe_row_hash == build_row_hash) and then using a row_equality_comparator |
66 | | - * to compare the contents of the row indices that are stored as the payload in |
67 | | - * the hash map. |
68 | | - * |
69 | | - * @tparam Comparator The row comparator type to perform row equality comparison from row indices. |
70 | | - */ |
71 | | -template <typename DeviceComparator> |
72 | | -class pair_equality { |
73 | | - public: |
74 | | - pair_equality(DeviceComparator check_row_equality) |
75 | | - : _check_row_equality{std::move(check_row_equality)} |
76 | | - { |
77 | | - } |
78 | | - |
79 | | - // The parameters are build/probe rather than left/right because the operator |
80 | | - // is called by cuco's kernels with parameters in this order (note that this |
81 | | - // is an implementation detail that we should eventually stop relying on by |
82 | | - // defining operators with suitable heterogeneous typing). Rather than |
83 | | - // converting to left/right semantics, we can operate directly on build/probe |
84 | | - template <typename LhsPair, typename RhsPair> |
85 | | - __device__ __forceinline__ bool operator()(LhsPair const& lhs, RhsPair const& rhs) const noexcept |
86 | | - { |
87 | | - using detail::row::lhs_index_type; |
88 | | - using detail::row::rhs_index_type; |
89 | | - |
90 | | - return lhs.first == rhs.first and |
91 | | - _check_row_equality(lhs_index_type{rhs.second}, rhs_index_type{lhs.second}); |
92 | | - } |
93 | | - |
94 | | - private: |
95 | | - DeviceComparator _check_row_equality; |
96 | | -}; |
97 | | - |
98 | | -/** |
99 | | - * @brief Computes the trivial left join operation for the case when the |
100 | | - * right table is empty. |
101 | | - * |
102 | | - * In this case all the valid indices of the left table |
103 | | - * are returned with their corresponding right indices being set to |
104 | | - * `JoinNoMatch`, i.e. `cuda::std::numeric_limits<size_type>::min()`. |
105 | | - * |
106 | | - * @param left Table of left columns to join |
107 | | - * @param stream CUDA stream used for device memory operations and kernel launches |
108 | | - * @param mr Device memory resource used to allocate the result |
109 | | - * |
110 | | - * @return Join output indices vector pair |
111 | | - */ |
112 | | -std::pair<std::unique_ptr<rmm::device_uvector<size_type>>, |
113 | | - std::unique_ptr<rmm::device_uvector<size_type>>> |
114 | | -get_trivial_left_join_indices(table_view const& left, |
115 | | - rmm::cuda_stream_view stream, |
116 | | - rmm::device_async_resource_ref mr); |
117 | | - |
118 | | -/** |
119 | | - * @brief Builds the hash table based on the given `build_table`. |
120 | | - * |
121 | | - * @tparam MultimapType The type of the hash table |
122 | | - * |
123 | | - * @param build Table of columns used to build join hash. |
124 | | - * @param preprocessed_build shared_ptr to cudf::detail::row::equality::preprocessed_table |
125 | | - * for build |
126 | | - * @param hash_table Build hash table. |
127 | | - * @param has_nested_nulls Flag to denote if build or probe tables have nested nulls |
128 | | - * @param nulls_equal Flag to denote nulls are equal or not. |
129 | | - * @param bitmask Bitmask to denote whether a row is valid. |
130 | | - * @param stream CUDA stream used for device memory operations and kernel launches. |
131 | | - */ |
132 | | -template <typename HashTable> |
133 | | -void build_join_hash_table( |
134 | | - cudf::table_view const& build, |
135 | | - std::shared_ptr<detail::row::equality::preprocessed_table> const& preprocessed_build, |
136 | | - HashTable& hash_table, |
137 | | - bool has_nested_nulls, |
138 | | - null_equality nulls_equal, |
139 | | - [[maybe_unused]] bitmask_type const* bitmask, |
140 | | - rmm::cuda_stream_view stream) |
141 | | -{ |
142 | | - CUDF_EXPECTS(0 != build.num_columns(), "Selected build dataset is empty", std::invalid_argument); |
143 | | - CUDF_EXPECTS(0 != build.num_rows(), "Build side table has no rows", std::invalid_argument); |
144 | | - |
145 | | - auto insert_rows = [&](auto const& build, auto const& d_hasher) { |
146 | | - auto const iter = cudf::detail::make_counting_transform_iterator(0, pair_fn{d_hasher}); |
147 | | - |
148 | | - if (nulls_equal == cudf::null_equality::EQUAL or not nullable(build)) { |
149 | | - hash_table.insert_async(iter, iter + build.num_rows(), stream.value()); |
150 | | - } else { |
151 | | - auto const stencil = thrust::counting_iterator<size_type>{0}; |
152 | | - auto const pred = row_is_valid{bitmask}; |
153 | | - |
154 | | - // insert valid rows |
155 | | - hash_table.insert_if_async(iter, iter + build.num_rows(), stencil, pred, stream.value()); |
156 | | - } |
157 | | - }; |
158 | | - |
159 | | - auto const nulls = nullate::DYNAMIC{has_nested_nulls}; |
160 | | - |
161 | | - auto const row_hash = detail::row::hash::row_hasher{preprocessed_build}; |
162 | | - auto const d_hasher = row_hash.device_hasher(nulls); |
163 | | - |
164 | | - insert_rows(build, d_hasher); |
165 | | -} |
166 | | - |
167 | | -// Convenient alias for a pair of unique pointers to device uvectors. |
168 | | -using VectorPair = std::pair<std::unique_ptr<rmm::device_uvector<size_type>>, |
169 | | - std::unique_ptr<rmm::device_uvector<size_type>>>; |
170 | | - |
171 | | -/** |
172 | | - * @brief Takes two pairs of vectors and returns a single pair where the first |
173 | | - * element is a vector made from concatenating the first elements of both input |
174 | | - * pairs and the second element is a vector made from concatenating the second |
175 | | - * elements of both input pairs. |
176 | | - * |
177 | | - * This function's primary use is for computing the indices of a full join by |
178 | | - * first performing a left join, then separately getting the complementary |
179 | | - * right join indices, then finally calling this function to concatenate the |
180 | | - * results. In this case, each input VectorPair contains the left and right |
181 | | - * indices from a join. |
182 | | - * |
183 | | - * Note that this is a destructive operation, in that at least one of a or b |
184 | | - * will be invalidated (by a move) by this operation. Calling code should |
185 | | - * assume that neither input VectorPair is valid after this function executes. |
186 | | - * |
187 | | - * @param a The first pair of vectors. |
188 | | - * @param b The second pair of vectors. |
189 | | - * @param stream CUDA stream used for device memory operations and kernel launches |
190 | | - * |
191 | | - * @return A pair of vectors containing the concatenated output. |
192 | | - */ |
193 | | -VectorPair concatenate_vector_pairs(VectorPair& a, VectorPair& b, rmm::cuda_stream_view stream); |
194 | | - |
195 | | -/** |
196 | | - * @brief Creates a table containing the complement of left join indices. |
197 | | - * |
198 | | - * This table has two columns. The first one is filled with `JoinNoMatch` |
199 | | - * and the second one contains values from 0 to right_table_row_count - 1 |
200 | | - * excluding those found in the right_indices column. |
201 | | - * |
202 | | - * @param right_indices Vector of indices |
203 | | - * @param left_table_row_count Number of rows of left table |
204 | | - * @param right_table_row_count Number of rows of right table |
205 | | - * @param stream CUDA stream used for device memory operations and kernel launches. |
206 | | - * @param mr Device memory resource used to allocate the returned vectors. |
207 | | - * |
208 | | - * @return Pair of vectors containing the left join indices complement |
209 | | - */ |
210 | | -std::pair<std::unique_ptr<rmm::device_uvector<size_type>>, |
211 | | - std::unique_ptr<rmm::device_uvector<size_type>>> |
212 | | -get_left_join_indices_complement(std::unique_ptr<rmm::device_uvector<size_type>>& right_indices, |
213 | | - size_type left_table_row_count, |
214 | | - size_type right_table_row_count, |
215 | | - rmm::cuda_stream_view stream, |
216 | | - rmm::device_async_resource_ref mr); |
217 | | - |
218 | 51 | /** |
219 | 52 | * @brief Device functor to determine if an index is contained in a range. |
220 | 53 | */ |
|
0 commit comments