文档
注册
评分
提单
论坛
小AI

vec_reduce_max

功能说明

在所有的输入数据中找出最大值及最大值对应的索引位置。

注意:如果有多个最大值,返回哪个最大值,请看注意事项

函数原型

vec_reduce_max(mask, dst, src, work_tensor, repeat_times, src_rep_stride, cal_index=False)

参数说明

表1 参数说明

参数名称

输入/输出

含义

mask

输入

请参考表1中mask参数描述。

dst

输入

目的操作数,tensor起始element,起始地址要求4Byte对齐。

Tensor的scope为Unified Buffer

src

输入

源操作数,tensor起始element,起始地址对齐要求请见通用约束

Tensor的scope为Unified Buffer

work_tensor

输入

指令执行期间存储中间结果,用于内部计算所需操作空间,需特别注意空间大小,参见各指令注意事项。

repeat_times

输入

重复迭代次数。Scalar(int32)、立即数(int)、Expr(int32)。注意,推荐使用立即数,性能比较高。

src_rep_stride

输入

相邻迭代间,源操作数相同block地址步长。支持的数据类型为:Scalar(int16/int32/int64/uint16/uint32/uint64)、立即数(int)、Expr(int16/int32/int64/uint16/uint32/uint64)。

cal_index

输入

指定是否获取最值的索引,仅支持bool类型,默认值为False,取值:

  • True:同时获取最值和最值索引。
  • False:不获取索引,只获取最值。

dst、src和work_tensor的数据类型需保持一致。

Atlas 200/300/500 推理产品,dst、src和work_tensor支持的数据类型为:Tensor(float16)

Atlas 训练系列产品,dst、src和work_tensor支持的数据类型为:Tensor(float16)

Atlas推理系列产品(Ascend 310P处理器)AI Core,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)

Atlas推理系列产品(Ascend 310P处理器)Vector Core,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32/int16)

Atlas A2训练系列产品/Atlas 800I A2推理产品,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)

Atlas 200/500 A2推理产品,dst、src和work_tensor支持的数据类型为:Tensor(float16/float32)

返回值

支持的型号

Atlas 200/300/500 推理产品

Atlas 训练系列产品

Atlas推理系列产品(Ascend 310P处理器)AI Core

Atlas推理系列产品(Ascend 310P处理器)Vector Core

Atlas A2训练系列产品/Atlas 800I A2推理产品

Atlas 200/500 A2推理产品

注意事项

  • repeat_times支持的数据类型为:Scalar(int32)、立即数(int)、Expr(int32)。
    • 当cal_index=False时,repeat_times[1,4095]
    • 当cal_index=True时:
      • 当操作数数据类型为int16时,操作数最大表示数值为32767,因此最多支持255次迭代,repeat_times[1,255]。
      • 当操作数数据类型为float16,操作数最大表示数值为65504,因此最多支持511次迭代,repeat_times[1,511]。
      • 当操作数数据类型为float32时,repeat_times[1,4095]。
  • src_rep_stride[0,65535],支持的数据类型为:Scalar(int16/int32/int64/uint16/uint32/uint64)、立即数(int)、Expr(int16/int32/int64/uint16/uint32/uint64)。
  • dst结果存储顺序为最值,最值索引。返回结果中索引index数据实际上是按照相应整数类型进行存储的,如dst定义为float16时,index为uint16类型,如果按照float16格式进行读取,index 的值不对,因此注意index使用时需要使用reinterpret_cast_to()方法转换到相应整数类型。
  • dst和work_tensor之间不能存在地址重叠。
  • 如果存在多个最大值,索引取第一个最大值的索引。
  • work_tensor空间限制如下:
    • 当cal_index=False时,至少需要repeat_times*2个elements。例如当repeat_times=120时,work_tensor的size至少为240个elements。
    • 当cal_index=True时,需要使用公式计算空间大小,公式如下,举例请参考调用示例
      # DTYPE_SIZE指数据类型所占的空间,以Byte为单位,如float16类型占2Bytes。elements_per_block指每个block所需的element个数
      elements_per_block = block_size // DTYPE_SIZE[dtype]
      elements_per_repeat = block_size * 8 // DTYPE_SIZE[dtype]  # elements_per_repeat指每个repeat所需的element个数
      it1_output_count = 2*repeat_times  # 第一轮操作产生的元素个数
      
      def ceil_div(a_value, b_value):
          return (a_value + b_value - 1) // b_value
      
      it2_align_start = ceil_div(it1_output_count, elements_per_block)*elements_per_block # 第二轮操作起始位置偏移,ceil_div功能为相除之后向上取整
      it2_output_count = ceil_div(it1_output_count, elements_per_repeat)*2 # 第二轮操作产生的元素个数
      it3_align_start = ceil_div(it2_output_count, elements_per_block)*elements_per_block # 第三轮操作起始位置偏移
      it3_output_count = ceil_div(it2_output_count, elements_per_repeat)*2 # 第三轮操作产生的元素个数
      it4_align_start = ceil_div(it3_output_count, elements_per_block)*elements_per_block # 第四轮操作起始位置偏移
      it4_output_count = ceil_div(it3_output_count, elements_per_repeat)*2 # 第四轮操作产生的元素个数
      final_work_tensor_need_size = it2_align_start + it3_align_start + it4_align_start + it4_output_count # 最终所需的work_tensor大小

调用示例

  1. 【举例一】

    src, work_tensor, dst均为float16的tensor,src的shape为(65, 128),vec_reduce_max/vec_reduce_min的repeat_times为65。

    接口调用示例为:

    tik_instance.vec_reduce_max(128, dst, src, work_tensor, 65, 8, cal_index=True)

    此时work_tensor的空间计算过程为:

    elements_per_block = 16 (elements)
    elements_per_repeat = 128 (elements)
    it1_output_count = 2*65 = 130 (elements)
    
    def ceil_div(a_value, b_value):
        return (a_value + b_value - 1) // b_value
    
    it2_align_start = ceil_div(130, 16)*16 = 144 (elements)
    it2_output_count = ceil_div(130, 128)*2 = 4 (elements)
    it3_align_start = ceil_div(4, 16)*16 = 16 (elements)
    it3_output_count = ceil_div(4, 128)*2 = 2 (elements)

    三轮即可拿到最终的最值以及下标,需要的空间work_tensor为:it2_align_start + it3_align_start + it3_output_count = 144 + 16 + 2 = 162 (elements)

  2. 【举例二】

    src, work_tensor, dst均为float16的tensor,src的shape为(65, 128),vec_reduce_max/vec_reduce_min的repeat_times为scalar,值65。对于repeat_times为scalar或包含scalar的情况,需要做四轮计算。

    接口调用示例为:

    scalar = tik_instance.Scalar(init_value=65, dtype=”int32”)
    tik_instance.vec_reduce_max(128, dst, src, work_tensor, scalar, 8, cal_index=True)

    此时work_tensor的空间计算过程:

    elements_per_block = 16 (elements)
    elements_per_repeat = 128 (elements)
    it1_output_count = 2*65 = 130 (elements)
    
    def ceil_div(a_value, b_value):
        return (a_value + b_value - 1) // b_value
    
    it2_align_start = ceil_div(130, 16)*16 = 144 (elements)
    it2_output_count = ceil_div(130, 128)*2 = 4 (elements)
    it3_align_start = ceil_div(4, 16)*16 = 16 (elements)
    it3_output_count = ceil_div(4, 128)*2 = 2 (elements)
    it4_align_start = ceil_div(2, 16)*16 = 16 (elements)
    it4_output_count = ceil_div(2, 128)*2 = 2(elements)

    对于repeat_times为scalar或包含scalar的情况,虽然第三轮就能拿到结果,但是由于在Python编译时无法获取scalar的值,因此还是跑了四轮,需要的空间work_tensor为:it2_align_start + it3_align_start + it4_align_start + it4_output_count = 144 + 16 + 16 + 2 = 178 (elements)

  3. 【举例三】

    src, work_tensor, dst均为float32的tensor,src的shape为(65, 64),vec_reduce_max/vec_reduce_min的repeat_times为65。

    接口调用示例为:

    tik_instance.vec_reduce_max(64, dst, src, work_tensor, 65, 8, cal_index=True)

    此时work_tensor的空间计算过程为:

    elements_per_block = 8 (elements)
    elements_per_repeat = 64 (elements)
    it1_output_count = 2*65 = 130 (elements)
    
    def ceil_div(a_value, b_value):
        return (a_value + b_value - 1) // b_value
    
    it2_align_start = ceil_div(130, 8)*8 = 136 (elements)
    it2_output_count = ceil_div(130, 64)*2 = 6 (elements)
    it3_align_start = ceil_div(6, 8)*8 = 8 (elements)
    it3_output_count = ceil_div(6, 64)*2 = 2 (elements)

    此时三轮即可拿到最终的最值以及下标,需要的空间work_tensor为:it2_align_start + it3_align_start + it3_output_count = 136 + 8 + 2 = 146 (elements)

  4. 【举例四】

    src, work_tensor, dst均为float32的tensor,src的shape为(65, 64),vec_reduce_max/vec_reduce_min的repeat_times为scalar,值65。对于repeat_times为scalar或包含scalar的情况,需要做四轮计算。

    接口调用示例为:

    scalar = tik_instance.Scalar(init_value=65, dtype=”int32”)
    tik_instance.vec_reduce_max(64, dst, src, work_tensor, scalar, 8, cal_index=True)

    此时work_tensor的空间计算过程为:

    elements_per_block = 8 (elements)
    elements_per_repeat = 64 (elements)
    it1_output_count = 2*65 = 130 (elements)
    
    def ceil_div(a_value, b_value):
        return (a_value + b_value - 1) // b_value
    
    it2_align_start = ceil_div(130, 8)*8 = 136 (elements)
    it2_output_count = ceil_div(130, 64)*2 = 6 (elements)
    it3_align_start = ceil_div(6, 8)*8 = 8 (elements)
    it3_output_count = ceil_div(6, 64)*2 = 2 (elements)
    it4_align_start = ceil_div(2, 8)*8 = 8 (elements)
    it4_output_count = ceil_div(2, 64)*2 = 2(elements)

    对于repeat_times为scalar或包含scalar的情况,虽然第三轮就能拿到结果,但是由于在Python编译时无法获取scalar的值,因此还是跑了四轮,需要的空间work_tensor为:it2_align_start + it3_align_start + it4_align_start + it4_output_count = 136 + 8 + 8 + 2 = 154 (elements)

  5. 完整示例一
    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", (16,), 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", (16,), name="dst_ub", scope=tik.scope_ubuf)
    work_tensor_ub = tik_instance.Tensor("float16", (18,), tik.scope_ubuf, "work_tensor_ub")
    # 将用户输入数据从gm搬运到ub
    tik_instance.data_move(src_ub, src_gm, 0, 1, 16, 0, 0)
    # 给dst_ubuf赋初始值0,这样输出结果更加直观
    tik_instance.vec_dup(16, dst_ub, 0, 1, 1)
    tik_instance.vec_reduce_max(128, dst_ub, src_ub, work_tensor_ub, 2, 8, cal_index=True)
    # 将计算结果从ub搬运到gm
    tik_instance.data_move(dst_gm, dst_ub, 0, 1, 1, 0, 0)
    
    tik_instance.BuildCCE(kernel_name="vec_reduce_max", inputs=[src_gm], outputs=[dst_gm])

    结果示例:

    输入数据(src_gm):
    [-3.326   -6.883    3.607   -0.969   -0.179    2.254   -3.957    3.242
      6.133   -3.559    3.656   -9.88     2.19     4.707   -7.027   -3.598
     -3.264    4.44     6.04    -6.35     0.525   -6.492    0.341   -4.477
      1.375    6.484   -7.957   -1.243   -9.586   -2.871   -6.688    2.088
      5.      -1.808   -5.62     9.47     1.311    2.69     8.58     9.3
      5.754   -6.25     4.516   -6.6     -0.331   -8.586    4.844    9.81
      7.695   -0.332   -7.137   -2.79     2.66     5.316    8.72     1.954
      5.043   -7.816    1.207    2.508   -5.06    -1.697    8.5     -6.637
     -0.647   -1.211   -3.229   -3.074    7.89     5.043   -3.059   -0.7544
      9.484   -2.809   -7.145   -1.051    9.45     7.688    6.695   -2.318
     -0.3562  -0.674    1.736    2.994   -2.018   -2.605   -7.113    6.09
     -1.766    6.574   -4.47     7.367   -7.93     6.88     7.83     6.527
      5.816   -3.135    6.195   -6.734   -8.85     1.705   -5.023    5.992
      6.062   -3.342    8.03    -0.748    0.9883   3.191    2.75     8.39
      9.17    -5.887    1.378   -8.77    -9.05    -3.11    -7.203    9.79
      9.64     3.945    9.32     7.812    7.066    0.664    5.234   -4.61
     -3.559   -7.73     1.441    5.434    8.23     4.785   -1.231    8.03
      0.293   -0.1658  -5.48    -3.293    8.89    -7.926   -9.66     1.597
      0.5396   9.25    -6.74     7.086   -0.954    8.96     2.318   -2.395
     -9.19    -6.176   -4.297   -7.812   -1.787   -5.39     6.5      9.055
     -0.9556   2.4      2.092    7.35     0.7017   1.548   -2.637   -5.145
     -2.938    5.617   -3.451    7.5     -5.426   -7.62     7.535   -9.14
     -8.7     -3.436    2.283   -6.18     2.836    5.707   -1.356    8.664
      1.625   -3.717    1.478   -6.67    -4.023    2.652    4.805   -8.25
      2.63    -1.394   -3.227    1.595    7.49     7.574   -3.053   -1.841
     -7.06     0.4524  -5.71     5.37     8.72     8.51     4.836   -5.05
     -7.043    5.188   -5.332    5.62    -0.6465   5.773    8.53     7.793
     -4.215    7.47    -2.451    8.18     5.543   -7.367    7.105   -0.10364
      4.465    0.3362   0.9287   2.447   -9.87     7.844    2.084    4.527
      7.582   -3.217   -5.695   -6.375    0.627    2.24     6.625   -9.55
     -5.613    7.055    9.48    -6.613    5.49     5.066    4.117    9.516
     -4.594   -0.781    2.102    9.94     6.49    -7.82     0.11975  3.146  ]
    
    输出数据(dst_gm):
    [9.938e+00 1.496e-05 0.000e+00 0.000e+00 0.000e+00 0.000e+00 0.000e+00
     0.000e+00 0.000e+00 0.000e+00 0.000e+00 0.000e+00 0.000e+00 0.000e+00
     0.000e+00 0.000e+00]
  6. 完整示例二
    def ceil_div(a_value, b_value):
        return (a_value + b_value - 1) // b_value
    
    
    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)
    
    # 拷贝用户输入数据到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)
    
    # mask 应用于每个迭代的源操作数, 不同的数据类型其取值范围不同,可参见对应的章节,此示例以每次迭代处理34个数
    mask = 34
    # cal_index 指定是否获取最值的索引,此处以True为例
    cal_index = True
    # 可根据实际情况配置相应的迭代, 此处以6次迭代为例
    repeat_times = tik_instance.Scalar(dtype="int32", init_value=6)
    elements_per_block = 32 // dtype_size[dtype]  # 16
    elements_per_repeat = 256 // dtype_size[dtype]  # 128
    it1_output_count = 2 * 6  # 12
    # 第二轮操作起始位置偏移,ceil_div功能为相除之后向上取整,16
    it2_align_start = ceil_div(it1_output_count, elements_per_block) * elements_per_block
    # 第二轮操作产生的元素个数 2
    it2_output_count = ceil_div(it1_output_count, elements_per_repeat) * 2
    # 第三轮操作起始位置偏移,ceil_div功能为相除之后向上取整,16
    it3_align_start = ceil_div(it2_output_count, elements_per_block) * elements_per_block
    # 第二轮操作产生的元素个数 2
    it3_output_count = ceil_div(it2_output_count, elements_per_repeat) * 2
    # 第四轮操作起始位置偏移,ceil_div功能为相除之后向上取整,16
    it4_align_start = ceil_div(it3_output_count, elements_per_block) * elements_per_block
    # 第四轮操作产生的元素个数 2
    it4_output_count = ceil_div(it3_output_count, elements_per_repeat) * 2
    
    # 需要的空间至少 50
    final_work_tensor_need_size = it2_align_start + it3_align_start + it4_align_start + it4_output_count
    cal_shape = (final_work_tensor_need_size,)
    
    work_tensor_ub = tik_instance.Tensor(dtype, cal_shape, tik.scope_ubuf, "work_tensor_ub")
    tik_instance.vec_dup(final_work_tensor_need_size, work_tensor_ub, 0, 1, 1)
    
    # 相邻迭代间,操作数头与头之间的步长,单位为block,当前表示第一次迭代的头与第二次迭代头间隔3个block
    src_rep_stride = 3
    
    tik_instance.vec_reduce_max(mask, dst_ub, src_ub, work_tensor_ub, repeat_times, src_rep_stride, cal_index=cal_index)
    # 当前示例中work_tensor_ub 存储的值是[3.30e+01 1.97e-06 8.10e+01 1.97e-06 1.29e+02 1.97e-06 1.77e+02 1.97e-06
    #  2.25e+02 1.97e-06 2.73e+02 1.97e-06  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_max", inputs=[src_gm], outputs=[dst_gm])
    
    示例结果
    输入数据(src_gm):
    [[  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.  12.  13.
       14.  15.  16.  17.  18.  19.  20.  21.  22.  23.  24.  25.  26.  27.
       28.  29.  30.  31.  32.  33.  34.  35.  36.  37.  38.  39.  40.  41.
       42.  43.  44.  45.  46.  47.  48.  49.  50.  51.  52.  53.  54.  55.
       56.  57.  58.  59.  60.  61.  62.  63.  64.  65.  66.  67.  68.  69.
       70.  71.  72.  73.  74.  75.  76.  77.  78.  79.  80.  81.  82.  83.
       84.  85.  86.  87.  88.  89.  90.  91.  92.  93.  94.  95.  96.  97.
       98.  99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111.
      112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125.
      126. 127.]
     [128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141.
      142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155.
      156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169.
      170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183.
      184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197.
      198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211.
      212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225.
      226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239.
      240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253.
      254. 255.]
     [256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269.
      270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283.
      284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297.
      298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311.
      312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325.
      326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339.
      340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353.
      354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367.
      368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381.
      382. 383.]]
    
    输出数据(dst_gm):
    [2.73e+02 1.63e-05 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00
     0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00 0.00e+00]
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词