重看这门课,有很多内容的认识更深了,做一些记录。
为什么不能将网络节点融合
这个问题关联到另一个问题:为什么我们需要激活函数?
使用线性的神经元堆叠得到的方程最后也是线性方程,无法表征非线性的信息,但生活中很多信息是非线性的。因此需要通过激活函数将一个线性关系变为非线性关系,多层非线性的网络堆叠可以拟合更复杂的非线性关系。
因此由于激活函数的存在,无法将各层的网络结点进行融合。
如何快速了解一个模型的计算图
Tensorflow可以通过tensorboard展现,mindspore可以通过mind slight展现。
算子运行
算子运行有很多种方式,其中较为简单的是KernelLaunch的方式。
算子开发圣经
AscendC处理器的结构
可以看到,处理器本质上是一套异构计算系统。
为什么需要CopyIn和CopyOut操作
昇腾AI处理器的逻辑见上图,可以看到,片上层次化存储和AICore还有距离,因此需要将数据拷贝到AI Core中,可以理解为从内存拷贝到寄存器。
什么是孪生调试
在CPU侧可以模拟NPU侧的效果,进行算子的开发和调试。
算子开发
kernel函数的签名必须以void作为返回值类型,在kernel中需要返回的值,通过形参指针的方式进行传递。
也提供了上述的宏来遍历参数定义。
aclrt是什么
AscendCL是在算子上层的API,Compute Language用于封装算子的调用,将API开放给上层的深度学习框架。
因此在调用算子的main.cpp文件中会有很多aclrt的命令。aclrt指的就是AsendCL runtime。
昇腾社区文件说明
算子CPU运行命令
bash run.sh -r cpu -v Ascend310P1
为什么需要数据管理,以及AscendC中如何进行数据的同步和通信
为了更大限度的提高并行度,在系统的同一时间既有数据搬入、也有计算、也有数据搬出(大多数情况下,除了开始和结尾的几个小的时间片)。那么这些不同的数据之间就有了同步的要求,否则的话对于并行的任务无法正确的进行计算。
AscendC中使用到一个Queue队列来完成任务之间的数据通信和同步,使用不同的逻辑任务来确保AI core能够正确的操作数据。
在上面这张图中可以更清晰的看到,队列就像一个生产者-消费者模型,通过这个队列就完美的解决了并行任务的数据依赖问题。
Host侧算子开发
具体的各个过程看下图:
如何定义Tiling
标准流程和快速流程的区别
前者是自定义算子FrameworkLaunch模式,后者是快速流程的KernelLaunch模式。
类似于自己写代码和写库代码的区别,自己写代码就会写调用和测试,写库代码的话就不需要这样。
生成工程框架
可以通过上述工具生成标准算子工程框架。
不同的编译方式
高维切分
一个repeat可以取256B的数据,repeat times控制迭代的次数。
block_stride控制block间的stride值。
上面这段在说啥呢? 其实说的就是计算的API,比如最简单的四则运算,在实现复杂的算子时,可能需要使用到这些小算子的结合,在结合过程中,需要灵活的取数据和计算方式,因此需要提供上述的几个参数。
内存管理
TQue有两个逻辑位置:VECIN,VECOUT
TBuf有一个逻辑位置:VECCALC
高阶API
高阶API还可以支持用户分配的内存传入作为临时存储,此时可以通过这个函数计算API需要的缓存大小。