CuPy在TITAN RTX运行报错,TITAN V正常,请求技术支持
CUDA_ERROR_CONTEXT_IS_DESTROYED When Switching to TITAN RTX with CuPy + PyTorch
我帮你分析下这个问题,你遇到的CUDA_ERROR_CONTEXT_IS_DESTROYED本质是PyTorch和CuPy的CUDA上下文没同步,加上初始化时的设备绑定问题导致的。下面一步步给你解决思路:
问题根源
你的DataLoadTest在初始化阶段就创建了CuPy的RawModule和CUDA数组,但此时如果没显式指定设备,CuPy会默认绑定到GPU 0(TITAN V)。当你切换到GPU 1运行PyTorch代码时,PyTorch会创建GPU 1的上下文,但CuPy的资源还挂在GPU 0的上下文上,一旦GPU 0的上下文被销毁或不可用,后续CuPy操作就会报错。
另外,我还发现你的CUDA Kernel参数传递顺序有问题,虽然不是当前报错的直接原因,但后续可能引发内存越界,顺便一起修正。
具体解决方案
1. 同步PyTorch和CuPy的设备上下文
在创建任何CUDA资源之前,一定要显式指定要使用的GPU,确保两者绑定到同一个设备。修改你的主代码:
import data_load_test from tqdm import tqdm import torch import cupy as cp from torch.utils.data import DataLoader def main(): # 指定要使用的GPU(这里是设备1,TITAN RTX) target_gpu = 1 # 让PyTorch切换到目标GPU torch.cuda.set_device(target_gpu) # 让CuPy也切换到目标GPU cp.cuda.Device(target_gpu).use() dataset = data_load_test.DataLoadTest() training_loader = DataLoader(dataset, batch_size=1) with torch.cuda.device(target_gpu): pbar = tqdm(training_loader) for epoch in range(3): for i, img in enumerate(pbar): print("see the message") if __name__ == "__main__": main()
2. 修正CUDA Kernel的参数顺序
你的Kernel定义里cols对应图像宽度,rows对应高度,但调用时你把高度h放在了宽度w前面,这会导致索引计算错误。修改DataLoadTest中调用Kernel的代码:
# 原来的参数是(self.input, self.output, self.h, self.w),改成下面的顺序 self.myfunc(self.grid_size, self.block_size, (self.input, self.output, self.w, self.h))
3. 优化CUDA资源的初始化时机(可选)
如果之后你要开启多进程DataLoader(num_workers>0),主进程初始化的CUDA资源没法在子进程共享,建议把RawModule和CUDA数组的初始化移到__getitem__里,确保每个样本加载时都在当前设备创建资源:
class DataLoadTest(Dataset): def __init__(self): # 只提前加载CUDA代码,不初始化GPU资源 self.cuda_source = read_cuda_file("cuda/cuda_code.cu") self.img_path = "hi.png" def __len__(self): return 1 def __getitem__(self, idx): # 在加载样本时才初始化GPU资源 module = cp.RawModule(code=self.cuda_source) myfunc = module.get_function('myfunc') input_img = cp.asarray(cv2.imread(self.img_path,-1), cp.uint8) h, w, _ = input_img.shape output_img = cp.zeros((w, h, 3), dtype=cp.uint8) block_size = (32, 32) grid_size = (h // block_size[1], w // block_size[0]) myfunc(grid_size, block_size, (input_img, output_img, w, h)) return cp.asnumpy(output_img)
验证步骤
- 先跑
nvidia-smi确认GPU 1的状态正常; - 重启Python环境(避免之前的CUDA上下文残留),运行修改后的代码;
- 如果还是有问题,检查是否有其他代码偷偷切换了GPU设备。
内容的提问来源于stack exchange,提问作者promush
相关产品推荐
相关产品推荐

