跳转到主要内容

通过上下文管理器或IPython魔法在Dask集群上运行代码

项目描述

Afar

Python Version Version License Build Status Coverage Status Code style

一个人的魔法是另一个人的工程
罗伯特·A·海因莱因


安装

可以使用pip安装afar

pip install afar

或使用conda

conda install -c conda-forge afar

它是什么?

afar 允许您使用上下文管理器和IPython魔法在远程 Dask 集群 上运行代码。例如

import afar
from dask.distributed import Client
client = Client()

with afar.run, remotely:
    import dask_cudf
    df = dask_cudf.read_parquet("s3://...")
    result = df.sum().compute()

在上下文之外,result 是一个数据位于工作者的 Dask Future。需要result.result()来复制数据到本地。

默认情况下,仅保存最后一个赋值。可以指定要保存哪些变量

with afar.run("one", "two"), remotely:
    one = 1
    two = one + 1

onetwo 现在都是Futures。它们可以直接用于其他afar.run上下文

with afar.run as data, remotely:
    three = one + two

assert three.result() == 3
assert data["three"].result() == 3

上面的data是一个变量名到Futures的字典。有时可能需要从这里获取数据。或者,您可以将映射传递给afar.run以用作数据。

run = afar.run(data={"four": 4})
with run, remotely:
    seven = three + four
assert run.data["seven"].result() == 7

如果您想自动将数据收集到本地(以避免调用.result()),请使用afar.get而不是afar.run

with afar.get, remotely:
    five = two + three
assert five == 5

Jupyter中的交互性

在Jupyter Notebook、Qt控制台、JupyterLab或任何支持丰富显示的基于IPython的前端中使用afar时,有几个增强功能。

如果最终表达式不是赋值,则将显示其丰富的repr。

with afar.run, remotely:
    three + seven
# displays 10!

打印被捕获并在本地显示

with afar.run, remotely:
    print(three)
    print(seven, file=sys.stderr)
# 3
# 7

这些操作是通过ipywidgets异步完成的。

魔法!

首先加载afar魔法扩展

%load_ext afar

现在您可以使用 afar 作为行或单元格魔法。 %%afar 类似于 with afar.run, remotely:。它可以可选地接受一个变量名列表以保存。

%%afar x, y
x = 1
y = x + 1

并且

z = %afar x + y

这是一个好主意吗?

我不知道,但使用它确实是一种乐趣 😃 !

关于动力,请参阅 https://github.com/dask/distributed/issues/4003

对于非传统语法和魔法,人们通常会持怀疑态度。 afar 既是非传统的也是神奇的,但它也工作得很好,并且出人意料地 有趣!为什么不试一试看看您认为如何?

我们仍在探索 afar 的可用性 并想听听您的看法。在您学习 afar 的过程中,请自己问一些问题,例如

  • 我们能拼写得更好吗?
  • 这提供了哪些机会?
  • 什么是令人惊讶的?
  • 什么是缺乏的?

这是一个机会的例子

on_gpus = afar.remotely(resources={"GPU": 1})

with afar.run, on_gpus:
    ...

现在它工作了!传递给 remotely 的关键字参数将被传递给 client.submit

我不知道您是否如此,但我认为这开始看起来和感觉有点好,可能还可以更好 :)

注意事项和陷阱

重复复制数据

afar 会自动从外部作用域获取所需的数据--只有所需的数据--并将其发送到 Dask 集群进行计算。由于我们不知道在调用 afar 之间本地数据是否已被修改,我们每次使用 runget 时都会序列化和发送本地变量。这通常是正常的:它工作,它是安全的,并且通常足够快。但是,如果您经常使用相对较大的数据执行此操作,性能可能会受到影响,并且您可能在本地机器上使用了不必要的更多内存。

在 Dask 中,一个常见的模式是使用 scatter 将数据发送到集群,并返回一个 Future。这有效

A = np.arange(10**7)
A = client.scatter(A)
with afar.run, remotely:
    B = A + 1
# A and B are now both Futures; their data is on the cluster

另一个选项是将 data 传递给 run

run = afar.run(data={"A": np.arange(10**7)})
with afar.run, remotely:
    B = A + 1
# run.data["A"] and B are now both Futures; their data is on the cluster

如果您在一个 IPython 笔记本中,这里有一个巧妙的技巧:使用 data=globals()

run = afar.run(data=globals())
A = np.arange(10**7)
with run, remotely:
    B = A + 1
# A and B are now both Futures; their data is on the cluster

修改远程数据

与任何 Dask 工作负载一样,应小心不要修改可能被重用的远程数据。

修改本地数据

同样,在远程运行的代码无法修改本地变量。例如

d = {}
with afar.run, remotely:
    d['key'] = 'value'
# d == {}

✨ 这段代码非常实验性和神奇!✨

项目详情


下载文件

为您的平台下载文件。如果您不确定选择哪一个,请了解更多关于 安装包 的信息。

源分发

afar-0.6.1.tar.gz (35.6 kB 查看哈希)

上传时间

构建分发

afar-0.6.1-py3-none-any.whl (20.0 kB 查看哈希)

上传于 Python 3

支持