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

List element Equality comparator #10289

Merged
merged 129 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
933c974
First commit
devavret Aug 26, 2021
a1636e5
testing and profiling deep single hierarchy struct
devavret Aug 27, 2021
d59f54c
Merge branch 'branch-22.02' into struct-row-comp
devavret Jan 12, 2022
765dd8d
Merge branch 'branch-22.02' into struct-row-comp
devavret Jan 12, 2022
3d21daf
Make the sandboxed test compile again
devavret Jan 14, 2022
9f32e6b
Update my row_comparator with nullate
devavret Jan 15, 2022
53d3c90
Merge branch 'branch-22.02' into struct-row-comp
devavret Jan 21, 2022
022e2a4
Basic verticalization utility and experimental namespace
devavret Jan 24, 2022
7fef643
clean up most of row operators that I didn't change.
devavret Jan 26, 2022
930d8de
Sliced column test
devavret Jan 27, 2022
0ecc4f8
column order and null precendence support
devavret Jan 28, 2022
ff36d2d
Manually managed stack
devavret Jan 28, 2022
cd0f938
New depth based method to avoid superimpose nulls
devavret Feb 2, 2022
7b8e060
Put sort2 impl in separate TU
devavret Feb 2, 2022
25eb237
Merge branch 'branch-22.04' into struct-row-comp
devavret Feb 2, 2022
c8e527e
Basic working list == comp
devavret Feb 4, 2022
eb87ed7
Merge branch 'branch-22.04' into list-row-eq
devavret Feb 4, 2022
cc1584d
deeper list test
devavret Feb 4, 2022
925481a
benchmark list ==
devavret Feb 7, 2022
b2b41c7
small cleanups
devavret Feb 7, 2022
d2937cf
Merge branch 'branch-22.04' into struct-row-comp
devavret Feb 10, 2022
d55c9c7
Move verticalization code to row_comparator.cpp
devavret Feb 15, 2022
b7cdfe0
Merge branch 'struct-row-comp' into list-row-eq
devavret Feb 15, 2022
8309151
Use regular type dispatcher with new id type map
devavret Feb 15, 2022
8717b9c
Early return from unequal leaf elements
devavret Feb 15, 2022
21df6cf
Combined struct and list equality operator
devavret Feb 17, 2022
fa35461
Add null testing to list level also
devavret Feb 18, 2022
3bd749e
Owning row lex operator
devavret Feb 22, 2022
613d664
merge fixes
devavret Feb 23, 2022
2ef3ac7
Move struct logic out of main row loop and into element_relational_co…
devavret Feb 24, 2022
5577431
pushing even more logic into element_relational_comparator
devavret Feb 24, 2022
f037bc0
More optimizations.
devavret Feb 24, 2022
8c54a85
review changes
devavret Feb 24, 2022
9d24a87
Checks to ensure tables can be compared
devavret Feb 24, 2022
4e5fe21
Merge branch 'struct-row-comp' into list-row-eq
devavret Feb 24, 2022
693dbca
Owning row eq operator
devavret Feb 24, 2022
294b0cf
Another attempt at new API
devavret Mar 2, 2022
a4c799a
Remove stack based struct comparator + cleanups
devavret Mar 7, 2022
ecb2eb0
thrust::pair -> cuda::std::pair
devavret Mar 7, 2022
34a6564
optional device spans
devavret Mar 7, 2022
fa4abb4
Prevent device comparator construction from any table_device_view
devavret Mar 7, 2022
b213210
Nullate default and fix for non nested depth
devavret Mar 7, 2022
6f9bedd
Fix an unsurfaced bug about depth passing
devavret Mar 7, 2022
be69ffa
Switch over sort impl to new comparator
devavret Mar 8, 2022
76d535a
Copyright changes to satiate ci
devavret Mar 8, 2022
78d10fc
Migrate struct sort benchmark to nvbench
devavret Mar 8, 2022
15920ee
Avoid optional::value in favor of *
devavret Mar 8, 2022
d01fc30
throw when trying to sort List
devavret Mar 8, 2022
ac2eb0d
Leftover change for struct sort nvbench
devavret Mar 8, 2022
076c4c1
struct without null pushdown test
devavret Mar 9, 2022
e8a9202
Remove temporary sort2_test
devavret Mar 9, 2022
a4b1167
Remove temporary sort2 files
devavret Mar 9, 2022
62f6914
leftover sort2 in cmake
devavret Mar 9, 2022
8f628ae
cleanup benchmark headers
devavret Mar 9, 2022
dc7d125
Docs
devavret Mar 9, 2022
fa7d940
Merge branch 'branch-22.04' into struct-row-comp
devavret Mar 10, 2022
bdc1cb6
Merge branch 'struct-row-comp' into list-row-eq
devavret Mar 10, 2022
83ba4bf
Match API with self lex comparator
devavret Mar 10, 2022
9c0060f
Guard null check code with nullate
devavret Mar 10, 2022
57fdd1e
remove redundant size check
devavret Mar 10, 2022
76c883f
Apply suggestions from code review
devavret Mar 14, 2022
5fc82a9
Docs
devavret Mar 14, 2022
82db9d6
port benchmark to nvbench
devavret Mar 14, 2022
7871c48
privatise row_equality_comparator's ctor
devavret Mar 14, 2022
c9e5dc3
List rank test cleanup and merge with reduction test
devavret Mar 14, 2022
98b253b
rmm pool in benchmark + style fixes
devavret Mar 14, 2022
38fa66f
Merge branch 'struct-row-comp' into list-row-eq
devavret Mar 14, 2022
3255dc5
Merge branch 'branch-22.04' into struct-row-comp
devavret Mar 14, 2022
44d3735
Merge branch 'struct-row-comp' into list-row-eq
devavret Mar 14, 2022
e2d4b93
run cmake-format
devavret Mar 14, 2022
52e3a35
Review changes
devavret Mar 15, 2022
9470f06
More review changes
devavret Mar 15, 2022
7c897c3
Review changes req by @vyasr
devavret Mar 17, 2022
e0467c7
add a runtime is_relationally_comparable funtion
devavret Mar 17, 2022
fc1e993
Review changes
devavret Mar 18, 2022
096593f
Review changes
devavret Mar 18, 2022
f539647
Avoid WAR of storing a table_device_view
devavret Mar 18, 2022
01be0bc
Rename struct_linearize to decompose_structs and Improve docs
devavret Mar 18, 2022
de95530
review changes req by @ttnghia
devavret Mar 21, 2022
6c45cd4
Namespace changes and making element comparator private
devavret Mar 21, 2022
f72ce8b
Merge branch 'struct-row-comp' into list-row-eq
devavret Mar 21, 2022
c624317
put in row namespace
devavret Mar 21, 2022
0ca2d14
Review on lex applied to equality
devavret Mar 21, 2022
f309837
create method just like struct lex
devavret Mar 21, 2022
81f9ab8
loop 0 to size -> start off to end off
devavret Mar 22, 2022
9bfd08e
Update cpp/include/cudf/table/experimental/row_operators.cuh
devavret Mar 22, 2022
70e4581
Merge branch 'struct-row-comp' into list-row-eq
devavret Mar 22, 2022
dd8650d
We also need to keep the null mask buffers around
devavret Mar 22, 2022
6cab5c4
Fix slices struct issues
devavret Mar 22, 2022
14f9d25
Handle sliced list column
devavret Mar 23, 2022
bcd6962
Merge branch 'branch-22.04' into list-row-eq
devavret Mar 23, 2022
0c12c15
Move equality comparator to experimental header
devavret Mar 23, 2022
b41b3fa
Style fixes
devavret Mar 23, 2022
4919b04
Merge branch 'branch-22.06' into list-row-eq
devavret Mar 23, 2022
3dfc133
Review changes
devavret Mar 24, 2022
9031900
Review changes requested by @hyperbolic2346
devavret Mar 24, 2022
119d830
Add an equality comparable check similar to lex comparable check
devavret Mar 24, 2022
1cefa5a
Move linked column to a common header in utilities
devavret Mar 24, 2022
34aa66b
Review changes
devavret Mar 28, 2022
e7ea7f9
Change to progressive slicing logic
devavret Mar 28, 2022
e60fbd4
pull type dispatcher out of element compare loop
devavret Mar 28, 2022
42319ad
Move slicing logic to lists_column_device_view and new structs_column…
devavret Mar 28, 2022
67c035c
Move list size iterator and make it only constructible from list_colu…
devavret Mar 28, 2022
e5fe24c
push slice logic into columns_device_view
devavret Mar 29, 2022
85861a9
Add validity safe iterator
devavret Mar 29, 2022
9db7479
Move element_range_comparator to element_comparator's private
devavret Mar 29, 2022
db3b79b
style fixes
devavret Mar 29, 2022
6ca7deb
Docs for the newly added stuff
devavret Mar 29, 2022
2fc3d3d
Merge branch 'branch-22.06' into list-row-eq
devavret Mar 29, 2022
1c3a99d
review changes
devavret Mar 29, 2022
a0e581c
review changes
devavret Mar 30, 2022
046c407
Review changes
devavret Mar 30, 2022
6a282a6
linked_column_view inherit from column_view_base
devavret Mar 30, 2022
0f768ac
spell check
devavret Mar 30, 2022
92c1ff5
Change composition to private inheritance
devavret Mar 31, 2022
4c0e7fa
Replace __host__ __device__ with macro
devavret Mar 31, 2022
75104bb
Add more null frequencies to benchmark
devavret Mar 31, 2022
1e1053b
Templatize make_validity_iterator
devavret Mar 31, 2022
bcfe91b
Increase testing for null frequency
devavret Mar 31, 2022
981438d
curr_col -> temp_col
devavret Mar 31, 2022
5bbf18e
element_range_comparator -> column_comparator
devavret Mar 31, 2022
8e18d66
cleaner column_view conversion
devavret Mar 31, 2022
75eaed4
delete copy ctor and assignment operator
devavret Apr 1, 2022
be98357
iterator docs
devavret Apr 1, 2022
f4c509a
Handle empty struct in list equality
devavret Apr 8, 2022
d1386cf
Handle empty list (without offsets)
devavret Apr 8, 2022
6aef29f
Merge branch 'branch-22.06' into list-row-eq
devavret Apr 8, 2022
3cc1159
Merge branch 'branch-22.06' into list-row-eq
devavret Apr 11, 2022
8078e3c
Column_device_view review changes
devavret Apr 12, 2022
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
1 change: 1 addition & 0 deletions conda/recipes/libcudf/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ outputs:
- test -f $PREFIX/include/cudf/detail/transpose.hpp
- test -f $PREFIX/include/cudf/detail/unary.hpp
- test -f $PREFIX/include/cudf/detail/utilities/alignment.hpp
- test -f $PREFIX/include/cudf/detail/utilities/column.hpp
- test -f $PREFIX/include/cudf/detail/utilities/integer_utils.hpp
- test -f $PREFIX/include/cudf/detail/utilities/int_fastdiv.h
- test -f $PREFIX/include/cudf/detail/utilities/vector_factories.hpp
Expand Down
2 changes: 1 addition & 1 deletion cpp/benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ ConfigureBench(
REDUCTION_BENCH reduction/anyall.cpp reduction/dictionary.cpp reduction/minmax.cpp
reduction/reduce.cpp reduction/scan.cpp
)
ConfigureNVBench(REDUCTION_NVBENCH reduction/segment_reduce.cu)
ConfigureNVBench(REDUCTION_NVBENCH reduction/segment_reduce.cu reduction/rank.cpp)

# ##################################################################################################
# * reduction benchmark ---------------------------------------------------------------------------
Expand Down
64 changes: 64 additions & 0 deletions cpp/benchmarks/reduction/rank.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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 <benchmarks/common/generate_input.hpp>
#include <benchmarks/fixture/rmm_pool_raii.hpp>

#include <cudf/detail/scan.hpp>
#include <cudf/filling.hpp>
#include <cudf/lists/list_view.cuh>

#include <nvbench/nvbench.cuh>

template <typename type>
static void nvbench_reduction_scan(nvbench::state& state, nvbench::type_list<type>)
{
cudf::rmm_pool_raii pool_raii;

auto const dtype = cudf::type_to_id<type>();

double const null_frequency = state.get_float64("null_frequency");
size_t const size = state.get_int64("data_size");

data_profile table_data_profile;
table_data_profile.set_distribution_params(dtype, distribution_id::UNIFORM, 0, 5);
table_data_profile.set_null_frequency(null_frequency);

auto const table = create_random_table({dtype}, table_size_bytes{size / 2}, table_data_profile);

auto const new_tbl = cudf::repeat(table->view(), 2);
cudf::column_view input(new_tbl->view().column(0));

state.exec(nvbench::exec_tag::sync, [&](nvbench::launch& launch) {
rmm::cuda_stream_view stream_view{launch.get_stream()};
auto result = cudf::detail::inclusive_dense_rank_scan(
input, stream_view, rmm::mr::get_current_device_resource());
});
}

using data_type = nvbench::type_list<int32_t, cudf::list_view>;

NVBENCH_BENCH_TYPES(nvbench_reduction_scan, NVBENCH_TYPE_AXES(data_type))
.set_name("rank_scan")
.add_float64_axis("null_frequency", {0, 0.1, 0.5, 0.9})
.add_int64_axis("data_size",
{
10000, // 10k
100000, // 100k
1000000, // 1M
10000000, // 10M
100000000, // 100M
});
92 changes: 72 additions & 20 deletions cpp/include/cudf/column/column_device_view.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class alignas(16) column_device_view_base {
*/
template <typename T = void,
CUDF_ENABLE_IF(std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
__host__ __device__ T const* head() const noexcept
[[nodiscard]] CUDF_HOST_DEVICE T const* head() const noexcept
{
return static_cast<T const*>(_data);
}
Expand All @@ -132,20 +132,20 @@ class alignas(16) column_device_view_base {
* @return T const* Typed pointer to underlying data, including the offset
*/
template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
__host__ __device__ T const* data() const noexcept
[[nodiscard]] CUDF_HOST_DEVICE T const* data() const noexcept
{
return head<T>() + _offset;
}

/**
* @brief Returns the number of elements in the column.
*/
[[nodiscard]] __host__ __device__ size_type size() const noexcept { return _size; }
[[nodiscard]] CUDF_HOST_DEVICE size_type size() const noexcept { return _size; }

/**
* @brief Returns the element type
*/
[[nodiscard]] __host__ __device__ data_type type() const noexcept { return _type; }
[[nodiscard]] CUDF_HOST_DEVICE data_type type() const noexcept { return _type; }

/**
* @brief Indicates whether the column can contain null elements, i.e., if it
Expand All @@ -156,7 +156,7 @@ class alignas(16) column_device_view_base {
* @return true The bitmask is allocated
* @return false The bitmask is not allocated
*/
[[nodiscard]] __host__ __device__ bool nullable() const noexcept { return nullptr != _null_mask; }
[[nodiscard]] CUDF_HOST_DEVICE bool nullable() const noexcept { return nullptr != _null_mask; }

/**
* @brief Returns raw pointer to the underlying bitmask allocation.
Expand All @@ -165,7 +165,7 @@ class alignas(16) column_device_view_base {
*
* @note If `null_count() == 0`, this may return `nullptr`.
*/
[[nodiscard]] __host__ __device__ bitmask_type const* null_mask() const noexcept
[[nodiscard]] CUDF_HOST_DEVICE bitmask_type const* null_mask() const noexcept
{
return _null_mask;
}
Expand All @@ -174,7 +174,7 @@ class alignas(16) column_device_view_base {
* @brief Returns the index of the first element relative to the base memory
* allocation, i.e., what is returned from `head<T>()`.
*/
[[nodiscard]] __host__ __device__ size_type offset() const noexcept { return _offset; }
[[nodiscard]] CUDF_HOST_DEVICE size_type offset() const noexcept { return _offset; }

/**
* @brief Returns whether the specified element holds a valid value (i.e., not
Expand Down Expand Up @@ -269,11 +269,11 @@ class alignas(16) column_device_view_base {
size_type _offset{}; ///< Index position of the first element.
///< Enables zero-copy slicing

column_device_view_base(data_type type,
size_type size,
void const* data,
bitmask_type const* null_mask,
size_type offset)
CUDF_HOST_DEVICE column_device_view_base(data_type type,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking, this macro is really only necessary in a .hpp file that is expected to work in both host and device code TUs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change made as part of this feedback #10289 (comment). I can revert the macro changes made to all .cuh headers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking, this macro is really only necessary in a .hpp file that is expected to work in both host and device code TUs.

I agree that it's not necessary in cuh. I made this suggestion because not everyone will think about that and people will invariably copy-paste, so uniformly using CUDF_HOST_DEVICE helps reduce the chance of future errors and leaves one less thing for developers to think about. It's a minor suggestion though, if you prefer to use it more surgically that's OK with me.

size_type size,
void const* data,
bitmask_type const* null_mask,
size_type offset)
: _type{type}, _size{size}, _data{data}, _null_mask{null_mask}, _offset{offset}
{
}
Expand Down Expand Up @@ -329,6 +329,33 @@ class alignas(16) column_device_view : public detail::column_device_view_base {
*/
column_device_view(column_view column, void* h_ptr, void* d_ptr);

/**
* @brief Get a new column_device_view which is a slice of this column.
*
* Example:
* @code{.cpp}
* // column = column_device_view([1, 2, 3, 4, 5, 6, 7])
* auto c = column.slice(1, 3);
* // c = column_device_view([2, 3, 4])
* auto c1 = column.slice(2, 3);
* // c1 = column_device_view([3, 4, 5])
* @endcode
*
* @param offset The index of the first element in the slice
* @param size The number of elements in the slice
*/
[[nodiscard]] CUDF_HOST_DEVICE column_device_view slice(size_type offset,
size_type size) const noexcept
{
return column_device_view{this->type(),
size,
this->head(),
this->null_mask(),
this->offset() + offset,
d_children,
this->num_child_columns()};
}

/**
* @brief Returns reference to element at the specified index.
*
Expand All @@ -346,7 +373,7 @@ class alignas(16) column_device_view : public detail::column_device_view_base {
* @param element_index Position of the desired element
*/
template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
__device__ T element(size_type element_index) const noexcept
[[nodiscard]] __device__ T element(size_type element_index) const noexcept
{
return data<T>()[element_index];
}
Expand All @@ -365,9 +392,8 @@ class alignas(16) column_device_view : public detail::column_device_view_base {
template <typename T, CUDF_ENABLE_IF(std::is_same_v<T, string_view>)>
__device__ T element(size_type element_index) const noexcept
{
size_type index = element_index + offset(); // account for this view's _offset
const int32_t* d_offsets =
d_children[strings_column_view::offsets_column_index].data<int32_t>();
size_type index = element_index + offset(); // account for this view's _offset
const auto* d_offsets = d_children[strings_column_view::offsets_column_index].data<int32_t>();
const char* d_strings = d_children[strings_column_view::chars_column_index].data<char>();
size_type offset = d_offsets[index];
return string_view{d_strings + offset, d_offsets[index + 1] - offset};
Expand Down Expand Up @@ -763,11 +789,37 @@ class alignas(16) column_device_view : public detail::column_device_view_base {
*
* @return The number of child columns
*/
[[nodiscard]] __host__ __device__ size_type num_child_columns() const noexcept
[[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
{
return _num_children;
}

private:
/**
* @brief Creates an instance of this class using pre-existing device memory pointers to data,
* nullmask, and offset.
*
* @param type The type of the column
* @param size The number of elements in the column
* @param data Pointer to the device memory containing the data
* @param null_mask Pointer to the device memory containing the null bitmask
* @param offset The index of the first element in the column
* @param children Pointer to the device memory containing child data
* @param num_children The number of child columns
*/
CUDF_HOST_DEVICE column_device_view(data_type type,
size_type size,
void const* data,
bitmask_type const* null_mask,
size_type offset,
column_device_view* children,
size_type num_children)
: column_device_view_base(type, size, data, null_mask, offset),
d_children(children),
_num_children(num_children)
{
}

protected:
column_device_view* d_children{}; ///< Array of `column_device_view`
///< objects in device memory.
Expand Down Expand Up @@ -852,7 +904,7 @@ class alignas(16) mutable_column_device_view : public detail::column_device_view
*/
template <typename T = void,
CUDF_ENABLE_IF(std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
__host__ __device__ T* head() const noexcept
CUDF_HOST_DEVICE T* head() const noexcept
{
return const_cast<T*>(detail::column_device_view_base::head<T>());
}
Expand All @@ -870,7 +922,7 @@ class alignas(16) mutable_column_device_view : public detail::column_device_view
* @return T* Typed pointer to underlying data, including the offset
*/
template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
__host__ __device__ T* data() const noexcept
CUDF_HOST_DEVICE T* data() const noexcept
{
return const_cast<T*>(detail::column_device_view_base::data<T>());
}
Expand Down Expand Up @@ -912,7 +964,7 @@ class alignas(16) mutable_column_device_view : public detail::column_device_view
*
* @note If `null_count() == 0`, this may return `nullptr`.
*/
[[nodiscard]] __host__ __device__ bitmask_type* null_mask() const noexcept
[[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
{
return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
}
Expand Down
47 changes: 34 additions & 13 deletions cpp/include/cudf/detail/iterator.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ namespace detail {
* @return A transform iterator that applies `f` to a counting iterator
*/
template <typename UnaryFunction>
inline auto make_counting_transform_iterator(cudf::size_type start, UnaryFunction f)
CUDF_HOST_DEVICE inline auto make_counting_transform_iterator(cudf::size_type start,
UnaryFunction f)
{
return thrust::make_transform_iterator(thrust::make_counting_iterator(start), f);
}
Expand Down Expand Up @@ -117,26 +118,42 @@ struct null_replaced_value_accessor {

/**
* @brief validity accessor of column with null bitmask
* A unary functor returns validity at `id`.
* `operator() (cudf::size_type id)` computes validity flag at `id`
* This functor is only allowed for nullable columns.
* A unary functor that returns validity at index `i`.
devavret marked this conversation as resolved.
Show resolved Hide resolved
*
* @throws cudf::logic_error if the column is not nullable.
* @tparam safe If false, the accessor with throw logic_error if the column is not nullable. If
* true, the accessor checks for nullability and if col is not nullable, returns true.
*/
template <bool safe = false>
struct validity_accessor {
column_device_view const col;

/**
* @brief constructor
*
* @throws cudf::logic_error if not safe and `col` does not have a validity bitmask
*
* @param[in] _col column device view of cudf column
*/
validity_accessor(column_device_view const& _col) : col{_col}
CUDF_HOST_DEVICE validity_accessor(column_device_view const& _col) : col{_col}
{
// verify valid is non-null, otherwise, is_valid() will crash
CUDF_EXPECTS(_col.nullable(), "Unexpected non-nullable column.");
if constexpr (not safe) {
// verify col is nullable, otherwise, is_valid_nocheck() will crash
#if defined(__CUDA_ARCH__)
cudf_assert(_col.nullable() && "Unexpected non-nullable column.");
#else
CUDF_EXPECTS(_col.nullable(), "Unexpected non-nullable column.");
#endif
}
}

__device__ inline bool operator()(cudf::size_type i) const { return col.is_valid_nocheck(i); }
__device__ inline bool operator()(cudf::size_type i) const
{
if constexpr (safe) {
return col.is_valid(i);
} else {
return col.is_valid_nocheck(i);
}
}
};

/**
Expand Down Expand Up @@ -289,16 +306,20 @@ auto make_pair_rep_iterator(column_device_view const& column)
*
* Dereferencing the returned iterator for element `i` will return the validity
* of `column[i]`
* This iterator is only allowed for nullable columns.
* This iterator is only allowed for nullable columns if `safe` = false
* When safe = true, if the column is not nullable then the validity is always true.
*
* @throws cudf::logic_error if the column is not nullable.
* @throws cudf::logic_error if the column is not nullable when safe = false
*
* @tparam safe If false, the accessor with throw logic_error if the column is not nullable. If
* true, the accessor checks for nullability and if col is not nullable, returns true.
* @param column The column to iterate
devavret marked this conversation as resolved.
Show resolved Hide resolved
* @return auto Iterator that returns validities of column elements.
*/
auto inline make_validity_iterator(column_device_view const& column)
template <bool safe = false>
CUDF_HOST_DEVICE auto inline make_validity_iterator(column_device_view const& column)
{
return make_counting_transform_iterator(cudf::size_type{0}, validity_accessor{column});
return make_counting_transform_iterator(cudf::size_type{0}, validity_accessor<safe>{column});
}

/**
Expand Down
Loading