目标/问题
在Python中,我正在寻找快速读写内存映射文件中的数据到GPU的方法。
在之前的一个SO溢出帖子中[Cupy OutOfMemoryError when trying to cupy.load larger dimension .npy files in memory map mode, but np.load works fine]
提到了使用CUDA固定的“零拷贝”内存可能是可行的。此外,似乎这种方法是由这个人开发的[ cuda - Zero-copy memory, memory-mapped file ],虽然那个人是在C++中工作。
我的以前尝试是使用Cupy,但我对任何cuda方法都持开放态度。
我已经尝试过的方法
我提到了我尝试使用Cupy,它允许您以内存映射模式打开numpy文件。
import os
import numpy as np
import cupy
#Create .npy files.
for i in range(4):
numpyMemmap = np.memmap( 'reg.memmap'+str(i), dtype='float32', mode='w+', shape=( 2200000 , 512))
np.save( 'reg.memmap'+str(i) , numpyMemmap )
del numpyMemmap
os.remove( 'reg.memmap'+str(i) )
# Check if they load correctly with np.load.
NPYmemmap = []
for i in range(4):
NPYmemmap.append( np.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' ) )
del NPYmemmap
# Eventually results in memory error.
CPYmemmap = []
for i in range(4):
print(i)
CPYmemmap.append( cupy.load( 'reg.memmap'+str(i)+'.npy' , mmap_mode = 'r+' ) )
我尝试的结果
我的尝试导致了OutOfMemoryError:
有人提到:
似乎cupy.load需要将整个文件先适应主机内存,然后在设备内存中适应。
还有人提到:
CuPy无法处理内存映射。因此,默认情况下CuPy直接使用GPU内存。 https://docs-cupy.chainer.org/en/stable/reference/generated/cupy.cuda.MemoryPool.html#cupy.cuda.MemoryPool.malloc 如果您想使用统一内存,则可以更改默认的内存分配器。
我尝试使用
cupy.cuda.set_allocator(cupy.cuda.MemoryPool(cupy.cuda.memory.malloc_managed).malloc)
但这似乎没有什么效果。在出现错误时,我的CPU Ram约为16 GB,而GPU Ram为0.32 GB。我正在使用Google colab,在那里我的CPU Ram为25 GB,GPU Ram为12 GB。因此,在将整个文件托管在主机内存中后,它检查是否可以适应设备内存,当它看到只有12个需要的16个GB时,它会抛出一个错误(我最好的猜测)。
因此,现在我正在尝试找到一种使用固定的“零拷贝”内存来处理内存映射文件的方法,该文件将向GPU提供数据。
如果重要,我尝试传输的数据类型是浮点数组。通常,对于只读数据,将二进制文件加载到GPU内存中,但我正在处理希望在每个步骤中都进行读写操作的数据。