WSL运行代码触发RuntimeError:主机内存指针未注册CUDA设备求解
CUDA内存指针注册错误解决方法
问题场景
在WSL环境运行代码时,执行torch.as_tensor(candidates, device='cuda')时触发内存指针注册错误,错误信息显示指定指针位于主机内存且未注册到任何CUDA设备。
原代码片段
with cp.cuda.Device(cp_device): candidates = cp.zeros((point_idxs.shape[0], num_rots, 3), cp.float32) block_size = (point_idxs.shape[0] + 512 - 1) // 512 rot_voting_kernel( (block_size, 1, 1), (512, 1, 1), ( cp.asarray(pc), cp.asarray(preds_tr[0].cpu().numpy()), cp.asarray(direction[0].cpu().numpy()), candidates, cp.asarray(point_idxs).astype(cp.int32), cp.asarray(corners[0]).astype(cp.float32), cp.float32(cfg.res), point_idxs.shape[0], num_rots, grid_obj.shape[0], grid_obj.shape[1], grid_obj.shape[2] ) ) sph_cp = torch.tensor(sphere_pts.T, dtype=torch.float32).cuda() start = np.arange(0, point_idxs.shape[0] * num_rots, num_rots) np.random.shuffle(start) sub_sample_idx = (start[:10000, None] + np.arange(num_rots)[None]).reshape(-1) candidates = torch.as_tensor(candidates, device='cuda').reshape(-1, 3) candidates = candidates[torch.LongTensor(sub_sample_idx).cuda()] cos = candidates.mm(sph_cp) counts = torch.sum(cos > np.cos(angle_tol / 180 * np.pi), 0).cpu().numpy() best_dir = np.array(sphere_pts[np.argmax(counts)])
错误回溯信息
Traceback (most recent call last): File "nocs/inference.py", line 298, in <module> candidates = torch.as_tensor(candidates, device='cuda').reshape(-1, 3) RuntimeError: The specified pointer resides on host memory and is not registered with any CUDA device.
解决方法
错误根源是CuPy数组与PyTorch在WSL环境下的内存交互兼容性问题,torch.as_tensor无法正确识别CuPy数组的CUDA内存指针。以下两种方案可解决:
方案一:利用CuPy的CUDA数组接口直接传递内存指针(无拷贝,高效)
将出错的行替换为:
candidates = torch.as_tensor(candidates.__cuda_array_interface__).reshape(-1, 3)
通过__cuda_array_interface__让PyTorch直接接管CuPy数组的CUDA内存,无需数据拷贝,同时自动关联到对应CUDA设备。
方案二:先拷贝到CPU再转回CUDA(兼容性更好)
如果方案一无效,采用数据拷贝方式兼容:
candidates = torch.tensor(candidates.get(), device='cuda').reshape(-1, 3)
candidates.get()将CuPy数组从CUDA内存拷贝到CPU,再转为PyTorch张量并移回CUDA设备,会产生一次CPU-GPU数据传输,但兼容性更强。
额外优化:减少CPU-GPU数据传输
原代码中sub_sample_idx的创建使用了NumPy,可改为PyTorch API直接在GPU上生成,避免不必要的数据传输:
start = torch.arange(0, point_idxs.shape[0] * num_rots, num_rots, device='cuda') torch.randperm(start.shape[0], out=start) sub_sample_idx = (start[:10000, None] + torch.arange(num_rots, device='cuda')[None]).reshape(-1)
内容的提问来源于stack exchange,提问作者fdjianc
相关产品推荐
相关产品推荐

