Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove probe-time null equality parameters in cudf::hash_join #10260

Merged
merged 4 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
8 changes: 4 additions & 4 deletions cpp/benchmarks/join/join.cu
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021, NVIDIA CORPORATION.
* Copyright (c) 2019-2022, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -49,7 +49,7 @@ void nvbench_inner_join(nvbench::state& state,
cudf::null_equality compare_nulls,
rmm::cuda_stream_view stream) {
cudf::hash_join hj_obj(left_input.select(left_on), compare_nulls, stream);
return hj_obj.inner_join(right_input.select(right_on), compare_nulls, std::nullopt, stream);
return hj_obj.inner_join(right_input.select(right_on), std::nullopt, stream);
};

BM_join<key_type, payload_type, Nullable>(state, join);
Expand All @@ -71,7 +71,7 @@ void nvbench_left_join(nvbench::state& state,
cudf::null_equality compare_nulls,
rmm::cuda_stream_view stream) {
cudf::hash_join hj_obj(left_input.select(left_on), compare_nulls, stream);
return hj_obj.left_join(right_input.select(right_on), compare_nulls, std::nullopt, stream);
return hj_obj.left_join(right_input.select(right_on), std::nullopt, stream);
};

BM_join<key_type, payload_type, Nullable>(state, join);
Expand All @@ -93,7 +93,7 @@ void nvbench_full_join(nvbench::state& state,
cudf::null_equality compare_nulls,
rmm::cuda_stream_view stream) {
cudf::hash_join hj_obj(left_input.select(left_on), compare_nulls, stream);
return hj_obj.full_join(right_input.select(right_on), compare_nulls, std::nullopt, stream);
return hj_obj.full_join(right_input.select(right_on), std::nullopt, stream);
};

BM_join<key_type, payload_type, Nullable>(state, join);
Expand Down
20 changes: 3 additions & 17 deletions cpp/include/cudf/join.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2020, NVIDIA CORPORATION.
* Copyright (c) 2019-2022, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -530,7 +530,6 @@ class hash_join {
* provided `output_size` is smaller than the actual output size.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param output_size Optional value which allows users to specify the exact output size.
* @param stream CUDA stream used for device memory operations and kernel launches
* @param mr Device memory resource used to allocate the returned table and columns' device
Expand All @@ -543,7 +542,6 @@ class hash_join {
std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
inner_join(cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
std::optional<std::size_t> output_size = {},
rmm::cuda_stream_view stream = rmm::cuda_stream_default,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()) const;
Expand All @@ -554,7 +552,6 @@ class hash_join {
* provided `output_size` is smaller than the actual output size.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param output_size Optional value which allows users to specify the exact output size.
* @param stream CUDA stream used for device memory operations and kernel launches
* @param mr Device memory resource used to allocate the returned table and columns' device
Expand All @@ -567,7 +564,6 @@ class hash_join {
std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
left_join(cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
std::optional<std::size_t> output_size = {},
rmm::cuda_stream_view stream = rmm::cuda_stream_default,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()) const;
Expand All @@ -578,7 +574,6 @@ class hash_join {
* provided `output_size` is smaller than the actual output size.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param output_size Optional value which allows users to specify the exact output size.
* @param stream CUDA stream used for device memory operations and kernel launches
* @param mr Device memory resource used to allocate the returned table and columns' device
Expand All @@ -591,7 +586,6 @@ class hash_join {
std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
full_join(cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
std::optional<std::size_t> output_size = {},
rmm::cuda_stream_view stream = rmm::cuda_stream_default,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()) const;
Expand All @@ -601,39 +595,32 @@ class hash_join {
* probe table.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param stream CUDA stream used for device memory operations and kernel launches
*
* @return The exact number of output when performing an inner join between two tables with
* `build` and `probe` as the the join keys .
*/
[[nodiscard]] std::size_t inner_join_size(
cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
rmm::cuda_stream_view stream = rmm::cuda_stream_default) const;
cudf::table_view const& probe, rmm::cuda_stream_view stream = rmm::cuda_stream_default) const;

/**
* Returns the exact number of matches (rows) when performing a left join with the specified probe
* table.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param stream CUDA stream used for device memory operations and kernel launches
*
* @return The exact number of output when performing a left join between two tables with `build`
* and `probe` as the the join keys .
*/
[[nodiscard]] std::size_t left_join_size(
cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
rmm::cuda_stream_view stream = rmm::cuda_stream_default) const;
cudf::table_view const& probe, rmm::cuda_stream_view stream = rmm::cuda_stream_default) const;

/**
* Returns the exact number of matches (rows) when performing a full join with the specified probe
* table.
*
* @param probe The probe table, from which the tuples are probed.
* @param compare_nulls Controls whether null join-key values should match or not.
* @param stream CUDA stream used for device memory operations and kernel launches
* @param mr Device memory resource used to allocate the intermediate table and columns' device
* memory.
Expand All @@ -643,7 +630,6 @@ class hash_join {
*/
std::size_t full_join_size(
cudf::table_view const& probe,
null_equality compare_nulls = null_equality::EQUAL,
rmm::cuda_stream_view stream = rmm::cuda_stream_default,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource()) const;

Expand Down
76 changes: 33 additions & 43 deletions cpp/src/join/hash_join.cu
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, NVIDIA CORPORATION.
* Copyright (c) 2020-2022, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -140,8 +140,8 @@ probe_join_hash_table(cudf::table_device_view build_table,
std::size_t get_full_join_size(cudf::table_device_view build_table,
cudf::table_device_view probe_table,
multimap_type const& hash_table,
bool has_nulls,
null_equality compare_nulls,
bool const has_nulls,
null_equality const compare_nulls,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
Expand Down Expand Up @@ -235,6 +235,7 @@ hash_join::hash_join_impl::hash_join_impl(cudf::table_view const& build,
null_equality compare_nulls,
rmm::cuda_stream_view stream)
: _is_empty{build.num_rows() == 0},
_nulls_equal{compare_nulls},
_hash_table{compute_hash_table_size(build.num_rows()),
std::numeric_limits<hash_value_type>::max(),
cudf::detail::JoinNoneValue,
Expand All @@ -253,50 +254,43 @@ hash_join::hash_join_impl::hash_join_impl(cudf::table_view const& build,

if (_is_empty) { return; }

build_join_hash_table(_build, _hash_table, compare_nulls, stream);
cudf::detail::build_join_hash_table(_build, _hash_table, _nulls_equal, stream);
}

std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
hash_join::hash_join_impl::inner_join(cudf::table_view const& probe,
null_equality compare_nulls,
std::optional<std::size_t> output_size,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
{
CUDF_FUNC_RANGE();
return compute_hash_join<cudf::detail::join_kind::INNER_JOIN>(
probe, compare_nulls, output_size, stream, mr);
return compute_hash_join<cudf::detail::join_kind::INNER_JOIN>(probe, output_size, stream, mr);
}

std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
hash_join::hash_join_impl::left_join(cudf::table_view const& probe,
null_equality compare_nulls,
std::optional<std::size_t> output_size,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
{
CUDF_FUNC_RANGE();
return compute_hash_join<cudf::detail::join_kind::LEFT_JOIN>(
probe, compare_nulls, output_size, stream, mr);
return compute_hash_join<cudf::detail::join_kind::LEFT_JOIN>(probe, output_size, stream, mr);
}

std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
hash_join::hash_join_impl::full_join(cudf::table_view const& probe,
null_equality compare_nulls,
std::optional<std::size_t> output_size,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
{
CUDF_FUNC_RANGE();
return compute_hash_join<cudf::detail::join_kind::FULL_JOIN>(
probe, compare_nulls, output_size, stream, mr);
return compute_hash_join<cudf::detail::join_kind::FULL_JOIN>(probe, output_size, stream, mr);
}

std::size_t hash_join::hash_join_impl::inner_join_size(cudf::table_view const& probe,
null_equality compare_nulls,
rmm::cuda_stream_view stream) const
{
CUDF_FUNC_RANGE();
Expand All @@ -316,12 +310,11 @@ std::size_t hash_join::hash_join_impl::inner_join_size(cudf::table_view const& p
*flattened_probe_table_ptr,
_hash_table,
cudf::has_nulls(flattened_probe_table) | cudf::has_nulls(_build),
compare_nulls,
_nulls_equal,
stream);
}

std::size_t hash_join::hash_join_impl::left_join_size(cudf::table_view const& probe,
null_equality compare_nulls,
rmm::cuda_stream_view stream) const
{
CUDF_FUNC_RANGE();
Expand All @@ -341,12 +334,11 @@ std::size_t hash_join::hash_join_impl::left_join_size(cudf::table_view const& pr
*flattened_probe_table_ptr,
_hash_table,
cudf::has_nulls(flattened_probe_table) | cudf::has_nulls(_build),
compare_nulls,
_nulls_equal,
stream);
}

std::size_t hash_join::hash_join_impl::full_join_size(cudf::table_view const& probe,
null_equality compare_nulls,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
{
Expand All @@ -362,20 +354,20 @@ std::size_t hash_join::hash_join_impl::full_join_size(cudf::table_view const& pr
auto build_table_ptr = cudf::table_device_view::create(_build, stream);
auto flattened_probe_table_ptr = cudf::table_device_view::create(flattened_probe_table, stream);

return get_full_join_size(*build_table_ptr,
*flattened_probe_table_ptr,
_hash_table,
cudf::has_nulls(flattened_probe_table) | cudf::has_nulls(_build),
compare_nulls,
stream,
mr);
return cudf::detail::get_full_join_size(
*build_table_ptr,
*flattened_probe_table_ptr,
_hash_table,
cudf::has_nulls(flattened_probe_table) | cudf::has_nulls(_build),
_nulls_equal,
stream,
mr);
}

template <cudf::detail::join_kind JoinKind>
std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
hash_join::hash_join_impl::compute_hash_join(cudf::table_view const& probe,
null_equality compare_nulls,
std::optional<std::size_t> output_size,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
Expand Down Expand Up @@ -403,42 +395,40 @@ hash_join::hash_join_impl::compute_hash_join(cudf::table_view const& probe,
[](const auto& b, const auto& p) { return b.type() == p.type(); }),
"Mismatch in joining column data types");

return probe_join_indices<JoinKind>(
flattened_probe_table, compare_nulls, output_size, stream, mr);
return probe_join_indices<JoinKind>(flattened_probe_table, output_size, stream, mr);
}

template <cudf::detail::join_kind JoinKind>
std::pair<std::unique_ptr<rmm::device_uvector<size_type>>,
std::unique_ptr<rmm::device_uvector<size_type>>>
hash_join::hash_join_impl::probe_join_indices(cudf::table_view const& probe,
null_equality compare_nulls,
hash_join::hash_join_impl::probe_join_indices(cudf::table_view const& probe_table,
std::optional<std::size_t> output_size,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr) const
{
// Trivial left join case - exit early
if (_is_empty and JoinKind != cudf::detail::join_kind::INNER_JOIN) {
return get_trivial_left_join_indices(probe, stream, mr);
return get_trivial_left_join_indices(probe_table, stream, mr);
}

CUDF_EXPECTS(!_is_empty, "Hash table of hash join is null.");

auto build_table_ptr = cudf::table_device_view::create(_build, stream);
auto probe_table_ptr = cudf::table_device_view::create(probe, stream);

auto join_indices =
cudf::detail::probe_join_hash_table<JoinKind>(*build_table_ptr,
*probe_table_ptr,
_hash_table,
cudf::has_nulls(probe) | cudf::has_nulls(_build),
compare_nulls,
output_size,
stream,
mr);
auto probe_table_ptr = cudf::table_device_view::create(probe_table, stream);

auto join_indices = cudf::detail::probe_join_hash_table<JoinKind>(
*build_table_ptr,
*probe_table_ptr,
_hash_table,
cudf::has_nulls(probe_table) | cudf::has_nulls(_build),
_nulls_equal,
output_size,
stream,
mr);

if constexpr (JoinKind == cudf::detail::join_kind::FULL_JOIN) {
auto complement_indices = detail::get_left_join_indices_complement(
join_indices.second, probe.num_rows(), _build.num_rows(), stream, mr);
join_indices.second, probe_table.num_rows(), _build.num_rows(), stream, mr);
join_indices = detail::concatenate_vector_pairs(join_indices, complement_indices, stream);
}
return join_indices;
Expand Down
Loading