本次笔记包含第一课和第二课
vector<vector<vector<float>>>
在内存中并不连续,容易造成内存的访问,扩容以及修改的不方便(比如卷积的时候cache不命中)
KuiperInfer框架中使用Armadillo里的arma::mat
和arma::cube
类作为数据管理类来实现Tensor类。Tensor类的主要工作是封装arma::cube
并提供了方便数据访问的对外接口
class Tensor{
public:
void Function1(); // 对外接口1
void Function2(); // 对外接口2
private:
std::vector<uint32_t> raw_shapes_;
arma::fcube data_; //具体的数据管理者
}
Cube与Matrix关系详见本文,可以简单的认为就是按照BCHW方式保存
namespace kuiper_infer {
Tensor<float>::Tensor(uint32_t channels, uint32_t rows, uint32_t cols) {
data_ = arma::fcube(rows, cols, channels);
}
其中fcube是float cube
知识点:1. 赋值函数,2. 拷贝构造函数
uint32_t Tensor<float>::cols() const {
}
uint32_t Tensor<float>::channels() const {
}
uint32_t Tensor<float>::size() const {
}
void Tensor<float>::set_data(const arma::fcube& data) {
}
bool Tensor<float>::empty() const {
}
float Tensor<float>::index(uint32_t offset) const {
}
float& Tensor<float>::index(uint32_t offset) {
}
std::vector<uint32_t> Tensor<float>::shapes() const {
}
float Tensor<float>::at(uint32_t channel, uint32_t row, uint32_t col) const {
}
float& Tensor<float>::at(uint32_t channel, uint32_t row, uint32_t col) {
}
void Tensor<float>::Fill(float value) {
}
void Tensor<float>::Fill(const std::vector<float>& values) {
}
知识点:
3. CHECK的使用
4. 以下函数有什么区别
float Tensor<float>::index(uint32_t offset) const {
CHECK(offset < this->data_.size()) << "Tensor capacity is not enough!";
return this->data_.at(offset);
}
float& Tensor<float>::index(uint32_t offset) {
CHECK(offset < this->data_.size()) << "Tensor capacity is not enough!";
return this->data_.at(offset);
}
Tensor类模板
拥有两个特化类
知识点:
5. 特化类
6. std::move
Tensor(arma::cube)
是列主序的!
作业:
完成padding,fill函数