list_device_view.cuh
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
7 #include <cudf/detail/iterator.cuh>
8 #include <cudf/lists/lists_column_device_view.cuh>
9 #include <cudf/types.hpp>
11 
12 #include <cuda/iterator>
13 #include <cuda/std/utility>
14 #include <cuda_runtime.h>
15 
16 namespace CUDF_EXPORT cudf {
17 
24 
25  public:
26  list_device_view() = default;
27 
34  __device__ inline list_device_view(lists_column_device_view const& lists_column,
35  size_type const& row_index)
36  : lists_column(lists_column), _row_index(row_index)
37  {
38  column_device_view const& offsets = lists_column.offsets();
39  cudf_assert(row_index >= 0 && row_index < lists_column.size() && row_index < offsets.size() &&
40  "row_index out of bounds");
41 
42  begin_offset = offsets.element<int32_t>(row_index + lists_column.offset());
43  cudf_assert(begin_offset >= 0 && begin_offset <= lists_column.child().size() &&
44  "begin_offset out of bounds.");
45  _size = offsets.element<int32_t>(row_index + 1 + lists_column.offset()) - begin_offset;
46  }
47 
48  ~list_device_view() = default;
49 
74  [[nodiscard]] __device__ inline size_type element_offset(size_type idx) const
75  {
76  cudf_assert(idx >= 0 && idx < size() && "idx out of bounds");
77  return begin_offset + idx;
78  }
79 
87  template <typename T>
88  __device__ inline T element(size_type idx) const
89  {
90  return lists_column.child().element<T>(element_offset(idx));
91  }
92 
99  [[nodiscard]] __device__ inline bool is_null(size_type idx) const
100  {
101  cudf_assert(idx >= 0 && idx < size() && "Index out of bounds.");
102  auto element_offset = begin_offset + idx;
103  return lists_column.child().is_null(element_offset);
104  }
105 
111  [[nodiscard]] __device__ inline bool is_null() const { return lists_column.is_null(_row_index); }
112 
118  [[nodiscard]] __device__ inline size_type size() const { return _size; }
119 
125  [[nodiscard]] __device__ inline size_type row_index() const { return _row_index; }
126 
132  [[nodiscard]] __device__ inline lists_column_device_view const& get_column() const
133  {
134  return lists_column;
135  }
136 
137  template <typename T>
138  struct pair_accessor;
139 
140  template <typename T>
141  struct pair_rep_accessor;
142 
144  template <typename T>
146  cuda::transform_iterator<pair_accessor<T>, cuda::counting_iterator<cudf::size_type>>;
147 
149  template <typename T>
151  cuda::transform_iterator<pair_rep_accessor<T>, cuda::counting_iterator<cudf::size_type>>;
152 
169  template <typename T>
170  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_begin() const
171  {
172  return const_pair_iterator<T>{cuda::counting_iterator<size_type>{0}, pair_accessor<T>{*this}};
173  }
174 
182  template <typename T>
183  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_end() const
184  {
185  return const_pair_iterator<T>{cuda::counting_iterator<size_type>{size()},
186  pair_accessor<T>{*this}};
187  }
188 
207  template <typename T>
208  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_begin() const
209  {
210  return const_pair_rep_iterator<T>{cuda::counting_iterator<size_type>{0},
211  pair_rep_accessor<T>{*this}};
212  }
213 
221  template <typename T>
222  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_end() const
223  {
224  return const_pair_rep_iterator<T>{cuda::counting_iterator<size_type>{size()},
225  pair_rep_accessor<T>{*this}};
226  }
227 
228  private:
229  lists_column_device_view const& lists_column;
230  size_type _row_index{}; // Row index in the Lists column vector.
231  size_type _size{}; // Number of elements in *this* list row.
232 
233  size_type begin_offset; // Offset in list_column_device_view where this list begins.
234 
244  template <typename T>
245  struct pair_accessor {
247 
253  explicit CUDF_HOST_DEVICE inline pair_accessor(list_device_view const& _list) : list{_list} {}
254 
261  __device__ inline cuda::std::pair<T, bool> operator()(cudf::size_type i) const
262  {
263  return {list.element<T>(i), !list.is_null(i)};
264  }
265  };
266 
279  template <typename T>
282 
284 
290  explicit CUDF_HOST_DEVICE inline pair_rep_accessor(list_device_view const& _list) : list{_list}
291  {
292  }
293 
300  __device__ inline cuda::std::pair<rep_type, bool> operator()(cudf::size_type i) const
301  {
302  return {get_rep<T>(i), !list.is_null(i)};
303  }
304 
305  private:
306  template <typename R>
307  __device__ inline rep_type get_rep(cudf::size_type i) const
308  requires(std::is_same_v<R, rep_type>)
309  {
310  return list.element<R>(i);
311  }
312 
313  template <typename R>
314  __device__ inline rep_type get_rep(cudf::size_type i) const
315  requires(not std::is_same_v<R, rep_type>)
316  {
317  return list.element<R>(i).value();
318  }
319  };
320 };
321 
333  CUDF_HOST_DEVICE inline list_size_functor(lists_column_device_view const& d_col) : d_column(d_col)
334  {
335  }
342  __device__ inline size_type operator()(size_type idx)
343  {
344  if (d_column.is_null(idx)) return size_type{0};
345  return d_column.offset_at(idx + 1) - d_column.offset_at(idx);
346  }
347 };
348 
365 {
366  return detail::make_counting_transform_iterator(0, list_size_functor{c});
367 }
368 
369 } // namespace CUDF_EXPORT cudf
An immutable, non-owning view of device data as a column of elements that is trivially copyable and u...
T element(size_type element_index) const noexcept
Returns a copy of the element at the specified index.
CUDF_HOST_DEVICE size_type size() const noexcept
Returns the number of elements in the column.
A non-owning, immutable view of device data that represents a list of elements of arbitrary type (inc...
const_pair_rep_iterator< T > pair_rep_end() const
Fetcher for a pair iterator to one position past the last element in the list_device_view.
T element(size_type idx) const
Fetches the element at the specified index within the list row.
size_type element_offset(size_type idx) const
Fetches the offset in the list column's child that corresponds to the element at the specified list i...
bool is_null() const
Checks whether this list row is null.
const_pair_iterator< T > pair_end() const
Fetcher for a pair iterator to one position past the last element in the list_device_view.
size_type row_index() const
Returns the row index of this list in the original lists column.
cuda::transform_iterator< pair_accessor< T >, cuda::counting_iterator< cudf::size_type > > const_pair_iterator
const pair iterator for the list
bool is_null(size_type idx) const
Checks whether the element is null at the specified index in the list.
const_pair_rep_iterator< T > pair_rep_begin() const
Fetcher for a pair iterator to the first element in the list_device_view.
cuda::transform_iterator< pair_rep_accessor< T >, cuda::counting_iterator< cudf::size_type > > const_pair_rep_iterator
const pair iterator type for the list
list_device_view(lists_column_device_view const &lists_column, size_type const &row_index)
Constructs a list_device_view from a list column and index.
const_pair_iterator< T > pair_begin() const
Fetcher for a pair iterator to the first element in the list_device_view.
lists_column_device_view const & get_column() const
Fetches the lists_column_device_view that contains this list.
size_type size() const
Fetches the number of elements in this list row.
Given a column_device_view, an instance of this class provides a wrapper on this compound column for ...
column_device_view offsets() const
Fetches the offsets column of the underlying list column.
size_type offset_at(size_type idx) const
Fetches the list offset value at a given row index while taking column offset into account.
column_device_view child() const
Fetches the child column of the underlying list column.
std::conditional_t< std::is_same_v< numeric::decimal32, T >, int32_t, std::conditional_t< std::is_same_v< numeric::decimal64, T >, int64_t, std::conditional_t< std::is_same_v< numeric::decimal128, T >, __int128_t, T > >> device_storage_type_t
"Returns" the corresponding type that is stored on the device when using cudf::column
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:76
cuDF interfaces
Definition: host_udf.hpp:27
CUDF_HOST_DEVICE auto make_list_size_iterator(lists_column_device_view const &c)
Makes an iterator that returns size of the list by row index.
requires(is_index_type< IndexType >() &&is_relationally_comparable< KeyType, KeyType >()) struct dictionary_element
A type tag to specify that a column should be treated as a dictionary column.
pair accessor for elements in a list_device_view
CUDF_HOST_DEVICE pair_accessor(list_device_view const &_list)
constructor
list_device_view const & list
The list_device_view to access.
cuda::std::pair< T, bool > operator()(cudf::size_type i) const
Accessor for the {data, validity} pair at the specified index.
pair rep accessor for elements in a list_device_view
list_device_view const & list
The list_device_view whose rows are being accessed.
device_storage_type_t< T > rep_type
The type used to store the value on the device.
CUDF_HOST_DEVICE pair_rep_accessor(list_device_view const &_list)
constructor
cuda::std::pair< rep_type, bool > operator()(cudf::size_type i) const
Accessor for the {rep_data, validity} pair at the specified index.
Returns the size of the list by row index.
CUDF_HOST_DEVICE list_size_functor(lists_column_device_view const &d_col)
Constructor.
lists_column_device_view const d_column
The list column to access.
size_type operator()(size_type idx)
Returns size of the list by row index.
Defines the mapping between cudf::type_id runtime type information and concrete C++ types.
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:21