我正在以dask分布的4-5TB zarr阵列执行重分块操作,并试图了解重分块顺序对内存占用量以及该操作的调度程序计算负载的影响。
以下是比较两种不同方法的极简示例代码:
nx, ny, nt = 32, 64, 128
ds = xr.Dataset({}, coords={'x':np.arange(nx),'y':np.arange(ny), 't':
np.arange(nt)})
ds = ds.assign(v_cost=np.cos(2.*np.pi*ds.t/100))
ds = ds.assign(v_cosx=np.cos(2.*np.pi/100*ds.x))
ds = ds.assign(v_y=ds.y*1.)
ds['v'] = ds.v_cost*ds.v_cosx*ds.v_y
ds0 = ds
ds = ds0.chunk({'t': nt/2})
ds.to_zarr('data_t.zarr', mode='w')
# method 1: t then x
ds = xr.open_zarr('data_t.zarr')
ds = ds.chunk({'t': nt, 'x': nx/2}) # equivalent to rechunking along t then x
dot_graph(ds.v.data.dask)
这将输出以下图形:
但是,如果我们这样做:
# method 2: x then t
ds = xr.open_zarr('data_t.zarr')
ds = ds.chunk({'x': nx/2})
ds = ds.chunk({'t': nt})
dot_graph(ds.v.data.dask)
它导致下图:
因此,我的天真印象是第一个方法(先t然后x)导致较少的操作(对于调度程序来说更好),但是可能需要更多的内存(concatenate3圈)。 另一方面,第二种方法具有更复杂的图,这可能会给调度程序带来更大的负担,但似乎只能处理较小的数据集
另外:
您能否确认dask中的操作大小没有意义?
矩形和圆形之间有什么区别?
谢谢