我有大量的defaultdict(dict)
的numpy数组。我想将其保存在共享内存中,并在其完全形成后使用它进行写入。
我正在为此目的使用joblib。
from collections import defaultdict import os, tempfile from joblib import Parallel, delayed, load, dump import numpy as np def mean(data, i): return np.mean([np.mean(data[i][j]) for j in data[i]]) class BigData(object): def __init__(self, tmp_dir="/mnt/", workers = 10): self.big_data = defaultdict(dict) self.workers = workers assert os.path.isdir(tmp_dir), "tmp_dir does not exists" self.temp_folder = tempfile.mkdtemp(dir=tmp_dir) filename = os.path.join(self.temp_folder, "big_data.json") if os.path.exists(filename): os.unlink(filename) dump(self.big_data, filename) self.big_data = load(filename, mmap_mode="w+") print("Memory map of big_data: {}".format(filename)) self.fill_big_data() # dump(self.big_data, filename) # self.big_data = load(filename, mmap_mode="r+") self.use_big_data() def fill_big_data(self): for i in range(100): for j in range(10): self.big_data[i][j] = list(np.ones(int(1e6))) def use_big_data(self): results = Parallel(n_jobs = self.workers)(delayed(mean)(self.big_data,i) for i in range(10)) print(results) bd = BigData(tmp_dir="/mnt/tmp_data")
上面是我想要做的一个玩具示例。我不想将self.big_data
更改为numpy array
。
执行Parallel时,此代码崩溃。如果我正确理解,joblib
将使用提供的参数在后端运行几个独立的进程。每个进程的参数将被复制,因此将self.big_data传递给多个进程变得不可行。
但是,当我创建memmap
的{{1}}时,似乎是将其填充到内存中,而不是实际写入文件中。我知道这样做是因为否则速度会成为问题。
我想假设,由于self.big_data
是self.big_data
,因此在调用Parallel时,进程应该将指针传递到memmap
。相反,它将为每个进程复制整个字典。
传递temp_folder似乎也无济于事。
Parallel(n_jobs = self.workers, temp_folder="/mnt/")(delayed(mean)(self.big_data,i) for i in range(10))
当将memmap作为指针而不是数据结构传递时,有人可以阐明一下吗?