开发者
资源
[object Object]
[object Object]

使用tensor高维切分计算API可充分发挥硬件优势,支持开发者控制指令的迭代执行和操作数的地址间隔,功能更加灵活。

矢量计算通过Vector计算单元完成,矢量计算的源操作数和目的操作数均通过Unified Buffer(UB)来进行存储。Vector计算单元每个迭代会从UB中取出8datablock(每个datablock数据块内部地址连续,长度32Byte),进行计算,并写入对应的8个datablock中。下图为单次迭代内的8个datablock进行Exp计算的示意图。

图 1 单次迭代内的8个datablock进行Exp计算示意图[object Object][object Object]

  • 矢量计算API支持开发者通过repeatTime来配置迭代次数,从而控制指令的多次迭代执行。假设repeatTime设置为2,矢量计算单元会进行2个迭代的计算,可计算出2 * 8(每个迭代8个datablock) * 32Byte(每个datablock32Byte) = 512Byte的结果。如果数据类型为half,则计算了256个元素。下图展示了2次迭代Exp计算的示意图。由于硬件限制,repeatTime不能超过255。

    图 2 2次迭代Exp计算[object Object][object Object]

  • 针对同一个迭代中的数据,可以通过mask参数进行掩码操作来控制实际参与计算的个数。下图为进行Abs计算时通过mask逐比特模式按位控制哪些元素参与计算的示意图,1表示参与计算,0表示不参与计算。

    图 3 通过mask参数进行掩码操作示意图(以float数据类型为例)[object Object][object Object]

  • 矢量计算单元还支持带间隔的向量计算,通过dataBlockStride(单次迭代内不同datablock间地址步长)和repeatStride(相邻迭代间相同datablock的地址步长)来进行配置。

    • dataBlockStride

      如果需要控制单次迭代内,数据处理的步长,可以通过设置同一迭代内不同datablock的地址步长dataBlockStride来实现。下图给出了单次迭代内非连续场景的示意图,示例中源操作数的dataBlockStride配置为2,表示单次迭代内不同datablock间地址步长(起始地址之间的间隔)为2个datablock。

      图 4 单次迭代内非连续场景的示意图[object Object][object Object]

    • repeatStride

      当repeatTime大于1,需要多次迭代完成矢量计算时,您可以根据不同的使用场景合理设置相邻迭代间相同datablock的地址步长repeatStride的值。

      下图给出了多次迭代间非连续场景的示意图,示例中源操作数和目的操作数的repeatStride均配置为9,表示相邻迭代间相同datablock起始地址之间的间隔为9个datablock。相同datablock是指datablock在迭代内的位置相同,比如下图中的src1和src9处于相邻迭代,在迭代内都是第一个datablock的位置,其间隔即为repeatStride的数值。

      图 5 多次迭代间非连续场景的示意图[object Object][object Object]

下文中给出了dataBlockStride、repeatStride、mask的详细配置说明和示例。

[object Object]

dataBlockStride是指同一迭代内不同datablock的地址步长。

  • 连续计算,dataBlockStride设置为1,对同一迭代内的8个datablock数据连续进行处理。

  • 非连续计算,dataBlockStride值大于1(如取2),同一迭代内不同datablock之间在读取数据时出现一个datablock的间隔,如下图所示。

    图 6 dataBlockStride不同取值举例[object Object][object Object]

[object Object]

repeatStride是指相邻迭代间相同datablock的地址步长。

  • 连续计算场景:假设定义一个Tensor供目的操作数和源操作数同时使用(即地址重叠),repeatStride取值为8。此时,矢量计算单元第一次迭代读取连续8个datablock,第二轮迭代读取下一个连续的8个datablock,通过多次迭代即可完成所有输入数据的计算。

  • 非连续计算场景:repeatStride取值大于8(如取10)时,则相邻迭代间矢量计算单元读取的数据在地址上不连续,出现2个datablock的间隔。

  • 反复计算场景:repeatStride取值为0时,矢量计算单元会对首个连续的8个datablock进行反复读取和计算。

  • 部分重复计算:repeatStride取值大于0且小于8时,相邻迭代间部分数据会被矢量计算单元重复读取和计算,此种情形一般场景不涉及。

[object Object]

mask用于控制每次迭代内参与计算的元素。可通过连续模式和逐bit模式两种方式进行设置。

  • 连续模式:表示前面连续的多少个元素参与计算。数据类型为uint64_t。取值范围和源操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同(当前数据类型单次迭代时能处理的元素个数最大值为:256 / sizeof(数据类型))。当操作数的数据类型占bit位16位时(如half/uint16_t),mask∈[1, 128];当操作数为32位时(如float/int32_t),mask∈[1, 64]。

    具体样例如下:

    [object Object]

    结果示例如下:

    [object Object]
    [object Object]

    结果示例如下:

    [object Object]
  • 逐bit模式:可以按位控制哪些元素参与计算,bit位的值为1表示参与计算,0表示不参与。

    mask为数组形式,数组长度和数组元素的取值范围和操作数的数据类型有关。当操作数为16位时,数组长度为2,mask[0]、mask[1]∈[0, 2[object Object]64[object Object]-1]并且不同时为0;当操作数为32位时,数组长度为1,mask[0]∈(0, 2[object Object]64[object Object]-1];当操作数为64位时,数组长度为1,mask[0]∈(0, 2[object Object]32[object Object]-1]。

    具体样例如下:

    [object Object]

    结果示例如下:

    [object Object]

    mask过程如下:

    mask={6148914691236517205, 6148914691236517205}(注:6148914691236517205表示64位二进制数0b010101....01,mask按照低位到高位的顺序排布)

    [object Object]

    结果示例如下:

    [object Object]

    mask过程如下:

    mask={6148914691236517205, 0}(注:6148914691236517205表示64位二进制数0b010101....01)