开始
从本篇开始,我们来拆解NCNN的代码,共同学习一下NCNN的相关知识.如果有错误,希望大佬指正,大家共同学习.
初步的大计划程如下:
漏斗显示我们计划还未开始.
由于今天开始DataReader的讲解,所以我们会把第一个漏斗变成一个小红旗:
后面的计划可能所有变化,以尽量合理为准.我们今天就开始第一课,那就是DataReader类的学习.
作用
DataReader的作用主要有两个:
- 读取深度模型的proto信息
- 读取深度模型的权重信息
模型的proto信息如下,主要是写了一些模型结构的信息,下面是官方的squeezenet的网络proto:
模型的权重信息则写到了一个二进制文件中.
实现
先来一张图来看一下类DataReader的实现方式:
DataReaderFromStdio是DataReader的子类,我们主要用它来实现DataReader类的主要功能.
它包含一个成员变量:
- fp
它其实是一个FILE的指针,也就是保存了当前读取的数据流的状态.
它包含两个成员函数:
- scan
- read
这两个成员函数分别是对fscan和fread的一个包装.
函数scan是按照format格式读取信息的,所以它非常适合读取模型的proto信息.
函数read是安装buffer长度读取信息的,所以它非常适合读取读取模型的权重信息.
具体的实现方式如下:
//scan的读取方式是按照format去读取
int DataReaderFromStdio::scan(const char* format, void* p) const
{
return fscanf(fp, format, p);
}
//read的读取方式是按照size去读取
size_t DataReaderFromStdio::read(void* buf, size_t size) const
{
return fread(buf, 1, size, fp);
}
代码示例
关于DataReader的测试代码在这里 ,代码结构如下:
代码中分别对scan和read做了测试.主要是学习一些基于format和基于buf_size去读取文件的差别.