【问题标题】:How to parallelize a nested loop with dask.distributed?如何使用 dask.distributed 并行化嵌套循环?
【发布时间】:2019-03-10 20:12:13
【问题描述】:

我正在尝试使用看起来像这样的 dask 分发并行化嵌套循环:

@dask.delayed
def delayed_a(e):
    a = do_something_with(e)
    return something

@dask.delayed
def delayed_b(element):
    computations = []
    for e in element:
        computations.add(delayed_a(e))

    b = dask.compute(*computations, scheduler='distributed',
                    num_workers=4)
    return b

list = [some thousands of elements here]
computations = []
for element in list:
    computations.append(delayed_b(element))
    results = dask.compute(*computations, scheduler='distributed',
                           num_workers=4)

如您所见,我正在使用distributed 调度程序。首先,我创建了一个computations 列表,其中包含一个惰性delayed_b 函数,该函数将list 中的一个元素作为参数。然后,delayed_b 创建一组新的computations,它们正在调用delayed_a 函数,并且一切都在分布式中执行。这个伪代码正在工作,但我发现如果delayed_a 不存在,它会更快。那么我的问题是——进行分布式并行 for 循环的正确方法是什么?

在历史的尽头,我想做的是:

list = [some thousands of elements here]
for element in list:
    for e in element:
        do_something_with(e)

我非常感谢任何有关使用dask.distributed 完成嵌套循环的最佳方法的建议。

【问题讨论】:

    标签: python-3.x parallel-processing dask dask-distributed dask-delayed


    【解决方案1】:

    简单:

    something = dask.delayed(do_something_with_e
    list = [some thousands of elements here]
    
    # this could be written as a one-line comprehension
    computations = []
    for element in list:
        part = []
        computations.append(part)
        for e in element:
            part.append(something(e))
    
    results = dask.compute(*computations, scheduler='distributed',
                           num_workers=4)
    

    您应该永远在延迟函数中调用延迟函数或compute()

    (请注意,默认情况下将使用分布式调度程序,只要您创建了客户端)

    【讨论】:

    • 感谢您的回复。我今天将测试它。你是对的,我昨天阅读了关于延迟功能的注意事项。当您使用 @delayed 装饰器时,是否可以实现您所写的相同?
    • dask.delayed() 的调用与装饰器的作用相同。如果您可以访问do_something_with_e 的代码,则可以添加装饰器。如果你做不到,要么做这里的事情,要么像原来一样编写一个装饰函数。
    • 我认为在你上面的 sn-p 中有一个 computations.append() 在循环遍历 element 列表后丢失。我仍然发现,将element 列表传递给执行for e in element 的延迟函数会更快。这正常吗?如您所见,我对使用 dask 和并行化都很陌生。提前致谢。
    • (已编辑 - 谢谢)是否更快取决于任务的大小以及它们的并行程度。您可以在延迟函数中循环,但不要在那里调用延迟/计算。
    • 不,他们没有,他们将调用延迟函数(“延迟对象”)的结果作为输入传递给其他延迟函数。
    猜你喜欢
    • 2020-09-27
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多