Skip to main content

broadcast关系

两段式接口

单算子API执行的算子接口一般定义为“两段式接口”,以NN类算子接口定义为例:

<br>1<br>2<br><br>aclnnStatus aclnnXxxGetWorkspaceSize(const aclTensor *src, ..., aclTensor *out, ..., uint64_t workspaceSize, aclOpExecutor **executor);<br>aclnnStatus aclnnXxx(void* workspace, int64 workspaceSize, aclOpExecutor* executor, aclrtStream stream);<br>

其中aclnnXxxGetWorkspaceSize为第一段接口,主要用于计算本次API调用计算过程中需要多少的workspace内存。获取到本次API计算需要的workspace大小后,按照workspaceSize大小申请昇腾AI处理器内存,然后调用第二段接口aclnnXxx。

:::note 说明

  • workspace是指除输入/输出外,API在昇腾AI处理器上完成计算所需要的临时内存。

  • 第二段接口aclnnXxx(...)不能重复调用,如下调用方式会出现异常:

    aclnnXxxGetWorkspaceSize(...)
    aclnnXxx(...)
    aclnnXxx(...)

:::

父主题: 基本概念

非连续的Tensor

目前大部分算子API的输入Tensor支持“非连续的Tensor”,即一个Tensor可以通过(shape, strides, offset)表示。

示例1

例如现有一个shape=(6, 5)、strides=(10, 1)、offset=22的Tensor,其内存排布如下:

a0,0, a0,1, a0,2, a0,3, a0,4, a0,5, a0,6, a0,7, a0,8, a0,9
a1,0, a1,1, a1,2, a1,3, a1,4, a1,5, a1,6, a1,7, a1,8, a1,9
a2,0, a2,1, a2,2, a2,3, a2,4, a2,5, a2,6, a2,7, a2,8, a2,9
a3,0, a3,1, a3,2, a3,3, a3,4, a3,5, a3,6, a3,7, a3,8, a3,9
a4,0, a4,1, a4,2, a4,3, a4,4, a4,5, a4,6, a4,7, a4,8, a4,9
a5,0, a5,1, a5,2, a5,3, a5,4, a5,5, a5,6, a5,7, a5,8, a5,9
a6,0, a6,1, a6,2, a6,3, a6,4, a6,5, a6,6, a6,7, a6,8, a6,9
a7,0, a7,1, a7,2, a7,3, a7,4, a7,5, a7,6, a7,7, a7,8, a7,9
a8,0, a8,1, a8,2, a8,3, a8,4, a8,5, a8,6, a8,7, a8,8, a8,9
a9,0, a9,1, a9,2, a9,3, a9,4, a9,5, a9,6, a9,7, a9,8, a9,9

即该Tensor排布如上图的深色位置。这个完整的Tensor在内存排布上是不连续的,strides描述Tensor维度上相邻两个元素的间隔,如果在维度1上的stride为1, 该维度是连续的;如果在维度0上的stride为10,那么相邻的元素间隔10个元素,即非连续。offset表示这个Tensor的首元素相对addr的偏移。

示例2

例如现有一个shape=(4, 3)、strides=(20, 2)、offset=22的Tensor,其内存排布如下:

a0,0, a0,1, a0,2, a0,3, a0,4, a0,5, a0,6, a0,7, a0,8, a0,9
a1,0, a1,1, a1,2, a1,3, a1,4, a1,5, a1,6, a1,7, a1,8, a1,9
a2,0, a2,1, a2,2, a2,3, a2,4, a2,5, a2,6, a2,7, a2,8, a2,9
a3,0, a3,1, a3,2, a3,3, a3,4, a3,5, a3,6, a3,7, a3,8, a3,9
a4,0, a4,1, a4,2, a4,3, a4,4, a4,5, a4,6, a4,7, a4,8, a4,9
a5,0, a5,1, a5,2, a5,3, a5,4, a5,5, a5,6, a5,7, a5,8, a5,9
a6,0, a6,1, a6,2, a6,3, a6,4, a6,5, a6,6, a6,7, a6,8, a6,9
a7,0, a7,1, a7,2, a7,3, a7,4, a7,5, a7,6, a7,7, a7,8, a7,9
a8,0, a8,1, a8,2, a8,3, a8,4, a8,5, a8,6, a8,7, a8,8, a8,9
a9,0, a9,1, a9,2, a9,3, a9,4, a9,5, a9,6, a9,7, a9,8, a9,9

即该Tensor排布如上图的深色位置。这个完整的Tensor在内存排布上是不连续的,strides描述Tensor维度上相邻两个元素的间隔,如果在维度1上的stride为2, 该维度上间隔1个元素;如果在维度0上的stride为20,那么相邻的元素间隔20个元素,即非连续。offset表示这个Tensor的首元素相对addr的偏移。

父主题: 基本概念

broadcast关系

广播概念

目前大部分算子API支持NumPy的broadcast特征。“broadcast”(广播)描述了NumPy在算术运算期间如何处理具有不同形状的数组。在某些情况下,较小的数组可以“广播至”较大的数组,使两者shape互相兼容。

广播提供了一种数组向量化操作,从而使得循环在C而不是Python中发生。它无需复制不必要的数据即可完成,通常算法的效率较高。然而在某些情况下,广播并不是一种好方法,因为它会导致内存使用效率降低,从而减缓计算速度。

广播规则

一般进行广播计算时,需要理解以下规则:

  • 规则1:让所有输入数组都向形状最长的数组看齐。形状不足的部分通过在前面(左侧)填充1。

    :::note 说明 形状其实就是指the number of dimensions。比如计算a+b,其中a.shape=(2, 2, 3)、b.shape=(2, 3),那么数组b将被broadcast为b.shape=(1, 2, 3)。 :::

  • 规则2:如果两个数组的形状在任何维度上均不匹配,但是某个数组中某一个维度为1,则该维度中形状为1的数组将被拉伸以匹配另一个数组对应维度形状。

    :::note 说明 本场景下,只需保证能在某一个维度做broadcast即可。比如计算a+b,其中a.shape=(1, 3)、b.shape=(3, 1),那么两个数组会boradcast为a.shape=(3, 3)、b.shape=(3, 3)。 :::

  • 规则3:如果两个数组的形状在任何维度上均不匹配,且均没有等于1的维度,则会报错。

父主题: 基本概念

互推导关系

推导规则

当一个API(如aclnnAdd、aclnnMul等)输入的Tensor数据类型不一致时,API内部会推导出一个数据类型,将输入数据转换成该数据类型进行计算。

类型推导的规则如表1表2所示。

:::note 说明

  • 为方便描述,表格中使用的数据类型是简写形式,代表的含义:ACL_FLOAT(f32)、ACL_FLOAT16(f16)、ACL_DOUBLE(f64)、ACL_BF16(bf16)、ACL_INT8(s8)、ACL_UINT8(u8)、ACL_INT16(s16)、ACL_UINT16(u16)、ACL_INT32(s32)、ACL_UINT32(u32)、ACL_INT64(s64)、ACL_UINT64(u64)、ACL_BOOL(bool)、ACL_COMPLEX32(c32)、ACL_COMPLEX64(c64)、ACL_COMPLEX128(c128)。
  • 表格里表头和最左侧一列分别表示待推导的两个输入数据类型,表格中对应位置表示推导出的数据类型。
  • NA表示这两种类型不能进行推导计算。
  • 当输入数据类型为bool与其他任意数据类型(非u16、u32、u32),其推导出的数据类型为其他任意数据类型。当输入数据类型为bool与u16、u32、u64其中一个,均不支持数据类型推导。
  • 当输入数据类型为u16与u16,其推导出的数据类型仍为u16。当输入数据类型为u16与非u16的任意数据类型,不支持数据类型推导。
  • 当输入数据类型为u32与u32,其推导出的数据类型仍为u32。当输入数据类型为u32与非u32的任意数据类型,不支持数据类型推导。
  • 当输入数据类型为u64与u64,其推导出的数据类型仍为u64。当输入数据类型为u64与非u64的任意数据类型,不支持数据类型推导。 :::

表1 常见数据类型推导关系

数据类型f32f16f64bf16s8u8s16s32s64c32c64c128
f32f32f32f64f32f32f32f32f32f32c64c64c128
f16f32f16f64f32f16f16f16f16f16c32c64c128
f64f64f64f64f64f64f64f64f64f64c64c64c128
bf16f32f64f64bf16bf16bf16bf16bf16bf16c32c64c128
s8f32f16f64bf16s8s16s16s32s64c32c64c128
u8f32f16f64bf16s16u8s16s32s64c32c64c128
s16f32f16f64bf16s16s16s16s32s64c32c64c128
s32f32f16f64bf16s32s32s32s32s64c32c64c128
s64f32f16f64bf16s64s64s64s64s64c32c64c128
c32c64c32c64c32c32c32c32c32c32c32c64c128
c64c64c64c64c64c64c64c64c64c64c64c64c128
c128c128c128c128c128c128c128c128c128c128c128c128c128

表2 特殊数据类型推导关系

数据类型f32f16f64bf16s8u8s16s32s64c32c64c128
u16NANANANANANANANANANANANA
u32NANANANANANANANANANANANA
u64NANANANANANANANANANANANA

推导示例

  • 调用aclnnAdd接口时,如果两个输入参数的数据类型不一致,一个为float16,一个为float32,那么API内部就会将float16的数据类型转换成float32的数据类型然后进行计算。
  • 调用aclnnAdd接口时,如果两个输入参数的数据类型不一致,一个为float32,一个为bool,那么API内部就会将bool的数据类型转换成float32的数据类型然后进行计算。

父主题: 基本概念

互转换关系

当一个API(如aclnnAdd、aclnnMul等)输出的Tensor数据类型输入的数据类型推导后的计算类型不一致时,API内部就会将计算结果转换成输出类型对应的数据类型。

数据类型转换需要满足以下规则,不满足规则的将不能进行转换,调用API时会出现参数校验失败。

  • 浮点数据类型:ACL_FLOAT16、ACL_FLOAT、ACL_DOUBLE、ACL_BF16间可以互相转换。
  • 整型数据类型:ACL_INT8、ACL_UINT8、ACL_INT16、ACL_UINT16、ACL_INT32、ACL_UINT32、ACL_INT64、ACL_UINT64间可以互相转换。
  • 整型数据类型可以往浮点类型转换。
  • 浮点数据类型不可以向整型转换。
  • 非BOOL型不可以往BOOL型转换。
  • 复数类型:ACL_COMPLEX64、ACL_COMPLEX128间可以转换,复数类型不可以和非复数类型互转。

父主题: 基本概念

数据格式

数据格式(format)是用于描述一个多维Tensor的轴的业务语义,表示数据的物理排布格式,定义了解读数据的维度,比如1D、2D、3D、4D、5D等。一般在CNN(Convolutional Neural Network)类的API中需要给出具体的数据排布格式。

:::note 说明

  • 数据格式一般形式为“ACL_FORMAT_X**XXX”,为方便描述,可简写为“X**XXX”。
  • 数据格式中维度含义:N(Batch)表示批量大小、H(Height)表示特征图高度、W(Width)表示特征图宽度、C(Channels)表示特征图通道、D(Depth)表示特征图深度。 :::

常见数据格式

目前大部分算子API都是支持ND数据格式的。例如aclnnAdd接口,均标明支持的数据格式是ND(即多维Tensor的,低维度优先连续排布的规则)。

对于aclnnConvolution,该API要求输入的aclTensor设置具有业务语义的格式,而不是ND格式。此类算子,在计算过程中需要知道Tensor中的业务语义才可以进行对应的计算。例如2D卷积中,需要知道Batch维度、Channel维度、Height维度、Width维度与Tensor维度的对应关系是什么。

当调用aclCreateTensor接口的时候,根据API要求设置Tensor的数据格式,当前支持的数据格式有:

ACL_FORMAT_ND、ACL_FORMAT_NCHW、ACL_FORMAT_NHWC、ACL_FORMAT_HWCN、ACL_FORMAT_NDHWC、ACL_FORMAT_NCDHW、ACL_FORMAT_NC、ACL_FORMAT_NCL。

对于非ND的Tensor,Tensor的维度要求与format表述是一致的。例如:

  • 5D的Tensor:要求为ACL_FORMAT_NCDHW、ACL_FORMAT_NDHWC或者ACL_FORMAT_ND(如果API参数说明中未标明支持ND,设置ND格式后API将会校验报错)。
  • 4D的Tensor:要求为ACL_FORMAT_NCHW、ACL_FORMAT_NHWC、ACL_FORMAT_HWCN或者ACL_FORMAT_ND。
  • 3D的Tensor:要求为ACL_FORMAT_NCL或者ACL_FORMAT_ND。
  • 2D的Tensor:要求为ACL_FORMAT_NC或者ACL_FORMAT_ND。
  • 其他维度的Tensor:要求为ACL_FORMAT_ND。

私有数据格式

除了常见的数据格式,还存在其他的数据格式,比如ACL_FORMAT_NC1HWC0、ACL_FORMAT_FRACTAL_Z、ACL_FORMAT_NC1HWC0_C04、ACL_FORMAT_FRACTAL_NZ、ACL_FORMAT_NDC1HWC0、ACL_FORMAT_FRACTAL_Z_3D等。

这些格式,属于NPU的一些私有格式,当前绝大多数的aclnn API还不支持这些格式。如果有个别API申明了支持的数据格式,请以该API实际描述为准。

父主题: 基本概念

在线提单