Dagger 是一个核心库之外并行计算的框架。它借鉴了Python 的 并行计算框架 Dask。它可以在许多Julia工作进程上以向无环图(DAGs)的形式高效地运行计算任务。DAGs 的数据结构就是Thunk,DAGs中每个节点成为Chunk。一个
Chunk的输出可以成为下一个
Chunk的输入参数。目前看
Chunk 都是延迟计算的。
核心函数
delayed(f; options...)
f :是一个给定输入的函数。
options... :包含一些控制DAGs的运行的可选参数。
get_result::Bool
——将实际结果返回给调度程序,而不是块对象。当f显式地构造块或当返回值很小时(例如,在reduce的情况下)使用meta::Bool
——将输入“Chunk”对象本身传递给f,而不是其中包含的值——这总是在主进程上运行persist::Bool
——此Thunk的结果在DAG中未使用后不应释放cache::Bool
——缓存这个Thunk的结果,这样如果再次计算Thunk,就可以重用缓存的值。如果它已从缓存中删除,请重新计算该值。
collect(ctx::Context, chunk::Chunk), 获取计算结果
compute(ctx, d::Thunk),创建一个完整的DAGs.
例子
下面是一个DAGs的计算拓扑图
简单的计算,并获取计算结果
using Dagger
add1(value) = value + 1
add2(value) = value + 2
combine(a...) = sum(a)
p = delayed(add1)(4)
q = delayed(add2)(p)
r = delayed(add1)(3)
s = delayed(combine,get_result=true,meta=true)(p, q, r)
@assert collect(s) == 16
生成DAGs图
using Dagger
add1(value) = value + 1
add2(value) = value + 2
combine(a...) = sum(a)
p = delayed(add1)(4)
q = delayed(add2)(p)
r = delayed(add1)(3)
s = delayed(combine,get_result=true,meta=true)(p, q, r)
group(x...) = [x...]
top_node = delayed(group)(p,q,r,s)
compute(top_node)
#Dagger.Chunk{Any,MemPool.DRef}(Array{Int64,1}, ArrayDomain{1}((1:4,)), MemPool.DRef(1, 6, 0x0000000000000020), false)
#ArrayDomain{1}((1:4,)) 可以看到,计算共有4个步骤
collect(top_node)#获取每个步骤的计算结果
# 4-element Array{Int64,1}:
# 5
# 7
# 4
# 16
其他高级特性
我简单尝试了下,像SchedulerOptions, ThunkOptions等还无法正常使用,最起码在julia 1.0.5版本还无法使用。所以要用的话,用一些简单的功能就好了。但是一定要注意性能问题。