span.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2020-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #pragma once
7 
8 #include <cudf/types.hpp>
9 #include <cudf/utilities/export.hpp>
10 
11 #include <rmm/device_buffer.hpp>
12 #include <rmm/device_uvector.hpp>
13 #include <rmm/device_vector.hpp>
14 
15 #include <cuda/std/span>
16 #include <thrust/detail/raw_pointer_cast.h>
17 #include <thrust/device_vector.h>
18 #include <thrust/host_vector.h>
19 #include <thrust/memory.h>
20 
21 #include <cstddef>
22 #include <span>
23 #include <type_traits>
24 #include <utility>
25 
31 namespace CUDF_EXPORT cudf {
38 constexpr std::size_t dynamic_extent = cuda::std::dynamic_extent;
39 
40 // ===== host_span =================================================================================
41 
42 template <typename T>
43 struct is_host_span_supported_container : std::false_type {};
44 
45 template <typename T, typename Alloc>
47  std::vector<T, Alloc>> : std::true_type {};
48 
49 template <typename T, typename Alloc>
51  thrust::host_vector<T, Alloc>> : std::true_type {};
52 
53 template <typename T, typename Alloc>
55  std::basic_string<T, std::char_traits<T>, Alloc>> : std::true_type {};
56 
64 template <typename T, std::size_t Extent = cudf::dynamic_extent>
65 struct host_span {
66  private:
67  using span_type = cuda::std::span<T, Extent>;
68 
69  public:
70  using element_type = typename span_type::element_type;
71  using value_type = typename span_type::value_type;
72  using size_type = typename span_type::size_type;
73  using difference_type = typename span_type::difference_type;
74  using pointer = typename span_type::pointer;
75  using const_pointer = typename span_type::const_pointer;
76  using reference = typename span_type::reference;
77  using const_reference = typename span_type::const_reference;
78  using iterator = pointer;
79 
80  static constexpr std::size_t extent = span_type::extent;
81 
82  constexpr host_span() noexcept {} // required to compile on centos
83 
92  CUDF_HOST_DEVICE constexpr host_span(T* data, std::size_t size) : _span{data, size} {}
93 
103  CUDF_HOST_DEVICE constexpr host_span(T* data, std::size_t size, bool is_device_accessible)
104  : _span{data, size}, _is_device_accessible{is_device_accessible}
105  {
106  }
107 
110  template <typename C,
111  // Only supported containers of types convertible to T
112  std::enable_if_t<is_host_span_supported_container<C>::value &&
113  std::is_convertible_v<
114  std::remove_pointer_t<decltype(thrust::raw_pointer_cast( // NOLINT
115  std::declval<C&>().data()))> (*)[],
116  T (*)[]>>* = nullptr> // NOLINT
117  constexpr host_span(C& in) : _span{thrust::raw_pointer_cast(in.data()), in.size()}
118  {
119  }
120 
123  template <typename C,
124  // Only supported containers of types convertible to T
125  std::enable_if_t<is_host_span_supported_container<C>::value &&
126  std::is_convertible_v<
127  std::remove_pointer_t<decltype(thrust::raw_pointer_cast( // NOLINT
128  std::declval<C&>().data()))> (*)[],
129  T (*)[]>>* = nullptr> // NOLINT
130  constexpr host_span(C const& in) : _span{thrust::raw_pointer_cast(in.data()), in.size()}
131  {
132  }
133 
134  // Copy construction to support const conversion
136  template <typename OtherT,
137  std::size_t OtherExtent,
138  std::enable_if_t<(Extent == OtherExtent || Extent == dynamic_extent) &&
139  std::is_convertible_v<OtherT (*)[], T (*)[]>, // NOLINT
140  void>* = nullptr>
141  constexpr host_span(host_span<OtherT, OtherExtent> const& other) noexcept
142  : _span{other.data(), other.size()}, _is_device_accessible{other.is_device_accessible()}
143  {
144  }
145 
146  // not noexcept due to undefined behavior when idx < 0 || idx >= size
156  constexpr reference operator[](size_type idx) const
157  {
158  static_assert(sizeof(idx) >= sizeof(size_t), "index type must not be smaller than size_t");
159  return _span[idx];
160  }
161 
162  // not noexcept due to undefined behavior when size = 0
170  [[nodiscard]] constexpr reference front() const { return _span.front(); }
171  // not noexcept due to undefined behavior when size = 0
179  [[nodiscard]] constexpr reference back() const { return _span.back(); }
180 
188  [[nodiscard]] CUDF_HOST_DEVICE constexpr iterator begin() const noexcept { return _span.data(); }
196  [[nodiscard]] CUDF_HOST_DEVICE constexpr iterator end() const noexcept
197  {
198  return _span.data() + _span.size();
199  }
205  [[nodiscard]] CUDF_HOST_DEVICE constexpr pointer data() const noexcept { return _span.data(); }
206 
212  [[nodiscard]] CUDF_HOST_DEVICE constexpr size_type size() const noexcept { return _span.size(); }
218  [[nodiscard]] CUDF_HOST_DEVICE constexpr size_type size_bytes() const noexcept
219  {
220  return _span.size_bytes();
221  }
222 
228  [[nodiscard]] CUDF_HOST_DEVICE constexpr bool empty() const noexcept { return _span.empty(); }
229 
236  [[nodiscard]] constexpr host_span first(size_type count) const noexcept
237  {
238  return host_span{_span.data(), count, _is_device_accessible};
239  }
240 
247  [[nodiscard]] constexpr host_span last(size_type count) const noexcept
248  {
249  return host_span{_span.data() + _span.size() - count, count, _is_device_accessible};
250  }
251 
257  [[nodiscard]] bool is_device_accessible() const { return _is_device_accessible; }
258 
266  [[nodiscard]] CUDF_HOST_DEVICE constexpr host_span subspan(size_type offset,
267  size_type count) const noexcept
268  {
269  return host_span{_span.data() + offset, count, _is_device_accessible};
270  }
271 
277  [[nodiscard]] constexpr operator std::span<T>() const noexcept
278  {
279  return std::span<T>(_span.data(), _span.size());
280  }
281 
282  private:
283  // TODO: could be std::span once base_2dspan moves to cuda::std::mdspan and host_span no longer
284  // needs to be device-usable.
285  span_type _span;
286  bool _is_device_accessible{false};
287 };
288 
289 // ===== device_span ===============================================================================
290 
295 template <typename T, std::size_t Extent = cuda::std::dynamic_extent>
296 using device_span = cuda::std::span<T, Extent>; // end of group
298 
299 namespace detail {
300 
306 template <typename T, template <typename, std::size_t> typename RowType>
307 class base_2dspan {
308  public:
309  using size_type =
310  std::pair<size_t, size_t>;
311 
312  constexpr base_2dspan() noexcept = default;
319  constexpr base_2dspan(RowType<T, dynamic_extent> flat_view, size_t columns)
320  : _flat{flat_view}, _size{columns == 0 ? 0 : flat_view.size() / columns, columns}
321  {
322 #ifndef __CUDA_ARCH__
323  CUDF_EXPECTS(_size.first * _size.second == flat_view.size(), "Invalid 2D span size");
324 #endif
325  }
326 
332  [[nodiscard]] CUDF_HOST_DEVICE constexpr auto data() const noexcept { return _flat.data(); }
333 
339  [[nodiscard]] CUDF_HOST_DEVICE constexpr auto size() const noexcept { return _size; }
340 
346  [[nodiscard]] CUDF_HOST_DEVICE constexpr auto count() const noexcept { return _flat.size(); }
347 
353  [[nodiscard]] CUDF_HOST_DEVICE constexpr bool is_empty() const noexcept { return count() == 0; }
354 
364  CUDF_HOST_DEVICE constexpr RowType<T, dynamic_extent> operator[](std::size_t row) const
365  {
366  return _flat.subspan(row * _size.second, _size.second);
367  }
368 
374  [[nodiscard]] CUDF_HOST_DEVICE constexpr RowType<T, dynamic_extent> flat_view() const
375  {
376  return _flat;
377  }
378 
386  template <typename OtherT,
387  template <typename, size_t> typename OtherRowType,
388  std::enable_if_t<std::is_convertible_v<OtherRowType<OtherT, dynamic_extent>,
389  RowType<T, dynamic_extent>>,
390  void>* = nullptr>
391  constexpr base_2dspan(base_2dspan<OtherT, OtherRowType> const& other) noexcept
392  : _flat{other.flat_view()}, _size{other.size()}
393  {
394  }
395 
396  protected:
397  RowType<T, dynamic_extent> _flat;
398  size_type _size{0, 0};
399 };
400 
406 template <class T>
408 
414 template <class T>
416 
417 } // namespace detail
418 } // namespace CUDF_EXPORT cudf
Generic class for row-major 2D spans. Not compliant with STL container semantics/syntax.
Definition: span.hpp:307
std::pair< size_t, size_t > size_type
Type used to represent the dimension of the span.
Definition: span.hpp:310
constexpr CUDF_HOST_DEVICE bool is_empty() const noexcept
Checks if the span is empty.
Definition: span.hpp:353
constexpr CUDF_HOST_DEVICE auto size() const noexcept
Returns the size in the span as pair.
Definition: span.hpp:339
constexpr CUDF_HOST_DEVICE auto count() const noexcept
Returns the number of elements in the span.
Definition: span.hpp:346
constexpr CUDF_HOST_DEVICE RowType< T, dynamic_extent > operator[](std::size_t row) const
Returns a reference to the row-th element of the sequence.
Definition: span.hpp:364
constexpr CUDF_HOST_DEVICE auto data() const noexcept
Returns a pointer to the beginning of the sequence.
Definition: span.hpp:332
constexpr CUDF_HOST_DEVICE RowType< T, dynamic_extent > flat_view() const
Returns a flattened span of the 2D span.
Definition: span.hpp:374
RowType< T, dynamic_extent > _flat
flattened 2D span
Definition: span.hpp:397
constexpr base_2dspan(base_2dspan< OtherT, OtherRowType > const &other) noexcept
Construct a 2D span from another 2D span of convertible type.
Definition: span.hpp:391
std::unique_ptr< column > count(strings_column_view const &input, string_scalar const &target, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Returns the number of times the given target string matches in each string.
#define CUDF_EXPECTS(...)
Macro for checking (pre-)conditions that throws an exception when a condition is violated.
Definition: error.hpp:182
cuda::std::span< T, Extent > device_span
Device span is an alias of cuda::std::span.
Definition: span.hpp:296
constexpr std::size_t dynamic_extent
A constant used to differentiate std::span of static and dynamic extent.
Definition: span.hpp:38
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:84
cuDF interfaces
Definition: host_udf.hpp:26
Host span, a non-owning view over a contiguous sequence of host-accessible elements.
Definition: span.hpp:65
typename span_type::reference reference
Reference returned by operator[].
Definition: span.hpp:76
constexpr CUDF_HOST_DEVICE host_span(T *data, std::size_t size)
Constructs a span from a pointer and a size.
Definition: span.hpp:92
constexpr host_span last(size_type count) const noexcept
Obtains a subspan consisting of the last count elements of the sequence.
Definition: span.hpp:247
typename span_type::const_reference const_reference
Const reference to an element.
Definition: span.hpp:77
constexpr reference back() const
Returns a reference to the last element in the span.
Definition: span.hpp:179
constexpr CUDF_HOST_DEVICE size_type size() const noexcept
Returns the number of elements in the span.
Definition: span.hpp:212
constexpr host_span(C const &in)
Definition: span.hpp:130
typename span_type::size_type size_type
Size type.
Definition: span.hpp:72
typename span_type::pointer pointer
Pointer returned by data()
Definition: span.hpp:74
typename span_type::difference_type difference_type
std::ptrdiff_t
Definition: span.hpp:73
constexpr reference operator[](size_type idx) const
Returns a reference to the idx-th element of the sequence.
Definition: span.hpp:156
bool is_device_accessible() const
Returns whether the data is device accessible (e.g. pinned memory)
Definition: span.hpp:257
typename span_type::const_pointer const_pointer
Pointer returned by data() const.
Definition: span.hpp:75
constexpr CUDF_HOST_DEVICE host_span subspan(size_type offset, size_type count) const noexcept
Obtains a span that is a view over the count elements of this span starting at offset.
Definition: span.hpp:266
constexpr CUDF_HOST_DEVICE iterator end() const noexcept
Returns an iterator to the element following the last element of the span.
Definition: span.hpp:196
constexpr host_span(host_span< OtherT, OtherExtent > const &other) noexcept
Definition: span.hpp:141
constexpr CUDF_HOST_DEVICE size_type size_bytes() const noexcept
Returns the size of the sequence in bytes.
Definition: span.hpp:218
constexpr reference front() const
Returns a reference to the first element in the span.
Definition: span.hpp:170
constexpr CUDF_HOST_DEVICE host_span(T *data, std::size_t size, bool is_device_accessible)
Constructor from pointer, size and device-accessibility flag.
Definition: span.hpp:103
constexpr host_span first(size_type count) const noexcept
Obtains a subspan consisting of the first count elements of the sequence.
Definition: span.hpp:236
pointer iterator
The type of the iterator returned by begin()
Definition: span.hpp:78
constexpr CUDF_HOST_DEVICE pointer data() const noexcept
Returns a pointer to the beginning of the sequence.
Definition: span.hpp:205
typename span_type::element_type element_type
Element type.
Definition: span.hpp:70
constexpr CUDF_HOST_DEVICE iterator begin() const noexcept
Returns an iterator to the first element of the span.
Definition: span.hpp:188
constexpr CUDF_HOST_DEVICE bool empty() const noexcept
Checks if the span is empty.
Definition: span.hpp:228
typename span_type::value_type value_type
Stored value type.
Definition: span.hpp:71
constexpr host_span(C &in)
Definition: span.hpp:117
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:21