diff --git a/cpp/include/cudf/detail/stream_compaction.hpp b/cpp/include/cudf/detail/stream_compaction.hpp index 1e7b34587968..acdb6fc8a4b5 100644 --- a/cpp/include/cudf/detail/stream_compaction.hpp +++ b/cpp/include/cudf/detail/stream_compaction.hpp @@ -48,6 +48,9 @@ enum class mask_type : bool { /** * @brief Filters @p input using @p boolean_mask. * + * @note An empty mask returns an empty table for @p mask_kind `RETENTION` and a copy of @p input + * for @p mask_kind `DELETION`. + * * @param input The input table to filter * @param boolean_mask A nullable BOOL8 column used to filter @p input * @param mask_kind Specifies how the boolean mask is treated (retentions or deletions) diff --git a/cpp/include/cudf/stream_compaction.hpp b/cpp/include/cudf/stream_compaction.hpp index cc49bb8c4ba0..2b6a2e435914 100644 --- a/cpp/include/cudf/stream_compaction.hpp +++ b/cpp/include/cudf/stream_compaction.hpp @@ -244,7 +244,8 @@ std::unique_ptr apply_retention_mask( * if the corresponding element `i` in the mask is non-null and `false`. * This operation is stable: the input order is preserved. * - * @note If @p deletion_mask is empty, or @p input has zero rows, an empty table is returned. + * @note If @p deletion_mask is empty, a copy of @p input is returned. If @p input has zero rows, + * an empty table is returned. * * @throws cudf::logic_error if non-empty @p input has different number of rows than @p * deletion_mask. diff --git a/cpp/src/stream_compaction/apply_mask.cu b/cpp/src/stream_compaction/apply_mask.cu index b77e97b96f9f..7d53d8b7bac3 100644 --- a/cpp/src/stream_compaction/apply_mask.cu +++ b/cpp/src/stream_compaction/apply_mask.cu @@ -67,7 +67,11 @@ std::unique_ptr
apply_mask(table_view const& input, cuda::stream_ref stream, rmm::device_async_resource_ref mr) { - if (boolean_mask.is_empty()) { return empty_like(input); } + auto const is_retention = (mask_kind == mask_type::RETENTION); + + if (boolean_mask.is_empty()) { + return is_retention ? empty_like(input) : std::make_unique
(input, stream, mr); + } CUDF_EXPECTS(boolean_mask.type().id() == type_id::BOOL8, "Mask must be Boolean type"); CUDF_EXPECTS(input.num_rows() == 0 || input.num_rows() == boolean_mask.size(), @@ -75,7 +79,6 @@ std::unique_ptr
apply_mask(table_view const& input, auto device_boolean_mask = cudf::column_device_view::create(boolean_mask, stream); - auto const is_retention = (mask_kind == mask_type::RETENTION); if (boolean_mask.has_nulls()) { if (is_retention) { return detail::copy_if(input, retention_mask_filter{*device_boolean_mask}, stream, mr); diff --git a/cpp/tests/stream_compaction/apply_mask_tests.cpp b/cpp/tests/stream_compaction/apply_mask_tests.cpp index b4b7a6c45c1b..f6feb0e7a1b2 100644 --- a/cpp/tests/stream_compaction/apply_mask_tests.cpp +++ b/cpp/tests/stream_compaction/apply_mask_tests.cpp @@ -415,14 +415,10 @@ TEST_F(ApplyDeletionMask, EmptyMask) cudf::test::fixed_width_column_wrapper col3{{10, 40, 70, 5, 2, 10}, {1, 1, 0, 1, 1, 0}}; cudf::table_view input{{col1, col2, col3}}; cudf::test::fixed_width_column_wrapper deletion_mask{}; - cudf::test::fixed_width_column_wrapper col1_expected{}; - cudf::test::fixed_width_column_wrapper col2_expected{}; - cudf::test::fixed_width_column_wrapper col3_expected{}; - cudf::table_view expected{{col1_expected, col2_expected, col3_expected}}; auto got = cudf::apply_deletion_mask(input, deletion_mask); - CUDF_TEST_EXPECT_TABLES_EQUAL(expected, got->view()); + CUDF_TEST_EXPECT_TABLES_EQUAL(input, got->view()); } TEST_F(ApplyDeletionMask, WrongMaskType) diff --git a/python/pylibcudf/pylibcudf/lists.pyx b/python/pylibcudf/pylibcudf/lists.pyx index 42b80cb6fed5..0b3c0ce8a16f 100644 --- a/python/pylibcudf/pylibcudf/lists.pyx +++ b/python/pylibcudf/pylibcudf/lists.pyx @@ -860,14 +860,14 @@ cpdef Column apply_retention_mask( input : Column The input column. retention_mask : Column - The boolean mask whose true values retain input elements. + A lists-of-bools column used as a retention mask. stream : Stream | None CUDA stream on which to perform the operation. Returns ------- Column - A Column of filtered elements based upon the retention mask. + Lists column with elements kept where retention mask is valid and true. """ cdef unique_ptr[column] c_result cdef ListsColumnView list_view = input.list_view() @@ -924,7 +924,7 @@ cpdef Column apply_deletion_mask( Returns ------- Column - Lists column with elements removed where deletion_mask is true. + Lists column with elements removed where deletion mask is valid and true. """ cdef unique_ptr[column] c_result cdef ListsColumnView list_view = input.list_view() diff --git a/python/pylibcudf/pylibcudf/stream_compaction.pyx b/python/pylibcudf/pylibcudf/stream_compaction.pyx index 0c7244572353..f7548c5ebcf0 100644 --- a/python/pylibcudf/pylibcudf/stream_compaction.pyx +++ b/python/pylibcudf/pylibcudf/stream_compaction.pyx @@ -143,12 +143,12 @@ cpdef Table apply_retention_mask( source_table : Table The input table to filter. retention_mask : Column - The boolean mask whose true values retain input rows. + A boolean column used as a retention mask. Returns ------- Table - A new table with rows removed based on the boolean mask. + A new table with rows kept where retention mask is valid and true. """ cdef unique_ptr[table] c_result @@ -200,7 +200,7 @@ cpdef Table apply_deletion_mask( Returns ------- Table - Table with rows removed where deletion_mask is true. + Table with rows removed where deletion mask is valid and true. """ cdef unique_ptr[table] c_result