释放 Pycuda 的内存

Posted

技术标签:

【中文标题】释放 Pycuda 的内存【英文标题】:Release memory for Pycuda 【发布时间】:2022-01-16 18:56:07 【问题描述】:

Pycuda 函数调用后如何释放内存?

例如在下面,我如何释放 a_gpu 使用的内存,这样我就有足够的内存分配给 b_gpu,而不是出现下面的错误?

我尝试导入 from pycuda.tools import PooledDeviceAllocationimport pycuda.tools.PooledDeviceAllocation 希望使用 free() 函数,但在导入 ImportError: cannot import name 'PooledDeviceAllocation' from 'pycuda.tools' (D:\ProgramData\Anaconda3\lib\site-packages\pycuda\tools.py)ModuleNotFoundError: No module named 'pycuda.tools.PooledDeviceAllocation'; 'pycuda.tools' is not a package 时它们都会导致错误。如果它应该适用于较新版本的 Pycuda,但只是我的 Pycuda 版本太旧,有没有其他方法可以在我的版本或旧版本的 Pycuda 中释放内存?我希望升级 Pycuda 是最后的手段,因为我的 NVidia 卡和 2060 系列一样旧,以防新版本的 Pycuda 不支持我的旧卡。

非常感谢。

import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
import os

_path = r"D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\Hostx64\x64"

if os.system("cl.exe"):
   os.environ['PATH'] += ';' + _path
if os.system("cl.exe"):
   raise RuntimeError("cl.exe still not found, path probably incorrect")

import numpy as np

a = np.zeros(1000000000).astype(np.float32)
a_gpu = cuda.mem_alloc(a.nbytes)
cuda.memcpy_htod(a_gpu, a)

mod = SourceModule("""
  __global__ void func1(float *a)
  
    a[0] = 1;
  
  """)
      
func = mod.get_function("func1")
func(a_gpu, block=(1,1,1))

a_out = np.empty_like(a)
cuda.memcpy_dtoh(a_out, a_gpu)
print (a_out)

# Memory release code wanted here

b = np.zeros(1000000000).astype(np.float32)
b_gpu = cuda.mem_alloc(b.nbytes)
cuda.memcpy_htod(b_gpu, b)

mod = SourceModule("""
  __global__ void func2(float *b)
  
    b[1] = 1;
  
  """)
      
func = mod.get_function("func2")
func(b_gpu, block=(1,1,1))

b_out = np.empty_like(b)
cuda.memcpy_dtoh(b_out, b_gpu)
print (b_out)

[1. 0. 0. ... 0. 0. 0.]
Traceback (most recent call last):

  File "D:\PythonProjects\Test\CUDA\Test_PyCUDA_MemoryRelease.py", line 47, in <module>
    b_gpu = cuda.mem_alloc(b.nbytes)

MemoryError: cuMemAlloc failed: out of memory

【问题讨论】:

【参考方案1】:

尝试将free() 应用于DeviceAllocation 对象(在本例中为a_gpu

import pycuda.driver as cuda

a = np.zeros(1000000000).astype(np.float32)
a_gpu = cuda.mem_alloc(a.nbytes)
a_gpu.free()

来自documentation:

free() 现在释放持有的设备内存,而不是在该对象变得无法访问时释放。对该对象的任何进一步使用都是错误的,并会导致未定义的行为。

检查:

cuda.mem_get_info()

【讨论】:

谢谢。我无法让cuda.free() 工作,但似乎a_gpu.free() 工作 @Henry 是有道理的,因为free() 是类的方法 `class pycuda.driver.DeviceAllocation 最重要的是,有什么方法可以知道有多少 GPU 内存被占用(或者还有多少空闲 GPU 内存可用)?

以上是关于释放 Pycuda 的内存的主要内容,如果未能解决你的问题,请参考以下文章

为啥有时会立即释放内存,而有时仅在自动释放池耗尽时才释放内存?

怎样释放内存,释放内存有啥作用?对电脑有伤害吗?

C 语言二级指针案例 ( 多级指针内存释放问题 | 多级指针避免野指针 )

linux何时自动释放内存

怎样释放JAVA程序运行中所用的内存

如何手动释放Linux内存的方法