简体   繁体   English

Memory for 循环和算术运算中大型 numpy arrays 的使用问题

[英]Memory usage issue for large numpy arrays within the for loop & arithmetic operations

I am quite new to python.我对 python 很陌生。 I have a implicit time integration for loop, that is, next step depends on the previous step.我有一个隐式的循环时间积分,即下一步取决于上一步。 Basically, I am trying to solve the time integration for all different cases by utilizing broadcast feature of numpy arrays without utilizing more for loops.基本上,我试图通过利用 numpy arrays 的广播功能来解决所有不同情况的时间积分,而不使用更多的循环。 Thus, I have large arrays.因此,我有大的 arrays。

The loop takes short time to run (2.5s) but while conducting the operations within the for loops my RAM (8 GB) reaches nearly its capacity.该循环运行时间很短(2.5 秒),但在 for 循环中执行操作时,我的 RAM(8 GB)几乎达到其容量。 Therefore, there is a memory usage issue I am trying to overcome.因此,我试图克服一个 memory 使用问题。

ndata = 9624
u.shape = (3, 9624, 11, 3, 1000)
p.shape = (9624, 11, 1, 1000)
a1.shape = (11, 3, 1000)
a2.shape = (11, 3, 1000)
a3.shape = (11, 3, 1000)
p_star.shape = (11, 3, 1000)
delta_t.shape =(11, 1, 1)
k_star.shape =(11, 3, 1000)

for i in range(0,ndata-1):
    p_star = p[i+1] + a1 * u[0,i] + a2 * u[1,i] + a3 * u[2,i]
    u[0,i+1] = p_star / k_star
    u[1,i+1] = gama * (u[0,i+1]-u[0,i]) / (beta * delta_t) + u[1,i] * (1 - gama/beta) + delta_t * u[2,i] * (1 - gama/(2*beta))
    u[2,i+1] = (u[0,i+1]-u[0,i]) / (beta * (delta_t ** 2)) - u[1,i] / (beta * delta_t) - u[2,i] * ((1 / (2*beta)) - 1)

You can see memory usage in the loop here您可以在此处的循环中查看 memory 用法

During the aritmatic operations, the temporary copies of the arrays are created and assigned.在计算操作期间,会创建并分配 arrays 的临时副本。 I think main issue here is creation the copies of the arrays.我认为这里的主要问题是创建 arrays 的副本。 To overcome this issue, arithmatic operations should be conducted in-place.为了克服这个问题,应该就地进行算术运算。

To conduct these operations, as far as I know, optional argument out= of numpy ufuncs should be defined or += -= *= /= should be used.要进行这些操作,据我所知,应该定义 numpy ufuncs 的可选参数out=或者应该使用 += -= *= /= 。 For example, numpy.sum(a1,a2, out=a1) .例如, numpy.sum(a1,a2, out=a1)

But in order to conduct above mentioned operations in in-place fashion I have to define a lot of auxiliary (or buffer) variables.但是为了以就地方式进行上述操作,我必须定义很多辅助(或缓冲区)变量。 My question is what is the optimal way to decrease this memory usage.我的问题是减少这种 memory 使用的最佳方法是什么。 I believe that, in python, there must be a elegant way to do these type of arithmetic operations in-place.我相信,在 python 中,必须有一种优雅的方式来就地执行这些类型的算术运算。

I am open to other suggestions as well.我也愿意接受其他建议。

buff1 = np.zeros_like(u[0,0])
buff2 = np.zeros_like(u[0,0])
buff3 = np.zeros_like(u[0,0])
buff4 = np.zeros_like(u[0,0])
for i in range(0,ndata-1):
    # first line
    np.multiply(a1, u[0,i], out = buff1);
    np.multiply(a2, u[1,i], out = buff2);
    np.multiply(a3, u[2,i], out = buff3);
    buff1 += p[i+1];
    buff1 += buff2;
    buff1 += buff3;
    #second line
    np.divide(buff1, k_star, out = u[0,i+1])
    #third line
    np.subtract(u[0,i+1], u[0,i], out = buff1);
    buff1 *= gama
    buff1 /= beta
    buff1 /= delta_t
    np.divide(gama,beta, out = buff2)
    np.subtract(1, buff2, out=buff2)
    np.multiply(u[1,i], buff2, out=buff2)
    np.multiply(2, beta, out = buff3)
    np.divide(gama, buff3, out = buff3)
    np.subtract(1, buff3, out = buff3)
    np.multiply(u[2,i], buff3, out = buff3)
    np.multiply(delta_t, buff3, out = buff3)
    np.add(buff1, buff2, out = u[1,i+1])
    np.add(buff3, u[1,i+1], out = u[1,i+1])
    #last line goes like that
    

The problem is actually the size of the arrays p and u.问题实际上是 arrays p 和 u 的大小。 Combined, they are made of roughly a billion floats, each represented with 64 bits.结合起来,它们由大约十亿个浮点数组成,每个浮点数用 64 位表示。 Or, in total, 8 GBs.或者,总共 8 GB。 I am afraid that there is not much that you can do about it if you need to keep all 9264 time steps -- of course the situation changes if you can keep only the two last time steps.如果您需要保留所有 9264 个时间步,恐怕您无能为力——当然,如果您只能保留最后两个时间步,情况就会改变。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM