PyTorch Tensor 与 TensorImpl 机制解读
PyTorch Tensor 与 TensorImpl 机制解读 1. 为什么要把 Tensor 和 TensorImpl 分成两层 初次接触 PyTorch 源码的人常有一个疑惑:Python 里 torch.Tensor 明明是一个对象,为什么 C++ 里又有 at::Tensor 和 c10::TensorImpl 两个类? 答案是值语义 vs 数据本体的分离: at::Tensor:一个轻量的"引用/handle",本身几乎不存储数据,可以随意拷贝、传参、放进容器,开销只是一次引用计数的加减。 c10::TensorImpl:真正持有 sizes/strides/dtype/device/storage 等元信息的对象,在堆上只有一份。 多个 at::Tensor 可以指向同一个 TensorImpl(比如 view 操作、赋值拷贝),它们共享同一份元信息和底层数据,改一个,另一个也能看到变化——这正是 PyTorch “view 语义"和"就地修改语义"的根基。 at::Tensor a; at::Tensor b = a; // 只拷贝了指针,refcount+1 │ │ └──────────┬─────────────┘ ▼ c10::TensorImpl (堆上唯一一份) ├── sizes/strides ├── storage_ ──────────► StorageImpl(真正的数据 buffer) ├── dtype / device └── ... 这种设计在 C++ 里通过 c10::intrusive_ptr<TensorImpl> 实现:at::Tensor 内部只有一个 intrusive_ptr<TensorImpl> 成员,拷贝 Tensor 就是拷贝这个智能指针。 ...