list_device_view.cuh
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-2025, NVIDIA CORPORATION.
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_runtime.h>
13 #include <thrust/iterator/counting_iterator.h>
14 #include <thrust/iterator/transform_iterator.h>
15 #include <thrust/pair.h>
16 
17 namespace CUDF_EXPORT cudf {
18 
25 
26  public:
27  list_device_view() = default;
28 
35  __device__ inline list_device_view(lists_column_device_view const& lists_column,
36  size_type const& row_index)
37  : lists_column(lists_column), _row_index(row_index)
38  {
39  column_device_view const& offsets = lists_column.offsets();
40  cudf_assert(row_index >= 0 && row_index < lists_column.size() && row_index < offsets.size() &&
41  "row_index out of bounds");
42 
43  begin_offset = offsets.element<size_type>(row_index + lists_column.offset());
44  cudf_assert(begin_offset >= 0 && begin_offset <= lists_column.child().size() &&
45  "begin_offset out of bounds.");
46  _size = offsets.element<size_type>(row_index + 1 + lists_column.offset()) - begin_offset;
47  }
48 
49  ~list_device_view() = default;
50 
75  [[nodiscard]] __device__ inline size_type element_offset(size_type idx) const
76  {
77  cudf_assert(idx >= 0 && idx < size() && "idx out of bounds");
78  return begin_offset + idx;
79  }
80 
88  template <typename T>
89  __device__ inline T element(size_type idx) const
90  {
91  return lists_column.child().element<T>(element_offset(idx));
92  }
93 
100  [[nodiscard]] __device__ inline bool is_null(size_type idx) const
101  {
102  cudf_assert(idx >= 0 && idx < size() && "Index out of bounds.");
103  auto element_offset = begin_offset + idx;
104  return lists_column.child().is_null(element_offset);
105  }
106 
112  [[nodiscard]] __device__ inline bool is_null() const { return lists_column.is_null(_row_index); }
113 
119  [[nodiscard]] __device__ inline size_type size() const { return _size; }
120 
126  [[nodiscard]] __device__ inline size_type row_index() const { return _row_index; }
127 
133  [[nodiscard]] __device__ inline lists_column_device_view const& get_column() const
134  {
135  return lists_column;
136  }
137 
138  template <typename T>
139  struct pair_accessor;
140 
141  template <typename T>
142  struct pair_rep_accessor;
143 
145  template <typename T>
147  thrust::transform_iterator<pair_accessor<T>, thrust::counting_iterator<cudf::size_type>>;
148 
150  template <typename T>
152  thrust::transform_iterator<pair_rep_accessor<T>, thrust::counting_iterator<cudf::size_type>>;
153 
170  template <typename T>
171  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_begin() const
172  {
173  return const_pair_iterator<T>{thrust::counting_iterator<size_type>(0), pair_accessor<T>{*this}};
174  }
175 
183  template <typename T>
184  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_end() const
185  {
186  return const_pair_iterator<T>{thrust::counting_iterator<size_type>(size()),
187  pair_accessor<T>{*this}};
188  }
189 
208  template <typename T>
209  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_begin() const
210  {
211  return const_pair_rep_iterator<T>{thrust::counting_iterator<size_type>(0),
212  pair_rep_accessor<T>{*this}};
213  }
214 
222  template <typename T>
223  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_end() const
224  {
225  return const_pair_rep_iterator<T>{thrust::counting_iterator<size_type>(size()),
226  pair_rep_accessor<T>{*this}};
227  }
228 
229  private:
230  lists_column_device_view const& lists_column;
231  size_type _row_index{}; // Row index in the Lists column vector.
232  size_type _size{}; // Number of elements in *this* list row.
233 
234  size_type begin_offset; // Offset in list_column_device_view where this list begins.
235 
245  template <typename T>
246  struct pair_accessor {
248 
254  explicit CUDF_HOST_DEVICE inline pair_accessor(list_device_view const& _list) : list{_list} {}
255 
262  __device__ inline thrust::pair<T, bool> operator()(cudf::size_type i) const
263  {
264  return {list.element<T>(i), !list.is_null(i)};
265  }
266  };
267 
280  template <typename T>
283 
285 
291  explicit CUDF_HOST_DEVICE inline pair_rep_accessor(list_device_view const& _list) : list{_list}
292  {
293  }
294 
301  __device__ inline thrust::pair<rep_type, bool> operator()(cudf::size_type i) const
302  {
303  return {get_rep<T>(i), !list.is_null(i)};
304  }
305 
306  private:
307  template <typename R>
308  __device__ inline rep_type get_rep(cudf::size_type i) const
309  requires(std::is_same_v<R, rep_type>)
310  {
311  return list.element<R>(i);
312  }
313 
314  template <typename R>
315  __device__ inline rep_type get_rep(cudf::size_type i) const
316  requires(not std::is_same_v<R, rep_type>)
317  {
318  return list.element<R>(i).value();
319  }
320  };
321 };
322 
335  : d_column(d_col)
336  {
337  }
344  __device__ inline size_type operator()(size_type idx)
345  {
346  if (d_column.is_null(idx)) return size_type{0};
347  return d_column.offset_at(idx + 1) - d_column.offset_at(idx);
348  }
349 };
350 
367 {
368  return detail::make_counting_transform_iterator(0, list_size_functor{c});
369 }
370 
371 } // 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.
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.
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.
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.
thrust::transform_iterator< pair_accessor< T >, thrust::counting_iterator< cudf::size_type > > const_pair_iterator
const pair iterator for the list
thrust::transform_iterator< pair_rep_accessor< T >, thrust::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.
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:84
cuDF interfaces
Definition: host_udf.hpp:26
CUDF_HOST_DEVICE auto make_list_size_iterator(detail::lists_column_device_view const &c)
Makes an iterator that returns size of the list by row index.
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.
thrust::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
thrust::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.
detail::lists_column_device_view const d_column
The list column to access.
CUDF_HOST_DEVICE list_size_functor(detail::lists_column_device_view const &d_col)
Constructor.
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