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  bitmask_type const* _null_mask{};
274  size_type _offset{};
276 
287  size_type size,
288  void const* data,
289  bitmask_type const* null_mask,
290  size_type offset)
291  : _type{type}, _size{size}, _data{data}, _null_mask{null_mask}, _offset{offset}
292  {
293  }
294 
295  template <typename C, typename T, typename = void>
296  struct has_element_accessor_impl : cuda::std::false_type {};
297 
298  template <typename C, typename T>
299  struct has_element_accessor_impl<
300  C,
301  T,
302  void_t<decltype(cuda::std::declval<C>().template element<T>(cuda::std::declval<size_type>()))>>
303  : cuda::std::true_type {};
304 };
305 // @cond
306 // Forward declaration
307 template <typename T>
308 struct value_accessor;
309 template <typename T, typename Nullate>
310 struct optional_accessor;
311 template <typename T, bool has_nulls>
312 struct pair_accessor;
313 template <typename T, bool has_nulls>
314 struct pair_rep_accessor;
315 template <typename T>
316 struct mutable_value_accessor;
317 // @endcond
318 } // namespace detail
319 
327  public:
328  column_device_view_core() = delete;
329  ~column_device_view_core() = default;
344 
354  column_device_view_core(column_view column, void* h_ptr, void* d_ptr);
355 
373  size_type size) const noexcept
374  {
375  return column_device_view_core{this->type(),
376  size,
377  this->head(),
378  this->null_count(),
379  this->null_mask(),
380  this->offset() + offset,
381  d_children,
382  this->num_child_columns()};
383  }
384 
402  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
403  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
404  {
405  return data<T>()[element_index];
406  }
407 
419  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
420  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
421  {
422  size_type index = element_index + offset(); // account for this view's _offset
423  char const* d_strings = static_cast<char const*>(_data);
424  auto const offsets = child(offsets_column_index);
425  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
426  auto const offset = itr[index];
427  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
428  }
429 
430  public:
441  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
442  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
443  {
444  using namespace numeric;
445  using rep = typename T::rep;
446  auto const scale = scale_type{_type.scale()};
447  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
448  }
449 
456  [[nodiscard]] __device__ column_device_view_core child(size_type child_index) const noexcept
457  {
458  return d_children[child_index];
459  }
460 
466  [[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
467  {
468  return _num_children;
469  }
470 
476  [[nodiscard]] CUDF_HOST_DEVICE size_type null_count() const noexcept { return _null_count; }
477 
478  protected:
493  size_type size,
494  void const* data,
496  bitmask_type const* null_mask,
497  size_type offset,
498  column_device_view_core* children,
499  size_type num_children)
500  : column_device_view_base(type, size, data, null_mask, offset),
501  d_children(children),
502  _num_children(num_children),
503  _null_count{null_count}
504  {
505  }
506 
507  protected:
508  column_device_view_core* d_children{};
512  size_type _num_children{};
513  size_type _null_count{};
514 };
515 
523  public:
525  ~mutable_column_device_view_core() = default;
527  default;
529  default;
542 
559  template <typename T = void,
560  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
561  CUDF_HOST_DEVICE T* head() const noexcept
562  {
563  return const_cast<T*>(detail::column_device_view_base::head<T>());
564  }
565 
578  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
579  CUDF_HOST_DEVICE T* data() const noexcept
580  {
581  return const_cast<T*>(detail::column_device_view_base::data<T>());
582  }
583 
598  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
599  [[nodiscard]] __device__ T& element(size_type element_index) const noexcept
600  {
601  return data<T>()[element_index];
602  }
603 
611  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
612  __device__ void assign(size_type element_index, T value) const noexcept
613  {
614  data<T>()[element_index] = value;
615  }
616 
625  template <typename T, CUDF_ENABLE_IF(is_fixed_point<T>())>
626  __device__ void assign(size_type element_index, T value) const noexcept
627  {
628  // consider asserting that the scale matches
629  using namespace numeric;
630  using rep = typename T::rep;
631  data<rep>()[element_index] = value.value();
632  }
633 
642  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
643  {
644  return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
645  }
646 
653  [[nodiscard]] __device__ mutable_column_device_view_core
654  child(size_type child_index) const noexcept
655  {
656  return d_children[child_index];
657  }
658 
659 #ifdef __CUDACC__ // because set_bit in bit.hpp is wrapped with __CUDACC__
674  __device__ void set_valid(size_type element_index) const noexcept
675  {
676  return set_bit(null_mask(), element_index);
677  }
678 
692  __device__ void set_null(size_type element_index) const noexcept
693  {
694  return clear_bit(null_mask(), element_index);
695  }
696 
697 #endif
698 
709  __device__ void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
710  {
711  null_mask()[word_index] = new_word;
712  }
713 
714  protected:
728  size_type size,
729  void const* data,
730  bitmask_type const* null_mask,
731  size_type offset,
733  size_type num_children)
734  : column_device_view_base(type, size, data, null_mask, offset),
735  d_children(children),
736  _num_children(num_children)
737  {
738  }
739 
744  size_type _num_children{};
745 };
746 
747 } // 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,...
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.
CUDF_HOST_DEVICE column_device_view_base(data_type type, size_type size, void const *data, bitmask_type const *null_mask, size_type offset)
Constructs a column with the specified type, size, data, nullmask and offset.
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.
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.
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.
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...
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