我最近发现以下语句:
np.savez不是多进程安全的,因为它始终使用
gettempdir()+键+“ .npy”。因此,如果您正在运行相同的脚本
在不同的数据集上,当一个
进程删除另一个进程的/tmp/arr_0.npy。
碰巧的是,我正处于那种情况下,所以我有一个
错误示例:
Traceback (most recent call last): File
"/home/pedro/prospectus/prelim/bbvs/bin/skldthresh", line 99, in <module> main()
File "/home/pedro/prospectus/prelim/bbvs/bin/skldthresh", line 90, in main
np.savez("%smask-t%0.2f" % (outfile,threshold), result)
File "/usr/lib/python2.5/site-packages/numpy/lib/io.py", line 230, in savez
zip.write(filename, arcname=fname)
File "/usr/lib/python2.5/zipfile.py", line 541, in write
st = os.stat(filename) OSError: [Errno 2] No such file or directory: '/tmp/arr_0.npy'
幸运的是,将
tempfile.gettempdir()
替换为tempfile.mkdtemp()
并记得最后用
os.rmdir(direc)
进行清理据我所知,需要修复它。
这到底是什么意思,我个人如何避免这种情况? numpy是否将写入
.npz
文件的数据存储在临时文件中,这些文件的名称可能与其他脚本中的其他.npz
临时文件一样?我进行了一些科学实验,历时数小时,并通过
np.savez
保存结果。 savez
保存的结果的目标路径是不同的,因此每个实验都有自己的结果路径。但是,它们脚本本身位于同一目录中。有趣的是,脚本有时会在此错误发生前几个小时运行:
> Traceback (most recent call last): File
> "/work/var/slurmd/state.node348.d/job20832/slurm_script", line 53, in
> <module>
> E = Exp6_06() File
> "/work/experiments/s06/cs06_ex06.py", line
> 150, in __init__
> self.__start() File "/work/experiments/s06/cs06_ex06.py", line
> 374, in __start
> File "/home/fx092/.local/lib/python2.7/site-packages/numpy/lib/npyio.py",
> line 600, in savez_compressed
> _savez(file, args, kwds, True) File "/home/fx092/.local/lib/python2.7/site-packages/numpy/lib/npyio.py",
> line 630, in _savez
> fd, tmpfile = tempfile.mkstemp(suffix='-numpy.npy') File "/sw/env/openmpi/2Q4/lib/python2.7/tempfile.py",
> line 314, in mkstemp
> return _mkstemp_inner(dir, prefix, suffix, flags) File "/sw/env/openmpi/2Q4/lib/python2.7/tempfile.py",
> line 244, in _mkstemp_inner
> fd = _os.open(file, flags, 0600) OSError: [Errno 2] No such file or directory:
> '/work/tmp/node001.admin.2016-03-06-152506.fx092.27432/tmp5UulEz-numpy.npy'
使用的numpy版本:1.10.4
最佳答案
您的错误发生在mkstemp
中。引号建议使用mkdtemp
代替:
https://docs.python.org/2/library/tempfile.html
tempfile.mkstemp([后缀=''[,prefix ='tmp'[,dir = None [,text = False]]]]))
以最安全的方式创建一个临时文件。假设平台正确实现了os.open()的os.O_EXCL标志,则文件的创建中没有竞争条件。该文件只能由创建用户ID来读写。如果平台使用权限位指示文件是否可执行,则该文件无人可执行。文件描述符不被子进程继承。
和
tempfile.mkdtemp([后缀=''[,前缀='tmp'[,dir =无]]])
以最安全的方式创建一个临时目录。目录的创建中没有竞争条件。该目录只有创建用户ID才可读,可写和可搜索。
mkdtemp()的用户负责在完成后删除临时目录及其内容。
创建临时文件并将其收集到zip
后,似乎会出现引用的错误。创建一个临时文件时,您的错误似乎发生了。
我还没有足够使用这些功能来理解它们之间的区别。
我们可能需要在_savez
中学习lib/npyio.py
。
您正在使用什么操作系统? Linux,Mac,Windows?
这是_savez
的核心,现在在lib/npyio.py
文件中:
def _savez(file, args, kwds, compress):
....
zip = zipfile_factory(file, mode="w", compression=compression)
# Stage arrays in a temporary file on disk, before writing to zip.
=> fd, tmpfile = tempfile.mkstemp(suffix='-numpy.npy')
os.close(fd)
try:
for key, val in namedict.items():
fname = key + '.npy'
fid = open(tmpfile, 'wb')
try:
format.write_array(fid, np.asanyarray(val))
fid.close()
fid = None
=> zip.write(tmpfile, arcname=fname)
finally:
if fid:
fid.close()
finally:
os.remove(tmpfile)
zip.close()
当将临时“保存”文件添加到归档文件时,引用的错误会在循环快结束时发生。当您获取临时目录和临时文件(fd)时,您的错误就会提前发生。请注意,该操作将放弃打开文件句柄,而仅使用名称(每个数组重复此名称)。
令人惊讶的是,temp目录在
mkstemp
函数调用期间应该消失了。几乎感觉像是一个openmpi
问题,而不是savez
问题。关于python - Numpy Savez异常(exception),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35836054/