我在尝试并行化的地方有以下代码:
import numpy as np
from joblib import Parallel, delayed
lst = [[0.0, 1, 2], [3, 4, 5], [6, 7, 8]]
arr = np.array(lst)
w, v = np.linalg.eigh(arr)
def proj_func(i):
return np.dot(v[:,i].reshape(-1, 1), v[:,i].reshape(1, -1))
proj = Parallel(n_jobs=-1)(delayed(proj_func)(i) for i in range(len(w)))
proj
返回一个非常大的列表,这会导致内存问题。
我有办法解决这个问题吗?我曾考虑过要返回一个生成器而不是一个列表,但是我不知道该怎么做。任何其他方式也将受到欢迎。
非常感谢。
Q:“有没有办法可以解决this?”
那到底取决于什么[this
代表。
如上所述,鉴于您的MCVE,MEMORY的大小取决于N = arr.size
并且您的系统至少具有:-N * 3 * 8 [B]
RAM,用于容纳lst, arr, w
-[N * N * 8 [B]
用于保存v
]的RAM>
总共,必须有比[[<n_CPUs_> * 8 * N * ( 3 + N ) [B]
n_jobs == -1
python解释器过程的完整副本(对于MacOS / WinOS绝对是这样,对于linux,因为fork / method在2019/2020年被记录为产生不稳定/不安全的结果)之前代码甚至试图进行[C0的第一次调用如果这不是您系统的容量,则可以直接停止阅读。proj_func( i )
N
的调用,每个调用都增加了-[proj_func( i )
RAM空间的额外RAM分配,用于保存N * N * 8 [B]
-结果总共超过[[np.dot()
个用于保存k * N * N * N * 8 [B]
结果的RAM,其中np.dot()
k >> 2
结果中的每一个必须获得[C0 ]打包(再次为此分配一些RAM空间),然后每个这样的N
-ed-payload必须从远程<< [SER
-executor转发到主进程(这里再次为SER
负载分配了一些RAM空间),接下来,此RAM存储的中间二进制有效负载必须进行joblib.Parallel()(delayed()(...))
序列化(因此再次分配一些额外的RAM-用于存储原始大小为[[SER
的DES
-ed数据的空间,以便最终将此SER / DES管道产品乘以DES
-次并附加到初始N * N * 8 [B]
如上述使用N
子句的指定语法所坚持并强制执行。proj == []
RESUMÉ:这很快就扩展了(即使我们假设没有其他python进程joblib.Parallel(…)( delayed( proj_func )( i ) for i in range( len( w ) ) )
-s和静态数据时),对于任何[<_nCPUs_> * 8 * N * ( 3 + N ) // static storage: data + all python process-replicas + <_nCPUs_> * 8 * N * N * k // dynamic storage: SER/DES on joblib.Parallel()(delayed…) + 8 * N * N * N // collective storage: proj-collected N-( np.dot() )-results ~ = 8 * N * ( N * N + <_nCPUs_> * ( 3 + N * ( k + 1 ) ) )
import
: >N
EPILOGUE:
所以一个简单的SLOC,使用与== arr.size >= 1E3
一样简单的语法,如果至少在原始代码上没有花费适当的设计精力,就可以立即以一种无法挽救的方式破坏整个计算图的全部工作。数据处理定量估计。