-
Notifications
You must be signed in to change notification settings - Fork 919
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Configurable NaN handling in device_row_comparators (#10870)
Further splitting up #9452 -- split off at the suggestion of @bdice Related to #10781 and #4760 -- issues and discussions related to NaN comparison behavior. Authors: - Ryan Lee (https://github.com/rwlee) - Bradley Dice (https://github.com/bdice) Approvers: - Jake Hemstad (https://github.com/jrhemstad) - Bradley Dice (https://github.com/bdice) - Nghia Truong (https://github.com/ttnghia) URL: #10870
- Loading branch information
Showing
10 changed files
with
534 additions
and
81 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
/* | ||
* Copyright (c) 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. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <cudf_test/base_fixture.hpp> | ||
#include <cudf_test/column_utilities.hpp> | ||
#include <cudf_test/column_wrapper.hpp> | ||
#include <cudf_test/type_lists.hpp> | ||
|
||
#include <cudf/column/column_view.hpp> | ||
#include <cudf/detail/utilities/vector_factories.hpp> | ||
#include <cudf/table/experimental/row_operators.cuh> | ||
#include <cudf/table/row_operators.cuh> | ||
#include <cudf/table/table_device_view.cuh> | ||
#include <cudf/table/table_view.hpp> | ||
|
||
#include <rmm/cuda_stream_view.hpp> | ||
#include <rmm/exec_policy.hpp> | ||
|
||
#include <thrust/iterator/counting_iterator.h> | ||
#include <thrust/transform.h> | ||
|
||
#include <cmath> | ||
#include <vector> | ||
|
||
using namespace cudf::test; | ||
using namespace cudf::experimental::row; | ||
|
||
template <typename T> | ||
struct TypedTableViewTest : public cudf::test::BaseFixture { | ||
}; | ||
|
||
using NumericTypesNotBool = Concat<IntegralTypesNotBool, FloatingPointTypes>; | ||
TYPED_TEST_SUITE(TypedTableViewTest, NumericTypesNotBool); | ||
|
||
template <typename PhysicalElementComparator> | ||
auto self_comparison(cudf::table_view input, | ||
std::vector<cudf::order> const& column_order, | ||
PhysicalElementComparator comparator) | ||
{ | ||
rmm::cuda_stream_view stream{}; | ||
|
||
auto const table_comparator = lexicographic::self_comparator{input, column_order, {}, stream}; | ||
auto const less_comparator = table_comparator.less(cudf::nullate::NO{}, comparator); | ||
|
||
auto output = cudf::make_numeric_column( | ||
cudf::data_type(cudf::type_id::BOOL8), input.num_rows(), cudf::mask_state::UNALLOCATED); | ||
|
||
thrust::transform(rmm::exec_policy(stream), | ||
thrust::make_counting_iterator(0), | ||
thrust::make_counting_iterator(input.num_rows()), | ||
thrust::make_counting_iterator(0), | ||
output->mutable_view().data<bool>(), | ||
less_comparator); | ||
return output; | ||
} | ||
|
||
template <typename PhysicalElementComparator> | ||
auto two_table_comparison(cudf::table_view lhs, | ||
cudf::table_view rhs, | ||
std::vector<cudf::order> const& column_order, | ||
PhysicalElementComparator comparator) | ||
{ | ||
rmm::cuda_stream_view stream{}; | ||
|
||
auto const table_comparator = | ||
lexicographic::two_table_comparator{lhs, rhs, column_order, {}, stream}; | ||
auto const less_comparator = table_comparator.less(cudf::nullate::NO{}, comparator); | ||
auto const lhs_it = cudf::experimental::row::lhs_iterator(0); | ||
auto const rhs_it = cudf::experimental::row::rhs_iterator(0); | ||
|
||
auto output = cudf::make_numeric_column( | ||
cudf::data_type(cudf::type_id::BOOL8), lhs.num_rows(), cudf::mask_state::UNALLOCATED); | ||
|
||
thrust::transform(rmm::exec_policy(stream), | ||
lhs_it, | ||
lhs_it + lhs.num_rows(), | ||
rhs_it, | ||
output->mutable_view().data<bool>(), | ||
less_comparator); | ||
return output; | ||
} | ||
|
||
template <typename PhysicalElementComparator> | ||
auto self_equality(cudf::table_view input, | ||
std::vector<cudf::order> const& column_order, | ||
PhysicalElementComparator comparator) | ||
{ | ||
rmm::cuda_stream_view stream{}; | ||
|
||
auto const table_comparator = equality::self_comparator{input, stream}; | ||
auto const equal_comparator = | ||
table_comparator.equal_to(cudf::nullate::NO{}, cudf::null_equality::EQUAL, comparator); | ||
|
||
auto output = cudf::make_numeric_column( | ||
cudf::data_type(cudf::type_id::BOOL8), input.num_rows(), cudf::mask_state::UNALLOCATED); | ||
|
||
thrust::transform(rmm::exec_policy(stream), | ||
thrust::make_counting_iterator(0), | ||
thrust::make_counting_iterator(input.num_rows()), | ||
thrust::make_counting_iterator(0), | ||
output->mutable_view().data<bool>(), | ||
equal_comparator); | ||
return output; | ||
} | ||
|
||
template <typename PhysicalElementComparator> | ||
auto two_table_equality(cudf::table_view lhs, | ||
cudf::table_view rhs, | ||
std::vector<cudf::order> const& column_order, | ||
PhysicalElementComparator comparator) | ||
{ | ||
rmm::cuda_stream_view stream{}; | ||
|
||
auto const table_comparator = equality::two_table_comparator{lhs, rhs, stream}; | ||
auto const equal_comparator = | ||
table_comparator.equal_to(cudf::nullate::NO{}, cudf::null_equality::EQUAL, comparator); | ||
auto const lhs_it = cudf::experimental::row::lhs_iterator(0); | ||
auto const rhs_it = cudf::experimental::row::rhs_iterator(0); | ||
|
||
auto output = cudf::make_numeric_column( | ||
cudf::data_type(cudf::type_id::BOOL8), lhs.num_rows(), cudf::mask_state::UNALLOCATED); | ||
|
||
thrust::transform(rmm::exec_policy(stream), | ||
lhs_it, | ||
lhs_it + lhs.num_rows(), | ||
rhs_it, | ||
output->mutable_view().data<bool>(), | ||
equal_comparator); | ||
return output; | ||
} | ||
|
||
TYPED_TEST(TypedTableViewTest, TestLexicographicalComparatorTwoTables) | ||
{ | ||
using T = TypeParam; | ||
|
||
auto const col1 = fixed_width_column_wrapper<T>{{1, 2, 3, 4}}; | ||
auto const col2 = fixed_width_column_wrapper<T>{{0, 1, 4, 3}}; | ||
auto const column_order = std::vector{cudf::order::DESCENDING}; | ||
auto const lhs = cudf::table_view{{col1}}; | ||
auto const rhs = cudf::table_view{{col2}}; | ||
|
||
auto const expected = fixed_width_column_wrapper<bool>{{1, 1, 0, 1}}; | ||
auto const got = | ||
two_table_comparison(lhs, rhs, column_order, lexicographic::physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, got->view()); | ||
|
||
auto const sorting_got = two_table_comparison( | ||
lhs, rhs, column_order, lexicographic::sorting_physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, sorting_got->view()); | ||
} | ||
|
||
TYPED_TEST(TypedTableViewTest, TestLexicographicalComparatorSameTable) | ||
{ | ||
using T = TypeParam; | ||
|
||
auto const col1 = fixed_width_column_wrapper<T>{{1, 2, 3, 4}}; | ||
auto const column_order = std::vector{cudf::order::DESCENDING}; | ||
auto const input_table = cudf::table_view{{col1}}; | ||
|
||
auto const expected = fixed_width_column_wrapper<bool>{{0, 0, 0, 0}}; | ||
auto const got = | ||
self_comparison(input_table, column_order, lexicographic::physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, got->view()); | ||
|
||
auto const sorting_got = self_comparison( | ||
input_table, column_order, lexicographic::sorting_physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, sorting_got->view()); | ||
} | ||
|
||
template <typename T> | ||
struct NaNTableViewTest : public cudf::test::BaseFixture { | ||
}; | ||
|
||
TYPED_TEST_SUITE(NaNTableViewTest, FloatingPointTypes); | ||
|
||
TYPED_TEST(NaNTableViewTest, TestLexicographicalComparatorTwoTableNaNCase) | ||
{ | ||
using T = TypeParam; | ||
|
||
auto const col1 = fixed_width_column_wrapper<T>{{T(NAN), T(NAN), T(1), T(1)}}; | ||
auto const col2 = fixed_width_column_wrapper<T>{{T(NAN), T(1), T(NAN), T(1)}}; | ||
auto const column_order = std::vector{cudf::order::DESCENDING}; | ||
|
||
auto const lhs = cudf::table_view{{col1}}; | ||
auto const rhs = cudf::table_view{{col2}}; | ||
|
||
auto const expected = fixed_width_column_wrapper<bool>{{0, 0, 0, 0}}; | ||
auto const got = | ||
two_table_comparison(lhs, rhs, column_order, lexicographic::physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, got->view()); | ||
|
||
auto const sorting_expected = fixed_width_column_wrapper<bool>{{0, 1, 0, 0}}; | ||
auto const sorting_got = two_table_comparison( | ||
lhs, rhs, column_order, lexicographic::sorting_physical_element_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(sorting_expected, sorting_got->view()); | ||
} | ||
|
||
TYPED_TEST(NaNTableViewTest, TestEqualityComparatorTwoTableNaNCase) | ||
{ | ||
using T = TypeParam; | ||
|
||
auto const col1 = fixed_width_column_wrapper<T>{{T(NAN), T(NAN), T(1), T(1)}}; | ||
auto const col2 = fixed_width_column_wrapper<T>{{T(NAN), T(1), T(NAN), T(1)}}; | ||
auto const column_order = std::vector{cudf::order::DESCENDING}; | ||
|
||
auto const lhs = cudf::table_view{{col1}}; | ||
auto const rhs = cudf::table_view{{col2}}; | ||
|
||
auto const expected = fixed_width_column_wrapper<bool>{{0, 0, 0, 1}}; | ||
auto const got = | ||
two_table_equality(lhs, rhs, column_order, equality::physical_equality_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(expected, got->view()); | ||
|
||
auto const nan_equal_expected = fixed_width_column_wrapper<bool>{{1, 0, 0, 1}}; | ||
auto const nan_equal_got = | ||
two_table_equality(lhs, rhs, column_order, equality::nan_equal_physical_equality_comparator{}); | ||
CUDF_TEST_EXPECT_COLUMNS_EQUAL(nan_equal_expected, nan_equal_got->view()); | ||
} |