创建算子工程
- 编写算子的原型定义json文件,用于生成算子开发工程。json文件的配置参数详细说明请参考表1。例如,AddCustom算子的json文件命名为add_custom.json,文件内容如下:
[ { "op": "AddCustom", "input_desc": [ { "name": "x", "param_type": "required", "format": [ "ND", "ND", "ND" ], "type": [ "fp16", "float", "int32" ] }, { "name": "y", "param_type": "required", "format": [ "ND", "ND", "ND" ], "type": [ "fp16", "float", "int32" ] } ], "output_desc": [ { "name": "z", "param_type": "required", "format": [ "ND", "ND", "ND" ], "type": [ "fp16", "float", "int32" ] } ] } ]
例如,ReduceMaxCustom算子(包含属性)的json文件命名为reduce_max_custom.json,文件内容如下:[ { "op": "ReduceMaxCustom", "input_desc": [ { "name": "x", "param_type": "required", "format": ["ND"], "type": ["float16"] } ], "output_desc": [ { "name": "y", "param_type": "required", "format": ["ND"], "type": ["float16"] }, { "name": "idx", "param_type": "required", "format": ["ND"], "type": ["int32"] } ], "attr": [ { "name": "reduceDim", "param_type": "required", "type": "int" }, { "name": "isKeepDim", "param_type": "optional", "type": "int", "default_value": 1 } ] } ]
表1 json文件配置参数说明 配置字段
类型
含义
是否必选
op
-
字符串
算子的Operator Type。
是
input_desc
-
列表
输入参数描述。
否
name
字符串
算子输入参数的名称。
param_type
字符串
参数类型:
- required
- optional
- dynamic
未配置默认为required。
format
列表
针对类型为tensor的参数,配置为tensor支持的数据排布格式。
包含如下取值:
ND,NHWC,NCHW,HWCN,NC1HWC0,FRACTAL_Z等。
format与type需一一对应。
type
列表
算子参数的类型。
取值范围:float16(fp16), float32(fp32), int8, int16, int32, uint8, uint16, bool, bfloat16(bf16)等。
format与type需一一对应。
output_desc
-
列表
输出参数描述。
是
name
字符串
算子输出参数的名称。
param_type
字符串
参数类型:
- required
- optional
- dynamic
未配置默认为required。
format
列表
针对类型为tensor的参数,配置为tensor支持的数据排布格式。
包含如下取值:
ND,NHWC,NCHW,HWCN,NC1HWC0,FRACTAL_Z等。
format与type需一一对应。
type
列表
算子参数的类型。
取值范围:float16(fp16), float32(fp32), int8, int16, int32, uint8, uint16, bool, bfloat16(bf16)等。
format与type需一一对应。
attr
-
列表
属性描述。
否
name
字符串
算子属性参数的名称。
param_type
字符串
参数类型:
- required
- optional
未配置默认为required。
type
字符串
算子参数的类型。
包含如下取值:
int、bool、float、string、list_int、list_float等。
default_value
-
默认值。
- json文件可以配置多个算子,json文件为列表,列表中每一个元素为一个算子。
- 若input_desc或output_desc中存在相同name参数,则后一个会覆盖前一参数。
- 若算子原型定义json文件中input_desc和output_desc存在相同的name参数,则仅需保留input_desc中对name参数的定义。
- input_desc,output_desc中的type需按顺序一一对应匹配,format也需按顺序一一对应匹配。
例如,第一个输入x的type配置为[“int8”,“int32”],第二个输入y的type配置为[“fp16”,“fp32”],输出z的type配置为[“int32”,“int64”],最终这个算子支持输入(“int8”,“fp16”)生成int32,或者(“int32”,“fp32”)生成int64,即输入和输出的type是垂直对应的,类型不能交叉。
- input_desc,output_desc中的type与format需一一对应匹配,数量保持一致。type的数据类型为以下取值("numbertype"、"realnumbertype"、"quantizedtype"、"BasicType"、"IndexNumberType"、"all")时,需识别实际的type数量是否与format数量保持一致,若数量不一致,创建工程会收到报错提示,同时format按照type的个数进行补齐,继续生成算子工程。若type的取值为基本数据类型(如:“int32”),且与format无法一一对应时,创建工程会收到报错提示,并停止运行。
- json文件可对“attr”算子属性进行配置,具体请参考编写原型定义文件。
- 算子的Operator Type需要采用大驼峰的命名方式,即采用大写字符区分不同的语义。
- 生成算子的开发工程。
以生成AddCustom的算子工程为例,进入msOpGen工具所在目录执行如下命令,参数说明请参见表2。
${INSTALL_DIR}/python/site-packages/bin/msopgen gen -i {*.json} -f {framework type} -c {Compute Resource} -lan cpp -out {Output Path}
- 命令执行完后,会在指定目录下生成算子工程目录,工程中包含算子实现的模板文件,编译脚本等。算子工程目录生成在 -out 所指定的目录下:./output_data,目录结构如下所示:
output_data ├── build.sh // 编译入口脚本 ├── cmake │ ├── config.cmake │ ├── util // 算子工程编译所需脚本及公共编译文件存放目录 ├── CMakeLists.txt // 算子工程的CMakeLists.txt ├── CMakePresets.json // 编译配置项 ├── framework // 算子插件实现文件目录,单算子模型文件的生成不依赖算子适配插件,无需关注 ├── op_host // host侧实现文件 │ ├── add_custom_tiling.h // 算子tiling定义文件 │ ├── add_custom.cpp // 算子原型注册、shape推导、信息库、tiling实现等内容文件 │ ├── CMakeLists.txt ├── op_kernel // kernel侧实现文件 │ ├── CMakeLists.txt │ ├── add_custom.cpp // 算子代码实现文件 ├── scripts // 自定义算子工程打包相关脚本所在目录
- 可选:在算子工程中追加算子。若需要在已存在的算子工程目录下追加其他自定义算子,命令行需配置“-m 1”参数。
进入msOpGen工具所在目录执行如下命令:
${INSTALL_DIR}/python/site-packages/bin/msopgen gen -i json_path/**.json -f tf -c ai_core-{Soc Version} -out ./output_data -m 1
- -i:指定算子原型定义文件add_custom.json所在路径。
- -c:参数中{Soc Version}为昇腾AI处理器的型号。
在算子工程目录下追加**.json中的算子。MindSpore算子工程不能够添加非MindSpore框架的算子。
- 完成算子工程创建,进行算子开发。