Skip to content
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3df7dce
nested template instantiation for hiding types
tgujar May 6, 2024
088042c
hasher conditional type dispatch works
tgujar May 7, 2024
34bad1e
delete dead comment block
tgujar May 8, 2024
40f291e
Fix docs
PointKernel May 14, 2024
b56bf75
fix type logic, minor refactor
tgujar May 17, 2024
078f53d
refactor
tgujar May 17, 2024
14785e4
added template specialization for equality comparator
tgujar May 29, 2024
b88b60b
added template specialized calls to comparator
tgujar May 30, 2024
1b89198
fix for register usage discrepancy
tgujar May 31, 2024
ca63201
fix for register usage discrepancy
tgujar May 31, 2024
ff5e0d4
revert edited comment blocks
tgujar Jun 3, 2024
80a9f61
added variant visitor pattern to avoid duplication for hasher
tgujar Jun 4, 2024
b8ad315
added variant visitor pattern for comparator
tgujar Jun 4, 2024
e29e346
add template specialization for hash joins
tgujar Jun 5, 2024
27fa7a0
add template specialization for hash join size
tgujar Jun 5, 2024
073a328
Merge branch 'branch-24.08' into hash-occupancy
PointKernel Jun 6, 2024
04f3906
minor refactor
tgujar Jun 7, 2024
90f33b4
fixup naming and docs
tgujar Jun 10, 2024
a016cd2
separate mixed semi join into multiple TU
tgujar Jul 12, 2024
8fc47df
Merge branch 'branch-24.08' into hash-occupancy
PointKernel Jul 12, 2024
0dc17ac
compile fails because traits not satisfied
tgujar Jul 15, 2024
ac5391d
compile fails with no instance of constructor
tgujar Jul 16, 2024
83ded25
compile fails with constructor not found
tgujar Jul 16, 2024
5306d1d
fix HasNested interaction, compile still fails
tgujar Jul 16, 2024
62c60fa
fails with illegal access
tgujar Jul 17, 2024
fbcf50f
fix illegal mem access
tgujar Jul 18, 2024
946d56f
fix index type
tgujar Jul 18, 2024
fe2ff8b
Merge branch 'branch-24.08' into distinct-join-occupancy
tgujar Jul 18, 2024
3febec0
Merge branch 'branch-24.08' into distinct-join-occupancy
tgujar Jul 26, 2024
77be694
Merge branch 'rapidsai:branch-24.10' into distinct-join-occupancy
tgujar Jul 26, 2024
0ad9407
Merge branch 'branch-24.10' into hash-occupancy
tgujar Jul 31, 2024
74219fe
use CUDF_HIDDEN
tgujar Jul 31, 2024
448b14b
address review comments
tgujar Aug 1, 2024
b30f6ed
Merge branch 'distinct-join-occupancy' into hash-occupancy
tgujar Aug 1, 2024
621e29f
Merge branch 'branch-24.10' into hash-occupancy
ttnghia Aug 2, 2024
970a829
address review comments
tgujar Aug 2, 2024
d063dbc
Merge branch 'branch-24.10' into hash-occupancy
tgujar Aug 23, 2024
50341bd
Merge branch 'branch-24.10' into hash-occupancy
PointKernel Aug 23, 2024
470d6e2
fix issue with distinct hash join
tgujar Aug 26, 2024
57c9b5e
address review comments
tgujar Sep 4, 2024
8e6e6e5
refactor find_any
tgujar Sep 4, 2024
9cd1bda
Merge branch 'branch-24.10' into hash-occupancy
tgujar Sep 4, 2024
7d48f52
Merge branch 'branch-24.10' into hash-occupancy
tgujar Sep 18, 2024
728478f
remove redundant SFINAE check
tgujar Sep 18, 2024
926342f
use distance from thrust namespace
tgujar Sep 18, 2024
d82754d
update docs
tgujar Sep 18, 2024
c78da6b
fix spelling
tgujar Sep 18, 2024
daa2b40
merge branch-24.10, needs fixes
tgujar Sep 19, 2024
30ab4e3
fail with instantiating correct type
tgujar Sep 25, 2024
f1db848
fix issue with constness
tgujar Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
363 changes: 344 additions & 19 deletions cpp/include/cudf/table/experimental/row_operators.cuh

Large diffs are not rendered by default.

126 changes: 77 additions & 49 deletions cpp/src/join/hash_join.cu
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <cstddef>
#include <iostream>
#include <numeric>
#include <variant>

namespace cudf {
namespace detail {
Expand Down Expand Up @@ -97,33 +98,44 @@ std::size_t compute_join_output_size(
}

auto const probe_nulls = cudf::nullate::DYNAMIC{has_nulls};
std::unordered_set<cudf::type_id> probe_column_types;
for (auto col : probe_table) {
probe_column_types.insert(col.type().id());
}

auto const row_hash = cudf::experimental::row::hash::row_hasher{preprocessed_probe};
auto const hash_probe = row_hash.device_hasher(probe_nulls);
auto const hash_probe = row_hash.device_hasher(probe_column_types, probe_nulls);
auto const empty_key_sentinel = hash_table.get_empty_key_sentinel();
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hash_probe, empty_key_sentinel});

auto const row_comparator =
cudf::experimental::row::equality::two_table_comparator{preprocessed_probe, preprocessed_build};
auto const comparator_helper = [&](auto device_comparator) {
pair_equality equality{device_comparator};

if (join == join_kind::LEFT_JOIN) {
return hash_table.pair_count_outer(
iter, iter + probe_table_num_rows, equality, stream.value());
return std::visit(
[&](auto&& hasher) {
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hasher, empty_key_sentinel});
return hash_table.pair_count_outer(
iter, iter + probe_table_num_rows, equality, stream.value());
},
hash_probe);
} else {
return hash_table.pair_count(iter, iter + probe_table_num_rows, equality, stream.value());
return std::visit(
[&](auto&& hasher) {
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hasher, empty_key_sentinel});
return hash_table.pair_count(iter, iter + probe_table_num_rows, equality, stream.value());
},
hash_probe);
}
};

if (cudf::detail::has_nested_columns(probe_table)) {
auto const device_comparator = row_comparator.equal_to<true>(has_nulls, nulls_equal);
return comparator_helper(device_comparator);
} else {
auto const device_comparator = row_comparator.equal_to<false>(has_nulls, nulls_equal);
return comparator_helper(device_comparator);
}
auto const device_comparator =
row_comparator.equal_to(probe_column_types, has_nulls, nulls_equal);
return std::visit([&](auto&& comparator) { return comparator_helper(comparator); },
device_comparator);
}

/**
Expand Down Expand Up @@ -187,12 +199,14 @@ probe_join_hash_table(
auto right_indices = std::make_unique<rmm::device_uvector<size_type>>(join_size, stream, mr);

auto const probe_nulls = cudf::nullate::DYNAMIC{has_nulls};
std::unordered_set<cudf::type_id> probe_column_types;
for (auto col : probe_table) {
probe_column_types.insert(col.type().id());
}

auto const row_hash = cudf::experimental::row::hash::row_hasher{preprocessed_probe};
auto const hash_probe = row_hash.device_hasher(probe_nulls);
auto const hash_probe = row_hash.device_hasher(probe_column_types, probe_nulls);
auto const empty_key_sentinel = hash_table.get_empty_key_sentinel();
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hash_probe, empty_key_sentinel});

cudf::size_type const probe_table_num_rows = probe_table.num_rows();

Expand All @@ -207,36 +221,42 @@ probe_join_hash_table(
pair_equality equality{device_comparator};

if (join == cudf::detail::join_kind::FULL_JOIN or join == cudf::detail::join_kind::LEFT_JOIN) {
[[maybe_unused]] auto [out1_zip_end, out2_zip_end] =
hash_table.pair_retrieve_outer(iter,
iter + probe_table_num_rows,
out1_zip_begin,
out2_zip_begin,
equality,
stream.value());
[[maybe_unused]] auto [out1_zip_end, out2_zip_end] = std::visit(
[&](auto&& hasher) {
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hasher, empty_key_sentinel});
return hash_table.pair_retrieve_outer(iter,
iter + probe_table_num_rows,
out1_zip_begin,
out2_zip_begin,
equality,
stream.value());
},
hash_probe);

if (join == cudf::detail::join_kind::FULL_JOIN) {
auto const actual_size = thrust::distance(out1_zip_begin, out1_zip_end);
left_indices->resize(actual_size, stream);
right_indices->resize(actual_size, stream);
}
} else {
hash_table.pair_retrieve(iter,
iter + probe_table_num_rows,
out1_zip_begin,
out2_zip_begin,
equality,
stream.value());
std::visit(
[&](auto&& hasher) {
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hasher, empty_key_sentinel});
hash_table.pair_retrieve(iter,
iter + probe_table_num_rows,
out1_zip_begin,
out2_zip_begin,
equality,
stream.value());
},
hash_probe);
}
};

if (cudf::detail::has_nested_columns(probe_table)) {
auto const device_comparator = row_comparator.equal_to<true>(probe_nulls, compare_nulls);
comparator_helper(device_comparator);
} else {
auto const device_comparator = row_comparator.equal_to<false>(probe_nulls, compare_nulls);
comparator_helper(device_comparator);
}
auto const device_comparator =
row_comparator.equal_to(probe_column_types, probe_nulls, compare_nulls);
std::visit([&](auto&& comparator) { comparator_helper(comparator); }, device_comparator);

return std::pair(std::move(left_indices), std::move(right_indices));
}
Expand Down Expand Up @@ -289,12 +309,14 @@ std::size_t get_full_join_size(
auto right_indices = std::make_unique<rmm::device_uvector<size_type>>(join_size, stream, mr);

auto const probe_nulls = cudf::nullate::DYNAMIC{has_nulls};
std::unordered_set<cudf::type_id> probe_column_types;
for (auto col : probe_table) {
probe_column_types.insert(col.type().id());
}

auto const row_hash = cudf::experimental::row::hash::row_hasher{preprocessed_probe};
auto const hash_probe = row_hash.device_hasher(probe_nulls);
auto const hash_probe = row_hash.device_hasher(probe_column_types, probe_nulls);
auto const empty_key_sentinel = hash_table.get_empty_key_sentinel();
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hash_probe, empty_key_sentinel});

cudf::size_type const probe_table_num_rows = probe_table.num_rows();

Expand All @@ -307,16 +329,22 @@ std::size_t get_full_join_size(
cudf::experimental::row::equality::two_table_comparator{preprocessed_probe, preprocessed_build};
auto const comparator_helper = [&](auto device_comparator) {
pair_equality equality{device_comparator};
hash_table.pair_retrieve_outer(
iter, iter + probe_table_num_rows, out1_zip_begin, out2_zip_begin, equality, stream.value());
std::visit(
[&](auto&& hasher) {
auto const iter = cudf::detail::make_counting_transform_iterator(
0, make_pair_function{hasher, empty_key_sentinel});
hash_table.pair_retrieve_outer(iter,
iter + probe_table_num_rows,
out1_zip_begin,
out2_zip_begin,
equality,
stream.value());
},
hash_probe);
};
if (cudf::detail::has_nested_columns(probe_table)) {
auto const device_comparator = row_comparator.equal_to<true>(probe_nulls, compare_nulls);
comparator_helper(device_comparator);
} else {
auto const device_comparator = row_comparator.equal_to<false>(probe_nulls, compare_nulls);
comparator_helper(device_comparator);
}
auto const device_comparator =
row_comparator.equal_to(probe_column_types, probe_nulls, compare_nulls);
std::visit([&](auto&& comparator) { comparator_helper(comparator); }, device_comparator);

// Release intermediate memory allocation
left_indices->resize(0, stream);
Expand Down
28 changes: 21 additions & 7 deletions cpp/src/join/join_common_utils.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -177,23 +177,37 @@ void build_join_hash_table(
CUDF_EXPECTS(0 != build.num_columns(), "Selected build dataset is empty");
CUDF_EXPECTS(0 != build.num_rows(), "Build side table has no rows");

std::unordered_set<cudf::type_id> build_column_types;
for (auto col : build) {
build_column_types.insert(col.type().id());
}

auto const row_hash = experimental::row::hash::row_hasher{preprocessed_build};
auto const hash_build = row_hash.device_hasher(nullate::DYNAMIC{has_nulls});
auto const hash_build = row_hash.device_hasher(build_column_types, nullate::DYNAMIC{has_nulls});

auto const empty_key_sentinel = hash_table.get_empty_key_sentinel();
make_pair_function pair_func{hash_build, empty_key_sentinel};

auto const iter = cudf::detail::make_counting_transform_iterator(0, pair_func);

size_type const build_table_num_rows{build.num_rows()};
if (nulls_equal == cudf::null_equality::EQUAL or (not nullable(build))) {
hash_table.insert(iter, iter + build_table_num_rows, stream.value());
std::visit(
[&](auto&& hasher) {
make_pair_function pair_func{hasher, empty_key_sentinel};
auto const iter = cudf::detail::make_counting_transform_iterator(0, pair_func);
hash_table.insert(iter, iter + build_table_num_rows, stream.value());
},
hash_build);
} else {
thrust::counting_iterator<size_type> stencil(0);
row_is_valid pred{bitmask};

// insert valid rows
hash_table.insert_if(iter, iter + build_table_num_rows, stencil, pred, stream.value());
std::visit(
[&](auto&& hasher) {
make_pair_function pair_func{hasher, empty_key_sentinel};
auto const iter = cudf::detail::make_counting_transform_iterator(0, pair_func);
// insert valid rows
hash_table.insert_if(iter, iter + build_table_num_rows, stencil, pred, stream.value());
},
hash_build);
}
}

Expand Down
13 changes: 12 additions & 1 deletion cpp/src/join/mixed_join_common_utils.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,18 @@ namespace detail {

using row_hash =
cudf::experimental::row::hash::device_row_hasher<cudf::hashing::detail::default_hash,
cudf::nullate::DYNAMIC>;
cudf::nullate::DYNAMIC,
cudf::experimental::type_identity_t>;

using row_hash_no_nested =
cudf::experimental::row::hash::device_row_hasher<cudf::hashing::detail::default_hash,
cudf::nullate::DYNAMIC,
cudf::experimental::dispatch_void_if_nested_t>;

using row_hash_no_compound =
cudf::experimental::row::hash::device_row_hasher<cudf::hashing::detail::default_hash,
cudf::nullate::DYNAMIC,
cudf::experimental::dispatch_void_if_compound_t>;

// // This alias is used by mixed_joins, which support only non-nested types
using row_equality = cudf::experimental::row::equality::strong_index_comparator_adapter<
Expand Down
52 changes: 48 additions & 4 deletions cpp/src/join/mixed_join_kernels_semi.cu
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ namespace cg = cooperative_groups;

#pragma GCC diagnostic ignored "-Wattributes"

template <cudf::size_type block_size, bool has_nulls>
template <cudf::size_type block_size, bool has_nulls, typename HashProbe>
__attribute__((visibility("hidden"))) __launch_bounds__(block_size) __global__
void mixed_join_semi(table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash const hash_probe,
HashProbe const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
Expand Down Expand Up @@ -74,7 +74,7 @@ __attribute__((visibility("hidden"))) __launch_bounds__(block_size) __global__
}
}

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, true>(
template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, true, row_hash>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
Expand All @@ -85,7 +85,7 @@ template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, true>(
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, false>(
template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, false, row_hash>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
Expand All @@ -96,6 +96,50 @@ template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, false>(
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, true, row_hash_no_nested>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash_no_nested const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, false, row_hash_no_nested>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash_no_nested const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, true, row_hash_no_compound>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash_no_compound const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

template __global__ void mixed_join_semi<DEFAULT_JOIN_BLOCK_SIZE, false, row_hash_no_compound>(
table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash_no_compound const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
cudf::ast::detail::expression_device_view device_expression_data);

} // namespace detail

} // namespace cudf
4 changes: 2 additions & 2 deletions cpp/src/join/mixed_join_kernels_semi.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ namespace detail {
* @param[in] device_expression_data Container of device data required to evaluate the desired
* expression.
*/
template <cudf::size_type block_size, bool has_nulls>
template <cudf::size_type block_size, bool has_nulls, typename HashProbe>
__global__ void mixed_join_semi(table_device_view left_table,
table_device_view right_table,
table_device_view probe,
table_device_view build,
row_hash const hash_probe,
HashProbe const hash_probe,
row_equality const equality_probe,
cudf::detail::semi_map_type::device_view hash_table_view,
cudf::device_span<bool> left_table_keep_mask,
Expand Down
Loading