column_device_view_base.cuh
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2025, 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 {
78 class alignas(16) column_device_view_base {
79  public:
80  // TODO: merge this offsets column index with `strings_column_view::offsets_column_index`
81  static constexpr size_type offsets_column_index{0};
82 
83  column_device_view_base() = delete;
84  ~column_device_view_base() = default;
99 
116  template <typename T = void,
117  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
118  [[nodiscard]] CUDF_HOST_DEVICE T const* head() const noexcept
119  {
120  return static_cast<T const*>(_data);
121  }
122 
138  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
139  [[nodiscard]] CUDF_HOST_DEVICE T const* data() const noexcept
140  {
141  return head<T>() + _offset;
142  }
143 
149  [[nodiscard]] CUDF_HOST_DEVICE size_type size() const noexcept { return _size; }
150 
156  [[nodiscard]] CUDF_HOST_DEVICE data_type type() const noexcept { return _type; }
157 
167  [[nodiscard]] CUDF_HOST_DEVICE bool nullable() const noexcept { return nullptr != _null_mask; }
168 
178  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type const* null_mask() const noexcept
179  {
180  return _null_mask;
181  }
182 
189  [[nodiscard]] CUDF_HOST_DEVICE size_type offset() const noexcept { return _offset; }
190 
205  [[nodiscard]] __device__ bool is_valid(size_type element_index) const noexcept
206  {
207  return not nullable() or is_valid_nocheck(element_index);
208  }
209 
222  [[nodiscard]] __device__ bool is_valid_nocheck(size_type element_index) const noexcept
223  {
224  return bit_is_set(_null_mask, offset() + element_index);
225  }
226 
240  [[nodiscard]] __device__ bool is_null(size_type element_index) const noexcept
241  {
242  return not is_valid(element_index);
243  }
244 
256  [[nodiscard]] __device__ bool is_null_nocheck(size_type element_index) const noexcept
257  {
258  return not is_valid_nocheck(element_index);
259  }
260 
270  [[nodiscard]] __device__ bitmask_type get_mask_word(size_type word_index) const noexcept
271  {
272  return null_mask()[word_index];
273  }
274 
275  protected:
276  data_type _type{type_id::EMPTY};
277  cudf::size_type _size{};
278  void const* _data{};
279  bitmask_type const* _null_mask{};
281  size_type _offset{};
283 
294  size_type size,
295  void const* data,
296  bitmask_type const* null_mask,
297  size_type offset)
298  : _type{type}, _size{size}, _data{data}, _null_mask{null_mask}, _offset{offset}
299  {
300  }
301 
302  template <typename C, typename T, typename = void>
303  struct has_element_accessor_impl : cuda::std::false_type {};
304 
305  template <typename C, typename T>
306  struct has_element_accessor_impl<
307  C,
308  T,
309  void_t<decltype(cuda::std::declval<C>().template element<T>(cuda::std::declval<size_type>()))>>
310  : cuda::std::true_type {};
311 };
312 // @cond
313 // Forward declaration
314 template <typename T>
315 struct value_accessor;
316 template <typename T, typename Nullate>
317 struct optional_accessor;
318 template <typename T, bool has_nulls>
319 struct pair_accessor;
320 template <typename T, bool has_nulls>
321 struct pair_rep_accessor;
322 template <typename T>
323 struct mutable_value_accessor;
324 // @endcond
325 } // namespace detail
326 
334  public:
335  column_device_view_core() = delete;
336  ~column_device_view_core() = default;
351 
361  column_device_view_core(column_view column, void* h_ptr, void* d_ptr);
362 
380  size_type size) const noexcept
381  {
382  return column_device_view_core{this->type(),
383  size,
384  this->head(),
385  this->null_mask(),
386  this->offset() + offset,
387  d_children,
388  this->num_child_columns()};
389  }
390 
408  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
409  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
410  {
411  return data<T>()[element_index];
412  }
413 
425  template <typename T, CUDF_ENABLE_IF(cuda::std::is_same_v<T, string_view>)>
426  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
427  {
428  size_type index = element_index + offset(); // account for this view's _offset
429  char const* d_strings = static_cast<char const*>(_data);
430  auto const offsets = child(offsets_column_index);
431  auto const itr = cudf::detail::input_offsetalator(offsets.head(), offsets.type());
432  auto const offset = itr[index];
433  return string_view{d_strings + offset, static_cast<cudf::size_type>(itr[index + 1] - offset)};
434  }
435 
436  public:
447  template <typename T, CUDF_ENABLE_IF(cudf::is_fixed_point<T>())>
448  [[nodiscard]] __device__ T element(size_type element_index) const noexcept
449  {
450  using namespace numeric;
451  using rep = typename T::rep;
452  auto const scale = scale_type{_type.scale()};
453  return T{scaled_integer<rep>{data<rep>()[element_index], scale}};
454  }
455 
462  [[nodiscard]] __device__ column_device_view_core child(size_type child_index) const noexcept
463  {
464  return d_children[child_index];
465  }
466 
472  [[nodiscard]] CUDF_HOST_DEVICE size_type num_child_columns() const noexcept
473  {
474  return _num_children;
475  }
476 
477  protected:
491  size_type size,
492  void const* data,
493  bitmask_type const* null_mask,
494  size_type offset,
495  column_device_view_core* children,
496  size_type num_children)
497  : column_device_view_base(type, size, data, null_mask, offset),
498  d_children(children),
499  _num_children(num_children)
500  {
501  }
502 
503  protected:
504  column_device_view_core* d_children{};
508  size_type _num_children{};
509 };
510 
518  public:
520  ~mutable_column_device_view_core() = default;
522  default;
524  default;
537 
554  template <typename T = void,
555  CUDF_ENABLE_IF(cuda::std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
556  CUDF_HOST_DEVICE T* head() const noexcept
557  {
558  return const_cast<T*>(detail::column_device_view_base::head<T>());
559  }
560 
573  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
574  CUDF_HOST_DEVICE T* data() const noexcept
575  {
576  return const_cast<T*>(detail::column_device_view_base::data<T>());
577  }
578 
593  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
594  [[nodiscard]] __device__ T& element(size_type element_index) const noexcept
595  {
596  return data<T>()[element_index];
597  }
598 
606  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
607  __device__ void assign(size_type element_index, T value) const noexcept
608  {
609  data<T>()[element_index] = value;
610  }
611 
620  template <typename T, CUDF_ENABLE_IF(is_fixed_point<T>())>
621  __device__ void assign(size_type element_index, T value) const noexcept
622  {
623  // consider asserting that the scale matches
624  using namespace numeric;
625  using rep = typename T::rep;
626  data<rep>()[element_index] = value.value();
627  }
628 
637  [[nodiscard]] CUDF_HOST_DEVICE bitmask_type* null_mask() const noexcept
638  {
639  return const_cast<bitmask_type*>(detail::column_device_view_base::null_mask());
640  }
641 
648  [[nodiscard]] __device__ mutable_column_device_view_core
649  child(size_type child_index) const noexcept
650  {
651  return d_children[child_index];
652  }
653 
654 #ifdef __CUDACC__ // because set_bit in bit.hpp is wrapped with __CUDACC__
669  __device__ void set_valid(size_type element_index) const noexcept
670  {
671  return set_bit(null_mask(), element_index);
672  }
673 
687  __device__ void set_null(size_type element_index) const noexcept
688  {
689  return clear_bit(null_mask(), element_index);
690  }
691 
692 #endif
693 
704  __device__ void set_mask_word(size_type word_index, bitmask_type new_word) const noexcept
705  {
706  null_mask()[word_index] = new_word;
707  }
708 
709  protected:
723  size_type size,
724  void const* data,
725  bitmask_type const* null_mask,
726  size_type offset,
728  size_type num_children)
729  : column_device_view_base(type, size, data, null_mask, offset),
730  d_children(children),
731  _num_children(num_children)
732  {
733  }
734 
739  size_type _num_children{};
740 };
741 
742 } // 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 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.
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.
CUDF_HOST_DEVICE column_device_view_core(data_type type, size_type size, void const *data, 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,...
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:238
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.
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