对所有输入数据求和。数据采用二叉树方式,两两相加。

假设源操作数为256个float16的数据[data0,data1,data2...data255],两个repeat可以计算完,计算过程如下。
vec_reduce_add(mask, dst, src, work_tensor, repeat_times, src_rep_stride)
参数名称 |
输入/输出 |
含义 |
|---|---|---|
mask |
输入 |
请参考表1中mask参数描述。 |
dst |
输出 |
目的操作数,tensor起始element。 Tensor的scope为Unified Buffer。 |
src |
输入 |
源操作数,tensor起始element。 Tensor的scope为Unified Buffer。 |
work_tensor |
输入 |
指令执行期间存储中间结果,用于内部计算所需操作空间,需特别注意空间大小,参见各指令注意事项。 |
repeat_times |
输入 |
重复迭代次数。 |
src_rep_stride |
输入 |
相邻迭代间,源操作数相同block地址步长。 |
dst、src和work_tensor的数据类型需保持一致。
Atlas 200/300/500 推理产品,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)
Atlas 训练系列产品,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)
Atlas 推理系列产品AI Core,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)
Atlas 推理系列产品Vector Core,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)
无
Atlas 200/300/500 推理产品
Atlas 训练系列产品
Atlas 推理系列产品AI Core
Atlas 推理系列产品Vector Core
[1, 4095]。支持的数据类型为:Scalar(int32)、立即数(int)、Expr(int32)。
[0,65535],支持的数据类型为:Scalar(int16/int32/int64/uint16/uint32/uint64)、立即数(int)、Expr(int16/int32/int64/uint16/uint32/uint64)。from tbe import tik
tik_instance = tik.Tik()
src_gm = tik_instance.Tensor("float16", (256,), name="src_gm", scope=tik.scope_gm)
dst_gm = tik_instance.Tensor("float16", (32,), name="dst_gm", scope=tik.scope_gm)
src_ub = tik_instance.Tensor("float16", (256,), name="src_ub", scope=tik.scope_ubuf)
dst_ub = tik_instance.Tensor("float16", (32,), name="dst_ub", scope=tik.scope_ubuf)
work_tensor_ub = tik_instance.Tensor("float16", (32,), tik.scope_ubuf, "work_tensor_ub")
# 拷贝用户输入数据到src ubuf
tik_instance.data_move(src_ub, src_gm, 0, 1, 16, 0, 0)
# 给dst ubuf赋初始值0,这样输出结果更加直观
tik_instance.vec_dup(32, dst_ub, 0, 1, 1)
tik_instance.vec_reduce_add(128, dst_ub, src_ub, work_tensor_ub, 2, 8)
# 将计算结果拷贝到目标gm
tik_instance.data_move(dst_gm, dst_ub, 0, 1, 2, 0, 0)
tik_instance.BuildCCE(kernel_name="vec_reduce_add", inputs=[src_gm], outputs=[dst_gm]) 结果示例如下:
输入: src_gm=[1,1,1,...,1] 输出结果为: dst_gm=[256,0,0,...,0]
tik_instance = tik.Tik()
dtype_size = {
"int8": 1,
"uint8": 1,
"int16": 2,
"uint16": 2,
"float16": 2,
"int32": 4,
"uint32": 4,
"float32": 4,
"int64": 8,
}
# Tensor 的形状
src_shape = (3, 128)
dst_shape = (64,)
# 数据量大小
src_elements = 3 * 128
dst_elements = 64
# 数据类型
dtype = "float16"
src_gm = tik_instance.Tensor(dtype, src_shape, name="src_gm", scope=tik.scope_gm)
dst_gm = tik_instance.Tensor(dtype, dst_shape, name="dst_gm", scope=tik.scope_gm)
src_ub = tik_instance.Tensor(dtype, src_shape, name="src_ub", scope=tik.scope_ubuf)
dst_ub = tik_instance.Tensor(dtype, dst_shape, name="dst_ub", scope=tik.scope_ubuf)
work_tensor_ub = tik_instance.Tensor(dtype, dst_shape, tik.scope_ubuf, "work_tensor_ub")
# 拷贝用户输入数据到src ubuf
# 搬移的片段数
nburst = 1
# 每次搬运的片段长度,单位32B
burst = src_elements * dtype_size[dtype] // 32 // nburst
dst_burst = dst_elements * dtype_size[dtype] // 32 // nburst
# 前burst尾与后burst头的距离,单位32B
dst_stride, src_stride = 0, 0
tik_instance.data_move(src_ub, src_gm, 0, nburst, burst, dst_stride, src_stride)
# 给dst ubuf赋初始值0,这样输出结果更加直观, 此处暂不对vec_dup 进行说明,详细内容请参考对应的章节
tik_instance.vec_dup(64, dst_ub, 0, 1, 1)
tik_instance.vec_dup(64, work_tensor_ub, 0, 1, 1)
# 每个迭代的源操作数, 不同的数据类型其取值范围不同,可参见对应的章节,此示例以每次迭代处理34个数
mask = 34
# 可根据实际情况配置相应的迭代, 此处以6次迭代为例
repeat_times = 6
# 相邻迭代间,操作数头与头之间的步长,单位为block,当前表示第一次迭代的头与第二次迭代头间隔3个block
src_rep_stride = 3
tik_instance.vec_reduce_add(mask, dst_ub, src_ub, work_tensor_ub, repeat_times, src_rep_stride)
# 当前示例中work_tensor_ub 存储的值是[34. 34. 36. 68. 68. 86. 0. 0. ...],分别为6次迭代的结果
# 将计算结果拷贝到目标gm
tik_instance.data_move(dst_gm, dst_ub, 0, nburst, dst_burst, dst_stride, src_stride)
tik_instance.BuildCCE(kernel_name="vec_reduce_add", inputs=[src_gm], outputs=[dst_gm])
示例结果
输入数据(src_gm):
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1.]
[2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.
2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.
2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.
2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.
2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.
2. 2. 2. 2. 2. 2. 2. 2.]
[3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.
3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.
3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.
3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.
3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.
3. 3. 3. 3. 3. 3. 3. 3.]]
输出数据(dst_gm):
[326. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0.]