复制分割#

group copy_split

函数

std::vector<packed_table> contiguous_split(cudf::table_view const &input, std::vector<size_type> const &splits, rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref())#

执行table_view的深拷贝分割,将其分割为packed_table的向量,其中每个packed_table使用单个连续的内存块来存储所有分割的列数据。

输出视图的内存分配在一个连续的rmm::device_buffer中,并在packed_table中返回。没有顶层的拥有表。

返回的input视图是从一个索引向量构建的,该向量指示每个分割应该发生的位置。第i个返回的table_view被切片为[0, splits[i])如果i=0,否则为[splits[i], input.size())如果i是最后一个视图,否则为[splits[i-1], splits[i]]

对于所有的 i,预期 splits[i] <= splits[i+1] <= input.size()。对于一个大小为 N 的 splits,输出中总是会有 N+1 个分割。

Example:
input:   [{10, 12, 14, 16, 18, 20, 22, 24, 26, 28},
          {50, 52, 54, 56, 58, 60, 62, 64, 66, 68}]
splits:  {2, 5, 9}
output:  [{{10, 12}, {14, 16, 18}, {20, 22, 24, 26}, {28}},
          {{50, 52}, {54, 56, 58}, {60, 62, 64, 66}, {68}}]

注意

调用者有责任确保返回的视图不会超过包含在返回的packed_tableall_data字段中的被查看设备内存。

Throws:
  • std::out_of_range – 如果 splits 的结束索引大于 input 的大小。

  • std::out_of_range – 当 splits 中的值不在范围 [0, input.size()) 内时。

  • std::invalid_argument – 当 splits 中的值“严格递减”时。

Parameters:
  • input – 要拆分的表的视图

  • splits – 一个索引向量,视图将在此处被分割

  • mr – 一个可选的内存资源,用于所有返回的设备分配

Returns:

splits指示的input请求视图集以及查看的内存缓冲区

packed_columns pack(cudf::table_view const &input, rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref())#

table_view深度复制到序列化的连续内存格式中。

来自table_view的元数据被复制到一个主机字节向量中,而来自table_view的数据被复制到一个device_buffer中。将此函数的输出传递给cudf::unpack以进行反序列化。

Parameters:
  • input – 要打包的表的视图

  • mr – 一个可选的内存资源,用于所有返回的设备分配

Returns:

packed_columns 一个结构体,包含分别在连续的主机和设备内存中序列化的元数据和数据

std::vector<uint8_t> pack_metadata(table_view const &table, uint8_t const *contiguous_buffer, size_t buffer_size)#

生成用于打包存储在连续缓冲区中的表的元数据。

来自table_view的元数据被复制到一个主机字节向量中,该向量可用于构建packed_columnspacked_table结构。调用者有责任确保表中的所有列都指向contiguous_buffer

Parameters:
  • table – 要打包的表的视图

  • contiguous_buffer – 一个设备内存的连续缓冲区,其中包含由table中的列引用的数据

  • buffer_sizecontiguous_buffer 的大小

Returns:

表示用于unpack packed_columns 结构的元数据的字节向量

table_view unpack(packed_columns const &input)#

反序列化cudf::pack的结果。

将序列化表的结果转换为指向存储在input中包含的连续设备缓冲区中的数据的table_view

调用者有责任确保输出中的table_view不会比输入中的数据更长久。

在此函数中没有分配新的设备内存。

Parameters:

input – 要解包的打包列

Returns:

解包的 table_view

table_view unpack(uint8_t const *metadata, uint8_t const *gpu_data)#

反序列化 cudf::pack 的结果。

将序列化表的结果转换为指向存储在gpu_data中的连续设备缓冲区中的数据的table_view,使用主机缓冲区metadata中包含的元数据。

调用者有责任确保输出中的table_view不会比输入中的数据更长久。

在此函数中没有分配新的设备内存。

Parameters:
  • metadata – 由初始 pack() 调用生成的主机端元数据缓冲区

  • gpu_data – 设备端的连续缓冲区,存储将由生成的table_view引用的数据

Returns:

解包的 table_view

std::vector<column_view> split(column_view const &input, host_span<size_type const> splits, rmm::cuda_stream_view stream = cudf::get_default_stream())#

根据预期分割的索引集,将column_view分割成一组column_view

返回的视图的input由分割向量构建,该向量指示分割应发生的位置。第i个返回的column_view被切片为[0, splits[i])如果i=0,否则为[splits[i], input.size())如果i是最后一个视图,否则为[splits[i-1], splits[i]]

对于所有的 i,预期 splits[i] <= splits[i+1] <= input.size() 对于一个大小为 N 的 splits,输出中总会有 N+1 个分割

Example:
input:   {10, 12, 14, 16, 18, 20, 22, 24, 26, 28}
splits:  {2, 5, 9}
output:  {{10, 12}, {14, 16, 18}, {20, 22, 24, 26}, {28}}

注意

调用者有责任确保返回的视图不会超过被查看设备内存的寿命。

Throws:
  • std::out_of_range – 如果 splits 的结束索引大于 input 的大小。

  • std::out_of_range – 当 splits 中的值不在范围 [0, input.size()) 内时。

  • std::invalid_argument – 当 splits 中的值“严格递减”时。

Parameters:
  • input – 要拆分的列的视图

  • splits – 视图将被分割的索引

  • stream – 用于设备内存操作和内核启动的CUDA流

Returns:

splits指示的input请求视图集

std::vector<column_view> split(column_view const &input, std::initializer_list<size_type> splits, rmm::cuda_stream_view stream = cudf::get_default_stream())#

根据预期分割的索引集,将column_view分割成一组column_view

返回的视图的input由分割向量构建,该向量指示分割应发生的位置。第i个返回的column_view被切片为[0, splits[i])如果i=0,否则为[splits[i], input.size())如果i是最后一个视图,否则为[splits[i-1], splits[i]]

对于所有的 i,预期 splits[i] <= splits[i+1] <= input.size() 对于一个大小为 N 的 splits,输出中总会有 N+1 个分割

Example:
input:   {10, 12, 14, 16, 18, 20, 22, 24, 26, 28}
splits:  {2, 5, 9}
output:  {{10, 12}, {14, 16, 18}, {20, 22, 24, 26}, {28}}

注意

调用者有责任确保返回的视图不会超过被查看设备内存的寿命。

Throws:
  • std::out_of_range – 如果 splits 的结束索引大于 input 的大小。

  • std::out_of_range – 当 splits 中的值不在范围 [0, input.size()) 内时。

  • std::invalid_argument – 当 splits 中的值“严格递减”时。

Parameters:
  • input – 要拆分的列的视图

  • splits – 视图将被分割的索引

  • stream – 用于设备内存操作和内核启动的CUDA流

Returns:

splits指示的input请求视图集

std::vector<table_view> split(table_view const &input, host_span<size_type const> splits, rmm::cuda_stream_view stream = cudf::get_default_stream())#

根据预期分割的索引集,将table_view分割成一组table_view

返回的input视图由分割向量构建,该向量指示分割应发生的位置。第i个返回的table_view被切片为[0, splits[i])如果i=0,否则为[splits[i], input.size())如果i是最后一个视图,否则为[splits[i-1], splits[i]]

对于所有的 i,预期 splits[i] <= splits[i+1] <= input.size() 对于一个大小为 N 的 splits,输出中总会有 N+1 个分割

Example:
input:   [{10, 12, 14, 16, 18, 20, 22, 24, 26, 28},
          {50, 52, 54, 56, 58, 60, 62, 64, 66, 68}]
splits:  {2, 5, 9}
output:  [{{10, 12}, {14, 16, 18}, {20, 22, 24, 26}, {28}},
          {{50, 52}, {54, 56, 58}, {60, 62, 64, 66}, {68}}]

注意

调用者有责任确保返回的视图不会超过被查看设备内存的寿命。

Throws:
  • std::out_of_range – 如果 splits 的结束索引大于 input 的大小。

  • std::out_of_range – 当 splits 中的值不在范围 [0, input.size()) 内时。

  • std::invalid_argument – 当 splits 中的值“严格递减”时。

Parameters:
  • input – 要拆分的表的视图

  • splits – 视图将被分割的索引

  • stream – 用于设备内存操作和内核启动的CUDA流

Returns:

splits指示的input请求视图集

std::vector<table_view> split(table_view const &input, std::initializer_list<size_type> splits, rmm::cuda_stream_view stream = cudf::get_default_stream())#

根据预期分割的索引集,将table_view分割成一组table_view

返回的input视图由分割向量构建,该向量指示分割应发生的位置。第i个返回的table_view被切片为[0, splits[i])如果i=0,否则为[splits[i], input.size())如果i是最后一个视图,否则为[splits[i-1], splits[i]]

对于所有的 i,预期 splits[i] <= splits[i+1] <= input.size() 对于一个大小为 N 的 splits,输出中总会有 N+1 个分割

Example:
input:   [{10, 12, 14, 16, 18, 20, 22, 24, 26, 28},
          {50, 52, 54, 56, 58, 60, 62, 64, 66, 68}]
splits:  {2, 5, 9}
output:  [{{10, 12}, {14, 16, 18}, {20, 22, 24, 26}, {28}},
          {{50, 52}, {54, 56, 58}, {60, 62, 64, 66}, {68}}]

注意

调用者有责任确保返回的视图不会超过被查看设备内存的寿命。

Throws:
  • std::out_of_range – 如果 splits 的结束索引大于 input 的大小。

  • std::out_of_range – 当 splits 中的值不在范围 [0, input.size()) 内时。

  • std::invalid_argument – 当 splits 中的值“严格递减”时。

Parameters:
  • input – 要拆分的表的视图

  • splits – 视图将被分割的索引

  • stream – 用于设备内存操作和内核启动的CUDA流

Returns:

splits指示的input请求视图集

struct packed_columns#
#include <contiguous_split.hpp>

以序列化格式的列数据。

包含来自列数组的数据,这些数据存储在两个连续的缓冲区中:一个在主机上,包含表元数据;另一个在设备上,包含表数据。

公共函数

inline packed_columns(std::unique_ptr<std::vector<uint8_t>> &&md, std::unique_ptr<rmm::device_buffer> &&gd)#

构造一个新的打包列对象。

Parameters:
  • md – 主机端元数据缓冲区

  • gd – 设备端数据缓冲区

公共成员

std::unique_ptr<std::vector<uint8_t>> metadata#

主机端元数据缓冲区。

std::unique_ptr<rmm::device_buffer> gpu_data#

设备端数据缓冲区。

struct packed_table#
#include <contiguous_split.hpp>

cudf::contiguous_split 的结果。

每个由contiguous_split执行的拆分操作生成的table_view,将被包装在packed_table中返回。此结构中的table_view和内部column_views不属于顶级cudf::tablecudf::column。相反,支持的内存和元数据由data字段拥有,并且位于一个连续的块中。

用户有责任确保table或任何派生的table_views不会超过data所拥有的内存。

公共成员

cudf::table_view table#

结果 table_viewcudf::contiguous_split

packed_columns data#

拥有的列数据。

class chunked_pack#
#include <contiguous_split.hpp>

使用用户提供的缓冲区(大小为user_buffer_size)对输入的table_view执行分块的“打包”操作。

此操作的目的是在GPU内存不足时以流式方式使用,我们希望尽量减少小规模的cudaMemcpy调用次数,并减少与cudf表相关的所有元数据的跟踪。由于内存限制,所有的thrust和临时内存分配都仅使用传入的内存资源,而不是每个设备的资源。

这个类定义了两个必须一起使用的方法来执行chunked_pack:has_next 和 next。以下是一个示例:

// Create a table_view
cudf::table_view tv = ...;

// Choose a memory resource (optional). This memory resource is used for scratch/thrust temporary
// data. In memory constrained cases, this can be used to set aside scratch memory
// for `chunked_pack` at the beginning of a program.
auto mr = cudf::get_current_device_resource_ref();

// Define a buffer size for each chunk: the larger the buffer is, the more SMs can be
// occupied by this algorithm.
//
// Internally, the GPU unit of work is a 1MB batch. When we instantiate `cudf::chunked_pack`,
// all the 1MB batches for the source table_view are computed up front. Additionally,
// chunked_pack calculates the number of iterations that are required to go through all those
// batches given a `user_buffer_size` buffer. The number of 1MB batches in each iteration (chunk)
// equals the number of CUDA blocks that will be used for the main kernel launch.
//
std::size_t user_buffer_size = 128*1024*1024;

auto chunked_packer = cudf::chunked_pack::create(tv, user_buffer_size, mr);

std::size_t host_offset = 0;
auto host_buffer = ...; // obtain a host buffer you would like to copy to

while (chunked_packer->has_next()) {
  // get a user buffer of size `user_buffer_size`
  cudf::device_span<uint8_t> user_buffer = ...;
  std::size_t bytes_copied = chunked_packer->next(user_buffer);

  // buffer will hold the contents of at most `user_buffer_size` bytes
  // of the contiguously packed input `table_view`. You are now free to copy
  // this memory somewhere else, for example, to host.
  cudaMemcpyAsync(
    host_buffer.data() + host_offset,
    user_buffer.data(),
    bytes_copied,
    cudaMemcpyDefault,
    stream);

  host_offset += bytes_copied;
}

公共函数

explicit chunked_pack(cudf::table_view const &input, std::size_t user_buffer_size, rmm::device_async_resource_ref temp_mr = cudf::get_current_device_resource_ref())#

构造一个 chunked_pack 类。

Parameters:
  • input – 要打包的源 table_view

  • user_buffer_size – 传递给 next 的缓冲区大小(以字节为单位)。必须至少为1MB

  • temp_mr – 一个可选的内存资源,仅用于临时和暂存分配

~chunked_pack()#

析构函数将作为默认实现。在此声明并定义,因为在此阶段contiguous_split_state是不完整的。

std::size_t get_total_contiguous_size() const#

获取连续打包的table_view的总大小。

Returns:

所有块的总大小(以字节为单位)

bool has_next() const#

用于检查是否还有剩余块需要复制的函数。

Returns:

如果还有剩余的数据块需要复制,则为 true,否则为 false

std::size_t next(cudf::device_span<uint8_t> const &user_buffer)#

将下一个数据块打包到 user_buffer 中。只要 has_next 返回 true,就应该调用此方法。如果在 has_next 为 false 时调用 next,则会抛出异常。

Throws:
Parameters:

user_buffer – 设备的跨度目标用于该块。此跨度的大小必须等于在构造时传递的 user_buffer_size 参数

Returns:

写入user_buffer的字节数(最多为user_buffer_size

std::unique_ptr<std::vector<uint8_t>> build_metadata() const#

为所有添加的列构建不透明的元数据。

Returns:

包含序列化列元数据的向量

公共静态函数

static std::unique_ptr<chunked_pack> create(cudf::table_view const &input, std::size_t user_buffer_size, rmm::device_async_resource_ref temp_mr = cudf::get_current_device_resource_ref())#

创建一个chunked_pack实例来执行table_view“input”的“打包”操作,其中user_buffer_size的缓冲区被整个操作的块填充。此操作可用于GPU内存受限的情况。

内存资源(temp_mr)可能是一种特殊的内存资源,用于在GPU内存不足的情况下,我们希望从一个小型保留的内存池中进行临时分配。请注意,它默认使用常规的cuDF每设备资源。

Throws:

cudf::logic_error – 当 user_buffer_size 小于 1MB 时

Parameters:
  • input – 要打包的源 table_view

  • user_buffer_size – 传递给 next 的缓冲区大小(以字节为单位)。必须至少为1MB

  • temp_mr – 仅用于临时和暂存分配的RMM内存资源

Returns:

一个唯一的 chunked_pack 的 unique_ptr