---
title: 选择算子开发方式
description: "在章节CANN算子类型介绍中，我们了解到CANN算子有几种开发方式：TBE DSL、TBE TIK与AI CPU。针对全新开发的算子，在进行代码开发前，首先需要选择合适的算子实现方式。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/others/tbeaicpudevg/atlasopdev_10_0018.html
sourcePath: /source/zh/canncommercial/900/others/tbeaicpudevg/atlasopdev_10_0018.html
indexId: 067c40be82a4e9899470a697f75431b8d85b76f616677426d46d54305dd610ea73
---
# 选择算子开发方式

#### 简介

在章节CANN算子类型介绍中，我们了解到CANN算子有几种开发方式：TBE DSL、TBE TIK与AI CPU。针对全新开发的算子，在进行代码开发前，首先需要选择合适的算子实现方式。

本节我们就介绍全新开发算子的场景下，如何进行算子开发方式的选择，并以一些具体实例进行介绍。


#### 开发方式选择步骤

图1 选择算子开发方式流程

1. 分析算子算法的原理，提取出算子的数学表达式。
2. 对指令流程进行分析，选择合适的算子开发方式。

  a. 根据分析的数学表达式，并查看
《算子库(https://www.hiascend.com/document/detail/zh/canncommercial/900/API/aolapi/operatorlist_00001.html)》，分析是否可以通过CANN内置算子组装。

    - 若可以通过CANN内置算子组装，则优先选择通过CANN内置算子组合的方式进行功能的实现。

      - 若算子的应用场景为：将推理场景下应用程序中的某计算（例如查找最大值，进行数据类型转换等）利用AI处理器进行加速，无需将算子应用到原始框架网络中，这种场景下可通过Ascend Graph接口构图的方式实现计算的功能，然后将构建的模型在AscendCL应用程序中进行加载并执行推理即可，详细的构图方法可参见《图开发(https://www.hiascend.com/document/detail/zh/canncommercial/900/programug/graphdevg/atlasag_25_0081.html)》，本手册不再展开说明。
      - 若算子需要应用到原始框架网络中，则您只需参见        框架适配开发
，实现原始网络中的算子到CANN中算子的映射即可。
    - 若无法通过CANN内置算子组装的方式实现，则参见      2.b
。
  b. 分析通过TBE DSL计算接口是否可表达。
    TBE DSL计算接口已高度封装，开发者仅需完成计算过程的表达，后续的调度、优化及编译都可通过已有接口一键式完成，实现较为简单。

    但提供的TBE DSL计算接口有限，一般适用于实现多个向量运算的组合；对于较复杂的矩阵类计算接口，不支持与其他计算接口组合使用，详细可参见TBE DSL API中对应接口的约束说明。

    若通过TBE DSL计算接口，无法表达算子的计算逻辑，则参见2.c。

  c. 若前两种方式都无法表达算子逻辑，则分析TBE TIK计算接口是否可表达。
TBE TIK适用各类算子的开发，对于无法通过lambda表达描述的复杂计算场景也有很好的支持，例如排序类操作。但此开发方式难度较大，需要开发者使用TBE TIK提供的API完成计算过程的描述及Schedule过程，需要手工控制数据搬运的参数和调度。

    - 若由于TBE TIK计算接口对某些数据类型不支持，导致无法使用TBE TIK实现算子，您可以选择使用AI CPU的方式进行算子的实现。
    - 若您想快速打通网络，而TBE TIK的实现难度较大，此时，您也可以优先选择AI CPU的方式进行算子的实现，后续性能调测过程中再将AI CPU自定义算子转换为TBE TIK算子实现。


#### 开发方式对比一览


**表1 算子开发方式对比**

| \- | CANN内置算子组合 | TBE DSL | TBE TIK | AI CPU |
| --- | --- | --- | --- | --- |
| 语言 | C++ | Python | Python | C++ |
| 推荐级别 | 优选 | 次优选 | 次选 | 再次选 |
| 优点 | 仅需理解算子的数学逻辑，进行组装即可。 无需感知算子实现逻辑，不需要在CANN中自定义算子实现、算子原型、算子信息库这些交付件。 构图后，CANN会完成自动融合。 | TBE DSL开发方式无需感知硬件内部逻辑，入门较快。 | TBE TIK对数据的操作更加灵活，开发者自行控制数据搬运的参数和Schedule过程，对于熟悉AI处理器架构的开发者，可以很快开发出高效的算子。 | AI CPU算子的开发接口即为原生C++接口，具备C++程序开发能力的开发者能够较容易的开发出AI CPU算子，入门较快。 AI CPU开发方式无需感知硬件内部逻辑。 |
| 适用场景 | 功能可以通过CANN内置算子组装实现的场景。 | 适用于逻辑简单的向量运算。 | 适用各类算子的开发，对于无法通过lambda表达描述的复杂计算场景也有很好的支持，例如排序类操作。 | 无法通过AI Core实现某些算子，或者需要临时快速打通网络的场景。 不适合跑在AI Core上的算子，例如非矩阵类的复杂计算，逻辑比较复杂的分支密集型算子等。 例如，Dump、profiling等控制算子，Queue、Stack等资源状态类算子，TopK、Where等检索类算子。 AI Core不支持的算子，比如算子需要支持某些数据类型，但AI Core无法支持。 |
| 不足 | 仅支持需要实现的逻辑可通过内置算子组合实现的场景。 | TBE DSL计算接口有限，复杂算子逻辑无法支持表达。 当前版本，针对矩阵/卷积/池化类等接口，不支持与其他计算接口组合使用，详细可参见TBE DSL API中对应接口的约束说明。 | 开发难度较大，需要理解AI处理器架构，并且需要熟悉TIK API特征。 | AI CPU性能较低。 由于AI CPU未提供封装的计算接口，针对算子的计算过程实现会相对繁琐。 |


#### 算子开发方式选择示例

- 示例1：需要实现矩阵乘[M,K] * [K,N] ，然后对结果[M,N]进行TOPN计算。
  以上功能，可以通过CANN内置的MatMul算子与TopK算子组合实现，所以优先选用通过内置算子进行组合的方式实现。

- 示例2：假设需要实现Rsqrt算子（假设算子库中不存在此算子），Rsqrt算子的功能是计算“x”元素平方根的倒数，数学表达式为：y = 1/sqrt(x)。
  优先分析DSL计算接口，sqrt(x)可以通过tbe.dsl.vsqrt接口实现，除法可以通过tbe.dsl.vdiv接口实现，所以此算子可以选用TBE DSL的开发方式实现。

- 示例3：假设需要实现ScatterNdAdd算子（假设算子库中不存在此算子），该算子有三个输入var、indices和updates，功能为使用updates更新var中indices指定位置的数据，即在var指定位置的数据上加上updates的值。
  由于此算子涉及对tensor的不同维度上的不同元素同时计算，TBE DSL计算接口无法满足此算子的计算要求，所以需要考虑使用TIK方式进行实现。
