column_device_view_base.cuh
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
8 #include <cudf/detail/offsets_iterator.cuh>
10 #include <cudf/strings/string_view.cuh>
11 #include <cudf/types.hpp>
12 #include <cudf/utilities/bit.hpp>
14 
15 #include <cuda/std/algorithm>
16 #include <cuda/std/optional>
17 #include <cuda/std/type_traits>
18 
24 namespace CUDF_EXPORT cudf {
25 
35 struct nullate {
36  struct YES : cuda::std::true_type {};
37  struct NO : cuda::std::false_type {};
43  struct DYNAMIC {
44  DYNAMIC() = delete;
53  constexpr explicit DYNAMIC(bool b) noexcept : value{b} {}
60  CUDF_HOST_DEVICE constexpr operator bool() const noexcept { return value; }
61  bool value;
62  };
63 };
64 
71 template <typename IndexType, typename KeyType>
72  requires(is_index_type<IndexType>() && is_relationally_comparable<KeyType, KeyType>())
73 struct dictionary_element {
74  using index_type = IndexType;
75  using key_type = KeyType;
76 
77  key_type key{};
78 };
79 
84 template <typename T>
85 inline constexpr bool is_dictionary_encoded = false;
86 
92 template <typename IndexType, typename KeyType>
93 inline constexpr bool is_dictionary_encoded<dictionary_element<IndexType, KeyType>> = true;
94 
95 namespace detail {
100 class alignas(16) column_device_view_base {
101  public:
102  static constexpr size_type offsets_column_index =
103  cudf::offsets_column_index;
104 
105  column_device_view_base() = delete;
106  ~column_device_view_base() = default;
121 
138  template <typename T = void,
139  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
140  [[nodiscard]] CUDF_HOST_DEVICE T const* head() const noexcept
141  {
142  return static_cast<T const*>(_data);
143  }
144 
160  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
161  [[nodiscard]] CUDF_HOST_DEVICE T const* data() const noexcept
162  {
163  return head<T>() + _offset;
164  }
165 
171  [[nodiscard]] CUDF_HOST_DEVICE size_type size() const noexcept { return _size; }
172 
178  [[nodiscard]] CUDF_HOST_DEVICE data_type type() const noexcept { return _type; }
179 
189  [[nodiscard]] CUDF_HOST_DEVICE bool nullable() const noexcept { return nullptr != _null_mask; }
190 
200  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type const* null_mask() const noexcept
201  {
202  return _null_mask;
203  }
204 
211  [[nodiscard]] CUDF_HOST_DEVICE size_type offset() const noexcept { return _offset; }
212 
227  [[nodiscard]] __device__ bool is_valid(size_type element_index) const noexcept
228  {
229  return not nullable() or is_valid_nocheck(element_index);
230  }
231 
244  [[nodiscard]] __device__ bool is_valid_nocheck(size_type element_index) const noexcept
245  {
246  return bit_is_set(_null_mask, offset() + element_index);
247  }
248 
262  [[nodiscard]] __device__ bool is_null(size_type element_index) const noexcept
263  {
264  return not is_valid(element_index);
265  }
266 
278  [[nodiscard]] __device__ bool is_null_nocheck(size_type element_index) const noexcept
279  {
280  return not is_valid_nocheck(element_index);
281  }
282 
292  [[nodiscard]] __device__ bitmask_type get_mask_word(size_type word_index) const noexcept
293  {
294  return null_mask()[word_index];
295  }
296 
297  protected:
298  data_type _type{type_id::EMPTY};
299  cudf::size_type _size{};
300  void const* _data{};
301  size_type _null_count{};
302  bitmask_type const* _null_mask{};
304  size_type _offset{};
306  void* _children{};
307  size_type _num_children{};
308 
322  size_type size,
323  void const* data,
325  bitmask_type const* null_mask,
326  size_type offset,
327  void* children,
328  size_type num_children)
329  : _type{type},
330  _size{size},
331  _data{data},
332  _null_count{null_count},
333  _null_mask{null_mask},
334  _offset{offset},
335  _children{children},
336  _num_children{num_children}
337  {
338  }
339 
340  template <typename C, typename T, typename = void>
341  struct has_element_accessor_impl : cuda::std::false_type {};
342 
343  template <typename C, typename T>
344  struct has_element_accessor_impl<
345  C,
346  T,
347  void_t<decltype(cuda::std::declval<C>().template element<T>(cuda::std::declval<size_type>()))>>
348  : cuda::std::true_type {};
349 };
350 // @cond
351 // Forward declaration
352 template <typename T>
353 struct value_accessor;
354 template <typename T, typename Nullate>
355 struct optional_accessor;
356 template <typename T, bool has_nulls>
357 struct pair_accessor;
358 template <typename T, bool has_nulls>
359 struct pair_rep_accessor;
360 template <typename T>
361 struct mutable_value_accessor;
362 // @endcond
363 } // namespace detail
364 
372  public:
373  static constexpr bool is_mutable =
374  false;
375 
376  column_device_view_core() = delete;
377  ~column_device_view_core() = default;
392 
402  column_device_view_core(column_view column, void* h_ptr, void* d_ptr);
403 
421  size_type size) const noexcept
422  {
423  return column_device_view_core{this->type(),
424  size,
425  this->head(),
426  this->null_count(),
427  this->null_mask(),
428  this->offset() + offset,
429  static_cast<column_device_view_core*>(_children),
430  this->num_child_columns()};
431  }
432 
450  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
451  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
452  {
453  return data<T>()[element_index];
454  }
455 
467  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
468  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
469  {
470  size_type index = element_index + offset(); // account for this view's _offset
471  char const* d_strings = static_cast<char const*>(_data);
472  auto const offsets = child(offsets_column_index);
473  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
474  auto const offset = itr[index];
475  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
476  }
477 
478  public:
489  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
490  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
491  {
492  using namespace numeric;
493  using rep = typename T::rep;
494  auto const scale = scale_type{_type.scale()};
495  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
496  }
497 
515  template <typename T, CUDF_ENABLE_IF(is_dictionary_encoded<T>)>
516  [[nodiscard]] __device__ decltype(auto) element(size_type element_index) const noexcept
517  {
518  auto const& indices = child(dictionary_indices_column_index);
519  auto const& keys = child(dictionary_keys_column_index);
520  auto const index = indices.template element<typename T::index_type>(
521  element_index + offset()); // account for this view's _offset
522  return keys.template element<typename T::key_type>(index);
523  }
524 
533  template <typename T>
534  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
535  size_type element_index) const noexcept
536  {
537  if (is_null(element_index)) { return cuda::std::nullopt; }
538  return element<T>(element_index);
539  }
540 
547  [[nodiscard]] __device__ column_device_view_core child(size_type child_index) const noexcept
548  {
549  return static_cast<column_device_view_core*>(_children)[child_index];
550  }
551 
557  [[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
558  {
559  return _num_children;
560  }
561 
567  [[nodiscard]] CUDF_HOST_DEVICE size_type null_count() const noexcept { return _null_count; }
568 
569  protected:
584  size_type size,
585  void const* data,
587  bitmask_type const* null_mask,
588  size_type offset,
589  column_device_view_core* children,
590  size_type num_children)
591  : column_device_view_base(
592  type, size, data, null_count, null_mask, offset, children, num_children)
593  {
594  }
595 };
596 
605  public:
606  static constexpr bool is_mutable =
607  true;
608 
610  ~mutable_column_device_view_core() = default;
612  default;
614  default;
627 
644  template <typename T = void,
645  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
646  [[nodiscard]] CUDF_HOST_DEVICE T* head() const noexcept
647  {
648  return const_cast<T*>(detail::column_device_view_base::head<T>());
649  }
650 
663  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
664  [[nodiscard]] CUDF_HOST_DEVICE T* data() const noexcept
665  {
666  return const_cast<T*>(detail::column_device_view_base::data<T>());
667  }
668 
683  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
684  [[nodiscard]] __device__ T& element(size_type element_index) const noexcept
685  {
686  return data<T>()[element_index];
687  }
688 
700  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
701  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
702  {
703  size_type index = element_index + offset(); // account for this view's _offset
704  char const* d_strings = static_cast<char const*>(_data);
705  auto const offsets = child(offsets_column_index);
706  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
707  auto const offset = itr[index];
708  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
709  }
710 
721  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
722  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
723  {
724  using namespace numeric;
725  using rep = typename T::rep;
726  auto const scale = scale_type{_type.scale()};
727  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
728  }
729 
738  template <typename T>
739  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
740  size_type element_index) const noexcept
741  {
742  if (is_null(element_index)) { return cuda::std::nullopt; }
743  return element<T>(element_index);
744  }
745 
753  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
754  __device__ void assign(size_type element_index, T value) const noexcept
755  {
756  data<T>()[element_index] = value;
757  }
758 
767  template <typename T, CUDF_ENABLE_IF(is_fixed_point<T>())>
768  __device__ void assign(size_type element_index, T value) const noexcept
769  {
770  // consider asserting that the scale matches
771  using namespace numeric;
772  using rep = typename T::rep;
773  data<rep>()[element_index] = value.value();
774  }
775 
784  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
785  {
786  return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
787  }
788 
795  [[nodiscard]] __device__ mutable_column_device_view_core
796  child(size_type child_index) const noexcept
797  {
798  return static_cast<mutable_column_device_view_core*>(_children)[child_index];
799  }
800 
801 #ifdef __CUDACC__ // because set_bit in bit.hpp is wrapped with __CUDACC__
816  __device__ void set_valid(size_type element_index) const noexcept
817  {
818  return set_bit(null_mask(), element_index);
819  }
820 
834  __device__ void set_null(size_type element_index) const noexcept
835  {
836  return clear_bit(null_mask(), element_index);
837  }
838 
839 #endif
840 
851  __device__ void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
852  {
853  null_mask()[word_index] = new_word;
854  }
855 
856  protected:
870  size_type size,
871  void const* data,
872  bitmask_type const* null_mask,
873  size_type offset,
875  size_type num_children)
876  : column_device_view_base(type,
877  size,
878  data,
879  0, // unused
880  null_mask,
881  offset,
882  children,
883  num_children)
884  {
885  }
886 };
887 
888 } // 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:286
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:35
Constants for child column indices within compound column types.
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:38
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:47
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:101
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:30
#define CUDF_ENABLE_IF(...)
Convenience macro for SFINAE as an unnamed template parameter.
Definition: traits.hpp:43
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)
constexpr bool is_dictionary_encoded
A type trait to determine if a type is a dictionary encoded type.
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.
fixed_point and supporting types
Definition: fixed_point.hpp:30
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 traits for classifying and querying properties of cudf column and scalar 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