Pytorch1.4报RuntimeError: max_pool2d_with_indices_out_cuda_frame failed with error code 0

RuntimeError: max_pool2d_with_indices_out_cuda_frame failed with error code 0

问题描述

pytorch前向推理模型, 在1.3版本下可以运行, 但切换到1.4后报RuntimeError: max_pool2d_with_indices_out_cuda_frame failed with error code 0. 然后进一步分析, 定位错误在torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode), 然而该函数已近在前面几次执行过.

images = images.cuda() 
pred = model(images.permute(0, 3, 1, 2))

将上述代码修改成

images = images.cuda() 
pred = model(images.permute(0, 3, 1, 2).contigous())

成功解决问题.

  • Tensor多维数组底层实现是使用一块连续内存的1维数组(行优先顺序存储,下文描述),Tensor在元信息里保存了多维数组的形状,在访问元素时,通过多维度索引转化成1维数组相对于数组起始位置的偏移量即可找到对应的数据。某些Tensor操作(如transpose、permute、narrow、expand)与原Tensor是共享内存中的数据,不会改变底层数组的存储,但原来在语义上相邻、内存里也相邻的元素在执行这样的操作后,在语义上相邻,但在内存不相邻,即不连续了(is not contiguous)。
  • transpose、permute 操作虽然没有修改底层一维数组,但是新建了一份Tensor元信息,并在新的元信息中重新指定 stride。使用transpose、permute后再使用contiguous方法则会重新开辟一块内存空间保证数据是在逻辑顺序和内存中是一致的,连续内存布局减少了CPU对对内存的请求次数(访问内存比访问寄存器慢100倍),相当于空间换时间.torch.view 方法约定了不修改数组本身,只是使用新的形状查看数据.

is_contiguous直观的解释是Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致. 如果想要变得连续使用contiguous方法,如果Tensor不是连续的,则会重新开辟一块内存空间保证数据是在内存中是连续的,如果Tensor是连续的,则contiguous无操作。
permute可以同时操作于tensor的若干维度,transpose只能同时作用于tensor的两个维度;view只能作用在contiguous的variable上,如果在view之前调用了transpose、permute等,就需要调用contiguous()来返回一个contiguous copy;

你可能感兴趣的:(Pytorch,onnx)