column_view.hpp
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 
7 #include <cudf/types.hpp>
10 #include <cudf/utilities/span.hpp>
13 
14 #include <cuda/std/span>
15 
16 #include <limits>
17 #include <type_traits>
18 #include <vector>
19 
24 namespace CUDF_EXPORT cudf {
25 namespace detail {
45  public:
62  template <typename T = void,
63  CUDF_ENABLE_IF(std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
64  T const* head() const noexcept
65  {
66  return static_cast<T const*>(get_data());
67  }
68 
81  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
82  T const* data() const noexcept
83  {
84  return head<T>() + _offset;
85  }
86 
97  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
98  T const* begin() const noexcept
99  {
100  return data<T>();
101  }
102 
113  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
114  T const* end() const noexcept
115  {
116  return begin<T>() + size();
117  }
118 
124  [[nodiscard]] size_type size() const noexcept { return _size; }
125 
131  [[nodiscard]] bool is_empty() const noexcept { return size() == 0; }
132 
138  [[nodiscard]] data_type type() const noexcept { return _type; }
139 
149  [[nodiscard]] bool nullable() const noexcept { return nullptr != _null_mask; }
150 
156  [[nodiscard]] size_type null_count() const { return _null_count; }
157 
173  [[nodiscard]] size_type null_count(size_type begin,
174  size_type end,
175  cuda::stream_ref stream = cudf::get_default_stream()) const;
176 
184  [[nodiscard]] bool has_nulls() const { return null_count() > 0; }
185 
199  [[nodiscard]] bool has_nulls(size_type begin,
200  size_type end,
201  cuda::stream_ref stream = cudf::get_default_stream()) const
202  {
203  return null_count(begin, end, stream) > 0;
204  }
205 
214  [[nodiscard]] bitmask_type const* null_mask() const noexcept { return _null_mask; }
215 
222  [[nodiscard]] size_type offset() const noexcept { return _offset; }
223 
224  protected:
234  [[nodiscard]] virtual void const* get_data() const noexcept { return _data; }
235 
236  data_type _type{type_id::EMPTY};
237  size_type _size{};
238  void const* _data{};
239  bitmask_type const* _null_mask{};
242  mutable size_type _null_count{};
243  size_type _offset{};
245 
246  column_view_base() = default;
247  virtual ~column_view_base() = default;
248  column_view_base(column_view_base const&) = default;
262 
288  size_type size,
289  void const* data,
290  bitmask_type const* null_mask,
292  size_type offset = 0);
293 };
294 
295 } // namespace detail
296 
318  public:
319  column_view() = default;
320 
321  // these pragmas work around the nvcc issue where if a column_view is used
322  // inside of a __device__ code path, these functions will end up being created
323  // as __host__ __device__ because they are explicitly defaulted. However, if
324  // they then end up being called by a simple __host__ function
325  // (eg std::vector destructor) you get a compile error because you're trying to
326  // call a __host__ __device__ function from a __host__ function.
327 #ifdef __CUDACC__
328 #pragma nv_exec_check_disable
329 #endif
330  ~column_view() override = default;
331 #ifdef __CUDACC__
332 #pragma nv_exec_check_disable
333 #endif
334  column_view(column_view const&) = default;
335  column_view(column_view&&) = default;
341  column_view& operator=(column_view const&) = default;
348 
376  size_type size,
377  void const* data,
378  bitmask_type const* null_mask,
380  size_type offset = 0,
381  std::vector<column_view> const& children = {});
382 
389  [[nodiscard]] column_view child(size_type child_index) const noexcept
390  {
391  return _children[child_index];
392  }
393 
399  [[nodiscard]] size_type num_children() const noexcept { return _children.size(); }
400 
406  auto child_begin() const noexcept { return _children.cbegin(); }
407 
413  auto child_end() const noexcept { return _children.cend(); }
414 
423  template <typename T, CUDF_ENABLE_IF(cudf::is_numeric<T>() or cudf::is_chrono<T>())>
424  column_view(device_span<T const> data)
425  : column_view(
426  cudf::data_type{cudf::type_to_id<T>()}, data.size(), data.data(), nullptr, 0, 0, {})
427  {
428  CUDF_EXPECTS(
429  data.size() <= static_cast<std::size_t>(std::numeric_limits<cudf::size_type>::max()),
430  "Data exceeds the column size limit",
431  std::overflow_error);
432  }
433 
445  template <typename T, CUDF_ENABLE_IF(cudf::is_numeric<T>() or cudf::is_chrono<T>())>
446  [[nodiscard]] operator device_span<T const>() const
447  {
448  CUDF_EXPECTS(type() == cudf::data_type{cudf::type_to_id<T>()},
449  "Device span type must match column view type.");
450  CUDF_EXPECTS(!nullable(), "A nullable column view cannot be converted to a device span.");
451  return device_span<T const>(data<T>(), size());
452  }
453 
454  protected:
464  void const* get_data() const noexcept override;
465 
466  private:
467  friend column_view bit_cast(column_view const& input, data_type type);
468 
469  std::vector<column_view> _children{};
471 };
472 
494  public:
495  mutable_column_view() = default;
496 
497  ~mutable_column_view() override {
498  // Needed so that the first instance of the implicit destructor for any TU isn't 'constructed'
499  // from a host+device function marking the implicit version also as host+device
500  };
501 
516 
543  size_type size,
544  void* data,
545  bitmask_type* null_mask,
547  size_type offset = 0,
548  std::vector<mutable_column_view> const& children = {});
549 
565  template <typename T = void,
566  CUDF_ENABLE_IF(std::is_same_v<T, void> or is_rep_layout_compatible<T>())>
567  T* head() const noexcept
568  {
569  return const_cast<T*>(detail::column_view_base::head<T>());
570  }
571 
584  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
585  T* data() const noexcept
586  {
587  return const_cast<T*>(detail::column_view_base::data<T>());
588  }
589 
600  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
601  T* begin() const noexcept
602  {
603  return const_cast<T*>(detail::column_view_base::begin<T>());
604  }
605 
616  template <typename T, CUDF_ENABLE_IF(is_rep_layout_compatible<T>())>
617  T* end() const noexcept
618  {
619  return const_cast<T*>(detail::column_view_base::end<T>());
620  }
621 
631  [[nodiscard]] bitmask_type* null_mask() const noexcept
632  {
633  return const_cast<bitmask_type*>(detail::column_view_base::null_mask());
634  }
635 
643  void set_null_count(size_type new_null_count);
644 
651  [[nodiscard]] mutable_column_view child(size_type child_index) const noexcept
652  {
653  return mutable_children[child_index];
654  }
655 
661  [[nodiscard]] size_type num_children() const noexcept { return mutable_children.size(); }
662 
668  auto child_begin() const noexcept { return mutable_children.begin(); }
669 
675  auto child_end() const noexcept { return mutable_children.end(); }
676 
682  operator column_view() const;
683 
684  protected:
694  [[nodiscard]] void const* get_data() const noexcept override;
695 
696  private:
698 
699  std::vector<mutable_column_view> mutable_children;
700 };
701 
709 
734 
759 
760 namespace detail {
776 std::size_t shallow_hash(column_view const& input);
777 
799 bool is_shallow_equivalent(column_view const& lhs, column_view const& rhs);
800 
801 } // namespace detail
802 } // namespace CUDF_EXPORT cudf
A non-owning, immutable view of device data as a column of elements, some of which may be null as ind...
column_view(column_view &&)=default
Move constructor.
size_type num_children() const noexcept
Returns the number of child columns.
auto child_begin() const noexcept
Returns iterator to the beginning of the ordered sequence of child column-views.
column_view & operator=(column_view &&)=default
Move assignment operator.
column_view & operator=(column_view const &)=default
Copy assignment operator.
void const * get_data() const noexcept override
Returns pointer to the base device memory allocation.
auto child_end() const noexcept
Returns iterator to the end of the ordered sequence of child column-views.
column_view child(size_type child_index) const noexcept
Returns the specified child.
column_view(data_type type, size_type size, void const *data, bitmask_type const *null_mask, size_type null_count, size_type offset=0, std::vector< column_view > const &children={})
Construct a column_view from pointers to device memory for the elements and bitmask of the column.
column_view(column_view const &)=default
Copy constructor.
Indicator for the logical data type of an element in a column.
Definition: types.hpp:279
A non-owning, immutable view of device data as a column of elements, some of which may be null as ind...
Definition: column_view.hpp:44
T const * end() const noexcept
Return one past the last element after underlying data is casted to the specified type.
data_type type() const noexcept
Returns the element data_type
column_view_base(column_view_base &&)=default
Move constructor.
column_view_base(data_type type, size_type size, void const *data, bitmask_type const *null_mask, size_type null_count, size_type offset=0)
Construct a column_view_base from pointers to device memory for the elements and bitmask of the colum...
size_type null_count() const
Returns the count of null elements.
column_view_base & operator=(column_view_base const &)=default
Copy assignment operator.
column_view_base & operator=(column_view_base &&)=default
Move assignment operator.
size_type size() const noexcept
Returns the number of elements in the column.
bool has_nulls(size_type begin, size_type end, cuda::stream_ref stream=cudf::get_default_stream()) const
Indicates if the column contains null elements in the range [begin, end), i.e., null_count(begin,...
T const * begin() const noexcept
Return first element (accounting for offset) after underlying data is casted to the specified type.
Definition: column_view.hpp:98
T const * data() const noexcept
Returns the underlying data casted to the specified type, plus the offset.
Definition: column_view.hpp:82
size_type offset() const noexcept
Returns the index of the first element relative to the base memory allocation, i.e....
size_type null_count(size_type begin, size_type end, cuda::stream_ref stream=cudf::get_default_stream()) const
Returns the count of null elements in the range [begin, end)
virtual void const * get_data() const noexcept
Returns pointer to the base device memory allocation.
T const * head() const noexcept
Returns pointer to the base device memory allocation casted to the specified type.
Definition: column_view.hpp:64
bool has_nulls() const
Indicates if the column contains null elements, i.e., null_count() > 0
bitmask_type const * null_mask() const noexcept
Returns raw pointer to the underlying bitmask allocation.
bool nullable() const noexcept
Indicates if the column can contain null elements, i.e., if it has an allocated bitmask.
column_view_base(column_view_base const &)=default
Copy constructor.
bool is_empty() const noexcept
Returns true if size() returns zero, or false otherwise.
A non-owning, mutable view of device data as a column of elements, some of which may be null as indic...
T * head() const noexcept
Returns pointer to the base device memory allocation casted to the specified type.
size_type num_children() const noexcept
Returns the number of child columns.
T * begin() const noexcept
Return first element (accounting for offset) after underlying data is casted to the specified type.
void set_null_count(size_type new_null_count)
Set the null count.
auto child_begin() const noexcept
Returns iterator to the beginning of the ordered sequence of child column-views.
mutable_column_view(data_type type, size_type size, void *data, bitmask_type *null_mask, size_type null_count, size_type offset=0, std::vector< mutable_column_view > const &children={})
Construct a mutable_column_view from pointers to device memory for the elements and bitmask of the co...
T * data() const noexcept
Returns the underlying data casted to the specified type, plus the offset.
mutable_column_view(mutable_column_view const &)=default
Copy constructor.
mutable_column_view & operator=(mutable_column_view &&)=default
Move assignment operator.
mutable_column_view & operator=(mutable_column_view const &)=default
Copy assignment operator.
auto child_end() const noexcept
Returns iterator to the end of the ordered sequence of child column-views.
bitmask_type * null_mask() const noexcept
Returns raw pointer to the underlying bitmask allocation.
void const * get_data() const noexcept override
Returns pointer to the base device memory allocation.
mutable_column_view child(size_type child_index) const noexcept
Returns a reference to the specified child.
mutable_column_view(mutable_column_view &&)=default
Move constructor.
T * end() const noexcept
Return one past the last element after underlying data is casted to the specified type.
std::size_t shallow_hash(column_view const &input)
Computes a hash value from the shallow state of the specified column.
bool is_shallow_equivalent(column_view const &lhs, column_view const &rhs)
Uses only shallow state to determine if two column_views view equivalent columns.
APIs for querying the default CUDA stream and per-thread default stream status.
Exception types and error-checking macros used throughout libcudf.
size_type null_count(bitmask_type const *bitmask, size_type start, size_type stop, cuda::stream_ref stream=cudf::get_default_stream())
Given a validity bitmask, counts the number of null elements (unset bits) in the range [start,...
cuda::stream_ref const get_default_stream()
Get the current default stream.
#define CUDF_EXPECTS(...)
Macro for checking (pre-)conditions that throws an exception when a condition is violated.
Definition: error.hpp:182
cuda::std::span< T, Extent > device_span
Device span is an alias of cuda::std::span.
Definition: span.hpp:300
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:76
uint32_t bitmask_type
Bitmask type stored as 32-bit unsigned integer.
Definition: types.hpp:77
mutable_column_view bit_cast(mutable_column_view const &input, data_type type)
Zero-copy cast between types with the same size and compatible underlying representations.
constexpr CUDF_HOST_DEVICE bool is_chrono()
Indicates whether the type T is a chrono type.
Definition: traits.hpp:494
#define CUDF_ENABLE_IF(...)
Convenience macro for SFINAE as an unnamed template parameter.
Definition: traits.hpp:43
cuDF interfaces
Definition: host_udf.hpp:27
bool nullable(table_view const &view)
Returns True if any of the columns in the table is nullable. (not entire hierarchy)
size_type count_descendants(column_view parent)
Counts the number of descendants of the specified parent.
APIs for spans.
Type traits for classifying and querying properties of cudf column and scalar types.
Defines the mapping between cudf::type_id runtime type information and concrete C++ types.
Type declarations for libcudf.