图生成器#

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_rmat_edgelist(raft::handle_t const &handle, size_t scale, size_t num_edges, double a = 0.57, double b = 0.19, double c = 0.19, uint64_t seed = 0, bool clip_and_flip = false, bool scramble_vertex_ids = false)#

生成 R-mat 图的边列表。

已弃用

此函数将被弃用,应替换为接受 raft::random::RngState 作为参数的版本

此函数允许类似于 Graph 500 参考实现的重边和自环。

注意:为了生成符合 Graph 500 规范的图,需要调用 scramble_vertex_ids 函数(请注意,扰乱不会影响 cuGraph 的图构建性能,因此通常没有必要)。如果给定 edge_factor(例如 Graph 500),将 num_edges 设置为 (size_t{1} << scale) * edge_factor。要生成无向图,请将 b == c 并设置 clip_and_flip = true。所有生成的边将放置在图邻接矩阵的下三角部分(包括对角线)。

对于使用 P 个 GPU 进行多 GPU 生成,seed 在不同 GPU 中应设置为不同的值,以避免每个 GPU 生成相同的边集。num_edges 也应进行调整;例如,假设给定 edge_factor,则设置 num_edges = (size_t{1} << scale) * edge_factor / P + (rank < (((size_t{1} << scale) * edge_factor) % P) ? 1 : 0)。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • scale – 设置图中顶点数量的比例因子。顶点 ID 的值在 [0, V) 范围内,其中 V = 1 << scale

  • num_edges – 要生成的边数量。

  • a – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • b – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • c – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • seed – 随机数生成器的种子值。

  • clip_and_flip – 控制是否仅在图邻接矩阵的下三角部分(包括对角线)生成边(如果设置为 true)或不生成(如果设置为 false`)的标志。

  • scramble_vertex_ids – 控制是否扰乱顶点 ID 位(如果设置为 true)或不扰乱(如果设置为 false)的标志;扰乱顶点 ID 位会打破顶点 ID 值与顶点度之间的相关性。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_rmat_edgelist(raft::handle_t const &handle, raft::random::RngState &rng_state, size_t scale, size_t num_edges, double a = 0.57, double b = 0.19, double c = 0.19, bool clip_and_flip = false, bool scramble_vertex_ids = false)#

生成 R-mat 图的边列表。

此函数允许类似于 Graph 500 参考实现的重边和自环。

注意:为了生成符合 Graph 500 规范的图,需要调用 scramble_vertex_ids 函数(请注意,扰乱不会影响 cuGraph 的图构建性能,因此通常没有必要)。如果给定 edge_factor(例如 Graph 500),将 num_edges 设置为 (size_t{1} << scale) * edge_factor。要生成无向图,请将 b == c 并设置 clip_and_flip = true。所有生成的边将放置在图邻接矩阵的下三角部分(包括对角线)。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • rng_state – RAFT RNG 状态,每次调用都会更新

  • scale – 设置图中顶点数量的比例因子。顶点 ID 的值在 [0, V) 范围内,其中 V = 1 << scale

  • num_edges – 要生成的边数量。

  • a – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • b – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • c – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • clip_and_flip – 控制是否仅在图邻接矩阵的下三角部分(包括对角线)生成边(如果设置为 true)或不生成(如果设置为 false`)的标志。

  • scramble_vertex_ids – 控制是否扰乱顶点 ID 位(如果设置为 true)或不扰乱(如果设置为 false)的标志;扰乱顶点 ID 位会打破顶点 ID 值与顶点度之间的相关性。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_bipartite_rmat_edgelist(raft::handle_t const &handle, raft::random::RngState &rng_state, size_t src_scale, size_t dst_scale, size_t num_edges, double a = 0.57, double b = 0.19, double c = 0.19)#

生成二分 R-mat 图的边列表。

源顶点 ID 将在 [0, 2^src_scale) 范围内,目标顶点 ID 将在 [0, 2^dst_scale) 范围内。此函数允许重边。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • rng_state – RAFT RNG 状态,每次调用都会更新

  • src_scale – 设置二分图中源顶点 ID(或第一个顶点集)范围的比例因子。顶点 ID 的值在 [0, V_src) 范围内,其中 V_src = 1 << src_scale

  • dst_scale – 设置二分图中目标顶点 ID(或第二个顶点集)范围的比例因子。顶点 ID 的值在 [0, V_dst) 范围内,其中 V_dst = 1 << dst_scale

  • num_edges – 要生成的边数量。

  • a – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • b – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

  • c – R-mat 图生成器中的 a, b, c, d (= 1.0 - (a + b + c))(更多详细信息请访问 https://graph500.org)。a, b, c, d 应为非负数,且 a + b + c 应不大于 1.0。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::vector<std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>>> generate_rmat_edgelists(raft::handle_t const &handle, size_t n_edgelists, size_t min_scale, size_t max_scale, size_t edge_factor = 16, generator_distribution_t size_distribution = generator_distribution_t::POWER_LAW, generator_distribution_t edge_distribution = generator_distribution_t::POWER_LAW, uint64_t seed = 0, bool clip_and_flip = false, bool scramble_vertex_ids = false)#

使用 R-mat 图生成器生成多个边列表。

已弃用

此函数将被弃用,应替换为接受 raft::random::RngState 作为参数的版本

此函数允许类似于 Graph 500 参考实现的重边和自环。

注意:为了生成符合 Graph 500 规范的图,需要调用 scramble_vertex_ids 函数(请注意,扰乱不会影响 cuGraph 的图构建性能,因此通常没有必要)。如果给定 edge_factor(例如 Graph 500),将 num_edges 设置为 (size_t{1} << scale) * edge_factor。要生成无向图,请将 b == c 并设置 clip_and_flip = true。所有生成的边将放置在图邻接矩阵的下三角部分(包括对角线)。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • n_edgelists – 要生成的边列表(图)数量

  • min_scale – 设置图中最小顶点数量的比例因子。

  • max_scale – 设置图中最大顶点数量的比例因子。

  • edge_factor – 每个顶点要生成的平均边数量。

  • size_distribution – 图大小的分布,影响 R-MAT 生成器的比例参数

  • edge_distribution – 每个图的边分布,影响 R-MAT 参数 a,b,c,d 的设置方式。

  • seed – 随机数生成器的种子值。

  • clip_and_flip – 控制是否仅在图邻接矩阵的下三角部分(包括对角线)生成边(如果设置为 true)或不生成(如果设置为 false`)的标志。

  • scramble_vertex_ids – 控制是否扰乱顶点 ID 位(如果设置为 true)或不扰乱(如果设置为 false)的标志;扰乱顶点 ID 位会打破顶点 ID 值与顶点度之间的相关性。

返回:

一个大小为 n_edgelists 的 std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 向量,向量的每个元素都是一个元组,包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象。

template<typename vertex_t>
std::vector<std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>>> generate_rmat_edgelists(raft::handle_t const &handle, raft::random::RngState &rng_state, size_t n_edgelists, size_t min_scale, size_t max_scale, size_t edge_factor = 16, generator_distribution_t size_distribution = generator_distribution_t::POWER_LAW, generator_distribution_t edge_distribution = generator_distribution_t::POWER_LAW, bool clip_and_flip = false, bool scramble_vertex_ids = false)#

使用 R-mat 图生成器生成多个边列表。

此函数允许类似于 Graph 500 参考实现的重边和自环。

注意:为了生成符合 Graph 500 规范的图,需要调用 scramble_vertex_ids 函数(请注意,扰乱不会影响 cuGraph 的图构建性能,因此通常没有必要)。如果给定 edge_factor(例如 Graph 500),将 num_edges 设置为 (size_t{1} << scale) * edge_factor。要生成无向图,请将 b == c 并设置 clip_and_flip = true。所有生成的边将放置在图邻接矩阵的下三角部分(包括对角线)。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • rng_state – RAFT RNG 状态,每次调用都会更新

  • n_edgelists – 要生成的边列表(图)数量

  • min_scale – 设置图中最小顶点数量的比例因子。

  • max_scale – 设置图中最大顶点数量的比例因子。

  • edge_factor – 每个顶点要生成的平均边数量。

  • size_distribution – 图大小的分布,影响 R-MAT 生成器的比例参数

  • edge_distribution – 每个图的边分布,影响 R-MAT 参数 a,b,c,d 的设置方式。

  • clip_and_flip – 控制是否仅在图邻接矩阵的下三角部分(包括对角线)生成边(如果设置为 true)或不生成(如果设置为 false`)的标志。

  • scramble_vertex_ids – 控制是否扰乱顶点 ID 位(如果设置为 true)或不扰乱(如果设置为 false)的标志;扰乱顶点 ID 位会打破顶点 ID 值与顶点度之间的相关性。

返回:

一个大小为 n_edgelists 的 std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 向量,向量的每个元素都是一个元组,包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_path_graph_edgelist(raft::handle_t const &handle, std::vector<std::tuple<vertex_t, vertex_t>> const &component_parameters_v)#

生成路径图的边列表

大小为 n 的路径图将顶点 0 到 (n - 1) 连接成一条长路径:((0,1), (1,2), …, (n - 2, n - 1)

如果在多 GPU 环境下执行(handle comms 已初始化),路径将跨越所有 GPU,包括从 GPU i 的最后一个顶点到 GPU (i+1) 的第一个顶点的一条边

此函数将生成一组路径图。component_parameters_v 定义了生成每个组件的参数。component_parameters_v 的每个元素定义了一个元组,包含该组件的顶点数量和基本顶点 ID。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • component_parameters_v – 包含要生成的每个组件的顶点数量和基本顶点 ID 元组的向量。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_2d_mesh_graph_edgelist(raft::handle_t const &handle, std::vector<std::tuple<vertex_t, vertex_t, vertex_t>> const &component_parameters_v)#

生成二维网格图的边列表

将根据组件规范构建一系列二维网格图。每个二维网格图都配置有一个包含 (x, y, base_vertex_id) 的元组。component_parameters_v 将包含每个组件的元组。

如果在多 GPU 环境下执行(handle comms 已初始化),每个 GPU 将生成大小相等的互不相交的二维网格结构。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • component_parameters_v – 包含定义每个组件配置的元组的向量

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_3d_mesh_graph_edgelist(raft::handle_t const &handle, std::vector<std::tuple<vertex_t, vertex_t, vertex_t, vertex_t>> const &component_parameters_v)#

生成三维网格图的边列表

将根据组件规范构建一系列三维网格图。每个三维网格图都配置有一个包含 (x, y, z, base_vertex_id) 的元组。component_parameters_v 将包含每个组件的元组。

如果在多 GPU 环境下执行(handle comms 已初始化),每个 GPU 将生成大小相等的互不相交的三维网格结构。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • component_parameters_v – 包含定义每个组件配置的元组的向量

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_complete_graph_edgelist(raft::handle_t const &handle, std::vector<std::tuple<vertex_t, vertex_t>> const &component_parameters_v)#

生成一些完全图的边列表

将根据组件规范构建一系列完全图。每个完全图都配置有一个包含 (n, base_vertex_id) 的元组。component_parameters_v 将包含每个组件的元组。

如果在多 GPU 环境下执行(handle comms 已初始化),每个 GPU 将生成大小相等的互不相交的完全图结构。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • component_parameters_v – 包含定义每个组件配置的元组的向量

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_erdos_renyi_graph_edgelist_gnp(raft::handle_t const &handle, vertex_t num_vertices, float p, vertex_t base_vertex_id, uint64_t seed = 0)#

生成 Erdos-Renyi 图的边列表

此 API 支持 G(n,p) 模型,该模型需要 O(n^2) 的工作量。

如果在多 GPU 环境下执行(handle comms 已初始化),每个 GPU 将为其邻接矩阵二维划分的一部分生成 Erdos-Renyi 边。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • num_vertices – 生成图中使用的顶点数量

  • p – 边创建的概率

  • base_vertex_id – 生成图的起始顶点 ID

  • seed – 随机数生成器的种子值。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> generate_erdos_renyi_graph_edgelist_gnm(raft::handle_t const &handle, vertex_t num_vertices, size_t m, vertex_t base_vertex_id, uint64_t seed = 0)#

生成 Erdos-Renyi 图的边列表

此 API 支持 G(n,m) 模型

如果在多 GPU 环境下执行(handle comms 已初始化),每个 GPU 将为其邻接矩阵二维划分的一部分生成 Erdos-Renyi 边。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • num_vertices – 每个完全图中使用的顶点数量

  • m – 要生成的边数量

  • base_vertex_id – 生成图的起始顶点 ID

  • seed – 随机数生成器的种子值。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t, typename weight_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>, std::optional<rmm::device_uvector<weight_t>>> symmetrize_edgelist_from_triangular(raft::handle_t const &handle, rmm::device_uvector<vertex_t> &&d_src_v, rmm::device_uvector<vertex_t> &&d_dst_v, std::optional<rmm::device_uvector<weight_t>> &&optional_d_weights_v, bool check_diagonal = false)#

从图邻接矩阵的下(或上,但不同时包含上下)三角部分边的边列表进行对称化

模板参数:
  • vertex_t – 顶点标识符的类型。需要是整数类型。

  • weight_t – 权重的类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • d_src_v – 源顶点向量

  • d_dst_v – 目标顶点向量

  • d_weights_v – 可选的边权重向量

  • check_diagonal – 指示是否检查对角线边的标志。如果设置为 true,仅对源 != 目标 的边进行对称化(以避免重复每个自环)。

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> 一个包含边源顶点 ID 和边目标顶点 ID 的 rmm::device_uvector 对象的元组。

template<typename vertex_t>
rmm::device_uvector<vertex_t> scramble_vertex_ids(raft::handle_t const &handle, rmm::device_uvector<vertex_t> &&vertices, size_t lgN)#

扰乱图中的顶点 ID

给定图的顶点列表,扰乱输入的顶点 ID。

这里的扰乱代码遵循 Graph 500 参考实现 3.0.0 版本的算法。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • vertices – 输入顶点向量

  • lgN – 输入和输出(扰乱后的)顶点 ID 假定在 [0, 2^lgN) 范围内。

返回:

存储扰乱后的顶点 ID 的 rmm::device_uvector 对象。

template<typename vertex_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>> scramble_vertex_ids(raft::handle_t const &handle, rmm::device_uvector<vertex_t> &&srcs, rmm::device_uvector<vertex_t> &&dsts, size_t lgN)#

扰乱图中的顶点 ID

给定图的边列表,扰乱输入的顶点 ID。

这里的扰乱代码遵循 Graph 500 参考实现 3.0.0 版本的算法。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • d_src_v – 输入源顶点向量

  • d_dst_v – 输入目标顶点向量

  • lgN – 输入和输出(扰乱后的)顶点 ID 假定在 [0, 2^lgN) 范围内。

返回:

包含存储扰乱后的源顶点 ID 和目标顶点 ID 的两个 rmm::device_uvector 对象的元组。

template<typename vertex_t, typename weight_t>
std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>, std::optional<rmm::device_uvector<weight_t>>> combine_edgelists(raft::handle_t const &handle, std::vector<rmm::device_uvector<vertex_t>> &&d_sources, std::vector<rmm::device_uvector<vertex_t>> &&d_dests, std::optional<std::vector<rmm::device_uvector<weight_t>>> &&optional_d_weights, bool remove_multi_edges = true)#

将来自多个源的边列表合并成一个边列表。

如果在多 GPU 环境中执行(handle comms 已初始化),每个 GPU 将只处理其部分数据。在调用此函数之前,应完成任何将边移动到同一 GPU 的操作。

模板参数:

vertex_t – 顶点标识符的类型。需要是整数类型。

参数:
  • handle – 用于封装资源(例如 CUDA 流、通信器以及各种 CUDA 库的句柄)以运行图算法的 RAFT 句柄对象。

  • sources – 要合并的源顶点 ID

  • dests – 要合并的目标顶点 ID

  • weights – 可选的要合并的权重向量

  • remove_multi_edges – 如果为 true(默认值),则移除多重边;如果为 false,则保留它们

返回:

std::tuple<rmm::device_uvector<vertex_t>, rmm::device_uvector<vertex_t>, rmm::device_uvector<weight_t>> 一个包含 rmm::device_uvector 对象的元组,用于存储边的源顶点 ID、边的目标顶点 ID 和边的权重。