我正试图为一个相对较大的网络(8M个节点和17M条边)中的250k个特殊节点计算ego网络。由于每个特殊节点的切割过程需要3秒钟,因此我决定使用multiprocessing
:
from graph_tool import Graph, GraphView
from graph_tool.topology import shortest_distance
from graph_tool import load_graph
import multiprocessing
import time
NO_PROC = 4
DEGREE = 4 # neighbours of n-th degree
NO_SPECIAL_NODES = 250000
graph = load_graph('./graph.graphml') #8M nodes, 17M edges
def ego_net(g, ego, n):
print("Graph's identity: {}.".format(id(g))) # check if you use the same object as in other calls
d = shortest_distance(g=g, source=ego, max_dist=n) #O(V+E)
u = GraphView(g, vfilt=d.a < g.num_vertices()) #O(V)
u = Graph(u, prune=True)
return (ego, u)
if __name__ == "__main__":
# generate arguments
data = [(graph, node, DEGREE) for node in range(0, NO_SPECIAL_NODES)]
# choose forking strategy explicitly
ctx = multiprocessing.get_context('fork')
pool = ctx.Pool(NO_PROC)
results = pool.starmap(ego_net, [piece for piece in data])
这种方法的问题是,即使我显式地选择了fork
{a1},子流程也不会使用graph
对象,而是将大对象复制到每个子流程中。这种方法导致MemoryError
,因为我无法为graph
的副本提供足够的RAM
我知道multiprocessing
中定义的data structures支持进程之间的共享。它们似乎不支持Graph
等graph
是其实例的复杂对象。有没有办法只加载一次graph
并让所有进程都使用它?我确信ego_net
函数从graph
读取,并且不会以任何方式修改对象
目前没有回答
相关问题 更多 >
编程相关推荐