我試圖計算一個矩陣X的大小爲10,000 * 800,000的矩陣乘積Y = XX^T。矩陣X存儲在磁盤上的一個h5py文件中。生成的Y應該是存儲在同一個h5py文件中的10,000 * 10,000矩陣。這是一個可重現的示例代碼。dask核心外矩陣乘法調度
import dask.array as da
from blaze import into
into("h5py:///tmp/dummy::/X", da.ones((10**4, 8*10**5), chunks=(10**4,10**4)))
x = into(da.Array, "h5py:///tmp/dummy::/X", chunks=(10**4,10**4)))
y = x.dot(x.T)
into("h5py:///tmp/dummy::/Y", y)
我預計計算,以順利進行,因爲每個(10,000 * 10,000)塊應單獨換位,後面跟着一個點的產品,然後總結出最終結果。但是,運行此計算會填充我的RAM和交換內存,直到進程最終被終止。
這裏是計算圖的繪製樣品與dot_graph:Computation graph sample
按照SHEDULING文件,讓HTTP://dask.pydata.org/en/latest/scheduling-policy.html 我期望一旦個體計算出來,上面的tensordot中間結果被一個一個地總結爲最後的總和結果。這將釋放這些tensordot中間結果的記憶,以便我們不會面對記憶錯誤。
用較小的玩具如玩周圍:
from dask.diagnostics import Profiler, CacheProfiler, ResourceProfiler
# Experiment on a (1,0000 * 5,000) matrix X split into 500 chunks of size (1,000 * 10)
x = into(da.Array, "h5py:///tmp/dummy::/X", chunks=(10**3,10)))[:10**3,5000]
y = x.T.dot(x)
with Profiler() as prof, CacheProfiler() as cprof, ResourceProfiler() as rprof:
into("h5py:///tmp/dummy::/X", y)
rprof.visualize()
我得到以下顯示: Ressource profiler
凡綠條代表和操作,而黃色和紫色柱代表分別get_array和tensordot操作。這似乎表明總和操作在總結它們之前等待所有中間tensordot操作被執行。這也將解釋我的流程耗盡內存並被殺死。
所以我的問題是:
- 是該和操作的正常行爲?
- 有沒有辦法強制它計算所有中間產品tensordot產品計算並保存在內存中的中間和?
- 如果沒有,是否有解決方案不涉及溢出到磁盤?
任何幫助非常感謝!
非常感謝@MRocklin! – Grin
關於選項3,我遇到了https://github.com/dask/distributed/issues/927中提到的問題。 Hdf5序列化陣列似乎不適合分佈式調度器。修復它可以讓我使用分佈式調度程序的實時診斷/監視工具,這在這種情況下非常有用。另外,您是否知道pydata/python生態系統中的專門ooc線性代數庫?我最初開始使用dask是因爲它的核心線性代數特性與Numpy API結合在一起。 – Grin