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/algorithm>
15 #include <cuda/std/optional>
16 #include <cuda/std/type_traits>
17 
23 namespace CUDF_EXPORT cudf {
24 
34 struct nullate {
35  struct YES : cuda::std::true_type {};
36  struct NO : cuda::std::false_type {};
42  struct DYNAMIC {
43  DYNAMIC() = delete;
52  constexpr explicit DYNAMIC(bool b) noexcept : value{b} {}
59  CUDF_HOST_DEVICE constexpr operator bool() const noexcept { return value; }
60  bool value;
61  };
62 };
63 
64 namespace detail {
69 class alignas(16) column_device_view_base {
70  public:
71  // TODO: merge this offsets column index with `strings_column_view::offsets_column_index`
72  static constexpr size_type offsets_column_index{0};
73 
74  column_device_view_base() = delete;
75  ~column_device_view_base() = default;
90 
107  template <typename T = void,
108  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
109  [[nodiscard]] CUDF_HOST_DEVICE T const* head() const noexcept
110  {
111  return static_cast<T const*>(_data);
112  }
113 
129  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
130  [[nodiscard]] CUDF_HOST_DEVICE T const* data() const noexcept
131  {
132  return head<T>() + _offset;
133  }
134 
140  [[nodiscard]] CUDF_HOST_DEVICE size_type size() const noexcept { return _size; }
141 
147  [[nodiscard]] CUDF_HOST_DEVICE data_type type() const noexcept { return _type; }
148 
158  [[nodiscard]] CUDF_HOST_DEVICE bool nullable() const noexcept { return nullptr != _null_mask; }
159 
169  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type const* null_mask() const noexcept
170  {
171  return _null_mask;
172  }
173 
180  [[nodiscard]] CUDF_HOST_DEVICE size_type offset() const noexcept { return _offset; }
181 
196  [[nodiscard]] __device__ bool is_valid(size_type element_index) const noexcept
197  {
198  return not nullable() or is_valid_nocheck(element_index);
199  }
200 
213  [[nodiscard]] __device__ bool is_valid_nocheck(size_type element_index) const noexcept
214  {
215  return bit_is_set(_null_mask, offset() + element_index);
216  }
217 
231  [[nodiscard]] __device__ bool is_null(size_type element_index) const noexcept
232  {
233  return not is_valid(element_index);
234  }
235 
247  [[nodiscard]] __device__ bool is_null_nocheck(size_type element_index) const noexcept
248  {
249  return not is_valid_nocheck(element_index);
250  }
251 
261  [[nodiscard]] __device__ bitmask_type get_mask_word(size_type word_index) const noexcept
262  {
263  return null_mask()[word_index];
264  }
265 
266  protected:
267  data_type _type{type_id::EMPTY};
268  cudf::size_type _size{};
269  void const* _data{};
270  size_type _null_count{};
271  bitmask_type const* _null_mask{};
273  size_type _offset{};
275  void* _children{};
276  size_type _num_children{};
277 
291  size_type size,
292  void const* data,
294  bitmask_type const* null_mask,
295  size_type offset,
296  void* children,
297  size_type num_children)
298  : _type{type},
299  _size{size},
300  _data{data},
301  _null_count{null_count},
302  _null_mask{null_mask},
303  _offset{offset},
304  _children{children},
305  _num_children{num_children}
306  {
307  }
308 
309  template <typename C, typename T, typename = void>
310  struct has_element_accessor_impl : cuda::std::false_type {};
311 
312  template <typename C, typename T>
313  struct has_element_accessor_impl<
314  C,
315  T,
316  void_t<decltype(cuda::std::declval<C>().template element<T>(cuda::std::declval<size_type>()))>>
317  : cuda::std::true_type {};
318 };
319 // @cond
320 // Forward declaration
321 template <typename T>
322 struct value_accessor;
323 template <typename T, typename Nullate>
324 struct optional_accessor;
325 template <typename T, bool has_nulls>
326 struct pair_accessor;
327 template <typename T, bool has_nulls>
328 struct pair_rep_accessor;
329 template <typename T>
330 struct mutable_value_accessor;
331 // @endcond
332 } // namespace detail
333 
341  public:
342  static constexpr bool is_mutable =
343  false;
344 
345  column_device_view_core() = delete;
346  ~column_device_view_core() = default;
361 
371  column_device_view_core(column_view column, void* h_ptr, void* d_ptr);
372 
390  size_type size) const noexcept
391  {
392  return column_device_view_core{this->type(),
393  size,
394  this->head(),
395  this->null_count(),
396  this->null_mask(),
397  this->offset() + offset,
398  static_cast<column_device_view_core*>(_children),
399  this->num_child_columns()};
400  }
401 
419  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
420  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
421  {
422  return data<T>()[element_index];
423  }
424 
436  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
437  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
438  {
439  size_type index = element_index + offset(); // account for this view's _offset
440  char const* d_strings = static_cast<char const*>(_data);
441  auto const offsets = child(offsets_column_index);
442  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
443  auto const offset = itr[index];
444  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
445  }
446 
447  public:
458  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
459  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
460  {
461  using namespace numeric;
462  using rep = typename T::rep;
463  auto const scale = scale_type{_type.scale()};
464  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
465  }
466 
475  template <typename T>
476  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
477  size_type element_index) const noexcept
478  {
479  if (is_null(element_index)) { return cuda::std::nullopt; }
480  return element<T>(element_index);
481  }
482 
489  [[nodiscard]] __device__ column_device_view_core child(size_type child_index) const noexcept
490  {
491  return static_cast<column_device_view_core*>(_children)[child_index];
492  }
493 
499  [[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
500  {
501  return _num_children;
502  }
503 
509  [[nodiscard]] CUDF_HOST_DEVICE size_type null_count() const noexcept { return _null_count; }
510 
511  protected:
526  size_type size,
527  void const* data,
529  bitmask_type const* null_mask,
530  size_type offset,
531  column_device_view_core* children,
532  size_type num_children)
533  : column_device_view_base(
534  type, size, data, null_count, null_mask, offset, children, num_children)
535  {
536  }
537 };
538 
546  public:
547  static constexpr bool is_mutable =
548  true;
549 
551  ~mutable_column_device_view_core() = default;
553  default;
555  default;
568 
585  template <typename T = void,
586  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
587  [[nodiscard]] CUDF_HOST_DEVICE T* head() const noexcept
588  {
589  return const_cast<T*>(detail::column_device_view_base::head<T>());
590  }
591 
604  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
605  [[nodiscard]] CUDF_HOST_DEVICE T* data() const noexcept
606  {
607  return const_cast<T*>(detail::column_device_view_base::data<T>());
608  }
609 
624  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
625  [[nodiscard]] __device__ T& element(size_type element_index) const noexcept
626  {
627  return data<T>()[element_index];
628  }
629 
641  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
642  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
643  {
644  size_type index = element_index + offset(); // account for this view's _offset
645  char const* d_strings = static_cast<char const*>(_data);
646  auto const offsets = child(offsets_column_index);
647  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
648  auto const offset = itr[index];
649  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
650  }
651 
662  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
663  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
664  {
665  using namespace numeric;
666  using rep = typename T::rep;
667  auto const scale = scale_type{_type.scale()};
668  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
669  }
670 
679  template <typename T>
680  [[nodiscard]] __device__ cuda::std::optional<T> nullable_element(
681  size_type element_index) const noexcept
682  {
683  if (is_null(element_index)) { return cuda::std::nullopt; }
684  return element<T>(element_index);
685  }
686 
694  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
695  __device__ void assign(size_type element_index, T value) const noexcept
696  {
697  data<T>()[element_index] = value;
698  }
699 
708  template <typename T, CUDF_ENABLE_IF(is_fixed_point<T>())>
709  __device__ void assign(size_type element_index, T value) const noexcept
710  {
711  // consider asserting that the scale matches
712  using namespace numeric;
713  using rep = typename T::rep;
714  data<rep>()[element_index] = value.value();
715  }
716 
725  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
726  {
727  return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
728  }
729 
736  [[nodiscard]] __device__ mutable_column_device_view_core
737  child(size_type child_index) const noexcept
738  {
739  return static_cast<mutable_column_device_view_core*>(_children)[child_index];
740  }
741 
742 #ifdef __CUDACC__ // because set_bit in bit.hpp is wrapped with __CUDACC__
757  __device__ void set_valid(size_type element_index) const noexcept
758  {
759  return set_bit(null_mask(), element_index);
760  }
761 
775  __device__ void set_null(size_type element_index) const noexcept
776  {
777  return clear_bit(null_mask(), element_index);
778  }
779 
780 #endif
781 
792  __device__ void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
793  {
794  null_mask()[word_index] = new_word;
795  }
796 
797  protected:
811  size_type size,
812  void const* data,
813  bitmask_type const* null_mask,
814  size_type offset,
816  size_type num_children)
817  : column_device_view_base(type,
818  size,
819  data,
820  0, // unused
821  null_mask,
822  offset,
823  children,
824  num_children)
825  {
826  }
827 };
828 
829 } // 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:278
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
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:35
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:85
uint32_t bitmask_type
Bitmask type stored as 32-bit unsigned integer.
Definition: types.hpp:86
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:25
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