如何用Das编程模具

2024-05-29 11:01:48 发布

您现在位置:Python中文网/ 问答频道 /正文

在许多情况下,科学家们用一个模板来模拟系统的动态,这是在网格上卷积一个数学算子。通常,这种操作会消耗大量的计算资源。Here很好地解释了这个想法。在

在numpy中,编程二维5点模板的标准方法如下:

for i in range(rows):
    for j in range(cols):
        grid[i, j] = ( grid[i,j] + grid[i-1,j] + grid[i+1,j] + grid[i,j-1] + grid[i,j+1]) / 5

或者,更有效地使用切片:

^{pr2}$

然而,如果你的网格真的很大,它不会在你的内存中修复,或者如果卷积操作非常复杂,它将花费很长的时间,并行编程技术可以用来克服这个问题,或者只是为了更快地得到结果。像Dask这样的工具允许科学家自己以一种几乎透明的并行方式对模拟进行编程。目前,Dask不支持项目分配,所以,我如何用Dask编程一个模具。在


Tags: in模板网格for编程情况动态range
2条回答

好问题。你是正确的,dask.arraydo提供并行计算,但是don't不支持项分配。我们可以通过使一个函数一次对一个numy数据块进行操作,然后将该函数映射到边界稍有重叠的数组上,从而解决模板计算问题。在

纯函数

您应该创建一个接受numpy数组并返回一个应用了模具的新numpy数组的函数。这不应修改原始数组。在

def apply_stencil(x):
    out = np.empty_like(x)
    ...  # do arbitrary computations on out    
    return out

映射具有重叠区域的函数

Dask数组通过将一个数组分成不相交的小数组块来并行运行。像模板计算这样的操作需要相邻块之间有一点重叠。幸运的是,这可以用dask.array.ghost模块,尤其是dask.array.map_overlap方法来处理。在

{1d1>在前面的例子中,{1}实际上是有限差分

^{pr2}$

当你用磁盘阵列,您必须提供一些有关如何将其划分为的信息,如下所示:

grid = dask.array.zeros((100,100), chunks=(50,50))

这需要一个100x100的数组,分为4个块。现在,要在新创建的数组上卷积操作,必须共享块边界的信息。Dask ghost cells,管理这样的情况。在

共同的工作流程意味着:

  1. 创建数组(如果它以前不存在)
  2. 控制幽灵细胞的产生
  3. 绘制计算图
  4. 修剪边界

例如

^{pr2}$

记住Dask创建了一个字典来表示任务图,实际的计算是由s.compute()触发的。正如MRocklin指出的,映射函数必须返回numpy数组。在

关于调度程序的一点注记

默认情况下,磁盘阵列使用达斯克泰特调度程序来提高性能,但是一旦信息被共享,类似于模板的问题将是令人尴尬的并行问题,这意味着不必共享资源或信息,并且计算可以映射到不同的核心甚至不同的计算机上。为此,可以指示dask使用不同的调度程序,例如多处理公司名称:

import dask.multiprocessing
import dask

dask.set_options(get=dask.multiprocessing.get)

compute()被触发时,Dask将创建多个python实例,如果您的应用程序足够大,足以支付创建这个新实例的开销,那么Dask可能会创建多个python实例多处理会有更好的表现。 有关Dask调度程序的更多信息可以在here找到。在

相关问题 更多 >

    热门问题