我使用python中的多处理来计算几个迭代中的EcoInvent v3.2数据库中所有功能单元的LCA结果。
代码如下:
for worker_id in range(CPUS):
# Create child processes that can work apart from parent process
child = mp.Process(target=worker_process, args=(projects.current, output_dir, worker_id, activities, ITERATIONS, status))
workers.append(child)
child.start()
print(workers)
while any(i.is_alive() for i in workers):
time.sleep(0.1)
while not status.empty():
# Flush queue of progress reports
worker, completed = status.get()
progress[worker] = completed
progbar.update(sum(progress.values()))
progbar.finish()
定义worker_process
函数如下:
def worker_process(project, output_dir, worker_id, activities, iterations, progress_queue):
# Project is string; project name in Brightway2
# output_dir is a string
# worker_id is an integer
# activities is a list of dictionaries
# iterations is an integer
# progress_queue is a Queue where we can report progress to parent process
projects.set_current(project, writable=False)
lca = DirectSolvingPVLCA(activities[0])
lca.load_data()
samples = np.empty((iterations, lca.params.shape[0]))
supply_arrays = np.empty((iterations, len(activities), len(lca.product_dict)))
for index in range(iterations):
lca.rebuild_all()
samples[index, :] = lca.sample
lca.decompose_technosphere()
for act_index, fu in enumerate(activities):
lca.build_demand_array(fu)
supply_arrays[index, act_index, :] = lca.solve_linear_system()
progress_queue.put((worker_id, index))
观察到的问题是:
对于两名以上的工人,除两个工人外,两名工人都立即从
MemoryError
死亡(见下文)。对于两个幸存的工人来说,该代码似乎适用于10、100或5000个功能单元,但是当我们要求所有FUS时,它会分解并陷入相同的
MemoryError
。
此MemoryError
发生在每个 x 过程中:
Process Process-X:
Traceback (most recent call last):
File "C:bw2-pythonenvsbw2libmultiprocessingprocess.py", line 254, in_bootstrap
self.run()
File "C:bw2-pythonenvsbw2libmultiprocessingprocess.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "C:testDo all the calculations.py", line 49, in worker_process
supply_arrays = np.empty((iterations, len(activities), len(lca.product_dict)))
MemoryError
我的问题是:
为什么会发生这种情况?
如何解决这个问题?
您因为使用了太多内存而用完了内存。
当您使用以下方式分配新数组时:
np.empty((iterations, len(activities), len(lca.product_dict)))
和 activities
和 lca.product_dict
每个的长度为10.000,您使用的是10.000 * 10.000 * 8(假设您的默认float为64位,或8个字节)=每个迭代和每个工作过程的800 mb RAM。
一个简单的解决方案是在带有大量RAM的服务器上工作。
在内存中创建这些大数组的替代方法包括:
- 使用PYTABLES或H5PY
- 使用Numpy的
memmap
。
无论哪种情况,您都需要测试特定工作流和操作系统的最有效的编写和读取数据的方法。