1

假设有两个 pytorch 张量a,一个是float32shape [M, N]b一个是int64shape [K]。中的值在b[0, M-1] 内,因此以下行给出了一个新的张量,其c索引为b

c = a[b]    # [K, N] tensor whose i-th row is a[b[i]], with `IndexBackward`

但是,在我的一个项目中,此行总是报告以下错误(通过以下方式检测到torch.autograd.detect_anomaly()

  with torch.autograd.detect_anomaly():
[W python_anomaly_mode.cpp:104] Warning: Error detected in IndexBackward. Traceback of forward call that caused the error:
...
File "/home/user/project/model/network.py", line 60, in index_points
    c = a[b]
 (function _print_stack)

Traceback (most recent call last):
  File "main.py", line 589, in <module>
    main()
  File "main.py", line 439, in main
    train_stats = train(
  File "/home/user/project/train_eval.py", line 866, in train
    total_loss.backward()
  File "/home/user/.local/lib/python3.8/site-packages/torch/_tensor.py", line 255, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph, inputs=inputs)
  File "/home/user/.local/lib/python3.8/site-packages/torch/autograd/__init__.py", line 147, in backward
    Variable._execution_engine.run_backward(
RuntimeError: merge_sort: failed to synchronize: cudaErrorIllegalAddress: an illegal memory access was encountered

请注意,c = a[b]上面的行并不是唯一出现所述错误的行,而只是具有方括号索引的许多其他行之一。

但是,当我将索引样式从

c = a[b]

c = a.index_select(0, b)

我不明白为什么使用方括号进行索引会导致非法内存访问,但这给了我足够的理由相信方括号索引并且index_select实现方式不同。理解这一点可能是解释这一点的关键。另外,由于该项目相当大且不公开,我不能在这里分享确切的代码。您可以将上述内容视为背景,并专注于方括号索引和index_select不同之处。谢谢!


附加信息:

  • ubuntu 20.04 + cuda 11.2 + RTX3090
  • pytorch 1.9.0 + 火炬视觉 1.10.0 + pytorch3d 0.6.0
  • 该项目涉及训练网络,并且仅在我使用 pytorch3d 中的 Pulsar 渲染器渲染某些东西(实际上,任何东西,即使渲染的数据与原始代码完全无关)时才会出现错误。
4

1 回答 1

1

torch.index_select返回一个新的张量,它将索引字段复制到新的内存位置(docs)。

torch.Tensor.select或切片返回原始张量 ( docs )的视图。

在没有看到更多代码的情况下,很难说为什么这种特殊的功能差异可能会导致上述错误。

于 2021-11-03T14:29:25.103 回答