- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将我必须的 cpu 绑定(bind)算法转换为 GPU 算法,但我遇到了 cugraph 的各种问题。其中一部分是我的无知,另一部分是 cugraph 的初期和不发达,最后一部分是我只是在搞清楚优雅的矢量化方法。
假设我有 m 个数据观测值,其中包含 n 个特征。我通过计算所有观测值的所有观测值的欧氏距离来创建距离矩阵(注意:这不是我需要帮助的部分,也不是最佳的。只需添加这部分以获得易于理解、可重现的代码)
import numpy as np
def l1_distance(arr):
return np.linalg.norm(arr, 1)
X = np.random.randint(low=0, high=255, size=(700,4096))
W = np.empty((700,700))
for i in range(700):
for j in range(700):
W[i,j] = l1_distance(X[i,:] - X[j,:])
第一个挑战
import networkx as nx
def build_weighted_graph(W):
n = W.shape[0]
Graph = nx.DiGraph()
for i in range(n):
for j in range(n):
Graph.add_weighted_edges_from([(i,j,min(W[i,j], W[j,i]))])
return Graph
其中输入 W 矩阵是欧氏空间中的方形距离矩阵(节点最初由 x 特征组成)。例如。第 1 行第 9 行是节点 1 和节点 9 之间的距离,第 20 行第 30 行是节点 20 和节点 30 之间的距离,依此类推。图形现在在连接的节点之间绘制边,边的权重是欧氏距离测量.
我花了大约 8 个小时试图弄清楚如何将其转移到 GPU,但即使在 NVIDIA 自己的文档中,他们也声称
The code block is perfectly fine for NetworkX. However, the process of iterating over the dataframe and adding one node at a time is problematic for GPUs and something that we try and avoid. cuGraph stores data in columns (i.e. arrays). Resizing an array requires allocating a new array one element larger, copying the data, and adding the new value. That is not very efficient.
If your code follows the above model of inserting one element at atime, the we suggest either rewriting that code or using it as iswithin NetworkX and just accelerating the algorithms with cuGraph.
所以我放弃了,让那部分保持原样。算法的下一部分使用 dijkstra 算法并计算所有节点到所有其他节点的最短路径
res = dict(nx.all_pairs_dijkstra_path_length(Graph))
在 cugraphs 实现中,它们只有单一源 dijkstra,它将图形和源节点作为参数。这与 networkx 的库形成对比,networkx 的库随附上述方法并在所有节点上无处不在地应用 dijkstra。这意味着我将不得不为每个节点(更多 for 循环)迭代调用 SSSP(cugraph 的 dijkstra 实现)。
在我通过连接节点获得距离后,我创建了另一个方形距离矩阵,它现在基于通过连接节点的距离而不是最初采用欧氏距离。
D = np.zeros([n,n])
for i in range(n):
for j in range(n):
D[i,j] = res[i][j]
我这辈子都想不出如何为 GPU 向量化其中的任何一个。在正确方向上的任何帮助将不胜感激。目前对于我的算法运行的数据集,CPU 绑定(bind)算法需要大约 5 分钟才能运行 698 个节点。因此,为什么我要尝试在 GPU 方面加快速度
最佳答案
您的第一个问题——欧几里德距离矩阵的初始化——的答案似乎在 Using cupy to create a distance matrix from another matrix on GPU 中得到了解答。 ,但您当然可以使用 cuDF 和 cuGraph 优化图的创建和 Dijkstra 矩阵的计算。
要高效地创建图形,您可以构建一个列出边及其权重的 cuDF 数据框。由于欧几里德距离矩阵的结构,这很简单。 cuGraph 将此数据框作为边列表接收并返回图形。然后您可以遍历节点以计算最短的适用顶点。如果问题规模增加,这可以在以后与 Dask 并行化或分发。
对于这个问题大小,下面的代码比使用 nx.all_pairs_dijkstra_path_length 快大约 40 倍,它还包括初始距离计算。
import cupy as cp
import cudf as cd
import cugraph as cg
def build_weighted_graph_gpu(X, n):
X_d = cp.array(X)
G_d = cp.zeros([n, n])
for i in range(n):
G_d[i,:] = cp.abs(cp.broadcast_to(X_d[i,:], X_d.shape) - X_d).sum(axis=1)
return G_d
def dijkstras_matrix_gpu(W_d):
n = np.shape(W_d)[0]
# Create a columnar dataframe describing edges
df_g = cd.DataFrame({
'source': cp.array([x // n for x in range(n*n)]),
'destination': cp.array([x % n for x in range(n*n)]),
'weight': cp.minimum(W_d, cp.transpose(W_d)).ravel()})
graph_d = cg.Graph()
graph_d.from_cudf_edgelist(df_g, source='source', destination='destination', edge_attr='weight', renumber=False)
dist_d = cp.empty_like(W_d)
for i in range(n):
dist_d[i,:] = cp.asarray(cg.traversal.shortest_path(graph_d, i)['distance'])
return dist_d
distance_matrix = dijkstras_matrix_gpu(build_weighted_graph_gpu(X))
关于gpu - NetworkX all_pairs_dijkstras 的 CuGraph 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64567877/
我正在尝试对网络上的投票动态进行建模,并希望能够在 NetworkX 中创建一个图表,在其中我可以在节点上迭代投票过程,让它们的颜色变化对应于它们的投票“标签”。 我已设法获得此代码以查看每个节点的属
我无法计算简单 NetworkX 加权图的中心性。 这是正常的还是我做错了什么? 我使用简单的 add_edge(c[0],c[1],weight = my_values) 添加边,其中c[0],c[
我想在函数调用 d(n) 之前比较 networkx.Graph 对象 n 的状态(有副作用)之后与国家合作。 有一些可变的对象节点属性,例如 n.node[0]['attribute'],我想对其进
我正在使用 NetworkX 生成一些噪声数据的图表。我想通过删除虚假分支来“清理”图表,并希望避免重新发明轮子。 例如,链接的图片显示了一组示例图形,作为由灰线连接的彩色节点。我想修剪白框指示的节点
我目前正在尝试制定一种算法来在图中查找派系,幸运的是我从 Networkx 找到了一个函数的文档,该函数就是这样做的。不幸的是,变量名有点简洁,我很难理解代码的每一部分的作用。 这里是 find_cl
我正在尝试使用 NetworkX 在两个节点之间添加平行边,但由于以下错误而失败。我究竟做错了什么? import networkx as nx import graphviz g1 = nx.Mul
我希望将 Pajek 数据集转换为 networkx Graph()。数据集来自哥斯达黎加Family Ties 。我正在使用非常方便的 networkx.read_pajek(pathname) 函
我在networkx中有一个巨大的图,我想从每个节点获取深度为2的所有子图。有没有一种好的方法可以使用networkx中的内置函数来做到这一点? 最佳答案 正如我在评论中所说,networkx.ego
我希望将 Pajek 数据集转换为 networkx Graph()。数据集来自哥斯达黎加Family Ties 。我正在使用非常方便的 networkx.read_pajek(pathname) 函
我在使用以下代码时遇到问题。边连接节点。但是是否有可能有一个定向网络,如果一个“人”跟随一个“人”,但它只是一种方式,在边缘有箭头或方向。 plt.figure(figsize=(12, 12)) #
我正在 Windows 机器上使用 Python 3,尽管付出了很多努力,但仍未能安装 pygraphviz。单独讨论。 我有networkx和graphviz模块...是否有一个范例可以在netwo
我正在使用《Python 自然语言处理》一书(“www.nltk.org/book”)自学 Python 和 NLTK。 我在 NetworkX 上被困在第 4 章第 4 部分第 8 部分。当我尝试运
下面是我的代码: import networkx as nx for i in range(2): G = nx.DiGraph() if i==0: G.add_ed
我正在使用 deap 符号回归示例问题中的这段代码,图形显示正常,但我希望节点扩展为圆角矩形以适合文本 自动 . (我不想只是通过反复试验来指定节点大小)。我该怎么做? # show tree imp
我正在尝试使用 networkx 读取 gml 文件(很简单吧?),除非我尝试读取文件时出现错误“networkx.exception.NetworkXError: cannot tokenize u
如何按厚度在networkx中绘制N> 1000个节点的加权网络?如果我有一个源、目标节点和每个边的权重的 .csv 列表,我正在考虑使用该方法: for i in range(N) G.add_ed
我希望 networkx 在我的定向中找到绝对最长的路径, 无环图。 我知道 Bellman-Ford,所以我否定了我的图长度。问题: networkx 的 bellman_ford() 需要一个源节
我在图中有一个节点,它充当一种“临时连接器”节点。我想删除该节点并更新图中的边,以便其所有直接前辈都指向其直接后继者。 在 networkx 中是否有内置功能可以做到这一点,还是我需要推出自己的解决方
我有两张彩色图表。我想确定它们是否同构,条件是同构必须保留顶点颜色。 networkx 中是否有算法可以做到这一点? 这些图是无向且简单的。 最佳答案 检查documentation对于is_isom
我有一组起点-终点坐标,我想计算它们之间的最短路径。 我的起点-终点坐标有时位于一条长直线道路的中间。但是,OSMnx/networkx 计算的最短路径不会考虑中间边到最近节点的路径。 OSMnx 或
我是一名优秀的程序员,十分优秀!