复制分割#
- group 分割
函数
-
std::vector<packed_table> contiguous_split(cudf::table_view const &input, std::vector<size_type> const &splits, rmm::cuda_stream_view stream = cudf::get_default_stream(), 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
=0,则返回的第i
个table_view
被切片为[0, splits[i])
;如果i
是最后一个视图,则切片为[splits[i], input.size())
;否则切片为[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
字段中包含的被视图化的设备内存的生命周期。- 抛出:
std::out_of_range – 如果
splits
的结束索引大于input
的大小。std::out_of_range – 当
splits
中的值不在范围 [0, input.size()) 内时。std::invalid_argument – 当
splits
中的值“严格递减”时。
- 参数:
input – 要分割的表格视图
splits – 视图将被分割的索引向量
stream – 用于设备内存操作和内核启动的 CUDA 流
mr – 用于所有返回的设备分配的可选内存资源
- 返回:
由
splits
指定的input
的请求视图集以及被视图化的内存缓冲区
-
packed_columns pack(cudf::table_view const &input, rmm::cuda_stream_view stream = cudf::get_default_stream(), rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref())#
将
table_view
深度复制到序列化的连续内存格式中。从
table_view
复制的元数据被复制到一个主机字节向量中,table_view
的数据被复制到一个device_buffer
中。将此函数的输出传递给cudf::unpack
进行反序列化。- 参数:
input – 要打包的表格视图
stream – 用于设备内存操作和内核启动的 CUDA 流
mr – 用于所有返回的设备分配的可选内存资源
- 返回:
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
。- 参数:
table – 要打包的表格视图
contiguous_buffer – 一个包含由
table
中的列引用的数据的连续设备内存缓冲区buffer_size –
contiguous_buffer
的大小
- 返回:
表示用于
unpack
packed_columns 结构体的元数据的字节向量
-
table_view unpack(packed_columns const &input)#
反序列化
cudf::pack
的结果。将序列化表的结果转换为
table_view
,该视图指向存储在input
中包含的连续设备缓冲区中的数据。调用者有责任确保输出中的
table_view
不会超出输入中数据的生命周期。此函数中不会分配新的设备内存。
- 参数:
input – 要反打包的packed columns
- 返回:
反打包的
table_view
-
table_view unpack(uint8_t const *metadata, uint8_t const *gpu_data)#
反序列化
cudf::pack
的结果。将序列化表的结果转换为
table_view
,该视图指向存储在gpu_data
中包含的连续设备缓冲区中的数据,使用主机缓冲区metadata
中包含的元数据。调用者有责任确保输出中的
table_view
不会超出输入中数据的生命周期。此函数中不会分配新的设备内存。
- 参数:
metadata – 由初始 pack() 调用产生的主机端元数据缓冲区
gpu_data – 存储将被结果
table_view
引用的数据的设备端连续缓冲区
- 返回:
反打包的
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
=0,则返回的第i
个column_view
被切片为[0, splits[i])
;如果i
是最后一个视图,则切片为[splits[i], input.size())
;否则切片为[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}}
注意
调用者有责任确保返回的视图不会超出被视图化的设备内存的生命周期。
- 抛出:
std::out_of_range – 如果
splits
的结束索引大于input
的大小。std::out_of_range – 当
splits
中的值不在范围 [0, input.size()) 内时。std::invalid_argument – 当
splits
中的值“严格递减”时。
- 参数:
input – 要分割的列视图
splits – 视图将被分割的索引
stream – 用于设备内存操作和内核启动的 CUDA 流
- 返回:
由
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
=0,则返回的第i
个column_view
被切片为[0, splits[i])
;如果i
是最后一个视图,则切片为[splits[i], input.size())
;否则切片为[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}}
注意
调用者有责任确保返回的视图不会超出被视图化的设备内存的生命周期。
- 抛出:
std::out_of_range – 如果
splits
的结束索引大于input
的大小。std::out_of_range – 当
splits
中的值不在范围 [0, input.size()) 内时。std::invalid_argument – 当
splits
中的值“严格递减”时。
- 参数:
input – 要分割的列视图
splits – 视图将被分割的索引
stream – 用于设备内存操作和内核启动的 CUDA 流
- 返回:
由
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
=0,则返回的第table_view
被切片为[0, splits[i])
;如果i
是最后一个视图,则切片为[splits[i], input.size())
;否则切片为[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}}]
注意
调用者有责任确保返回的视图不会超出被视图化的设备内存的生命周期。
- 抛出:
std::out_of_range – 如果
splits
的结束索引大于input
的大小。std::out_of_range – 当
splits
中的值不在范围 [0, input.size()) 内时。std::invalid_argument – 当
splits
中的值“严格递减”时。
- 参数:
input – 要分割的表格视图
splits – 视图将被分割的索引
stream – 用于设备内存操作和内核启动的 CUDA 流
- 返回:
由
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
=0,则返回的第table_view
被切片为[0, splits[i])
;如果i
是最后一个视图,则切片为[splits[i], input.size())
;否则切片为[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}}]
注意
调用者有责任确保返回的视图不会超出被视图化的设备内存的生命周期。
- 抛出:
std::out_of_range – 如果
splits
的结束索引大于input
的大小。std::out_of_range – 当
splits
中的值不在范围 [0, input.size()) 内时。std::invalid_argument – 当
splits
中的值“严格递减”时。
- 参数:
input – 要分割的表格视图
splits – 视图将被分割的索引
stream – 用于设备内存操作和内核启动的 CUDA 流
- 返回:
由
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)#
构造一个新的packed columns对象。
- 参数:
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 和 scratch 内存分配仅使用传入的内存资源,而不是每个设备的内存资源。
此类定义了两个必须协同使用的方法来执行 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::cuda_stream_view stream = cudf::get_default_stream(), rmm::device_async_resource_ref temp_mr = cudf::get_current_device_resource_ref())#
构造一个新的
chunked_pack
类。- 参数:
input – 要打包的源
table_view
user_buffer_size – 在
next
时将传入的缓冲区大小(字节)。必须至少为 1MBstream – 用于设备内存操作和内核启动的 CUDA 流
temp_mr – 仅用于临时和 scratch 分配的可选内存资源
-
~chunked_pack()#
将被实现为默认的析构函数。此处声明并定义是因为 contiguous_split_state 在此阶段不完整。
-
std::size_t get_total_contiguous_size() const#
获取连续打包的
table_view
的总大小。- 返回:
所有块的总大小(字节)
-
bool has_next() const#
检查是否有剩余块待复制的函数。
- 返回:
如果还有剩余块待复制,则为 true,否则为 false
-
std::size_t next(cudf::device_span<uint8_t> const &user_buffer)#
将下一个块打包到
user_buffer
中。只要has_next
返回 true,就应该调用此方法。如果在has_next
为 false 时调用next
,将抛出异常。- 抛出:
cudf::logic_error – 如果
user_buffer
的大小与构造时传入的user_buffer_size
参数不同。cudf::logic_error – 如果在所有块复制完成后调用。
- 参数:
user_buffer – 块的目标设备 span。此 span 的大小必须等于构造时传入的
user_buffer_size
参数。- 返回:
写入到
user_buffer
的字节数(最多user_buffer_size
)
-
std::unique_ptr<std::vector<uint8_t>> build_metadata() const#
为所有添加的列构建不透明元数据。
- 返回:
包含序列化列元数据的向量
公共静态函数
-
static std::unique_ptr<chunked_pack> create(cudf::table_view const &input, std::size_t user_buffer_size, rmm::cuda_stream_view stream = cudf::get_default_stream(), 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 内存不足时,将 scratch 和临时分配从一小部分保留的内存池中进行的情况。请注意,它默认为常规的 cuDF 每设备资源。- 抛出:
cudf::logic_error – 当 user_buffer_size 小于 1MB 时。
- 参数:
input – 要打包的源
table_view
user_buffer_size – 在
next
时将传入的缓冲区大小(字节)。必须至少为 1MBstream – 用于设备内存操作和内核启动的 CUDA 流
temp_mr – 仅用于临时和 scratch 分配的 RMM 内存资源
- 返回:
一个 chunked_pack 的 unique_ptr
-
explicit chunked_pack(cudf::table_view const &input, std::size_t user_buffer_size, rmm::cuda_stream_view stream = cudf::get_default_stream(), 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::cuda_stream_view stream = cudf::get_default_stream(), rmm::device_async_resource_ref mr = cudf::get_current_device_resource_ref())#