MI IPU API
1. 概述¶
1.1. 模块说明¶
MI IPU模块实现了AI模型的推演功能加速。通过channel支持多个AI模型的推演,支持模块内部分配input/output Tensor,也支持直接使用前一级模块out buffer 作为input Tensor。
1.2. 流程框图¶
图1-1 Pudding框图
1.3. 关键词说明¶
-
IPU
智能处理器
-
Firmware
驱动IPU硬件的程序文件
-
Tensor
网络模型中的多维数据
-
Input Tensor
整个AI模型的输入Tensor
-
OutputTensor
整个AI 模型的输出Tensor
2. API参考¶
2.1. 功能模块API¶
表2-1
API名 | 功能 |
---|---|
MI_IPU_CreateDevice | 创建IPU设备 |
MI_IPU_DestroyDevice | 销毁IPU设备 |
MI_IPU_CreateCHN | 创建IPU通道 |
MI_IPU_DestroyCHN | 销毁指定IPU通道 |
MI_IPU_GetInOutTensorDesc | 获取指定通道的网络模型输入输出信息 |
MI_IPU_GetInputTensors | 从指定通道分配输入Tensor Buffer |
MI_IPU_PutInputTensors | 释放指定通道的输入Tensor Buffer |
MI_IPU_GetOutputTensors | 从指定通道分配输出Tensor Buffer |
MI_IPU_PutOutputTensors | 释放指定通道的输出Tensor Buffer |
MI_IPU_Invoke | 执行一次网络模型推演 |
MI_IPU_GetOfflineModeStaticInfo | 获取离线模型运行需要的variable buffer size和离线模型文件大小 |
2.2. MI_IPU_CreateDevice¶
-
功能
创建IPU设备。
-
语法
MI_S32 MI_IPU_CreateDevice(MI_IPU_DevAttr_t *pstIPUDevAttr, SerializedReadFunc pReadFunc, char *pReadCtx, MI_U32 FWSize);
-
形参
表2-2
参数名称 描述 输入/输出 pstIPUDevAttr IPU设备属性结构体指针 输入 pReadFunc 用户自定义读取文件函数指针(设为NULL默认使用MI IPU提供的文件读取函数) 输入 pReadCtx IPU firmware文件路径(设为NULL默认使用MI IPU提供的文件路径:/customer/ipu_firmware) 输入 FWSize IPU firmware文件大小(设为0默认MI IPU自动获取文件大小) 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
2.3. MI_IPU_DestroyDevice¶
-
功能
销毁IPU设备。
-
语法
MI_S32 MI_IPU_DestroyDevice(void);
-
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
举例
MI_IPU_DestroyDevice();
2.4. MI_IPU_CreateCHN¶
-
功能
创建IPU通道。
-
语法
MI_S32 MI_IPU_CreateCHN(MI_IPU_CHN *ptChnId,MI_IPUChnAttr_t *pstIPUChnAttr, SerializedReadFunc pReadFunc, char *pReadCtx);
-
参数
表2-3
参数名称 描述 输入/输出 ptChnId 获取IPU通道ID的指针 输出 pstIPUChnAttr IPU通道描述信息结构体指针 输入 pReadFunc 用户自定义读取文件函数(设为NULL默认使用MI IPU提供的文件读取函数) 输入 pReadCtx 网络模型文件路径(设为NULL默认使用MI IPU提供的文件路径:/customer/mbnet.tflite_sgsimg.img) 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
注意
-
MI_IPUChnAttr_t.u32InputBufDepth 为设定的输入预分配私有tensor buffer 个数, 比如 0 or 1 or 2 or 3, 当设置为0时,表示buffer来源于外部,如MI_DIVP模块。如果直接使用前级模块的输出MI buffer,建议此处设置input_depth为0避免内存浪费。
-
MI_IPUChnAttr_t. u32OutputBufDepth为设定的输出预分配私有tensor buffer 个数, 比如 0 or 1 or 2 or 3,当设置为0时,表示buffer来源于外部,如MI_RGN模块。
-
IPU最大通道数为16。
-
-
举例
MI_S32 s32Ret, buf_depth = 3; MI_IPU_CHN u32ChnId = 0; chnAttr.u32InputBufDepth = buf_depth; chnAttr.u32OutputBufDepth = buf_depth; char pReadCtx[] = "caffe_mobilenet_v2.tflite_sgsimg.img"; s32Ret = MI_IPU_CreateCHN(&u32ChnId, &chnAttr, NULL, pReadCtx); if (s32Ret != MI_SUCCESS) { printf("fail to create ipu channel\n"); MI_IPU_DestroyDevice(); return s32Ret; }
2.5. MI_IPU_DestroyCHN¶
-
功能
销毁指定IPU通道。
-
语法
MI_S32 MI_IPU_DestroyCHN(MI_IPU_CHN u32ChnId);
-
参数
表2-4
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
注意
- IPU最大通道数为16。
-
举例
MI_IPU_DestroyCHN(u32ChnId);
2.6. MI_IPU_GetInOutTensorDesc¶
-
描述
获取指定通道的网络模型输入输出信息。
-
语法
MI_S32 MI_IPU_GetInOutTensorDesc(MI_IPU_CHN u32ChnId,MI_IPU_SubNet_InputOutputDesc_t *pstDesc);
-
参数
表2-5
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 pstDesc 网络描述结构体指针 输出 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
注意
- IPU最大通道数为16。
2.7. MI_IPU_GetInputTensors¶
-
描述
从指定通道获取输入Tensor Buffer。
-
语法
MI_S32 MI_IPU_GetInputTensors(MI_IPU_CHN u32ChnId,MI_IPU_TensorVector_t *pstInputTensorVector);
-
参数
表2-6
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 pstInputTensorVector 输入IPU Tensor数组结构体指针 输出 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
注意
-
输入Tensor的Buffer来源有2种方式:
-
通过MI_IPU_GetInputTensors分配Buffer;
-
使用MI的其他模块已分配的Buffer。
-
-
-
举例
通过MI_IPU_GetInputTensors分配buffer
MI_IPU_TensorVector_t inputV; MI_IPU_TensorVector_t OutputV; MI_U8 au8MaggiePic[3*224*224] ; cv::Mat img = cv::imread(filename, -1); cv::Size inputSize = cv::Size(224,224,3) cv ::Mat imgResize ; cv::resize(img, imgResize, inputSize); memcpy(au8MaggiePic, imgResize.data, sizeof(au8MaggiePic)); s32Ret = MI_IPU_GetInputTensors(u32ChnId, &inputV); if (s32Ret == MI_SUCCESS) { memcpy(inputV.stArrayTensors[0].pstTensorData[0], au8MaggiePic, sizeof(au8MaggiePic)); MI_SYS_FlushInvCache(inputV.stArrayTensors[0].pstTensorData[0], sizeof(au8MaggiePic)); } else { printf(“fail to get buffer, please try again”); } MI_IPU_GetOutputTensors( u32ChannelID, &OutputV); if(MI_SUCCESS!=MI_IPU_Invoke(u32ChannelID, & inputV, &OutputV)) { cout<<"IPU invoke failed!!"<<endl; MI_IPU_DestroyCHN(u32ChannelID); MI_IPU_DestroyDevice(); return -1; }
使用MI其他模块已经分配的buffer
MI_IPU_TensorVector_t inputVector, outputVector; inputVector.u32TensorCount = 1; if (stBufInfo.eBufType == E_MI_SYS_BUFDATA_RAW) { inputVector.astArrayTensors[0].phyTensorAddr[0] = stBufInfo.stRawData.phyAddr; inputVector.astArrayTensors[0].ptTensorData[0] = stBufInfo.stRawData.pVirAddr; } else if (stBufInfo.eBufType == E_MI_SYS_BUFDATA_FRAME) { inputVector.astArrayTensors[0].phyTensorAddr[0] = stBufInfo.stFrameData.phyAddr[0]; inputVector.astArrayTensors[0].ptTensorData[0] = stBufInfo.stFrameData.pVirAddr[0]; inputVector.astArrayTensors[0].phyTensorAddr[1] = stBufInfo.stFrameData.phyAddr[1]; inputVector.astArrayTensors[0].ptTensorData[1] = stBufInfo.stFrameData.pVirAddr[1]; } //prepare output vector
s32Ret = MI_IPU_GetOutputTensors(FdaChn, &outputVector); s32Ret = MI_IPU_Invoke(FdaChn, &inputVector, &outputVector);
2.8. MI_IPU_PutInputTensors¶
-
功能
释放指定通道的输入Tensor Buffer。
-
语法
MI_S32 MI_IPU_PutInputTensors(MI_IPU_CHN u32ChnId,MI_IPU_TensorVector_t *pstInputTensorVector);
-
形参
表2-7
参数名称 描述 输入/输出 u32ChnId IPU通道号 输入 pstInputTensorVector 输入IPU Tensor数组结构体指针 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
2.9. MI_IPU_GetOutputTensors¶
-
功能
从指定通道获取输出Tensor Buffer。
-
语法
MI_S32 MI_IPU_GetOutputTensors(MI_IPU_CHN u32ChnId,MI_IPU_TensorVector_t *pstInputTensorVector);
-
形参
表2-8
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 pstInputTensorVector 输出IPU Tensor数组结构体指针 输出 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
2.10. MI_IPU_PutOutputTensors¶
-
功能
释放指定通道的输出Tensor Buffer。
-
语法
MI_S32 MI_IPU_PutOutputTensors(MI_IPU_CHN u32ChnId,MI_IPU_TensorVector_t *pstInputTensorVector);
-
形参
表2-9
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 pstInputTensorVector 输出IPU Tensor数组结构体指针 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
2.11. MI_IPU_Invoke¶
-
功能
执行一次AI网络推演过程。
-
语法
MI_S32 MI_IPU_Invoke(MI_IPU_CHN u32ChnId,MI_IPU_TensorVector_t *pstInputTensorVector,MI_IPU_TensorVector_t *pstOuputTensorVector);
-
形参
表2-10
参数名称 描述 输入/输出 u32ChnId IPU通道ID 输入 pstInputTensorVector 输入IPU Tensor数组结构体指针 输入 pstOuputTensorVector 输出IPU Tensor数组结构体指针 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
注意
MI_IPU_Invoke为同步API。
-
举例
s32Ret =MI_IPU_Invoke(u32ChnId, &inputV, &outputV); if (s32Ret == MI_SUCCESS) { // process output buffer data // ... }
2.12. MI_IPU_GetOfflineModeStaticInfo¶
-
功能
获取离线模型运行需要的variable buffer size和离线模型文件大小
-
语法
MI_S32 MI_IPU_GetOfflineModeStaticInfo(SerializedReadFunc pReadFunc, char *pReadCtx, MI_IPU_OfflineModelStaticInfo_t *pStaticInfo);
-
形参
表2-11
参数名称 描述 输入/输出 pReadFunc 用户自定义读取文件函数(设为NULL默认使用MI IPU提供的文件读取函数 输入 pReadCtx 离线模型文件路径 输入 pStaticInfo 离线模型静态信息结构体指针 输入 -
返回值
-
MI_SUCCESS成功。
-
非MI_SUCCESS失败,参照错误码。
-
-
依赖
-
头文件:mi_ipu.h
-
库文件:libmi_ipu.so
-
-
举例
MI_IPU_OfflineModelStaticInfo_t staticInfo; s32Ret = MI_IPU_GetOfflineModeStaticInfo(NULL, pModelImgPath, &staticInfo); if (s32Ret == MI_SUCCESS) { printf("variable buffer size: %u bytes\n%s size: %u bytes\n", staticInfo.u32VariableBufferSize, pModelImgPath, staticInfo.u32OfflineModelSize); }
3. 数据类型¶
3.1. 数据类型定义¶
表3-1
数据类型 | 定义 |
---|---|
SerializedReadFunc | 定义用于客制化的读取文件方式,用于支持客制化的AI网络存储格式 |
MI_IPU_ELEMENT_FORMAT | 定义IPU输入数据枚举类型 |
MI_IPU_TensorDesc_t | 定义IPU Tensor形状结构体 |
MI_IPU_SubNet_InputOutputDesc_t | 定义IPU子网络输入/输出描述结构体 |
MI_IPU_Tensor_t | 定义IPU Tensor地址结构体 |
MI_IPU_TensorVector_t | 定义IPU Tensor数组结构体指针 |
MI_IPU_DevAttr_t | 定义IPU设备属性结构体 |
MI_IPU_ChnAttr_t | 定义IPU通道属性结构体 |
MI_IPU_OfflineModelStaticInfo_t | 定义IPU离线模型静态信息结构体 |
3.2. SerializedReadFunc¶
-
说明
定义用于客制化的读取文件方式,用于支持客制化的AI网络存储格式。
-
语法
typedef int (*SerializedReadFunc)(void *dst_buf,int offset, int size, char *ctx);
-
成员
表3-2
成员名称 描述 dst_buf 数据存放地址 offset 文件指针偏移量 size 读取大小 ctx 文件路径
3.3. MI_IPU_ELEMENT_FORMAT¶
-
说明
定义IPU输入数据枚举类型。
-
语法
typedef enum { MI_IPU_FORMAT_U8, MI_IPU_FORMAT_NV12, MI_IPU_FORMAT_INT16, MI_IPU_FORMAT_INT32, MI_IPU_FORMAT_INT8, MI_IPU_FORMAT_FP32, MI_IPU_FORMAT_UNKNOWN, MI_IPU_FORMAT_ARGB8888, MI_IPU_FORMAT_ABGR8888, } MI_IPU_ELEMENT_FORMAT;
-
成员
表3-3
成员名称 描述 MI_IPU_FORMAT_U8 U8类型 MI_IPU_FORMAT_NV12 NV12类型,如YUV MI_IPU_FORMAT_INT16 INT16类型 MI_IPU_FORMAT_INT32 INT32类型 MI_IPU_FORMAT_INT8 INT8类型 MI_IPU_FORMAT_FP32 FLOAT类型 MI_IPU_FORMAT_UNKNOWN Unknown MI_IPU_FORMAT_ARGB8888 ARGB8888类型 MI_IPU_FORMAT_ABGR8888 ABGR8888类型 -
注意事项
-
ARGB/RGB/BGR tensor属于MI_IPU_FORMAT_U8数据类型
-
只有input tensor可以支援MI_IPU_FORMAT_NV12格式
-
只有output tensor可以支援MI_IPU_FORMAT_FP32格式
-
3.4. MI_IPU_TensorDesc_t¶
-
说明
定义IPU Tensor描述结构体。
-
语法
typedef struct MI_IPU_TensorDesc_s { MI_U32 u32TensorDim; MI_IPU_ELEMENT_FORMAT eElmFormat; MI_U32 u32TensorShape[MI_IPU_MAX_TENSOR_DIM]; MI_S8 name[MAX_TENSOR_NAME_LEN]; MI_U32 u32InnerMostStride; MI_FLOAT fScalar; MI_S64 s64ZeroPoint; MI_S32 s32AlignedBufSize; } MI_IPU_TensorDesc_t;
-
成员
表3-4
成员名称 描述 u32TensorDim Tensor维度 eElmFormat Tensor数据类型 u32TensorShape Tensor形状数组 name Tensor名称 u32InnerMostStride Tensor最内维长度(单位字节) fScalar Tensor量化系数 s64ZeroPoint Tensor量化offset s32AlignedBufSize Tensor buffer大小 -
注意事项
- Tensor维度最大为8。建议使用如下宏定义:
#define MI_IPU_MAX_TENSOR_DIM (8)
- Tensor维度最大为8。建议使用如下宏定义:
3.5. MI_IPU_SubNet_InputOutputDesc_t¶
-
说明
定义IPU子网络输入/输出描述结构体。
-
语法
typedef struct MI_IPU_SubNet_InputOutputDesc_s { MI_U32 u32InputTensorCount; MI_U32 u32OutputTensorCount; MI_IPU_TensorDesc_t astMI_InputTensorDescs[MI_IPU_MAX_INPUT_TENSOR_CNT]; MI_IPU_TensorDesc_t astMI_OutputTensorDescs[MI_IPU_MAX_OUTPUT_TENSOR_CNT]; } MI_IPU_SubNet_InputOutputDesc_t;
-
成员
表3-5
成员名称 描述 u32InputTensorCount 输入Tensor个数 u32OutputTensorCount 输出Tensor个数 astMI_InputTensorDescs 输入Tensor形状结构体数组 astMI_OutputTensorDescs 输出Tensor形状结构体数组
3.6. MI_IPU_Tensor_t¶
-
说明
定义IPU Tensor地址结构体。
-
语法
typedef struct MI_IPU_Tensor_s { void *ptTensorData[2]; MI_PHY phyTensorAddr[2];//notice that this is miu bus addr,not cpu bus addr. } MI_IPU_Tensor_t;
-
成员
表3-6
成员名称 描述 ptTensorData Tensor buffer虚拟地址 phyTensorAddr Tensor buffer物理地址
3.7. MI_IPU_TensorVector_t¶
- 说明
定义IPU Tensor数组结构体。
-
语法
typedef struct MI_IPU_TensorVector_s { MI_U32 u32TensorCount; MI_IPU_Tensor_t astArrayTensors[MI_IPU_MAX_TENSOR_CNT]; } MI_IPU_TensorVector_t;
-
成员
表3-7
成员名称 描述 u32TensorCount Tensor个数 astArrayTensors 每个Tensor的地址信息
3.8. MI_IPU_DevAttr_t¶
-
说明
定义IPU设备属性结构体。
-
语法
typedef struct MI_IPU_DevAttr_s { MI_U32 u32MaxVariableBufSize; MI_U32 u32YUV420_W_Pitch_Alignment; //default is 16 MI_U32 u32YUV420_H_Pitch_Alignment; //default is 2 MI_U32 u32XRGB_W_Pitch_Alignment; //default is 16 } MI_IPU_DevAttr_t;
-
成员
表3-8
成员名称 描述 u32MaxVariableBufSize 模型内部Tensor使用的memory的最大大小 u32YUV420_W_Pitch_Alignment YUV水平方向pitch大小(网络输入是YUV格式时有效) u32YUV420_H_Pitch_Alignment YUV垂直方向pitch大小(网络输入是YUV格式时有效) u32XRGB_W_Pitch_Alignment RGBA/BGRA水平方向pitch大小(网络输入是RGBA/BGRA格式时有效)
3.9. MI_IPU_ChnAttr_t¶
-
说明
定义IPU通道属性结构体。
-
语法
typedef struct MI_IPU_ChnAttr_s { MI_U32 u32SubNetId; MI_U32 u32OutputBufDepth; MI_U32 u32InputBufDepth; } MI_IPUChnAttr_t;
-
成员
表3-9
成员名称 描述 u32SubNetId 子网络ID u32OutputBufDepth 输出Tensor Buffer深度 u32InputBufDepth 输入Tensor Buffer深度 -
注意事项
- IPU输入/输出缓冲区最大深度为3。建议使用如下宏定义:
#define MAX_IPU_INPUT_OUTPUT_BUF_DEPTH (3)
- IPU输入/输出缓冲区最大深度为3。建议使用如下宏定义:
3.10. MI_IPU_OfflineModelStaticInfo_t¶
-
说明
定义IPU离线模型静态信息结构体。
-
语法
typedef struct MI_IPU_OfflineModelStaticInfo_s { MI_U32 u32VariableBufferSize; MI_U32 u32OfflineModelSize; } MI_IPU_OfflineModelStaticInfo_t;
-
成员
表3-10
成员名称 描述 u32VariableBufferSize 离线模型运行需要的variable buffer size u32OfflineModelSize 离线模型文件大小
4. 错误码¶
表4-1 IPU API错误码
错误代码 | 宏定义 | 描述 |
---|---|---|
0 | MI_SUCCESS | Success |
1 | E_IPU_ERR_INVALID_CHNID | Invlalid channel ID |
2 | E_IPU_ERR_CHNID_EXIST | Channel already exists |
3 | E_IPU_ERR_CHNID_UNEXIST | Channel does not exist |
4 | E_IPU_ERR_NOMEM | Failure caused by malloc memory |
5 | E_IPU_ERR_NOBUF | Failure caused by malloc buffer |
6 | E_IPU_ERR_BADADDR | Bad address, buffer address is not gotten from IPU buffer allocator |
7 | E_IPU_ERR_SYS_TIMEOUT | System timeout |
8 | E_IPU_ERR_FILE_OPERATION | File cannot be opened or read or written |
9 | E_IPU_ERR_ILLEGAL_TENSOR_BUFFER_SIZE | Tensor buffer size does not meet the requirement, usually less than the requirement |
10 | E_IPU_ERR_ILLEGAL_BUFFER_DEPTH | Input or output buffer depth quantum exceeds maximum number |
11 | E_IPU_ERR_ILLEGAL_INPUT_OUTPUT_DESC | Network description is illegal, usually input or output buffer quantum is wrong |
12 | E_IPU_ERR_ILLEGAL_INPUT_OUTPUT_PARAM | Uer's input or output buffer quantum does not match network description |
13 | E_IPU_ERR_MAP | Address mapping error |
14 | E_IPU_ERR_INIT_FIRMWARE | Fail to initialize IPU firmware |
15 | E_IPU_ERR_CREATE_CHANNEL | Fail to create channel |
16 | E_IPU_ERR_DESTROY_CHANNEL | Fail to destroy channel |
17 | E_IPU_ERR_INVOKE | Fail to invoke |
18 | E_IPU_ERR_SET_MALLOC_REGION | Fail to set malloc region for freertos |
19 | E_IPU_ERR_SET_IPU_PARAMETER | Fail to set IPU parameter |
20 | E_IPU_ERR_INVALID_PITCH_ALIGNMENT | Invalid pitch alignment |
21 | E_IPU_ERR_NO_CREATED_IPU_DEVICE | There is no created IPU device |
22 | E_IPU_ERR_GET_IPU_VERSION | Fail to get IPU version from IPU firmware |
23 | E_IPU_ERR_MISMATCH_IPU_HEAD_FILE | IPU head files version not matched |
24 | E_IPU_ERR_NO_SUPPORT_REQ | IPU firmware does not support this request |
25 | E_IPU_ERR_FAILED | Unexpected error |
26 | E_IPU_ERR_SEND_REQUEST | Fail to send request to IPU |
27 | E_IPU_ERR_GET_FIRMWARE_INFO | Fail to get ipu firmware information |
256 | E_IPU_ERR_NO_AVAILABLE_CHNID | There is no available channel |