转载请贴链接:https://blog.csdn.net/u013271656/article/details/106793636
1. 有效访问Tensor
使用Tensor的操作时,dynamic dispatch 成本相对较小。但是,在某些情况下,尤其是在自己的 kernels 中,需要高效的访问元素,但元素循环进行内部动态分配的成本非常高。ATen提供了accessors可动态检查Tensor的类型和数量。
accessors是Tensor的临时表示,仅在所查看Tensor的生命周期内有效,因此仅应在函数中使用,如迭代器。
ps: accessors 与内核函数内部的 CUDA-Tensor(CUDA tensors inside kernel)不兼容, Instead, 必须使用的 packed accessor 查看内核函数内部的CUDATensor。
1.1 CPU存取器 - CPU accessors
torch::Tensor foo = torch::rand({12, 12});
// assert foo is 2-dimensional and holds floats.
auto foo_a = foo.accessor<float,2>();
float trace = 0;
for(int i = 0; i < foo_a.size(0); i++) {
// use the accessor foo_a to get tensor data.
trace += foo_a[i][i];
}
1.2 CUDA访问器 - CUDA accessors
__global__ void packed_accessor_kernel(
PackedTensorAccessor64<float, 2> foo,
float* trace) {
int i=threadIdx.x
gpuAtomicAdd(trace, foo[i][i])
}
torch::Tensor foo = torch::rand({12, 12});
// assert foo is 2-dimensional and holds floats.
auto foo_a = foo.packed_accessor64<float,2>();
float trace = 0;
packed_accessor_kernel<<<1, 12>>>(foo_a, &trace);
除了 PackedTensorAccessor64 和之外,还有相应的 PackedTensorAccessor32 和 packed_accessor32 ,使用32位整数进行索引。这在CUDA上可能会快很多。
1.3 使用外部创建的数据
如果已经在内存(CPU或CUDA)中创建了Tensor,则可以通过ATen在内存中查看Tensor:
float data[] = { 1, 2, 3,
4, 5, 6 };
torch::Tensor f = torch::from_blob(data, {2, 3});
这些Tensor无法调整大小,因为ATen does not own the memory,但其表现的与普通Tensor相同。
1.4 Scalars and 零维 tensors
除了Tensor对象之外,ATen还包括
Scalar
s,它们代表单个数字。Scalar
s是动态typed,可以容纳ATen的任何一种数字类型。Scalar
s可以从C ++数字类型隐式构造。一些函数(like addmm)将数字与Tensor一起使用,并期望这些数字与Tensor具有相同的动态类型。由此可见,
Scalar
s的存在是很有必要的。它们还用于API中,以指示函数将始终返回标量值的位置,例如
sum
。
namespace torch {
Tensor addmm(Scalar beta, const Tensor & self,
Scalar alpha, const Tensor & mat1,
const Tensor & mat2);
Scalar sum(const Tensor & self);
} // namespace torch
// Usage.
torch::Tensor a = ...
torch::Tensor b = ...
torch::Tensor c = ...
torch::Tensor r = torch::addmm(1.0, a, .5, b, c);
除
Scalar
s外,ATen还允许Tensor对象为零维。
1.5 I created a tensor using a function from at::
and get error
官方文档给出:
当使用function from
at::
报错时,使用torch::
替换掉at::
。官方给出的解释是,at::
namespace创建的是Tensor,torch::
functions创建的是variables,而你的操作是基于variables。
Problem: You created a tensor using e.g.
at::ones
orat::randn
or any other tensor factory from theat::
namespace and are getting errors.Fix: Replace
at::
withtorch::
for factory function calls. You should never use factory functions from theat::
namespace, as they will create tensors. The correspondingtorch::
functions will create variables, and you should only ever deal with variables in your code.
参考libtorch docs: https://pytorch.org/cppdocs/notes/tensor_basics.html