我是mshadow中的新手,我无法理解为什么我从下面的代码片段中得到了这些内容:
TensorContainer<cpu, 2> lhs(Shape2(2, 3));
lhs = 1.0;
printf("%u %u\n", lhs.size(0), lhs.size(1));
printf("%u %u\n", lhs[0].shape_[0], lhs[0].shape_[1]);
printf("%u %u\n", lhs[0].size(0), lhs[0].size(1));
输出结果为:
2 3
3 4
3 3
为什么第二个和第三个输出这些数字?因为lhs[0]
是一维的,我认为它们应该完全相同,即3 0
。谁能告诉我哪里错了?提前谢谢!
答案 0 :(得分:1)
你是对的,Tensor lhs [0]是一维的,但是首先要回答你的问题让我展示一下发生了什么。 TensorContainer不会覆盖[]运算符,而是使用父运算符(即Tensor),更准确地说是调用following one:
MSHADOW_XINLINE Tensor<Device, kSubdim, DType> operator[](index_t idx) const {
return Tensor<Device, kSubdim, DType>(dptr_ + this->MemSize<1>() * idx,
shape_.SubShape(), stride_, stream_);
}
可以看出它在堆栈上创建了一个新的Tensor。虽然在大多数情况下它会创建通用N-dimensional Tensor,但对于1维情况,它将创建一个特殊的1-dimensional Tensor。
现在,当我们确定了运算符[]返回的内容时,让我们看一下该类的字段:
DType *dptr_;
Shape<1> shape_;
index_t stride_;
可以看出shape_这里只有1个维度!所以没有形状_ 1,而是通过调用shape _ 1它将返回stride_(或其中的一部分)。以下是对Tensor构造函数的修改,您可以尝试运行并查看其中实际发生的情况:
MSHADOW_XINLINE Tensor(DType *dptr, Shape<1> shape,
index_t stride, Stream<Device> *stream)
: dptr_(dptr), shape_(shape), stride_(stride), stream_(stream) {
std::cout << "shape[0]: " << shape[0] << std::endl; // 3
std::cout << "shape[1]: " << shape[1] << std::endl; // 0, as expected
std::cout << "_shape[0]: " << shape_[0] << std::endl; // 3, as expected
std::cout << "_shape[1]: " << shape_[1] << std::endl; // garbage (4)
std::cout << "address of _shape[1]: " << &(shape_[1]) << std::endl;
std::cout << "address of stride: " << &(stride_) << std::endl;
}
和输出:
shape[0]: 3
shape[1]: 0
_shape[0]: 3
_shape[1]: 4
address of _shape[1]: 0x7fffa28ec44c
address of stride: 0x7fffa28ec44c
_shape 1和步幅都有相同的地址(0x7fffa28ec44c)。