复制分割#
- 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_table的
all_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_columns或packed_table结构。调用者有责任确保表中的所有列都指向contiguous_buffer。- Parameters:
table – 要打包的表的视图
contiguous_buffer – 一个设备内存的连续缓冲区,其中包含由
table中的列引用的数据buffer_size –
contiguous_buffer的大小
- Returns:
表示用于
unpackpacked_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#
设备端数据缓冲区。
-
inline packed_columns(std::unique_ptr<std::vector<uint8_t>> &&md, std::unique_ptr<rmm::device_buffer> &&gd)#
-
struct packed_table#
- #include <contiguous_split.hpp>
每个由contiguous_split执行的拆分操作生成的table_view,将被包装在
packed_table中返回。此结构中的table_view和内部column_views不属于顶级cudf::table或cudf::column。相反,支持的内存和元数据由data字段拥有,并且位于一个连续的块中。用户有责任确保
table或任何派生的table_views不会超过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_viewuser_buffer_size – 传递给
next的缓冲区大小(以字节为单位)。必须至少为1MBtemp_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:
cudf::logic_error – 如果
user_buffer的大小与user_buffer_size不同cudf::logic_error – 如果在所有块都已复制后调用
- 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_viewuser_buffer_size – 传递给
next的缓冲区大小(以字节为单位)。必须至少为1MBtemp_mr – 仅用于临时和暂存分配的RMM内存资源
- Returns:
一个唯一的 chunked_pack 的 unique_ptr
-
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())#
-
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())#