第一部分
ATC——Ascend Tensor Compile。一、转换其他框架的模型文件;二、单算子编译,转换基于Ascend IR定义的单算子描述文件。主要步骤:
原始框架为Caffe时,.prototxt和.caffemodel的op name和op type必须保持一致,且输入数据最大支持四位。reshape、expanddim等算子不能输出五维。模型中所有算子不能维度为0.
AIPP是在模型转换的过程中配置的,通过配置文件的形式固化到om模型中。转RGB,减均值,乘系数,图像增强等操作是DVPP做不到的。AIPP输入是DVPP的结果,一定是YUV格式。AIPP将图片转换为模型接受的图片格式(如RGB)。MindStudio中配置AIPP界面如下
AIPP输入图片大小(Input Image Resolution) == DVPP输出图片大小(16 * 2 对齐)
aipp_op{
aipp_mode:static
related_input_rank : 0 # 标识对第1个输入进行AIPP处理
src_image_size_w : 608
src_image_size_h : 608
crop : false
input_format : YUV420SP_U8
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 298
matrix_r0c1 : 0
matrix_r0c2 : 409
matrix_r1c0 : 298
matrix_r1c1 : -100
matrix_r1c2 : -208
matrix_r2c0 : 298
matrix_r2c1 : 516
matrix_r2c2 : 0
input_bias_0 : 16
input_bias_1 : 128
input_bias_2 : 128
mean_chn_0 : 104
mean_chn_1 : 117
mean_chn_2 : 123
min_chn_0 : 0.0
min_chn_1 : 0.0
min_chn_2 : 0.0
var_rec1_chn_0 : 1.0
var_rec1_chn_1 : 1.0
var_rec1_chn_2 : 1.0
}
atc --help
验证环境搭建。
转换命令
atc --model= --weight= ...
AIPP配置文件名为insert_op.cfg
。详情参看atc手册
算子信息库
软件栈具备单算子推理能力,即把数据输入到单算子中得到结果,单算子在推理过程中也相当于一个模型。单算子配置文件是.json格式
假设有如下单算子op_list.json
配置文件
# ArgMaxD算子
# 实现输出置信度最大的类别
{
"op": "ArgMaxD", # 算子名称
"input_desc": [ # 输入描述
{
"format": "ND",
"shape": [1000],
"type": "float16"
}
],
"output_desc": [ # 输出算子
{
"format": "ND",
"shape": [1],
"type": "int32"
}
],
"attr": [ # 算子的属性信息
{
"name": "dimension",
"type": "int",
"value":0
}
]
}
转换命令
atc --singleop ./op_list.json --output ./output --soc_version Ascend310
,会在output中生成对应的om文件。一个算子对应一个om
类型 | 说明 | 必填 | |
---|---|---|---|
comfile_flag | INT32 | 默认0,表示精确编译 | 否 |
op | string | 算子类型 | 是 |
input_desc | TensorDesc数组 | 算子输入描述 | 是 |
output_desc | TensorDesc数组 | 算子输出描述 | 是 |
attr | Attr数组 | 算子属性 | 否 |
类型 | 说明 | 必填 | |
---|---|---|---|
format | INT32 | Tensor的排布方式,用0, 1, 2,3等代码指代。0为NCHW,1为NHWC | 是 |
shape | int数组 | Tensor的shape,如[1, 3, 224, 224] | 是 |
type | string | Tensor的数据类型 | 是 |
name | string | Tensor的名称。算子输入为动态输入时是必需的 | 否 |
dynamic_input | string | 动态输入,取值必须和算子信息库中该算子定义的输入name相同 | 否 |
类型 | 说明 | 必填 | |
---|---|---|---|
name | string | 属性名 | 是 |
type | string | 属性值的类型。bool, string, int, float, list_bool, … | 是 |
value | 由type的取值决定 | 属性值,根据type不同而不同 | 是 |
这里配置的算子决定了将来调用ACL接口执行算子计算过程中,匹配算子的规则。实际调用算子文件进行单算子计算时,配置的是一个目录,这个代码框架将整个目录里所有的om都加载进来,计算时根据配置信息匹配给具体单算子进行计算。
json字段内容是手写的,对应算子的属性。json文件配置格式参考(即3.1.4内容的完整版)
Cast和ArgMaxD是CANN已经实现的算子。CANN已经实现的算子清单
计算加速。可以实现模型加载,算子加载和执行,数据预处理,是基于C++的。管理设备、上下文、流
模型和数据启动在HOST,中间传到Device上计算,结果再回传至HOST
# include
# include "acl/acl.h"
// 设置宏
# define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
# define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
# define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
using namespace std;
int main(){
INFO_LOG("HELLO WORLD");
// ACL初始化
const char *aclConfigPath = "acl.json";
aclError ret = aclInit(aclConfigPath);
if (ret != ACL_ERROR_NONE){ // 判断初始化成功
ERROR_LOG("acl init failed");
}
INFO_LOG("acl init success");
ret = aclFinalize();
// ACL销毁
if (ret != ACL_ERROR_NONE){
ERROR_LOG("finalize acl failed");
}
INFO_LOG("end to finalize acl");
return 0;
}
# Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
# CMake lowest version requirement
cmake_minimum_required(VERSION 3.5.1)
# project information
project(ACL_HELLO_WORLD)
# Compile options
add_compile_options(-std=c++11)
# 指定生成路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../out")
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O2 -Wall")
set(INC_PATH $ENV{DDK_PATH})
if (NOT DEFINED ENV{DDK_PATH})
if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
set(INC_PATH "C:/Program Files/HuaWei/Ascend")
else ()
set(INC_PATH "/usr/local/Ascend")
endif ()
message(STATUS "set default INC_PATH: ${INC_PATH}")
else ()
message(STATUS "env INC_PATH: ${INC_PATH}")
endif ()
set(LIB_PATH $ENV{NPU_HOST_LIB})
# Dynamic libraries in the stub directory can only be used for compilation
if (NOT DEFINED ENV{NPU_HOST_LIB})
if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
set(LIB_PATH "C:/Program Files/HuaWei/Ascend/Acllib/lib64")
else ()
set(LIB_PATH "/usr/local/Ascend/acllib/lib64/stub/")
endif ()
message(STATUS "set default LIB_PATH: ${LIB_PATH}")
else ()
message(STATUS "env LIB_PATH: ${LIB_PATH}")
endif ()
# Header path
# 引用除acl.h 需要在此添加头文件
include_directories(
${INC_PATH}/acllib/include/
)
if(target STREQUAL "Simulator_Function")
add_compile_options(-DFUNC_SIM)
endif()
# add host lib path
link_directories(
${LIB_PATH}
)
# 可能变化的
# 想要编译的源文件
add_executable(main # 指生成的可执行文件
main.cpp) # 指待编译的源文件
if (target STREQUAL "Simulator_Function")
target_link_libraries(main funcsim)
else ()
if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
target_link_libraries(main
libascendcl)
else ()
target_link_libraries(main
ascendcl stdc++)
endif ()
endif ()
install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
NPU_HOST_LIB=/home/HwHiAiUser/Ascend/acllib/lib64/stub
DDK_PATH =home/HwHiAiUser/Ascend
LD_LIBRARY_PATH=/home/HwHiAiUser/Ascend/acllib/lib64:/usr/local/Ascend/ add-ons:/ home/HwHiAiUser/Ascend/atc/lib64:
生成编译文件
cmake . -DCMAKE_CXX_COMPILER=g++ -DCMAKE_SKIP_RPATH=TRUE
编译
make
加载acl.json
touch acl.json
# 创建空文件,与main可执行放在同一个目录下
cd home/ascend/log
# 小写的ascend
p-log:HOST日志