2. libtorch C++ 中 accessor、packed_accessor_kernel、from_blob 解读

转载请贴链接:https://blog.csdn.net/u013271656/article/details/106793636


 

1. 有效访问Tensor

使用Tensor的操作时,dynamic dispatch 成本相对较小。但是,在某些情况下,尤其是在自己的 kernels 中,需要高效的访问元素,但元素循环进行内部动态分配的成本非常高。ATen提供了accessors可动态检查Tensor的类型和数量。

accessorsTensor的临时表示,仅在所查看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还包括Scalars,它们代表单个数字。Scalars是动态typed,可以容纳ATen的任何一种数字类型。Scalars可以从C ++数字类型隐式构造。

一些函数(like addmm)将数字与Tensor一起使用,并期望这些数字与Tensor具有相同的动态类型。由此可见, Scalars的存在是很有必要的。

它们还用于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);

Scalars外,ATen还允许Tensor对象为零维。


 

1.5 I created a tensor using a function from at:: and get error

官方文档给出:

当使用function from at::报错时,使用torch:: 替换掉at::。官方给出的解释是,at:: namespace创建的是Tensortorch:: functions创建的是variables,而你的操作是基于variables。

Problem: You created a tensor using e.g. at::ones or at::randn or any other tensor factory from the at:: namespace and are getting errors.

Fix: Replace at:: with torch:: for factory function calls. You should never use factory functions from the at:: namespace, as they will create tensors. The corresponding torch:: 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 

猜你喜欢

转载自blog.csdn.net/u013271656/article/details/106793636