Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何避免任务图中的大型对象_Python_Dask_Dask Distributed_Dask Delayed - Fatal编程技术网

Python 如何避免任务图中的大型对象

Python 如何避免任务图中的大型对象,python,dask,dask-distributed,dask-delayed,Python,Dask,Dask Distributed,Dask Delayed,我正在使用dask.distributed运行模拟。我的模型是在一个延迟函数中定义的,我堆叠了几个实现。 以下代码片段给出了我所做工作的简化版本: import numpy as np import xarray as xr import dask.array as da import dask from dask.distributed import Client from itertools import repeat @dask.delayed def run_model(n_time

我正在使用dask.distributed运行模拟。我的模型是在一个延迟函数中定义的,我堆叠了几个实现。 以下代码片段给出了我所做工作的简化版本:

import numpy as np
import xarray as xr
import dask.array as da
import dask
from dask.distributed import Client
from itertools import repeat 

@dask.delayed
def run_model(n_time,a,b):
    result = np.array([a*np.random.randn(n_time)+b])
    return result

client = Client()

# Parameters
n_sims = 10000
n_time = 100
a_vals = np.random.randn(n_sims)
b_vals = np.random.randn(n_sims)
output_file = 'out.nc'

# Run simulations
out = da.stack([da.from_delayed(run_model(n_time,a,b),(1,n_time,),np.float64) for a,b in zip(a_vals, b_vals)])

# Store output in a dataframe
ds = xr.Dataset({'var1': (['realization', 'time'], out[:,0,:])},
             coords={'realization': np.arange(n_sims),
                     'time': np.arange(n_time)*.1})

# Save to a netcdf file -> at this point, computations will be carried out
ds.to_netcdf(output_file)
如果我想运行大量模拟,我会得到以下警告:

/home/user/miniconda3/lib/python3.6/site-packages/distributed/worker.py:840: UserWarning: Large object of size 2.73 MB detected in task graph: 
  ("('getitem-32103d4a23823ad4f97dcb3faed7cf07', 0,  ... cd39>]), False)
Consider scattering large objects ahead of time
with client.scatter to reduce scheduler burden and keep data on workers

    future = client.submit(func, big_data)    # bad

    big_future = client.scatter(big_data)     # good
    future = client.submit(func, big_future)  # good
  % (format_bytes(len(b)), s))
据我所知(来自和问题),警告提出的方法有助于将大数据导入函数。然而,我的输入都是标量值,所以它们不应该占用近3MB的内存。即使函数
run\u model()
根本不接受任何参数(因此没有传递任何参数),我也会收到相同的警告

我还查看了任务图,以查看是否存在需要加载大量数据的步骤。对于三种实现,它如下所示:

因此,在我看来,每一个实现都是单独处理的,这将使要处理的数据量保持在较低的水平


我想了解产生大型对象的步骤是什么,以及我需要做什么才能将其分解为更小的部分。

在这种情况下,信息有点误导。这一问题可以从以下方面得到证明:

> len(out[:, 0, :].dask)
40000
> out[:, 0, :].npartitions
10000
该图的pickle大小(其头部是消息中的
getitem
键)是~3MB。通过为计算的每个元素创建一个dask数组,您将得到一个具有与元素一样多的分区的堆叠数组,模型运行操作、项选择以及存储操作将应用于每个元素并存储在图形中。是的,它们是独立的,整个计算可能会完成,但这都是非常浪费的,除非建模函数在每个输入标量上运行相当长的时间


在您的实际情况中,内部数组实际上可能比您提供的单元素版本大,但在对数组执行numpy操作的一般情况下,在辅助对象上创建数组(使用随机或某些加载函数)并在大小>100MB的分区上操作是正常的。

感谢您的解释。为了更好地理解您的答案,我有一些问题:1)代码的第一行计算什么?2) 所有图的大小是3MB还是一个独立图的大小?3)我已经怀疑为每个实现创建一个dask数组会有点过分,尽管我的输出数组稍大一些(虽然不是数量级),并且模型函数(解决ODE系统)比示例中的要长一些。您的建议是否意味着我必须在
run\u model
函数中计算多个实现的模型输出,从而生成更大的输出数组,但dask数组更少?是的,我的建议是:让您的dask delayed函数在每次调用时运行多个模拟,以减少图中的任务总数。40000是图中的键数~任务数(尽管在图优化过程中dask可能会合并一些任务)。请注意,该消息只是一个警告,因此不执行任何操作是一个选项。减少需要写入netcdf文件的块数可能是正确的做法。但在从
dask写入结果时,似乎也存在酸洗问题。延迟
到netcdf: