已合并
[fix] resolve bool type 'repeatTimes' overflow issue #3564
nextyale创建于 6月26日
[fix] resolve bool type 'repeatTimes' overflow issue #3564
已合并
nextyale创建于 6月26日
4 个文件变更+54-5
Mmath/angle_v2/op_host/config/ascend950/angle_v2_binary.json+29-0
@@ -59,6 +59,35 @@
59 }59 }
60 ]60 ]
61 },61 },
62+ {
63+ "bin_filename": "AngleV2_bf16",
64+ "inputs": [
65+ {
66+ "name": "x",
67+ "index": 0,
68+ "dtype": "bfloat16",
69+ "format": "ND",
70+ "paramType": "required",
71+ "shape": [
72+ -2
73+ ],
74+ "format_match_mode": "FormatAgnostic"
75+ }
76+ ],
77+ "outputs": [
78+ {
79+ "name": "y",
80+ "index": 0,
81+ "dtype": "float32",
82+ "format": "ND",
83+ "paramType": "required",
84+ "shape": [
85+ -2
86+ ],
87+ "format_match_mode": "FormatAgnostic"
88+ }
89+ ]
90+ },
62 {91 {
63 "bin_filename": "AngleV2_a8c107f79de7b47ce419f0ec015539f7",92 "bin_filename": "AngleV2_a8c107f79de7b47ce419f0ec015539f7",
64 "inputs": [93 "inputs": [
Mmath/angle_v2/op_kernel/angle_v2.cpp+1-1
@@ -70,7 +70,7 @@ extern "C" __global__ __aicore__ void angle_v2(GM_ADDR x, GM_ADDR y, GM_ADDR wor
70 op.Init(x, y, &tilingData, &pipe);70 op.Init(x, y, &tilingData, &pipe);
71 op.Process();71 op.Process();
72 } 72 }
73-#if (__CCE_AICORE__ >= 320) // bf16 is only supported by 95073+#if (__CCE_AICORE__ >= 310) // bf16 is only supported by 950
74 else if (TILING_KEY_IS(KEY_DTYPE_BF16)) {74 else if (TILING_KEY_IS(KEY_DTYPE_BF16)) {
75 AngleV2N::AngleV2<bfloat16_t> op;75 AngleV2N::AngleV2<bfloat16_t> op;
76 op.Init(x, y, &tilingData, &pipe);76 op.Init(x, y, &tilingData, &pipe);
Mmath/angle_v2/op_kernel/angle_v2_base.h+1-0
@@ -23,6 +23,7 @@ using namespace AscendC;
23 23 
24constexpr int32_t BUFFER_NUM = 2;24constexpr int32_t BUFFER_NUM = 2;
25constexpr int32_t COEFFICENT = 2;25constexpr int32_t COEFFICENT = 2;
26+constexpr uint8_t UINT8_MAX_VALUE = 255;
26const double PI = 3.14159265358979323846;27const double PI = 3.14159265358979323846;
27 28 
28#ifndef INFINITY29#ifndef INFINITY
Mmath/angle_v2/op_kernel/angle_v2_u8.h+23-4
@@ -30,7 +30,15 @@ public:
30 {30 {
31 pipe = inputPipe;31 pipe = inputPipe;
32 this->BaseMemberDataInit(tilingData);32 this->BaseMemberDataInit(tilingData);
33- repeatTimes = (this->tileLength + this->mask - 1) / this->mask;33+ uint32_t actualRepeatTimes = (this->tileLength + this->mask - 1) / this->mask;
34+ if (actualRepeatTimes > UINT8_MAX_VALUE) {
35+ repeatTimes = UINT8_MAX_VALUE;
36+ loopCnt = actualRepeatTimes / repeatTimes;
37+ repeatLeft = actualRepeatTimes % repeatTimes;
38+ } else {
39+ repeatTimes = static_cast<uint8_t>(actualRepeatTimes);
40+ repeatLeft = 0;
41+ }
atomgit-bot
atomgit-botatomgit-bot6月26日

🟠 High Priority

Init()else 分支(即 actualRepeatTimes <= 255 的非溢出路径)中,仅设置了 repeatTimes = static_cast<uint8_t>(actualRepeatTimes),但成员变量 repeatLeft 保留了类内默认值 1loopCnt 保留了默认值 1

进入 Process() 后:

总重复次数 = repeatTimes + 1,而非预期的 actualRepeatTimes。例如 actualRepeatTimes = 5 时,实际写出 6 个 repeat;actualRepeatTimes = 0(极端边界情况)时,实际写出 1 个 repeat。

额外写入的 mask 个零值元素可能超出 zeroTensor 的分配边界(tileLength 个元素),存在越界写入风险。这是本次 diff 引入的逻辑回归——原代码只有一次 Duplicate,正确做了 repeatTimes 次 repeat。

建议:在 else 分支中将 repeatLeft 设为 0(或同时将 loopCnt 保持为 1),确保 Process()repeatLeft >= 1 的分支不被触发,总重复次数恰好等于 repeatTimes

改动建议
41
+ } else {
42
+ repeatTimes = static_cast<uint8_t>(actualRepeatTimes);
43
+ repeatLeft = 0;
41
44
  }
应用建议
likedislike
nextyale
6月26日 评论:
34 blockLen = this->tileLength / dataPerBlock;42 blockLen = this->tileLength / dataPerBlock;
35 43 
36 yGm.SetGlobalBuffer(reinterpret_cast<__gm__ yType*>(y) + this->offset, this->blockLength);44 yGm.SetGlobalBuffer(reinterpret_cast<__gm__ yType*>(y) + this->offset, this->blockLength);
@@ -42,10 +50,19 @@ public:
42 __aicore__ inline void Process()50 __aicore__ inline void Process()
43 {51 {
44 LocalTensor<yType> zeroTensor = outQueue.AllocTensor<yType>();52 LocalTensor<yType> zeroTensor = outQueue.AllocTensor<yType>();
45- Duplicate(
46- zeroTensor, static_cast<yType>(0.0), this->mask, repeatTimes, this->dupDstBlockStride,
47- this->dupDstRepeatStride);
48 53 
54+ for (uint32_t i = 0; i < loopCnt; i++) {
55+ Duplicate(
56+ zeroTensor, static_cast<yType>(0.0), this->mask, repeatTimes, this->dupDstBlockStride,
57+ this->dupDstRepeatStride);
58+ }
59+ if (repeatLeft >= 1) {
60+ Duplicate(
61+ zeroTensor[repeatTimes * loopCnt * this->mask], static_cast<yType>(0.0), this->mask, repeatLeft, this->dupDstBlockStride,
62+ this->dupDstRepeatStride);
63+ }
64+ 
65+ PipeBarrier<PIPE_ALL>();
49 // loop count need to be doubled, due to double buffer66 // loop count need to be doubled, due to double buffer
50 for (int64_t i = 0; i < this->tileNum; i++) {67 for (int64_t i = 0; i < this->tileNum; i++) {
51 int64_t coreOffset = i * this->tileLength;68 int64_t coreOffset = i * this->tileLength;
@@ -66,6 +83,8 @@ private:
66 TQue<QuePosition::VECOUT, BUFFER_NUM> outQueue;83 TQue<QuePosition::VECOUT, BUFFER_NUM> outQueue;
67 uint8_t repeatTimes;84 uint8_t repeatTimes;
68 int32_t dataPerBlock = 32 / sizeof(yType);85 int32_t dataPerBlock = 32 / sizeof(yType);
86+ uint32_t loopCnt = 1;
87+ uint8_t repeatLeft = 0;
69 uint16_t blockLen = 1;88 uint16_t blockLen = 1;
70};89};
71} // namespace AngleV2N90} // namespace AngleV2N