开发者
资源
[object Object]

章节已经介绍了kernel侧算子核心的实现方法,本章节侧重于介绍接入CANN框架时编程模式和API的使用。

[object Object]

在算子工程目录下的“op_kernel/xxx.cpp”文件中实现算子的核函数。核函数的定义模板已通过msOpGen工具自动生成,样例如下所示。注意这里参数的顺序按照“输入、输出、workspace、tiling”的顺序排布,开发者不要调整其顺序。

[object Object]
[object Object]
[object Object]

提供GET_TILING_DATA,用于获取算子kernel入口函数传入的tiling信息,并填入注册的Tiling结构体中,此函数会以宏展开的方式进行编译。注意,对应的算子host实现中需要定义TilingData结构体,实现并注册计算TilingData的Tiling函数。具体请参考

核函数中调用获取TilingData的样例如下:

[object Object]
[object Object]

算子工程在核函数内提供了DTYPE_<Arg>、ORIG_DTYPE_<Arg>、FORMAT_<Arg>三种宏用于表示核函数入参(算子的输入输出)的数据类型、原始数据类型和数据格式。其中<Arg>为入参的大写格式。

  • DTYPE_<Arg>,入参的数据类型。是指在Device侧实际可使用的数据类型,比如half、float等。
  • ORIG_DTYPE_<Arg>,入参的原始数据类型。是指在Host侧进行原型定义时,指定的数据类型(不包含命名空间),比如DT_FLOAT16、DT_FLOAT等。
  • FORMAT_<Arg>,入参的数据格式。是指在Host侧进行原型定义时,指定的数据格式(不包含命名空间),比如FORMAT_ND、FORMAT_NZ等。

样例如下:

[object Object]
[object Object]

某些算子,比如NonZero(统计tensor中非零值的个数),计算完成前无法得知算子输出的shape信息,算子计算完成后才能获取。该类算子在原型定义时,需要使用OutputShapeDependOnCompute接口进行标识,同时在算子核函数中将实际输出shape写入到出参中,便于框架侧基于该信息进行输出内存的管理。

在核函数所有输出的最后增加一个GM_ADDR类型的输出参数,并在核函数计算完成后,将输出shape信息写入到该出参中。shape信息的排布格式如下,大小为n * (8 + 1),每个元素的数据类型为uint64_t。其中n表示待刷新shape信息的输出个数,每个输出的shape信息都通过第1个元素来保存实际的shape维度(dim),后续的8个元素来保存具体每个维度的shape信息。

[object Object]
  • 如下示例中,算子中有一个输出依赖计算得出,输出tensor的数据类型为uint32_t,计算完成后,得到输出的shape为(32, 64),出参shape_out用于存放该shape信息,值为(2, 32, 64)。代码示例如下:

    [object Object]
  • 如下示例中,算子中有一个输出依赖计算得出,输出tensor的数据类型为uint64_t,计算完成后,得到输出的shape为(1, 64, 128, 128),出参shape_out用于存放该shape信息,值为(0x0000000080000000 | 4 , 1, 64, 128, 128)。代码示例如下:

    [object Object]
  • 如下示例中,算子中有两个输出依赖计算得出,输出tensor的数据类型为uint64_t,计算完成后,得到输出的shape为(16, 32)和 (1, 16, 16, 32),出参shape_out用于存放该shape信息。示例如下:

    [object Object]