list_device_view.cuh
1 /*
2  * Copyright (c) 2020-2024, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * https://apache.ac.cn/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <cudf/detail/iterator.cuh>
19 #include <cudf/lists/lists_column_device_view.cuh>
20 #include <cudf/types.hpp>
22 
23 #include <cuda_runtime.h>
24 #include <thrust/iterator/counting_iterator.h>
25 #include <thrust/iterator/transform_iterator.h>
26 #include <thrust/pair.h>
27 
28 namespace CUDF_EXPORT cudf {
29 
36 
37  public
38  list_device_view() = default;
39 
46  __device__ inline list_device_view(lists_column_device_view const& lists_column,
47  size_type const& row_index)
48  : lists_column(lists_column), _row_index(row_index)
49  {
50  column_device_view const& offsets = lists_column.offsets();
51  cudf_assert(row_index >= 0 && row_index < lists_column.size() && row_index < offsets.size() &&
52  "row_index 超出范围");
53 
54  begin_offset = offsets.element<size_type>(row_index + lists_column.offset());
55  cudf_assert(begin_offset >= 0 && begin_offset <= lists_column.child().size() &&
56  "begin_offset 超出范围。");
57  _size = offsets.element<size_type>(row_index + 1 + lists_column.offset()) - begin_offset;
58  }
59 
60  ~list_device_view() = default;
61 
86  [[nodiscard]] __device__ inline size_type element_offset(size_type idx) const
87  {
88  cudf_assert(idx >= 0 && idx < size() && "idx 超出范围");
89  return begin_offset + idx;
90  }
91 
99  template <typename T>
100  __device__ inline T element(size_type idx) const
101  {
102  return lists_column.child().element<T>(element_offset(idx));
103  }
104 
111  [[nodiscard]] __device__ inline bool is_null(size_type idx) const
112  {
113  cudf_assert(idx >= 0 && idx < size() && "索引超出范围。");
114  auto element_offset = begin_offset + idx;
115  return lists_column.child().is_null(element_offset);
116  }
117 
123  [[nodiscard]] __device__ inline bool is_null() const { return lists_column.is_null(_row_index); }
124 
130  [[nodiscard]] __device__ inline size_type size() const { return _size; }
131 
137  [[nodiscard]] __device__ inline size_type row_index() const { return _row_index; }
138 
144  [[nodiscard]] __device__ inline lists_column_device_view const& get_column() const
145  {
146  return lists_column;
147  }
148 
149  template <typename T>
150  struct pair_accessor;
151 
152  template <typename T>
153  struct pair_rep_accessor;
154 
156  template <typename T>
158  thrust::transform_iterator<pair_accessor<T>, thrust::counting_iterator<cudf::size_type>>;
159 
161  template <typename T>
163  thrust::transform_iterator<pair_rep_accessor<T>, thrust::counting_iterator<cudf::size_type>>;
164 
181  template <typename T>
182  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_begin() const
183  {
184  return const_pair_iterator<T>{thrust::counting_iterator<size_type>(0), pair_accessor<T>{*this}};
185  }
186 
194  template <typename T>
195  [[nodiscard]] __device__ inline const_pair_iterator<T> pair_end() const
196  {
197  return const_pair_iterator<T>{thrust::counting_iterator<size_type>(size()),
198  pair_accessor<T>{*this}};
199  }
200 
219  template <typename T>
220  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_begin() const
221  {
222  return const_pair_rep_iterator<T>{thrust::counting_iterator<size_type>(0),
223  pair_rep_accessor<T>{*this}};
224  }
225 
233  template <typename T>
234  [[nodiscard]] __device__ inline const_pair_rep_iterator<T> pair_rep_end() const
235  {
236  return const_pair_rep_iterator<T>{thrust::counting_iterator<size_type>(size()),
237  pair_rep_accessor<T>{*this}};
238  }
239 
240  private
241  lists_column_device_view const& lists_column;
242  size_type _row_index{}; // 在 Lists 列向量中的行索引。
243  size_type _size{}; // *此*列表行中的元素数量。
244 
245  size_type begin_offset; // 此列表在 list_column_device_view 中开始的偏移量。
246 
256  template <typename T>
257  struct pair_accessor {
259 
265  explicit CUDF_HOST_DEVICE inline pair_accessor(list_device_view const& _list) : list{_list} {}
266 
273  __device__ inline thrust::pair<T, bool> operator()(cudf::size_type i) const
274  {
275  return {list.element<T>(i), !list.is_null(i)};
276  }
277  };
278 
291  template <typename T>
294 
296 
302  explicit CUDF_HOST_DEVICE inline pair_rep_accessor(list_device_view const& _list) : list{_list}
303  {
304  }
305 
312  __device__ inline thrust::pair<rep_type, bool> operator()(cudf::size_type i) const
313  {
314  return {get_rep<T>(i), !list.is_null(i)};
315  }
316 
317  private
318  template <typename R, std::enable_if_t<std::is_same_v<R, rep_type>, void>* = nullptr>
319  __device__ inline rep_type get_rep(cudf::size_type i) const
320  {
321  return list.element<R>(i);
322  }
323 
324  template <typename R, std::enable_if_t<not std::is_same_v<R, rep_type>, void>* = nullptr>
325  __device__ inline rep_type get_rep(cudf::size_type i) const
326  {
327  return list.element<R>(i).value();
328  }
329  };
330 };
331 
344  : d_column(d_col)
345  {
346  }
353  __device__ inline size_type operator()(size_type idx)
354  {
355  if (d_column.is_null(idx)) return size_type{0};
356  return d_column.offset_at(idx + 1) - d_column.offset_at(idx);
357  }
358 };
359 
376 {
377  return detail::make_counting_transform_iterator(0, list_size_functor{c});
378 }
379 
380 } // 命名空间 CUDF_EXPORT cudf
一个不可变、非拥有、可轻松复制的设备数据视图,表示为元素列...
T element(size_type element_index) const noexcept
返回指定索引处元素的引用。
CUDF_HOST_DEVICE size_type size() const noexcept
返回列中的元素数量。
给定一个 column_device_view,此类的实例在此复合列上提供一个包装器,用于...
column_device_view offsets() const
获取底层列表列的偏移列。
size_type offset_at(size_type idx) const
获取给定行索引处的列表偏移值,同时考虑列偏移量。
column_device_view child() const
获取底层列表列的子列。
一个非拥有、不可变的设备数据视图,表示一个包含任意类型元素的列表(包括...
const_pair_rep_iterator< T > pair_rep_end() const
用于获取 list_device_view 中最后一个元素之后一个位置的 pair 迭代器。
T element(size_type idx) const
获取列表行中指定索引处的元素。
size_type element_offset(size_type idx) const
获取与指定列表索引处元素对应的列表列子列中的偏移量...
bool is_null() const
检查此列表行是否为空。
const_pair_iterator< T > pair_end() const
用于获取 list_device_view 中最后一个元素之后一个位置的 pair 迭代器。
size_type row_index() const
返回此列表在原始列表列中的行索引。
bool is_null(size_type idx) const
检查列表中指定索引处的元素是否为空。
const_pair_rep_iterator< T > pair_rep_begin() const
用于获取 list_device_view 中第一个元素的 pair 迭代器。
thrust::transform_iterator< pair_accessor< T >, thrust::counting_iterator< cudf::size_type > > const_pair_iterator
列表的 const pair 迭代器
thrust::transform_iterator< pair_rep_accessor< T >, thrust::counting_iterator< cudf::size_type > > const_pair_rep_iterator
列表的 const pair 迭代器类型
list_device_view(lists_column_device_view const &lists_column, size_type const &row_index)
从列表列和索引构造一个 list_device_view。
const_pair_iterator< T > pair_begin() const
用于获取 list_device_view 中第一个元素的 pair 迭代器。
lists_column_device_view const & get_column() const
获取包含此列表的 lists_column_device_view。
size_type size() const
获取此列表行中的元素数量。
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
“返回”使用 cudf::column 时存储在设备上的对应类型
int32_t size_type
用于列和表的行索引类型。
定义: types.hpp:95
cuDF 接口
定义: host_udf.hpp:37
CUDF_HOST_DEVICE auto make_list_size_iterator(detail::lists_column_device_view const &c)
创建一个迭代器,该迭代器按行索引返回列表的大小。
list_device_view 中元素的 pair 访问器
CUDF_HOST_DEVICE pair_accessor(list_device_view const &_list)
构造函数
list_device_view const & list
要访问的 list_device_view。
thrust::pair< T, bool > operator()(cudf::size_type i) const
用于访问指定索引处的 {数据, 有效性} pair 的访问器。
list_device_view 中元素的 pair rep 访问器
list_device_view const & list
正在访问其行的 list_device_view。
device_storage_type_t< T > rep_type
用于在设备上存储值的类型。
CUDF_HOST_DEVICE pair_rep_accessor(list_device_view const &_list)
构造函数
thrust::pair< rep_type, bool > operator()(cudf::size_type i) const
用于访问指定索引处的 {表示数据, 有效性} pair 的访问器。
按行索引返回列表的大小。
detail::lists_column_device_view const d_column
要访问的列表列。
CUDF_HOST_DEVICE list_size_functor(detail::lists_column_device_view const &d_col)
构造函数。
size_type operator()(size_type idx)
按行索引返回列表的大小。
定义 cudf::type_id 运行时类型信息与具体 C++ 类型之间的映射。
libcudf 的类型声明。
#define CUDF_HOST_DEVICE
指示函数或方法可在主机和设备上使用。
定义: types.hpp:32