使用并行python来并行化networkx中的节点上的循环

时间:2016-03-07 15:29:41

标签: python parallel-processing networkx parallel-python

我在networkx中做了一些复杂的计算。计算涉及为网络中的每个节点反复计算一些数量。正如这种计算的一个例子,假设我们想要计算网络中每个节点的平均邻居程度,并将该值保存为节点属性。以下代码段对我有用:

import networkx as nx

G = nx.erdos_renyi_graph(10, 0.5)

def ave_nbr_deg(node):
    value = 0.
    for nbr in G.neighbors(node):
        value += G.degree(nbr)
    G.node[node]['ave_nbr_deg'] = value/len(G.neighbors(node))

for node in G.nodes():
    ave_nbr_deg(node)

print G.nodes(data = True)

这给了我:

[(0, {'ave_nbr_deg': 5.4}), (1, {'ave_nbr_deg': 5.0}), (2, {'ave_nbr_deg': 5.333333333333333}), (3, {'ave_nbr_deg': 5.2}), (4, {'ave_nbr_deg': 5.6}), (5, {'ave_nbr_deg': 5.6}), (6, {'ave_nbr_deg': 5.2}), (7, {'ave_nbr_deg': 5.25}), (8, {'ave_nbr_deg': 5.5}), (9, {'ave_nbr_deg': 5.5})]

这里我有一个小疑问。对象G是在函数ave_nbr_deg之外创建的,我不知道函数如何有它的信息,即使我还没有宣布它是全局的。

现在,我想使用并行python模块来使用我系统上的所有内核进行此计算。在对上面的代码进行一些更改后,我得到以下代码:

import networkx as nx
import pp

G = nx.erdos_renyi_graph(10, 0.5)

def ave_nbr_deg(node):
    value = 0.
    for nbr in G.neighbors(node):
        value += G.degree(nbr)
    G.node[node]['ave_nbr_deg'] = value/len(G.neighbors(node))

job_server = pp.Server(ppservers = ())

print "Starting pp with", job_server.get_ncpus(), "workers"

for node in G.nodes():
    job_server.submit(ave_nbr_deg, args = (node,))()

print G.nodes(data = True)

但它返回以下错误:

An error has occured during the function execution
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/ppworker.py", line 90, in run
    __result = __f(*__args)
  File "<string>", line 5, in ave_nbr_deg
NameError: global name 'G' is not defined

我在提交中尝试了各种各样的事情,包括模块名nx,等等。但是,我没有得到确切的问题。不幸的是,documentation of smp太短,无法解决这个问题。如果有人能帮助我,我将非常感激。

提前致谢

1 个答案:

答案 0 :(得分:1)

回答第一个问题:Python首先在本地命名空间中查找变量。如果它在那里找不到它们,那么它将向上移动到父命名空间并在那里查找它。这就是它如何找到G,即使G未在当地宣布。以下是有关变量范围的更多信息:Python scoping

可能有两种解决方案:

1 - 将G作为参数传递给函数ave_nbr_deg,例如

for node in G.nodes():
    job_server.submit(ave_nbr_deg, args = (node,G))()

2 - 在提交参数中声明G作为全局变量(来自Parallel Python文档)

   submit(self, func, args=(), depfuncs=(), modules=(), 
       callback=None, callbackargs=(), group='default', globals=None)
Submits function to the execution queue

func - function to be executed
args - tuple with arguments of the 'func'
depfuncs - tuple with functions which might be called from 'func'
modules - tuple with module names to import
callback - callback function which will be called with argument 
        list equal to callbackargs+(result,) 
        as soon as calculation is done
callbackargs - additional arguments for callback function
group - job group, is used when wait(group) is called to wait for
jobs in a given group to finish
globals - dictionary from which all modules, functions and classes
will be imported, for instance: globals=globals()

在这种情况下,调用以下内容应该有效:

for node in G.nodes():
    job_server.submit(ave_nbr_deg, args = (node,G), globals=globals())()