concat 算子开发

37 阅读4分钟

零、前言

  1. 理解 HPC 组同学在算子开发这块的相关工作,理解NPU内部的基础运算逻辑。
  2. 在runtime 组同学和HPC 组同学沟通中,起到促进互相工作理解的目的。

算子开发的三个层次

  • 基础:
  1. 对开发的那个特定的算子有一些基础的认识,知道算子具体的数学运算。
  2. 知道host 传递给 device 侧的参数在算子侧怎么参与的运算
  3. 能够根据算子(运算规则)和硬件(存储层级)的特点,进行拆分(tiling) 瓦片化
  4. 了解基础硬件加速特性,比如 bulk 模式。
  • 中高级:
  1. 对硬件了如指掌,清楚的知道算子C语言转换为汇编后的每一条指令的 cycle .(CLA/FMA/SFU/Scalar/AIE)
  2. 对总线结构,数据通路的带宽有清晰的认识,明确带宽瓶颈。

目前的级别刚刚算是基础摸了一个门,对算子的理解也远不够深刻。只能说有幸参与。

  1. 先看demo

一个算子的开发 分成两部分。因为NPU 属于协处理器.所以自然就区分为 host侧 和 device 侧。

host 侧

device侧

三件事

  1. 准备要执行的 kernel 的指令

  2. 给kernel 传入参数,已经参数里面的数据要准备好

  3. 给kernel 传入一些配置,让kernel 知道该算多少。该用多少的资源算。

  4. 指令

module就加载了 kernel 指令, 也就是 mida 语言 (类 C 语言) 通过 XNCC 编译出来的 ELF 二进制文件。

这个二进制文件,就是 bell 这个NPU 架构的 ISA 指令集的一些组合。实现一个具体的运算功能需要的指令。

  1. 参数

kernel 是需要参数的,每个kernle 都需要输入输出以及一些针对输入输出需要的一些参数配置等。

这个kernel 传入了 5个参数, size1, output0_dev, size2, input0_dev, input1_dev. 这里就对应了 device 侧代码需要的具体参数。

  1. 配置

launch 配置 , 决定了 这个kernel 需要多少的资源来参与运算。这个资源的多少和这个kernel 要完成的工作密切相关,也和实现kernel 的具体算法相关,总体思想就是并行度尽可能的高,mac 利用率高,带宽 利用率

这里只暴露了两个参数,gridDim (1,1,1) blockDim(size,1,1)

先说 blockDim :

是一个包含3个变量的 结构体 传入了 size, 1, 1 这个3个值,其中用到了x.传到了 device 就变成了

blockDim.x 这个值约束了 threadIdx.x 的范围。也就是说 只能取值 0~(size-1).

再说 gridDim :

这个 gridDim是一个 结构体,有 x ,y, z 三个值,x 就对应 device侧的 一个内建变量 gridDim.x 这个值是一个确定的值,它约束了 blockIdx.x 的 值。 也就是说当 gridDim.x =1 时 blockIdx.x 只能 取 0, 当 gridDim.x =10 ,blockIdx.x = 0 ~ 9 每个TB 取各自的编号 。


总结:

最后这个算子就是完成了一个加法。每一个线程(一个小学生) 通过自己的编号(threadId.x: 班级内的编号。blockIdx.x 班级的序号) 组成了一个独一无二的 特定序号 idx. 每个线程都根据这个idx 需要 去 读入了不同的数据,做了一次加法,然后写入到不同的地方

  1. concat 算子

为什么需要开发单算子? XNNL需求以及上下游关系

xnnl 算子库和 XNGC 的关系?

  1. concat 算法数学实现

Concat算子设计方案 评审时的相关文档

XNNL P0算子

可能有多个输入,axis 是 0,1,-1.数据类型,这里只有float 类型。

F3 硬件 L2B 物理内存 8M, DSMEM 512k. 这里的存储空间大小,就限制了算子的写法。

  1. Device 侧写法

首先判断这个算子是运算瓶颈还是IO瓶颈,很明显是IO瓶颈

所以 需要让数据搬运尽可能的快起来。

首先最通用的,实现一个concat 算子,具体的数学做法是怎样的。

网上的参考:

核心就是要确定当前的这个数据

www.qianwen.com/chat/1184ce…

  • noraml

核心就是

  1. 确定当前线程应该去拿哪个输入 也就是 inputIndex

  2. 确定当前线程应该去取INPUT 里面的哪一个数,(展开成线程后,根据shape 和 axis 去取)

  3. Host侧 写法