1 常用数据结构 GlobalTensor
GlobalTensor 用来存放Global Memory (外部存储)的全局数据定义原型 定义原型
2 常用数据定义 LocalTensor
LocalTensor 用于存放核上Local Memory(内部存储)的数据 定义原型
3 矢量计算指令接口
矢量计算指令接口,能够启动Al Core中的Vector单元执行计算
- 单目指令操作:Exp、Ln、Abs、Reciprocal、Sqrt、Rsqrt、Not、Relu、Sigmoid、Tanh、...
- 双目指令操作:Add、Sub、Mul、Div、Max、Min、And、Or、...
- 标量双目指令操作:Adds、Muls、Maxs、Mins、ShiftLeft、ShiftRight、LeakyRelu、...
- 标量三目指令操作:Axpy..
- 比较指令操作:Compare、…
- 选择指令操作: Select、ReduceV2、..
- 精度转换指令操作:Cast、...
- 规约指令操作: ReduceMax、ReduceMin、ReduceSum、…
- 特殊规约指令操作: WholeReduce.BlockReduce、PairReduce、…
- 数据转换操作:Transpose、TransDataTo5HD、--.
- 数据填充操作:Duplicate、Brcb....
- 数据搬移操作:DataCopy.Copy...
4 指令API的3级接口
以下指令API拥有3级接口∶ Add : dstLocal = srceLocal + src1Local; Sub : dstLocal = srceLocal - src1Local; Mul : dstLocal = srceLocal * src1Local; Div ; dstLocal = srceLocal / src1Local; And : dstLocal = srceLocal & src1Local; or : dstLocal = srceLocal | src1Local; Compare dstLocal = src0Local < src1Local; dstLocal = srceLocal > src1Local; dstLocal = srceLocal <= src1Local; dstLocal = srceLocal >= src1Local; dstLocal = srceLocal == src1Local; dstLocal = srceLocal != src1Local;
注意∶ 三级接口会进行连续矢量运算,运算量为目的LocalTensor的总长度
5 指令API的2级接口
2级连续计算接口,针对源操作数srcLocal的连续cOUNT个数据进行计算,并连续写入目的操作数dstLocal,提供了一维Tensor的连续cONT个数据的计算支持
允许用户使用形如∶
大多数指令API拥有2级接口,2级接口相对于3级接口,可以自定义运算量
- Exp(dstLocal, srcLocal,512);
- Adds(dstLocal, srcLocal,scalarvalue,512);
- Select(dstLocal,maskLocal,srceLocal,src1Local,SELMODE::VSEL_CNPMASK_SPR,256);
- ReduceMin(dstLocal, srcLocal,workLocal,8328,true);
- Duplicate(dstLocal,inputval,256);
注意: 二级接口会进行连续矢量运算,开发者指定的运算量不能超过参与运算Tensor本身的大小
6 指令API的0级接口
0级功能灵活计算接口,是最底层的开发接口,可以完整发挥硬件优势的计算API,可以进行非连续的计算 该功能可以充分发挥CANN系列芯片的强大功能指令,支持对每个操作数的Block stride ,Repeat stride,MASk的操作,允许用户使用诸多的通用参数来定制化所需要的操作
通用参数包括:
- Repeat times (迭代的次数)
- Block stride (单次迭代内不同block间地址步长)
- Repeat stride (相邻迭代间相同block的地址步长)
- Mask(用于控制参与运算的计算单元)
允许用户使用形如∶
6.1 Mask逐比特模式
6.2 Mask连续模式
7 指令API的O级接口——重复迭代次数-Repeat times
Repeat times表示迭代的次数 矢量计算单元,一次最多可以计算256Bytes的数据,每次读取连续的8个block (每个block 32Bytes,共256Bytes )数据进行计算,为完成对输入数据的处理,必须通过多次迭代( repeat )才能完成所有数据的读取与计算。 待处理数据大小为16个block ( 512Bytes ),每次迭代处理8个block ( 256Bytes ),需要两次迭代完成计算,Repeat times应设置为2 struct UnaryRepeatParams i uint32_t blockNumber = kDefau1tB1kNum; uint16_t dstBlkStride = kDefaultBlkStride;uint16_t srcBlkStride = kDefaultBlkstride; uint8_t dstRepStride = kDefaultRepStride; uint8_t srcRepStride = kDefaultRepstride;bool repeatstrideMode = false; bool strideSizeMode = false;bool half_block = false; ); 
8 指令API的O级接口——相邻迭代间相同block的地址步长
Repeat stride表示相邻迭代间相同block的地址步长 当Repeat times大于1,需要多次迭代完成矢量计算时,可以根据不同的使用场景合理设置相邻迭代间相同black的地址步长Repeat stride的值
8.1 连续计算场景
假设定义一个Tensor供目的操作数和源操作数同时使用(即地址重叠),Repeat stride取值为8。此时,矢量计算单元第一次迭代读取连续8个block,第二轮迭代读取下一个连续的8个block,通过多次迭代即可完成所有输入数据的计算 
8.2 非连续计算场景
Repeat stride取值大于8(如取10 )时,则相邻迭代间矢量计算单元读取的数据在地址上不连续,出现2个block的间隔 
8.3 反复计算场景
Repeat stride取值为o时,矢量计算单元会对首个连续的8个block进行反复读取和计算 
8.4 部分重复计算
Repeat stride取值大于0且小于8时,相邻迭代间部分数据会被矢量计算单元重复读取和计算,此种情形一般场景不涉及 
9 指令API的O级接口——同一迭代内不同block的地址步长
Block stride表示同意迭代内不同block的地址步长 如果需要控制单次迭代内,数据处理的步长,可以通过设置同一迭代内不同block的地址步长Block stride来实现。连续计算,Block stride设置为1,对同一迭代内的8个block数据连续进行处理
非连续计算,Block stride值大于1,同一迭代内不同block之间在读取数据时出现一个block的间隔 
10 指令api的0级接口--Mask参数
Mask用于控制每次迭代内参与计算的元素。可通过连续模式和逐比特模式两种方式进行设置
10.1 连续模式
表示前面连续的多少个元素参与计算.数据类型为uint 64_t.取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同(当前数据类型单次迭代时能处理的元素个数最大值为:256/size of(数据类型))。当操作数的数据类型占比特位16位时(如Half,uint 16_t),Maske[1,128];当操作数为3z位时(如Float,int 32_t),Maske[1,64]。
10.2 逐比特模式
可以按位控制哪些元素参与计算,比特位的值为1表示参与计算,0表示不参与。
参数类型为长度为2的uint64_t类型数组 参数取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同。当操作数为16位时,mask[0]、mask[1]∈[0,$2^{64}$ -1];当dst/src为32位时,mask[1]为o ,mask[0]∈[0,$2^{64}$ -1]
1 常用数据结构 GlobalTensor
GlobalTensor 用来存放Global Memory (外部存储)的全局数据定义原型 定义原型
void Init( __gm__ uint8_t *_restrict__ src_&, __gm__ uint8_t *__restrict__ dst_gm) { uint32_t dataSize = 256; //设置input_global的大小为256 GlobalTensorcint32_t inputGlobal;//类型为int32_t //设置源操作数在Global Memmory上的起始地址为src_gn,所占外部存储的大小为256个int32_t inputGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ int32_t *>(src_gm),dataSize); LocalTensor<int32_t> inputLocal - inQueuex.AllocTensor<int32_t>(): DataCopy(inoutLocal,inputGlobal, dataSize);//将Global Nemmory上的inputGlobal拷贝到Local Momory的inputLocal上 ... }2 常用数据定义 LocalTensor
LocalTensor 用于存放核上Local Memory(内部存储)的数据 定义原型
template <typename T> class LocalTensor { T Getvalue(const uint32_t offset) const;//获取LocalTensor中的某个值,返回T类型的立即数 template ctypename T1> void Setvalue(const uint32_t offset,const T1 value)const;//设置tLcallensor中的某个值,ofset单位为element //获取距原LocalTensor起始地址偏移量为offset的新LocalTensor, 注意ofiset不能超过原有localTensor的sie大小ofiset单位为elementLocalTensor operator[](const uint32_t offset) const; uint32_t GetSize() const; l/获取当前LocalTensor size大小 }3 矢量计算指令接口
矢量计算指令接口,能够启动Al Core中的Vector单元执行计算
4 指令API的3级接口
以下指令API拥有3级接口∶ Add : dstLocal = srceLocal + src1Local; Sub : dstLocal = srceLocal - src1Local; Mul : dstLocal = srceLocal * src1Local; Div ; dstLocal = srceLocal / src1Local; And : dstLocal = srceLocal & src1Local; or : dstLocal = srceLocal | src1Local; Compare dstLocal = src0Local < src1Local; dstLocal = srceLocal > src1Local; dstLocal = srceLocal <= src1Local; dstLocal = srceLocal >= src1Local; dstLocal = srceLocal == src1Local; dstLocal = srceLocal != src1Local;
5 指令API的2级接口
2级连续计算接口,针对源操作数srcLocal的连续cOUNT个数据进行计算,并连续写入目的操作数dstLocal,提供了一维Tensor的连续cONT个数据的计算支持
允许用户使用形如∶
大多数指令API拥有2级接口,2级接口相对于3级接口,可以自定义运算量
6 指令API的0级接口
0级功能灵活计算接口,是最底层的开发接口,可以完整发挥硬件优势的计算API,可以进行非连续的计算 该功能可以充分发挥CANN系列芯片的强大功能指令,支持对每个操作数的Block stride ,Repeat stride,MASk的操作,允许用户使用诸多的通用参数来定制化所需要的操作
通用参数包括:
struct UnaryRepeatParams { uint32_t blockNumber = kDefau1tB1kNum; uint16_t dstBlkStride = kDefaultBlkStride;uint16_t srcBlkStride = kDefaultBlkstride; uint8_t dstRepStride = kDefaultRepStride; uint8_t srcRepStride = kDefaultRepstride; bool repeatstrideMode = false; bool strideSizeMode = false; bool half_block = false; };允许用户使用形如∶
6.1 Mask逐比特模式
6.2 Mask连续模式
7 指令API的O级接口——重复迭代次数-Repeat times
Repeat times表示迭代的次数 矢量计算单元,一次最多可以计算256Bytes的数据,每次读取连续的8个block (每个block 32Bytes,共256Bytes )数据进行计算,为完成对输入数据的处理,必须通过多次迭代( repeat )才能完成所有数据的读取与计算。 待处理数据大小为16个block ( 512Bytes ),每次迭代处理8个block ( 256Bytes ),需要两次迭代完成计算,Repeat times应设置为2 struct UnaryRepeatParams i uint32_t blockNumber = kDefau1tB1kNum; uint16_t dstBlkStride = kDefaultBlkStride;uint16_t srcBlkStride = kDefaultBlkstride; uint8_t dstRepStride = kDefaultRepStride; uint8_t srcRepStride = kDefaultRepstride;bool repeatstrideMode = false; bool strideSizeMode = false;bool half_block = false; );
8 指令API的O级接口——相邻迭代间相同block的地址步长
Repeat stride表示相邻迭代间相同block的地址步长 当Repeat times大于1,需要多次迭代完成矢量计算时,可以根据不同的使用场景合理设置相邻迭代间相同black的地址步长Repeat stride的值
8.1 连续计算场景
假设定义一个Tensor供目的操作数和源操作数同时使用(即地址重叠),Repeat stride取值为8。此时,矢量计算单元第一次迭代读取连续8个block,第二轮迭代读取下一个连续的8个block,通过多次迭代即可完成所有输入数据的计算
8.2 非连续计算场景
Repeat stride取值大于8(如取10 )时,则相邻迭代间矢量计算单元读取的数据在地址上不连续,出现2个block的间隔
8.3 反复计算场景
Repeat stride取值为o时,矢量计算单元会对首个连续的8个block进行反复读取和计算
8.4 部分重复计算
Repeat stride取值大于0且小于8时,相邻迭代间部分数据会被矢量计算单元重复读取和计算,此种情形一般场景不涉及
9 指令API的O级接口——同一迭代内不同block的地址步长
Block stride表示同意迭代内不同block的地址步长 如果需要控制单次迭代内,数据处理的步长,可以通过设置同一迭代内不同block的地址步长Block stride来实现。连续计算,Block stride设置为1,对同一迭代内的8个block数据连续进行处理
非连续计算,Block stride值大于1,同一迭代内不同block之间在读取数据时出现一个block的间隔
10 指令api的0级接口--Mask参数
Mask用于控制每次迭代内参与计算的元素。可通过连续模式和逐比特模式两种方式进行设置
10.1 连续模式
表示前面连续的多少个元素参与计算.数据类型为uint 64_t.取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同(当前数据类型单次迭代时能处理的元素个数最大值为:256/size of(数据类型))。当操作数的数据类型占比特位16位时(如Half,uint 16_t),Maske[1,128];当操作数为3z位时(如Float,int 32_t),Maske[1,64]。
//int16_t数据类型单次迭代能处理的元素个数最大值为256/sizeof(int16_t) m 128, mask m64, maske[1, 128],所以是合法输入 //repeatTimes = 1,共128个元素,单次迭代能处理128个元素,故repeatTimes = 1 //dstBlkStride,srceBlkStnide,snc1BlkStride = 1,单次迭代内连续读取和写入数据 //dstRepStride,srceRepStnide,snc1RepStride = 8,迭代间的数据连续读取和写入 uint64_t mask = 64; Add(dstLocal, srcBLocal, src1Local, mask,1,{ 1,1,1,8,8,8 )); 结果示例如下: 输入数据(src0Local): [1 2 3...64...128] 输入数据(src1Local): [1 2 3...64...128] 输出数据(dstLoca1):[2 4 6 ...128 undefined. . .undefined] // int32_t数据类型单次迭代能处理的元素个数最大值为256/sizeof(int32_t) =64, mask =64, mask∈[1,64],所以是合法输入 // repeatTimes= 1,共64个元素,单次迭代能处理64个元素,故repeatTimes= 1 //dstBlkStride, srceBlkStride,snc1BlkStride = 1,单次迭代内连续读取和写入数据 //dstRepStride,srcORepStride,src1RepStride = 8,迭代间的数据连续读取和写入 uint64_t mask =64; Add(dstLocal, srceLocal, src1Local, mask,1,{ 1,1,1,8, 8, 8 )); 结果示例如下: 输入数据(srceLacal):[1 2 3 ...64] 输入数据(src1Local):[1 2 3 ...64] 输出数据(dstLocal):[2 4 6... 128j10.2 逐比特模式
可以按位控制哪些元素参与计算,比特位的值为1表示参与计算,0表示不参与。
参数类型为长度为2的uint64_t类型数组 参数取值范围和操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同。当操作数为16位时,mask[0]、mask[1]∈[0,$2^{64}$ -1];当dst/src为32位时,mask[1]为o ,mask[0]∈[0,$2^{64}$ -1]