我具有以下功能,可以计算激光束在空腔中的传播。它取决于存储在称为core_data
的字典中的许多参数,该字典是一个基本参数集。
def propagate(N, core_data, **ddata):
cd = copy.deepcopy(core_data) # use initial configuration
cd.update(ddata) # update with data I want to change
cavity = get_new_cavity(cd) # get new cavity object
P = []
for i in range(N):
cavity.evolve(1)
P.append(cavity.get_power())
return P
如果我想更改参数并查看其对激光的影响,我可以像这样调用函数
P0 = propagate(1000, core_data, L1=1.2, M5=17)
这很好用。
现在,我将编写一个函数将此函数传递给ProcessPoolExecutor
,并使用相同的键迭代**ddata
的值。例如,它应该像这样工作(简单的示例):
propagate_parallel(1000, core_data,
L1=np.linspace(1, 2, 2),
M5=np.linspace(16, 17, 2))
然后应并行执行此操作:
propagate(1000, core_data, L1=1, M5=16)
propagate(1000, core_data, L1=1, M5=17)
propagate(1000, core_data, L1=2, M5=16)
propagate(1000, core_data, L1=2, M5=17)
这种情况适用于我的情况:
xrng = np.linspace(110e-30, 150e-30, Nx)
yrng = np.linspace(6.6e-9, 6.7e-9, Ny)
futures = []
with confu.ProcessPoolExecutor(max_workers=Ncores) as pool:
for y, x in it.product(yrng, xrng):
futures.append(pool.submit(propagate, RTs=1000,
core_data=core_data,
gdd_dm=x, dwl_filt=y))
问题在于,这并不灵活,如上所述,我无法将其纳入一个不错的函数中。应该是可以这样调用的函数,以便从上方重现代码:
propagate_parallel(1000, core_data, gdd_dm=xrng, dwl_filt=yrng)
如何将**ddata
中的密钥与相应密钥的迭代值一起传递?
仅供参考,我用过
import numpy as np
import concurrent.futures as confu
import itertools as it
答案 0 :(得分:0)
您要遍历笛卡尔积。
这是一种迭代笛卡尔坐标的方法。
from itertools import product
import numpy as np
L1=np.linspace(1, 2, 2)
M5=np.linspace(16, 17, 2)
dconf = dict(data=5)
size = L1.size
loop_size = size**2
def propagate(N, data, modifiers):
data.update(modifiers)
out = []
for i in range(N):
out.append('%s : %s : %s : %s'%(i, *data.values()))
return out
mod = (dict(L1=i, M5=j) for i, j in product(L1, M5))
m = map(propagate, np.arange(2, 2+loop_size), (dconf,)*loop_size, mod)
for outer in m:
for inner in outer:
print(inner)
这可以适应您的代码,如果您真的需要并行处理(这意味着在内核之间分配信息方面,所有这些都可以),请看一下Dask。
希望这足以使您前进。
编辑: 您的问题很难准确指出。 您的问题真的是如何实现简单的“函数调用”吗? 我想一个答案就是要做一个包装功能,就像...
def propagate(N, data, modifiers):
...
def call_propagate(N, data, L1_, M5_):
mod = ...
m = map(...
return m
for outer in call_propagate(1000, dconf, L1, M5)
for inner in outer:
print(inner)
答案 1 :(得分:0)
我认为我被某种方式阻止了……我一直在思考如何保留变量名(瞬时L1
)并将其作为变量传递给另一个函数。
@ ahead87:您的第一句话已经使我畅通无阻,我意识到**data
可以通过字典轻松处理。因此,最后,我只需要将输入字典转换为下一个函数的字典列表即可,就像这样(删除了一些不相关的部分):
def propagate_parallel(RTs, cav_data, **ddata):
keys = list(ddata.keys())
values = list(ddata.values())
futures = []
res = []
with confu.ProcessPoolExecutor(max_workers=32) as pool:
for i in it.product(*values):
futures.append(pool.submit(propagate, RTs=RTs,
cav_data=cav_data,
**dict(zip(keys, list(i)))))
for fut in futures:
res.append(fut)
return res
最后,我想我终于了解了**kwargs
,并且可以将其作为命令。谢谢!