我有一个简单的工作流程。当我打印出来时,它看起来像这样:
workflow = {
'a_task': (<function a_func at 0x7f1dc5ded598>,),
'b_task': (<function b_func at 0x7f1dc5ded620>,),
'c_task': (<function c_func at 0x7f1ddb07aea0>,),
'd_task': (<function d_func at 0x7f1dc5ded6a8>,),
'workflow_end_task': (<function aggregate_func at 0x7f1dc5ded730>,
'a_task', 'b_task', 'c_task', 'd_task')
}
结果证明b_func
是一个带for循环的小函数,它执行约1000次迭代,大约需要一个小时才能完成。基本上看起来像这样:
def b_func(args...):
data = []
for this in that:
data.append(...)
return data
虽然不必按顺序进行for循环。可以并行完成。
所以问题是:我该如何处理?我应该将for循环转换为工作流,然后在b_func
内添加另一个dask调用吗?还是应该退出此流程并扩展原始工作流程?
基本上,我可以嵌套繁琐的工作流程吗?或者这是个坏主意吗?
此外,您应该知道我正在使用from dask.distributed import Client
和Client.get
以便在整个计算机集群之间分配工作流。我不知道这是否会使dask.threaded.get
之后的事情变得复杂,但也许会有所作为。我猜这意味着,愚蠢的workers
中的一个将不得不在集群的所有计算机上设置新的调度程序和工作程序,然后将其工作流程传递给他们。也许是idk。
以前有没有人处理过这个问题?
答案 0 :(得分:1)
我应该将for循环转换为工作流,然后在b_func中放入另一个dask调用吗?还是应该退出此流程并扩展原始工作流程?
基本上,我可以嵌套繁琐的工作流程吗?或者这是个坏主意吗?
在一般情况下,不,您不应该在快速执行任务时也调用compute
。但是,您可以使用分布式调度程序执行此操作,事情应该就可以了。如果在任务中调用compute时未指定调度程序,则将使用当前调度程序。缺点是提交任务(在您的情况下为“ b_task”)将始终被阻止,这将占用工作线程(效率较低)。
在您的情况下,我会事先使用dask.delayed
(http://docs.dask.org/en/latest/delayed.html)建立整个图形。这使您可以编写循环正常的Python代码,并为您构建图表。有关更多信息,请参见延迟的文档。