我们有一个相对复杂的科学模型(https://github.com/OGGM/oggm/),它使用自制的多处理解决方案将工作分解为所谓的实体任务。
每个实体任务都在名为gdir的GlacierDirectory上运行。 它从字面上代表磁盘上的目录,其中包含该冰川的所有数据。 然后,每个实体任务都会下载原始数据文件(如果需要,还不存在,则从互联网下载),打开它们或来自先前实体任务的文件,对其进行处理,并将其写入gdir中的新文件中。
这显然不是很有效,并且不能很好地扩展超过一台机器。 最重要的是,模型具有大量的全局变量和状态。我已经开始着手将所有全局状态放入一个主要的OGGM类中,因此,在全局OGGM类的一个实例中,您可以拥有所有的状态而不是全局状态。
现在,我想替换目前手动执行的所有多重处理(有关主要功能,请参见https://github.com/OGGM/oggm/blob/master/oggm/workflow.py#L104)。 我无法一次迁移整个模型,因此需要某种缓慢的过渡。
我当前的想法是从以轻巧的方式替换当前的object_task模型开始,对任务本身进行最少的修改。
为此,我的想法是修改我们的entity_task包装器,使其始终返回作为输入获得的gdir,从而可以通过将前一个返回的(延迟的)返回值作为输入来完成多个实体任务的链接。下一个。
现在是实际问题... Dask文档在多个地方提到不要更改输入(https://docs.dask.org/en/latest/delayed-best-practices.html#don-t-mutate-inputs)。但是,我将非常变异输入gdir,甚至以其变异形式返回它。 为每个实体任务调用copy(gdir)似乎很浪费,特别是在将来我开始将数据实际存储在其中而不是将其写入磁盘然后从磁盘读回时。 处理此问题的正确方法是什么?
每个gdir也具有/将具有对oggm实例的引用,该实例将存储当前的全局状态。当我们开始跨多个物理节点分配任务时,这对我来说似乎很成问题。它会为每个函数调用继续复制我们的正式全局状态吗?它会意识到这都是相同的实例,并且仅将其复制到每个工作进程一次吗? 在不同的entity_tasks之间进行更改时会发生什么?随着它们现在被延迟,更改可能会丢失,我们需要一个新的helper-entity-task,以gdir作为输入,通过它修改oggm实例状态,然后再次返回gdir。 这使我回到了使延迟函数的输入对象发生变异的问题。
非常欢迎您提供有关此迁移的任何帮助,我对Dask的经验很少,仅阅读到目前为止的文档和示例已证明非常具有挑战性。