python – Scipy Sparse Eigensolver:多次通过循环后的MemoryError,在循环期间没有任何新的写入
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – Scipy Sparse Eigensolver:多次通过循环后的MemoryError,在循环期间没有任何新的写入,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2915字,纯文字阅读大概需要5分钟。
内容图文
![python – Scipy Sparse Eigensolver:多次通过循环后的MemoryError,在循环期间没有任何新的写入](/upload/InfoBanner/zyjiaocheng/794/9eafb24450694459aead789c2dbff7eb.jpg)
我正在使用Python Scipy来对齐化对角线上的随机条目的稀疏矩阵;特别是,我需要在光谱中间的特征值.我写的代码已经好几个月了,但现在我正在研究更大的矩阵并且遇到了“MemoryError”.让我感到困惑的是,这个错误只会在构建随机矩阵并对其进行对角化的几次迭代(即9次)之后出现,但是我没有看到任何方式我的代码在一次迭代中存储了额外的内存到了下一个,所以无法看到我的代码在第9次迭代期间如何失败而不是第1次.
以下是详细信息(如果我遗漏了任何内容,我会提前道歉,我很想在这个网站上发帖):
我构造的每个矩阵是16000×16000,具有15×16000非零条目.当我查看4000×4000大小的矩阵时,一切都运行良好.我的大部分代码都是
#Initialization
#...
for i in range(dim):
for n in range(N):
digit = (i % 2**(n+1)) / 2**n
index = (i % 2**n) + ((digit + 1) % 2)*(2**n) + (i / 2**(n+1))*(2**(n+1))
row[dim + N*i + n] = index
col[dim + N*i + n] = i
dat[dim + N*i + n] = -G
e_list = open(e_list_name + "_%03dk_%010ds" % (num_states, int(start_time)), "w")
e_log = open(e_log_name + "_%03dk_%010ds" % (num_states, int(start_time)), "w")
for t in range(num_itr): #Begin iterations
dat[0:dim] = math.sqrt(N/2.0)*np.random.randn(dim) #Get new diagonal elements
H = sparse.csr_matrix((dat, (row, col))) #Construct new matrix
vals = sparse.linalg.eigsh(H, k = num_states + 2, sigma = target_energy, which = 'LM', return_eigenvectors = False) #Get new eigenvalues
vals = np.sort(vals)
vals.tofile(e_list)
e_log.write("Iter %d complete\n" % (t+1))
e_list.flush()
e_log.flush()
e_list.close()
e_log.close()
我一直在设置num_itr为100.在第9次通过num_itr循环期间(如8行已写入e_log所示),程序崩溃并显示错误消息
Can’t expand MemType 0: jcol 7438
Traceback (most recent call last):
06001
MemoryError
果然,每次在我的机器上运行时,程序都会在第9次通过循环期间失败,当我尝试在具有更多内存的机器上运行此代码时,程序会在崩溃之前通过更多迭代,所以它看起来像电脑真的耗尽了内存.如果这就是它的全部,那么很好,但我无法理解的是为什么程序在第一次迭代期间不会崩溃.我没有在num_itr循环的8行中看到任何一点,在这些行中,某些内容被写入内存而不会在下一次迭代中被覆盖.我已经使用了Heapy的heap()函数来查看我的内存使用情况,并且它在每次传递时都打印出“Total size = 11715240 bytes”.
我觉得有一些基本的东西,我只是不知道在这里发生,要么是我写的一些我不知道要查找的错误,或者有关如何处理内存的一些细节.任何人都可以向我解释为什么这个代码在第9次传递期间通过num_itr循环而不是第1次失败?
解决方法:
好吧,这似乎可以在Scipy 0.14.0上重现.
显然可以通过添加来解决这个问题
import gc; gc.collect()
在循环内部强制Pythons循环垃圾收集器运行.
问题出现在scipy.sparse.eigh里面的某个地方有一个循环引用循环,依次是:
class Foo(object):
pass
a = Foo()
b = Foo()
a.spam = b
b.spam = a
del a, b # <- but a, b still refer to each other and are not dead
原则上这仍然完全可以:虽然Python的引用计数不会检测到这样的循环垃圾,但是会定期运行集合来收集这些对象.但是,如果每个对象在内存中都非常大(例如,大Numpy数组),则定期运行过于频繁,并且在下一次循环垃圾收集运行完成之前就会耗尽内存.
因此,当您知道要收集大量垃圾时,解决方法是强制GC运行.
更好的解决方法是更改??scipy.sparse.eigh,以便首先不生成此类循环垃圾.
内容总结
以上是互联网集市为您收集整理的python – Scipy Sparse Eigensolver:多次通过循环后的MemoryError,在循环期间没有任何新的写入全部内容,希望文章能够帮你解决python – Scipy Sparse Eigensolver:多次通过循环后的MemoryError,在循环期间没有任何新的写入所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。