column_device_view_base.cuh
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2026, NVIDIA CORPORATION.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
7 #include <cudf/detail/offsets_iterator.cuh>
9 #include <cudf/strings/string_view.cuh>
10 #include <cudf/types.hpp>
11 #include <cudf/utilities/bit.hpp>
13 
14 #include <cuda/std/optional>
15 #include <cuda/std/type_traits>
16 
17 #include <algorithm>
18 #include <type_traits>
19 
25 namespace CUDF_EXPORT cudf {
26 
36 struct nullate {
37  struct YES : cuda::std::true_type {};
38  struct NO : cuda::std::false_type {};
44  struct DYNAMIC {
45  DYNAMIC() = delete;
54  constexpr explicit DYNAMIC(bool b) noexcept : value{b} {}
61  CUDF_HOST_DEVICE constexpr operator bool() const noexcept { return value; }
62  bool value;
63  };
64 };
65 
66 namespace detail {
71 class alignas(16) column_device_view_base {
72  public:
73  // TODO: merge this offsets column index with `strings_column_view::offsets_column_index`
74  static constexpr size_type offsets_column_index{0};
75 
76  column_device_view_base() = delete;
77  ~column_device_view_base() = default;
92 
109  template <typename T = void,
110  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
111  [[nodiscard]] CUDF_HOST_DEVICE T const* head() const noexcept
112  {
113  return static_cast<T const*>(_data);
114  }
115 
131  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
132  [[nodiscard]] CUDF_HOST_DEVICE T const* data() const noexcept
133  {
134  return head<T>() + _offset;
135  }
136 
142  [[nodiscard]] CUDF_HOST_DEVICE size_type size() const noexcept { return _size; }
143 
149  [[nodiscard]] CUDF_HOST_DEVICE data_type type() const noexcept { return _type; }
150 
160  [[nodiscard]] CUDF_HOST_DEVICE bool nullable() const noexcept { return nullptr != _null_mask; }
161 
171  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type const* null_mask() const noexcept
172  {
173  return _null_mask;
174  }
175 
182  [[nodiscard]] CUDF_HOST_DEVICE size_type offset() const noexcept { return _offset; }
183 
198  [[nodiscard]] __device__ bool is_valid(size_type element_index) const noexcept
199  {
200  return not nullable() or is_valid_nocheck(element_index);
201  }
202 
215  [[nodiscard]] __device__ bool is_valid_nocheck(size_type element_index) const noexcept
216  {
217  return bit_is_set(_null_mask, offset() + element_index);
218  }
219 
233  [[nodiscard]] __device__ bool is_null(size_type element_index) const noexcept
234  {
235  return not is_valid(element_index);
236  }
237 
249  [[nodiscard]] __device__ bool is_null_nocheck(size_type element_index) const noexcept
250  {
251  return not is_valid_nocheck(element_index);
252  }
253 
263  [[nodiscard]] __device__ bitmask_type get_mask_word(size_type word_index) const noexcept
264  {
265  return null_mask()[word_index];
266  }
267 
268  protected:
269  data_type _type{type_id::EMPTY};
270  cudf::size_type _size{};
271  void const* _data{};
272  size_type _null_count{};
273  bitmask_type const* _null_mask{};
275  size_type _offset{};
277  void* _children{};
278  size_type _num_children{};
279 
293  size_type size,
294  void const* data,
296  bitmask_type const* null_mask,
297  size_type offset,
298  void* children,
299  size_type num_children)
300  : _type{type},
301  _size{size},
302  _data{data},
303  _null_count{null_count},
304  _null_mask{null_mask},
305  _offset{offset},
306  _children{children},
307  _num_children{num_children}
308  {
309  }
310 
311  template <typename C, typename T, typename = void>
312  struct has_element_accessor_impl : cuda::std::false_type {};
313 
314  template <typename C, typename T>
315  struct has_element_accessor_impl<
316  C,
317  T,
318  void_t<decltype(cuda::std::declval<C>().template element<T>(cuda::std::declval<size_type>()))>>
319  : cuda::std::true_type {};
320 };
321 // @cond
322 // Forward declaration
323 template <typename T>
324 struct value_accessor;
325 template <typename T, typename Nullate>
326 struct optional_accessor;
327 template <typename T, bool has_nulls>
328 struct pair_accessor;
329 template <typename T, bool has_nulls>
330 struct pair_rep_accessor;
331 template <typename T>
332 struct mutable_value_accessor;
333 // @endcond
334 } // namespace detail
335 
343  public:
344  static constexpr bool is_mutable =
345  false;
346 
347  column_device_view_core() = delete;
348  ~column_device_view_core() = default;
363 
373  column_device_view_core(column_view column, void* h_ptr, void* d_ptr);
374 
392  size_type size) const noexcept
393  {
394  return column_device_view_core{this->type(),
395  size,
396  this->head(),
397  this->null_count(),
398  this->null_mask(),
399  this->offset() + offset,
400  static_cast<column_device_view_core*>(_children),
401  this->num_child_columns()};
402  }
403 
421  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
422  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
423  {
424  return data<T>()[element_index];
425  }
426 
438  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
439  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
440  {
441  size_type index = element_index + offset(); // account for this view's _offset
442  char const* d_strings = static_cast<char const*>(_data);
443  auto const offsets = child(offsets_column_index);
444  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
445  auto const offset = itr[index];
446  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
447  }
448 
449  public:
460  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
461  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
462  {
463  using namespace numeric;
464  using rep = typename T::rep;
465  auto const scale = scale_type{_type.scale()};
466  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
467  }
468 
477  template <typename T>
478  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
479  size_type element_index) const noexcept
480  {
481  if (is_null(element_index)) { return cuda::std::nullopt; }
482  return element<T>(element_index);
483  }
484 
491  [[nodiscard]] __device__ column_device_view_core child(size_type child_index) const noexcept
492  {
493  return static_cast<column_device_view_core*>(_children)[child_index];
494  }
495 
501  [[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
502  {
503  return _num_children;
504  }
505 
511  [[nodiscard]] CUDF_HOST_DEVICE size_type null_count() const noexcept { return _null_count; }
512 
513  protected:
528  size_type size,
529  void const* data,
531  bitmask_type const* null_mask,
532  size_type offset,
533  column_device_view_core* children,
534  size_type num_children)
535  : column_device_view_base(
536  type, size, data, null_count, null_mask, offset, children, num_children)
537  {
538  }
539 };
540 
548  public:
549  static constexpr bool is_mutable =
550  true;
551 
553  ~mutable_column_device_view_core() = default;
555  default;
557  default;
570 
587  template <typename T = void,
588  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
589  [[nodiscard]] CUDF_HOST_DEVICE T* head() const noexcept
590  {
591  return const_cast<T*>(detail::column_device_view_base::head<T>());
592  }
593 
606  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
607  [[nodiscard]] CUDF_HOST_DEVICE T* data() const noexcept
608  {
609  return const_cast<T*>(detail::column_device_view_base::data<T>());
610  }
611 
626  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
627  [[nodiscard]] __device__ T& element(size_type element_index) const noexcept
628  {
629  return data<T>()[element_index];
630  }
631 
643  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
644  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
645  {
646  size_type index = element_index + offset(); // account for this view's _offset
647  char const* d_strings = static_cast<char const*>(_data);
648  auto const offsets = child(offsets_column_index);
649  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
650  auto const offset = itr[index];
651  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
652  }
653 
664  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
665  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
666  {
667  using namespace numeric;
668  using rep = typename T::rep;
669  auto const scale = scale_type{_type.scale()};
670  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
671  }
672 
681  template <typename T>
682  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
683  size_type element_index) const noexcept
684  {
685  if (is_null(element_index)) { return cuda::std::nullopt; }
686  return element<T>(element_index);
687  }
688 
696  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
697  __device__ void assign(size_type element_index, T value) const noexcept
698  {
699  data<T>()[element_index] = value;
700  }
701 
710  template <typename T, CUDF_ENABLE_IF(is_fixed_point<T>())>
711  __device__ void assign(size_type element_index, T value) const noexcept
712  {
713  // consider asserting that the scale matches
714  using namespace numeric;
715  using rep = typename T::rep;
716  data<rep>()[element_index] = value.value();
717  }
718 
727  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
728  {
729  return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
730  }
731 
738  [[nodiscard]] __device__ mutable_column_device_view_core
739  child(size_type child_index) const noexcept
740  {
741  return static_cast<mutable_column_device_view_core*>(_children)[child_index];
742  }
743 
744 #ifdef __CUDACC__ // because set_bit in bit.hpp is wrapped with __CUDACC__
759  __device__ void set_valid(size_type element_index) const noexcept
760  {
761  return set_bit(null_mask(), element_index);
762  }
763 
777  __device__ void set_null(size_type element_index) const noexcept
778  {
779  return clear_bit(null_mask(), element_index);
780  }
781 
782 #endif
783 
794  __device__ void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
795  {
796  null_mask()[word_index] = new_word;
797  }
798 
799  protected:
813  size_type size,
814  void const* data,
815  bitmask_type const* null_mask,
816  size_type offset,
818  size_type num_children)
819  : column_device_view_base(type,
820  size,
821  data,
822  0, // unused
823  null_mask,
824  offset,
825  children,
826  num_children)
827  {
828  }
829 };
830 
831 } // namespace CUDF_EXPORT cudf
Utilities for bit and bitmask operations.
An immutable, non-owning view of device data as a column of elements that is trivially copyable and u...
column_device_view_core(column_device_view_core const &)=default
Copy constructor.
CUDF_HOST_DEVICE column_device_view_core(data_type type, size_type size, void const *data, size_type null_count, bitmask_type const *null_mask, size_type offset, column_device_view_core *children, size_type num_children)
Creates an instance of this class using pre-existing device memory pointers to data,...
cuda::std::optional< T > nullable_element(size_type element_index) const noexcept
Returns a nullable element at the specified index. If the element is null, returns nullopt.
CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
Returns the number of child columns.
T element(size_type element_index) const noexcept
Returns a copy of the element at the specified index.
column_device_view_core & operator=(column_device_view_core const &)=default
Copy assignment operator.
CUDF_HOST_DEVICE size_type null_count() const noexcept
Returns the number of nulls in this column.
column_device_view_core(column_device_view_core &&)=default
Move constructor.
CUDF_HOST_DEVICE column_device_view_core slice(size_type offset, size_type size) const noexcept
Get a new raw_column_device_view which is a slice of this column.
column_device_view_core & operator=(column_device_view_core &&)=default
Move assignment operator.
column_device_view_core(column_view column, void *h_ptr, void *d_ptr)
Creates an instance of this class using the specified host memory pointer (h_ptr) to store child obje...
column_device_view_core child(size_type child_index) const noexcept
Returns the specified child.
A non-owning, immutable view of device data as a column of elements, some of which may be null as ind...
A container of nullable device data as a column of elements.
Definition: column.hpp:36
Indicator for the logical data type of an element in a column.
Definition: types.hpp:277
An immutable, non-owning view of device data as a column of elements that is trivially copyable and u...
CUDF_HOST_DEVICE T const * head() const noexcept
Returns pointer to the base device memory allocation casted to the specified type.
CUDF_HOST_DEVICE data_type type() const noexcept
Returns the element type.
column_device_view_base & operator=(column_device_view_base &&)=default
Move assignment operator.
CUDF_HOST_DEVICE size_type size() const noexcept
Returns the number of elements in the column.
CUDF_HOST_DEVICE column_device_view_base(data_type type, size_type size, void const *data, size_type null_count, bitmask_type const *null_mask, size_type offset, void *children, size_type num_children)
Constructs a column with the specified type, size, data, nullmask and offset.
bitmask_type get_mask_word(size_type word_index) const noexcept
Returns the specified bitmask word from the null_mask().
column_device_view_base(column_device_view_base &&)=default
Move constructor.
column_device_view_base(column_device_view_base const &)=default
Copy constructor.
CUDF_HOST_DEVICE bitmask_type const * null_mask() const noexcept
Returns raw pointer to the underlying bitmask allocation.
bool is_valid_nocheck(size_type element_index) const noexcept
Returns whether the specified element holds a valid value (i.e., not null)
CUDF_HOST_DEVICE T const * data() const noexcept
Returns the underlying data casted to the specified type, plus the offset.
column_device_view_base & operator=(column_device_view_base const &)=default
Copy assignment operator.
bool is_null(size_type element_index) const noexcept
Returns whether the specified element is null.
CUDF_HOST_DEVICE size_type offset() const noexcept
Returns the index of the first element relative to the base memory allocation, i.e....
bool is_null_nocheck(size_type element_index) const noexcept
Returns whether the specified element is null.
CUDF_HOST_DEVICE bool nullable() const noexcept
Indicates whether the column can contain null elements, i.e., if it has an allocated bitmask.
bool is_valid(size_type element_index) const noexcept
Returns whether the specified element holds a valid value (i.e., not null).
A mutable, non-owning view of device data as a column of elements that is trivially copyable and usab...
mutable_column_device_view_core(mutable_column_device_view_core const &)=default
Copy constructor.
mutable_column_device_view_core child(size_type child_index) const noexcept
Returns the specified child.
void assign(size_type element_index, T value) const noexcept
Assigns value to the element at element_index
CUDF_HOST_DEVICE T * data() const noexcept
Returns the underlying data casted to the specified type, plus the offset.
CUDF_HOST_DEVICE mutable_column_device_view_core(data_type type, size_type size, void const *data, bitmask_type const *null_mask, size_type offset, mutable_column_device_view_core *children, size_type num_children)
Creates an instance of this class using pre-existing device memory pointers to data,...
void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
Updates the specified bitmask word in the null_mask() with a new word.
T & element(size_type element_index) const noexcept
Returns reference to element at the specified index.
cuda::std::optional< T > nullable_element(size_type element_index) const noexcept
Returns a nullable element at the specified index. If the element is null, returns nullopt.
CUDF_HOST_DEVICE T * head() const noexcept
Returns pointer to the base device memory allocation casted to the specified type.
mutable_column_device_view_core & operator=(mutable_column_device_view_core const &)=default
Copy assignment operator.
mutable_column_device_view_core & operator=(mutable_column_device_view_core &&)=default
Move assignment operator.
T element(size_type element_index) const noexcept
Returns string_view to the string element at the specified index.
mutable_column_device_view_core(mutable_column_device_view_core &&)=default
Move constructor.
CUDF_HOST_DEVICE bitmask_type * null_mask() const noexcept
Returns raw pointer to the underlying bitmask allocation.
A non-owning, immutable view of device data that is a variable length char array representing a UTF-8...
Definition: string_view.hpp:33
Class definition for fixed point data type.
size_type null_count(bitmask_type const *bitmask, size_type start, size_type stop, rmm::cuda_stream_view stream=cudf::get_default_stream())
Given a validity bitmask, counts the number of null elements (unset bits) in the range [start,...
scale_type
The scale type for fixed_point.
Definition: fixed_point.hpp:33
std::unique_ptr< cudf::column > is_valid(cudf::column_view const &input, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Creates a column of type_id::BOOL8 elements where for every element in input true indicates the value...
std::unique_ptr< cudf::column > is_null(cudf::column_view const &input, rmm::cuda_stream_view stream=cudf::get_default_stream(), rmm::device_async_resource_ref mr=cudf::get_current_device_resource_ref())
Creates a column of type_id::BOOL8 elements where for every element in input true indicates the value...
constexpr CUDF_HOST_DEVICE size_type word_index(size_type bit_index)
Returns the index of the word containing the specified bit.
Definition: bit.hpp:48
CUDF_HOST_DEVICE bool bit_is_set(bitmask_type const *bitmask, size_type bit_index)
Indicates whether the specified bit is set to 1
Definition: bit.hpp:102
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:84
uint32_t bitmask_type
Bitmask type stored as 32-bit unsigned integer.
Definition: types.hpp:85
void void_t
Utility metafunction that maps a sequence of any types to the type void.
Definition: traits.hpp:26
#define CUDF_ENABLE_IF(...)
Convenience macro for SFINAE as an unnamed template parameter.
Definition: traits.hpp:39
cuDF interfaces
Definition: host_udf.hpp:26
bool nullable(table_view const &view)
Returns True if any of the columns in the table is nullable. (not entire hierarchy)
fixed_point and supporting types
Definition: fixed_point.hpp:23
nullate::DYNAMIC defers the determination of nullability to run time rather than compile time....
bool value
True if nulls are expected.
constexpr DYNAMIC(bool b) noexcept
Create a runtime nullate object.
Indicates the presence of nulls at compile-time or runtime.
Helper struct for constructing fixed_point when value is already shifted.
Type declarations for libcudf.
#define CUDF_HOST_DEVICE
Indicates that the function or method is usable on host and device.
Definition: types.hpp:21