MIGraphX推理框架第二章-编程模型

第一章介绍了简介,可以在此跳转进行回顾

shape

用来表示数据的形状。

可以通过如下方式构造一个shape对象:

  • shape(type_t t, std::vector < std::size_t > l);
  • shape(type_t t, std::vector < std::size_t > l, std::vector < std::size_t > s);

其中:

  • t:shape的类型,shape支持的类型包括:bool_type,half_type,float_type,double_type,uint8_type,int8_type,uint16_type,int16_type,int32_type,int64_type,uint32_type,uint64_type
  • l:每一个维度的大小
  • s:每一个维度的步长,如果没有指定步长,则按照shape为standard的形式根据l自动计算出步长,比如对于一个内存排布为 [N,C,H,W]格式的数据,对应的每一维的步长为[C * H * W,H * W,W,1]

shape中常用的成员函数:

  • const std::vector& lens() const 返回每一维的大小,维度顺序为(N,C,H,W)
  • std::size_t elements() const 返回所有元素的个数
  • std::size_t bytes() const 返回所有元素的字节数

示例:
resnet50中第一个卷积层的卷积核大小为7x7,输出特征图个数为64,即有64个7x7的卷积核,如果输入的是一个3通道的图像,则该卷积核的shape可以表示为migraphx::shape{migraphx::shape::float_type, {64, 3, 7, 7}},其中float_type表示shape的数据类型,这里采用float类型, {64, 3, 7, 7}表示每一个维度的大小,注意{64, 3, 7, 7}对应的是NCHW的内存模型,由于这里没有提供每一维的步长,所以步长会自动计算。自动计算出来的每一维的步长为{147,49,7,1},所以完整的shape表示为{migraphx::shape::float_type, {64, 3, 7, 7},{147,49,7,1}}

对于该卷积核的shape,lens()函数的返回值为{64, 3, 7, 7},elements()的返回值为9408, bytes()的返回值为9408*4=37632。一个float占4个字节。

argument

用来保存数据,类似Pytorch中的Tensor,常用来保存模型的输入和输出数据。

可以通过如下方式构造一个argument对象:

  • argument(const shape& s)
  • template argument(shape s, T* d)

第1种方式只需要提供shape就可以,系统会自动申请一段内存,该内存的大小等于shape的bytes()方法返回值的大小。

第2种方式除了提供shape之外,还需要提供该argument的数据指针,argument不会自动释放该数据。

argument中常用的成员函数:

  • const shape& get_shape() const 返回数据的形状
  • char* data() const 返回argument的数据,可以通过data()的返回值访问推理结果。

与cv::Mat之间的转换

cv::Mat转换为migraphx::argument:

cv::Mat inputData;// inputData表示一张224x224的3通道图像,数据类型为float类型,且为NCHW
形式
migraphx::shape inputShape=migraphx::shape{migraphx::shape::float_type, {1, 3,224, 224}};
migraphx::argument input= migraphx::argument{inputShape,(float*)inputData.data};// 注意,migraphx::argument不会释放inputData中的数据

migraphx::argument转换为cv::Mat:

migraphx::argument result;// result表示推理返回的结果,数据布局为NCHW
int shapeOfResult[]={result.get_shape().lens()[0],result.get_shape().lens()
[1],result.get_shape().lens()[2],result.get_shape().lens()[3]};// shapeOfResult表
示的维度顺序为N,C,H,W
cv::Mat output(4, shapeOfResult, CV_32F, (void *)(result.data()));// 注意,cv::Mat
不会释放result中的数据

literal

使用literal表示常量,比如可以使用literal表示卷积的权重。实际上literal是一种特殊的 argument,literal中的值不能修改,而argument中的值可以修改。

可以通过如下方式构造一个literal对象:

  • template literal(const shape& s, const std::vector& x)
  • template literal(const shape& s, T* x)
  • template literal(const shape& s, const std::initializer_list &x)

第一种构造方法是使用std::vector来创建一个常量,第二种使用数据指针来构造,第三种是使用 std::initializer_list来构造。

literal中常用的成员函数:

  • const shape& get_shape() const 返回常量的形状
  • const char* data() const返回常量的数据指针,注意:不能通过data()返回的指针修改literal的值

target

target表示支持的硬件平台,目前支持CPU模式和GPU模式,在编译模型的时候,需要指定一个target。

program

表示一个神经网络模型

program中常用的成员函数:

  • void compile(const target& t, compile_options options = compile_options{}) 编译模型。第一个参数t是一个target,第二个参数options表示编译的一些设置,比如可以通过options.device_id设 置使用哪一块显卡。
  • std::vector eval(parameter_map params) const 执行推理并返回推理结果,参数params表示模型的输入数据,params中保存模型每个输入节点对应的输入数据, parameter_map类型是std::unordered_map< std::string, argument>的别名,注意这是一个同步的方法。
  • std::unordered_map get_parameter_shapes() 返回模型的输入或输出参数信息,常用来获取模型的输入参数信息。
  • module* get_main_module() 获取主计算图,module表示模型中的子图

std::unordered_map是哈希容器,它可以存储一组键值对,并且支持快速的查找、插入和删除操作

module

现代神经网络模型中可能存在多个子图,MIGraphX中使用module表示子图,每个子图又是由指令组成。 创建program的时候,会自动创建一个主计算图,可以通过program的get_main_module()方法获取主计算图。

module中常用的成员函数:

  • instruction_ref add_parameter(std::string name, shape s) 主要用来添加模型的输入,name表示输入名,s表示输入形状,返回值表示添加到模型中的该条指令的引用。
  • instruction_ref add_literal(literal l) 添加常量,比如可以使用该成员函数添加卷积算子的权重,返回值表示添加到模型中的该条指令的引用。
  • instruction_ref add_instruction(const operation& op, std::vector args) 添加指令,第一个参数op表示算子,args表示算子的参数,返回值表示添加到模型中的该条指令的引用。
  • instruction_ref add_return(std::vector args) 添加结束指令,通常表示模型的结尾,args表示模型最后的指令。

注意:

  • add_parameter(),add_literal(),add_return()添加的是模型中特殊的指令,这些指令不能使用add_instruction()添加, add_instruction()一般用来添加除了输入,常量和结束指令之外的其他指令。
  • 上述所有添加指令的成员函数返回添加的这条指令的引用,MIGraphX中使用instruction_ref这个类型表示指令的引 用,后续指令如果需要使用该条指令作为输入,可以通过该引用来获取该指令。

instruction

instruction表示指令,可以通过module中的add_instruction()成员函数添加指令。MIGraphX中的指令相当 于ONNX模型中的一个节点或者caffe模型中的一个层。指令由操作符(算子)和操作数组成。

接下来进入第三章的学习!

附录

  • https://rocm.docs.amd.com/projects/AMDMIGraphX/en/latest/
  • https://cancon.hpccube.com:65024/4/main/inferexamples
  • https://dyedd.cn/960.html

你可能感兴趣的:(#,MIGraphX推理框架,深度学习,人工智能,c++,python)