山东网站制作哪家好徐州建设工程交易网浙江公正
昇腾AI创新大赛训练营
 14:00-14:30 基础知识-理论课
 一、CANN 、达芬奇架构和算子
 1.AI Core逻辑架构
 达芬奇架构包含三部分:
 1)计算类:矩阵计算单元(两个矩阵扔进去相乘)、向量计算单元、标量计算单元
 2)控制类:整个计算过程提供了指令控制
 3)存储类: 存储单元和数据通路构成了存储系统
 AI core是昇腾AI处理器的核心
 
计算单元包括Vector计算单元、Cube计算单元等
 2.计算单元
 包含:
 1)Scalar计算单元
 2)Cube计算单元
 异步指令流、同步信号流、计算数据流
 数据从AI core并行计算有六条流水线
 3.什么是算子-算子在神经网络中的定义
 算子对应数学含义:
 1)一个函数空间到另一个函数空间的映射,比如微分算子,不定积分算子
 常见算子,Relu算子,Sigmoid算子
 (计算机不能精确表达根号二,因为精度不够)
 算子基本概念-总览
 ● 算子名称 用于标志网络中的某个算子- Conv1,Conv2
 ● 算子类型
 ● 数据容器
 4.张量
   Tensor用于存储算子输入数据和输出数据的容器,TensorDesc是对输入数据与输出数据的描述。
 
tensor的shape:(4,20,20,3)
 长宽都是20,4张图片,像素点由红、绿、蓝三颜色组成,即数据排布格式
   深度学习中,多维数据通过多维数组存储,比如卷积网络中特征图(Feature Map)通常用四维张量来表示
 
 遍历一般是高维到低维进行的
 基本概念-轴
 轴(Axis):代表张量中维度的下标
 shape是(5,6),axis=0表示张量中的第一维
二、实践(昇腾Ascend C快速入门)
 指导:
 
更改ip地址:
 
远程登陆
 
 实验截图:
 1.连接板子
 
 2.查看网络连接:
 
 3.检查ip地址是否修改成功:
 
 4.连接Mobaterm
 
14:30-16:00 矢量计算-理论课
 1.什么是Ascend C算子
 什么场景需要开发自定义算子?
   一般场景下无需自己开发算子,但若是以下场景,开发者需要考虑自定义算子开发
   推理场景,将第三方框架模型使用ATC工具转换为适用昇腾适配器
 Device模块
   Device负责指定计算运行的真实设备,包含aclrtSetDevice、arlrtResetDevice、aclrtGetDevice、aclrtGetRunMode等众多运行时接口用于进行device管理。
 
 2.如何编写核函数
 核函数是Ascend C算子设备侧的一种扩展
 编写:使用变量类型限定符
 规则或建议:核函数必须有void返回类型
 核函数的调用:是C/C++函数调用语句的一种扩展:<<<...>>>
kernel_name<<<blockDim<<blockDim,12ctrl, srteam>>>(argument list);
 
blockDim:规定核函数将会在几个核上执行
 12ctrl:保留参数,暂时设置为固定值nullptr
 stream:
 编程模型—SPMD模型
 Ascend C算子编程是SPMD的编程,将需要处理的数据拆分并在多个计算核心上运行;多个AI core 共享相同的指令代码

编程用到Vector_in和Vector_out
 3.采用标准C++用法,基于类库API进行编程
 基础API
 高级API
 Ascend C匹配用户开发习惯,采用标准C++语法和一组类库API进行编程
 C++运算符重载
 整个tensor参与计算:dst=src1+src2
 tensor前n个数据计算:Add(dst,src1,src2,n)
 tensor高维切分计算:Add(dst,src1,src2,mask,repeatTimes,{dataBlockStride,....}
高级API
 编程范式–TPIPE并行计算
 Programming Paradigm
 Ascend
 4.典型的计算范式
 这里向我们展示了示例代码:
namespace ops {
class AddCustom : public OpDef {
public:explicit AddCustom(const char* name) : OpDef(name){ // Add算子的第一个输入this->Input("x").ParamType(REQUIRED)    // 代表输入必选.DataType({ ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_INT32 })   // 输入支持的数据类型.Format({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND })    // 输入支持的数据格式.UnknownShapeFormat({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND });  // 未知Shape情况下的Format的默认值// Add算子的第二个输入this->Input("y").ParamType(REQUIRED).DataType({ ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_INT32 }).Format({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND }).UnknownShapeFormat({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND });this->Output("z").ParamType(REQUIRED).DataType({ ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_INT32 }).Format({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND }).UnknownShapeFormat({ ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND });// 关联InferShape函数this->SetInferShape(ge::InferShape);// 关联Tiling函数this->AICore().SetTiling(optiling::TilingFunc);// 注册算子支持的AI处理器型号,请替换为实际支持的AI处理器型号this->AICore().AddConfig("ascendxxx");}
};
// 结束算子注册
OP_ADD(AddCustom);
} // namespace ops
 
基本的向量编程范式:CopyIn,CopyOut,Compute
 基本的矩阵编程范式
 复杂的矢量、矩阵编程范式
   计算并行流动起来,实行流水任务,矢量编程任务间通信和同步,矢量中任务间通信与同步
   执行加队列是因为,Enque本身是堵塞的,有一个Enque完成,vector才能启动;做同步是用队列实现
 开发流程
 算子分析
 核函数定义
 在add_custom核函数的实现中实例化KernelAdd算子类,调用Init()函数完成内存初始化
 根据编程范式,输入输出队列
 Init()函数实现
 Process函数实现
 创建local—copyin阶段
 x+y=z compute阶段
 –copyout阶段
 c++,申请之后就要释放,(比如app越用越卡,爆了)
   以上是关于内存的处理。

16:00-17:00 实践
cd ~/samples/operator/AddCustomSample/KernelLaunch/
cp -r AddKernelInvocationNeo/ test
cd test/
bash run.sh -r cpu -v Ascend310P1
 

观察结果
 

用MobaXTerm左侧的文件栏打开~/samples/operator/AddCustomSample/KernelLaunch/test/scripts/gen_data.py
修改其中代码:
input_x = np.random.uniform(1,10,[8,2048]).astype(np.float16)
golden = np.sinh(input_x).astype(np.float16)
保存
 

再打开add_custom.cpp
修改其中compute()函数,把“Add(xxxxxxxxxxxxxxxxx)”那一行注释掉,改成sinh的计算逻辑,用xLocal当输入,zLocal当输出,改完后保存。
 

测试方式:
bash run.sh -r cpu -v Ascend310P1输出“test pass”即为修改成功。 

 感悟:
   来到华为南京研究所,不仅感受到浓厚的科研氛围,舒适的办公环境,更是在短短几节课就收益良多,对Ascend算子有了初步的理解,并亲手连接板子进行实践,在老师的指导下进行测试,过程中虽然遇到了一些困难,最后却都能独立完成,我十分激动,对计算机知识也更加有兴趣,集训营第一天我就收获满满,期待明天的旅程,同时也坚定了自己以后做华为的一份子的决心!
