如何在两个Python进程间共享CuPy数组且不复制?有无类NumPy机制?
如何在Python进程间共享CuPy数组且无需复制?
是的,CuPy提供了类似NumPy multiprocessing.shared_memory的机制,核心依赖**CUDA IPC(进程间通信)**实现GPU内存的直接共享,无需数据复制。以下是两种实用实现方式:
方法1:使用CUDA IPC原生API
这是最直接的方式,利用CUDA原生内存句柄共享机制,让不同进程直接访问同一块GPU内存。
import multiprocessing as mp import cupy as cp import cupy.cuda.runtime as rt def worker(handle, shape, dtype): # 打开IPC内存句柄,获取设备指针 dev_ptr = rt.ipcOpenMemHandle(handle, rt.cudaIpcMemLazyEnablePeerAccess) # 用共享内存指针重新构造CuPy数组 shared_arr = cp.ndarray(shape, dtype=dtype, memptr=cp.cuda.MemoryPointer(cp.cuda.DevicePointer(dev_ptr), 0)) # 验证共享效果:修改数组 print(f"子进程读取数组:{shared_arr}") shared_arr[1] = 999 # 关闭句柄释放资源 rt.ipcCloseMemHandle(dev_ptr) if __name__ == "__main__": # 主进程创建CuPy数组 main_arr = cp.array([10, 20, 30, 40]) print(f"主进程初始数组:{main_arr}") # 获取数组底层内存的IPC句柄 ipc_handle = rt.ipcGetMemHandle(main_arr.data.ptr) # 启动子进程传递句柄、形状和数据类型 proc = mp.Process(target=worker, args=(ipc_handle, main_arr.shape, main_arr.dtype)) proc.start() proc.join() # 主进程查看子进程修改后的结果 print(f"主进程更新后数组:{main_arr}")
方法2:结合MemoryPointer复用GPU内存
如果不需要跨设备,也可以直接传递CuPy数组的内存指针信息,在子进程中重新绑定数组:
import multiprocessing as mp import cupy as cp def worker(ptr, shape, dtype): # 用内存指针直接构造数组,共享同一块GPU内存 shared_arr = cp.ndarray(shape, dtype=dtype, memptr=cp.cuda.MemoryPointer(cp.cuda.DevicePointer(ptr), 0)) print(f"子进程数组:{shared_arr}") shared_arr[0] = 1000 if __name__ == "__main__": arr = cp.array([1, 2, 3]) print(f"主进程初始数组:{arr}") # 传递指针地址、形状和类型 proc = mp.Process(target=worker, args=(arr.data.ptr, arr.shape, arr.dtype)) proc.start() proc.join() print(f"主进程更新后数组:{arr}")
关键注意事项
- 所有进程必须运行在同一台机器的同一个GPU上,CUDA IPC不支持跨GPU或跨机器共享。
- 共享期间要确保GPU内存块不被主进程提前释放,否则会导致子进程崩溃。
- 共享的数组在任意进程中的修改都会直接反映到其他进程,因为它们指向同一块内存。
内容的提问来源于stack exchange,提问作者vm123
相关产品推荐
相关产品推荐

