table_device_view.cuh
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2024, NVIDIA CORPORATION.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #pragma once
6 
8 #include <cudf/detail/utilities/cuda_memcpy.hpp>
9 #include <cudf/detail/utilities/vector_factories.hpp>
11 #include <cudf/types.hpp>
13 
14 #include <rmm/cuda_stream_view.hpp>
15 #include <rmm/device_buffer.hpp>
16 
17 #include <cassert>
18 #include <memory>
19 #include <numeric>
20 
26 namespace CUDF_EXPORT cudf {
27 namespace detail {
28 
45 template <typename ColumnDeviceView, typename HostTableView>
47  public:
48  table_device_view_base() = delete;
49  ~table_device_view_base() = default;
64 
70  __device__ ColumnDeviceView* begin() const noexcept { return _columns; }
71 
80  __device__ ColumnDeviceView* end() const noexcept { return _columns + _num_columns; }
81 
88  __device__ ColumnDeviceView const& column(size_type column_index) const noexcept
89  {
90  assert(column_index >= 0);
91  assert(column_index < _num_columns);
92  return _columns[column_index];
93  }
94 
101  __device__ ColumnDeviceView& column(size_type column_index) noexcept
102  {
103  assert(column_index >= 0);
104  assert(column_index < _num_columns);
105  return _columns[column_index];
106  }
107 
113  [[nodiscard]] __host__ __device__ size_type num_columns() const noexcept { return _num_columns; }
114 
120  [[nodiscard]] __host__ __device__ size_type num_rows() const noexcept { return _num_rows; }
121 
128  void destroy();
129 
130  private:
131  ColumnDeviceView* _columns{};
132  size_type _num_rows{};
133  size_type _num_columns{};
134 
135  protected:
142  table_device_view_base(HostTableView source_view, rmm::cuda_stream_view stream);
143 
145  rmm::device_buffer* _descendant_storage{};
146 };
147 } // namespace detail
148 
152 class table_device_view : public detail::table_device_view_base<column_device_view, table_view> {
153  public:
168  static auto create(table_view source_view,
170  {
171  auto deleter = [](table_device_view* t) { t->destroy(); };
172  return std::unique_ptr<table_device_view, decltype(deleter)>{
173  new table_device_view(source_view, stream), deleter};
174  }
175 
176  private:
178  : detail::table_device_view_base<column_device_view, table_view>(source_view, stream)
179  {
180  }
181 };
182 
189  : public detail::table_device_view_base<mutable_column_device_view, mutable_table_view> {
190  public:
205  static auto create(mutable_table_view source_view,
207  {
208  auto deleter = [](mutable_table_device_view* t) { t->destroy(); };
209  return std::unique_ptr<mutable_table_device_view, decltype(deleter)>{
210  new mutable_table_device_view(source_view, stream), deleter};
211  }
212 
213  private:
215  : detail::table_device_view_base<mutable_column_device_view, mutable_table_view>(source_view,
216  stream)
217  {
218  }
219 };
220 
230 template <typename ColumnDeviceView, typename HostTableView>
231 auto contiguous_copy_column_device_views(HostTableView source_view, rmm::cuda_stream_view stream)
232 {
233  // First calculate the size of memory needed to hold the
234  // table's ColumnDeviceViews. This is done by calling extent()
235  // for each of the table's ColumnViews columns.
236  std::size_t views_size_bytes = std::accumulate(
237  source_view.begin(), source_view.end(), std::size_t{0}, [](std::size_t init, auto col) {
238  return init + ColumnDeviceView::extent(col);
239  });
240  // pad the allocation for aligning the first pointer
241  auto padded_views_size_bytes = views_size_bytes + std::size_t{alignof(ColumnDeviceView) - 1};
242  // A buffer of CPU memory is allocated to hold the ColumnDeviceView
243  // objects. Once filled, the CPU memory is then copied to device memory
244  // and the pointer is set in the d_columns member.
245  auto h_buffer = cudf::detail::make_host_vector<int8_t>(padded_views_size_bytes, stream);
246  // Each ColumnDeviceView instance may have child objects which may
247  // require setting some internal device pointers before being copied
248  // from CPU to device.
249  // Allocate the device memory to be used in the result.
250  // We need this pointer in order to pass it down when creating the
251  // ColumnDeviceViews so the column can set the pointer(s) for any
252  // of its child objects.
253  // align both h_ptr, d_ptr
254  auto descendant_storage = std::make_unique<rmm::device_buffer>(padded_views_size_bytes, stream);
255  void* h_ptr = detail::align_ptr_for_type<ColumnDeviceView>(h_buffer.data());
256  void* d_ptr = detail::align_ptr_for_type<ColumnDeviceView>(descendant_storage->data());
257  auto d_columns = detail::child_columns_to_device_array<ColumnDeviceView>(
258  source_view.begin(), source_view.end(), h_ptr, d_ptr);
259 
260  auto const h_span = host_span<int8_t const>{h_buffer}.subspan(
261  static_cast<int8_t const*>(h_ptr) - h_buffer.data(), views_size_bytes);
262  auto const d_span = device_span<int8_t>{static_cast<int8_t*>(d_ptr), views_size_bytes};
263  cudf::detail::cuda_memcpy(d_span, h_span, stream);
264  return std::make_tuple(std::move(descendant_storage), d_columns);
265 }
266 
267 } // namespace CUDF_EXPORT cudf
An immutable, non-owning view of device data as a column of elements that is trivially copyable and u...
Base class for a device table of ColumnDeviceViews.
size_type num_rows() const noexcept
Returns the number of rows.
ColumnDeviceView const & column(size_type column_index) const noexcept
Returns a reference to the view of the specified column.
table_device_view_base(table_device_view_base &&)=default
Move constructor.
ColumnDeviceView * begin() const noexcept
Returns an iterator to the first view in the table.
void destroy()
Destroy the table_device_view object.
table_device_view_base(table_device_view_base const &)=default
Copy constructor.
size_type num_columns() const noexcept
Returns the number of columns.
table_device_view_base & operator=(table_device_view_base const &)=default
Copy assignment operator.
ColumnDeviceView * end() const noexcept
Returns an iterator one past the last column view in the table.
table_device_view_base(HostTableView source_view, rmm::cuda_stream_view stream)
Construct a new table device view base object from host table_view.
table_device_view_base & operator=(table_device_view_base &&)=default
Move assignment operator.
ColumnDeviceView & column(size_type column_index) noexcept
Returns a reference to the view of the specified column.
A mutable, non-owning view of device data as a column of elements that is trivially copyable and usab...
Mutable table device view that is usable in device memory.
static auto create(mutable_table_view source_view, rmm::cuda_stream_view stream=cudf::get_default_stream())
Factory to construct a mutable table device view that is usable in device memory.
A set of mutable_column_views of the same size.
Definition: table_view.hpp:257
Table device view that is usable in device memory.
static auto create(table_view source_view, rmm::cuda_stream_view stream=cudf::get_default_stream())
Factory to construct a table device view that is usable in device memory.
A set of cudf::column_view's of the same size.
Definition: table_view.hpp:189
Column device view class definitions.
rmm::cuda_stream_view const get_default_stream()
Get the current default stream.
int32_t size_type
Row index type for columns and tables.
Definition: types.hpp:84
cuDF interfaces
Definition: host_udf.hpp:26
auto contiguous_copy_column_device_views(HostTableView source_view, rmm::cuda_stream_view stream)
Copies the contents of a table_view to a column device view in contiguous device memory.
Device version of C++20 std::span with reduced feature set.
Definition: span.hpp:323
C++20 std::span with reduced feature set.
Definition: span.hpp:182
constexpr CUDF_HOST_DEVICE host_span subspan(typename base::size_type offset, typename base::size_type count) const noexcept
Obtains a span that is a view over the count elements of this span starting at offset.
Definition: span.hpp:291
Class definitions for (mutable)_table_view
Type declarations for libcudf.