私は dask 遅延関数を使用しており@dask.delayed、関数でデコレータを使用する際のすべきこととすべきでないことに慣れてきました。compute()ベスト プラクティスに従っていると思っていたにもかかわらず、結果を得るために 2 回電話する必要がある場合があることに気付きました。つまり、別の dask 遅延関数内で dask 遅延関数を呼び出さないでください。
この問題は 2 つのシナリオで発生しました。ネストされた関数がある場合と、遅延オブジェクトであるクラス メンバーを使用するクラスでメンバー関数を呼び出す場合です。
@dask.delayed
def add(a, b):
return a + b
def inc(a):
return add(a, 1)
@dask.delayed
def foo(x):
return inc(x)
x = foo(3)
x.compute()
class Add():
def __init__(self, a, b):
self.a = a
self.b = b
@dask.delayed
def calc(self):
return self.a+self.b
a = dask.delayed(1)
b = dask.delayed(2)
add = Add(a, b)
add.calc().compute()
最初の例でx.compute()は、結果は返されませんが、別の遅延オブジェクトが返さx.compute().compute()れるため、実際の結果を取得するには呼び出す必要があります。しかし、 inc は遅延関数ではないため、別の遅延関数内で遅延関数を呼び出さないという規則に違反していないと思いますか?
add.calc().compute().compute()2 番目の例でも、実際の結果を取得するために呼び出す必要があります。この場合self.a、 とself.bは単なる遅延属性であり、ネストされた遅延関数はどこにもありません。
compute()これら2つのケースで2回電話する必要がある理由を誰かが理解するのを手伝ってくれますか? またはさらに良いことに、dask遅延機能を使用するときの一般的な「ルール」を誰かが簡単に説明できますか? 私はドキュメントを読みましたが、それほど多くはありません。
compute()更新: @malbertは、遅延関数に関連する遅延結果があり、「別の遅延関数内での遅延関数の呼び出し」としてカウントされるため、例では 2 回呼び出す必要があると指摘しました。しかし、なぜ次のようなものは一度だけ呼び出す必要があるのcompute()でしょうか?
@dask.delayed
def add(a,b):
return a+b
a = dask.delayed(1)
b = dask.delayed(2)
c = add(a,b)
c.compute()
この例では、aとbも両方とも遅延結果であり、遅延関数で使用されています。私のランダムな推測は、実際に重要なのは、遅延された結果が遅延関数のどこにあるかということですか? それらが引数として渡された場合にのみ、おそらく問題ありませんか?