20 #include <cudf/detail/utilities/assert.cuh>
21 #include <cudf/hashing/detail/hash_functions.cuh>
22 #include <cudf/hashing/detail/hashing.hpp>
27 #include <cuda/std/limits>
28 #include <thrust/equal.h>
29 #include <thrust/execution_policy.h>
30 #include <thrust/iterator/counting_iterator.h>
31 #include <thrust/transform_reduce.h>
33 namespace CUDF_EXPORT
cudf {
58 template <
typename Element>
59 __device__ weak_ordering compare_elements(Element lhs, Element rhs)
62 return weak_ordering::LESS;
63 }
else if (rhs < lhs) {
64 return weak_ordering::GREATER;
66 return weak_ordering::EQUIVALENT;
79 template <
typename Element>
81 requires(std::is_floating_point_v<Element>)
83 if (isnan(lhs) and isnan(rhs)) {
84 return weak_ordering::EQUIVALENT;
85 }
else if (isnan(rhs)) {
86 return weak_ordering::LESS;
87 }
else if (isnan(lhs)) {
88 return weak_ordering::GREATER;
91 return detail::compare_elements(lhs, rhs);
104 if (lhs_is_null and rhs_is_null) {
105 return weak_ordering::EQUIVALENT;
106 }
else if (lhs_is_null) {
107 return (null_precedence == null_order::BEFORE) ? weak_ordering::LESS : weak_ordering::GREATER;
108 }
else if (rhs_is_null) {
109 return (null_precedence == null_order::AFTER) ? weak_ordering::LESS : weak_ordering::GREATER;
111 return weak_ordering::EQUIVALENT;
122 template <
typename Element>
123 __device__ weak_ordering relational_compare(Element lhs, Element rhs)
124 requires(not std::is_floating_point_v<Element>)
126 return detail::compare_elements(lhs, rhs);
137 template <
typename Element>
139 requires(std::is_floating_point_v<Element>)
141 if (isnan(lhs) and isnan(rhs)) {
return true; }
153 template <
typename Element>
154 __device__
bool equality_compare(Element
const lhs, Element
const rhs)
155 requires(not std::is_floating_point_v<Element>)
165 template <
typename Nullate>
184 : lhs{lhs}, rhs{rhs}, nulls{
has_nulls}, nulls_are_equal{nulls_are_equal}
195 template <
typename Element>
197 size_type rhs_element_index)
const noexcept
198 requires(cudf::is_equality_comparable<Element, Element>())
201 bool const lhs_is_null{lhs.is_null(lhs_element_index)};
202 bool const rhs_is_null{rhs.is_null(rhs_element_index)};
203 if (lhs_is_null and rhs_is_null) {
204 return nulls_are_equal == null_equality::EQUAL;
205 }
else if (lhs_is_null != rhs_is_null) {
211 rhs.element<Element>(rhs_element_index));
215 template <
typename Element>
217 requires(not cudf::is_equality_comparable<Element, Element>())
219 CUDF_UNREACHABLE(
"Attempted to compare elements of uncomparable types.");
224 column_device_view lhs;
225 column_device_view rhs;
235 template <
typename Nullate>
250 : lhs{lhs}, rhs{rhs}, nulls{
has_nulls}, nulls_are_equal{nulls_are_equal}
272 return thrust::equal(thrust::seq, lhs.begin(), lhs.end(), rhs.begin(), equal_elements);
287 template <
typename Nullate>
305 : lhs{lhs}, rhs{rhs}, nulls{
has_nulls}, null_precedence{null_precedence}
332 template <
typename Element>
334 size_type rhs_element_index)
const noexcept
335 requires(cudf::is_relationally_comparable<Element, Element>())
338 bool const lhs_is_null{lhs.is_null(lhs_element_index)};
339 bool const rhs_is_null{rhs.is_null(rhs_element_index)};
341 if (lhs_is_null or rhs_is_null) {
342 return null_compare(lhs_is_null, rhs_is_null, null_precedence);
347 rhs.element<Element>(rhs_element_index));
351 template <
typename Element>
353 requires(not cudf::is_relationally_comparable<Element, Element>())
355 CUDF_UNREACHABLE(
"Attempted to compare elements of uncomparable types.");
360 column_device_view lhs;
361 column_device_view rhs;
381 template <
typename Nullate>
406 order const* column_order =
nullptr,
411 _column_order{column_order},
412 _null_precedence{null_precedence}
414 CUDF_EXPECTS(_lhs.num_columns() == _rhs.num_columns(),
"Mismatched number of columns.");
428 for (
size_type i = 0; i < _lhs.num_columns(); ++i) {
429 bool ascending = (_column_order ==
nullptr) or (_column_order[i] == order::ASCENDING);
432 _null_precedence ==
nullptr ? null_order::BEFORE : _null_precedence[i];
440 if (state == weak_ordering::EQUIVALENT) {
continue; }
442 return state == (ascending ? weak_ordering::LESS : weak_ordering::GREATER);
452 order const* _column_order{};
461 template <
template <
typename>
class hash_function,
typename Nullate>
472 template <typename T, CUDF_ENABLE_IF(column_device_view::has_element_accessor<T>())>
476 return cuda::std::numeric_limits<hash_value_type>::max();
478 return hash_function<T>{}(col.
element<T>(row_index));
489 template <typename T, CUDF_ENABLE_IF(not column_device_view::has_element_accessor<T>())>
492 CUDF_UNREACHABLE(
"Unsupported type in hash.");
504 template <
template <
typename>
class hash_function,
typename Nullate>
526 : _seed{seed}, _null_hash{null_hash}, _has_nulls{
has_nulls}
538 template <typename T, CUDF_ENABLE_IF(column_device_view::has_element_accessor<T>())>
541 if (_has_nulls && col.
is_null(row_index)) {
return _null_hash; }
542 return hash_function<T>{_seed}(col.
element<T>(row_index));
553 template <typename T, CUDF_ENABLE_IF(not column_device_view::has_element_accessor<T>())>
556 CUDF_UNREACHABLE(
"Unsupported type in hash.");
560 uint32_t _seed{DEFAULT_HASH_SEED};
561 hash_value_type _null_hash{cuda::std::numeric_limits<hash_value_type>::max()};
571 template <
template <
typename>
class hash_function,
typename Nullate>
594 : _table{t}, _seed(seed), _has_nulls{
has_nulls}
607 auto const initial_hash = cudf::hashing::detail::hash_combine(
609 type_dispatcher<dispatch_storage_type>(
610 _table.column(0).type(),
616 auto hasher = [row_index,
this](
size_type column_index) {
617 return cudf::type_dispatcher<dispatch_storage_type>(
618 _table.column(column_index).type(),
620 _table.column(column_index),
625 return thrust::transform_reduce(
628 thrust::make_counting_iterator(1),
629 thrust::make_counting_iterator(_table.num_columns()),
633 return cudf::hashing::detail::hash_combine(lhs, rhs);
640 uint32_t _seed{DEFAULT_HASH_SEED};
An immutable, non-owning view of device data as a column of elements that is trivially copyable and u...
T element(size_type element_index) const noexcept
Returns a copy of the element at the specified index.
bool is_null(size_type element_index) const noexcept
Returns whether the specified element is null.
size_type num_columns() const noexcept
Returns the number of columns.
Performs an equality comparison between two elements in two columns.
bool operator()(size_type lhs_element_index, size_type rhs_element_index) const noexcept requires(cudf
Compares the specified elements for equality.
element_equality_comparator(Nullate has_nulls, column_device_view lhs, column_device_view rhs, null_equality nulls_are_equal=null_equality::EQUAL)
Construct type-dispatched function object for comparing equality between two elements.
Function object for computing the hash value of a row in a column.
element_hasher_with_seed(Nullate has_nulls, uint32_t seed)
Constructs a function object for hashing an element in the given column.
element_hasher_with_seed(Nullate has_nulls, uint32_t seed, hash_value_type null_hash)
Constructs a function object for hashing an element in the given column.
Computes the hash value of an element in the given column.
Nullate has_nulls
A cudf::nullate type describing how to check for nulls.
Performs a relational comparison between two elements in two columns.
element_relational_comparator(Nullate has_nulls, column_device_view lhs, column_device_view rhs)
Construct type-dispatched function object for performing a relational comparison between two elements...
weak_ordering operator()(size_type lhs_element_index, size_type rhs_element_index) const noexcept requires(cudf
Performs a relational comparison between the specified elements.
element_relational_comparator(Nullate has_nulls, column_device_view lhs, column_device_view rhs, null_order null_precedence)
Construct type-dispatched function object for performing a relational comparison between two elements...
Performs a relational comparison between two elements in two tables.
row_equality_comparator(Nullate has_nulls, table_device_view lhs, table_device_view rhs, null_equality nulls_are_equal=null_equality::EQUAL)
Construct a new row equality comparator object.
bool operator()(size_type lhs_row_index, size_type rhs_row_index) const noexcept
Compares the specified rows for equality.
Computes the hash value of a row in the given table.
CUDF_HOST_DEVICE row_hasher(Nullate has_nulls, table_device_view t, uint32_t seed)
Constructs a row_hasher object with a seed value.
CUDF_HOST_DEVICE row_hasher(Nullate has_nulls, table_device_view t)
Constructs a row_hasher object.
auto operator()(size_type row_index) const
Computes the hash value of the row at row_index in the table
Computes whether one row is lexicographically less than another row.
bool operator()(size_type lhs_index, size_type rhs_index) const noexcept
Checks whether the row at lhs_index in the lhs table compares lexicographically less than the row at ...
row_lexicographic_comparator(Nullate has_nulls, table_device_view lhs, table_device_view rhs, order const *column_order=nullptr, null_order const *null_precedence=nullptr)
Construct a function object for performing a lexicographic comparison between the rows of two tables.
Table device view that is usable in device memory.
Column device view class definitions.
uint32_t hash_value_type
Type of hash value.
CUDF_HOST_DEVICE constexpr decltype(auto) __forceinline__ type_dispatcher(cudf::data_type dtype, Functor f, Ts &&... args)
Invokes an operator() template with the type instantiation based on the specified cudf::data_type's i...
#define CUDF_EXPECTS(...)
Macro for checking (pre-)conditions that throws an exception when a condition is violated.
null_order
Indicates how null values compare against all other values.
null_equality
Enum to consider two nulls as equal or unequal.
int32_t size_type
Row index type for columns and tables.
order
Indicates the order in which elements should be sorted.
bool has_nulls(table_view const &view)
Returns True if the table has nulls in any of its columns.
bool equality_compare(Element lhs, Element rhs) requires(std
A specialization for floating-point Element type to check if lhs is equivalent to rhs....
weak_ordering relational_compare(Element lhs, Element rhs) requires(std
A specialization for floating-point Element type relational comparison to derive the order of the ele...
weak_ordering
Result type of the element_relational_comparator function object.
@ EQUIVALENT
Indicates a is ordered neither before nor after b
auto null_compare(bool lhs_is_null, bool rhs_is_null, null_order null_precedence)
Compare the nulls according to null order.
Table device view class definitions.
Defines the mapping between cudf::type_id runtime type information and concrete C++ types.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.