已合并
修复real_div不同soc支持逻辑 #3880
jiangjiawei创建于 7月7日
修复real_div不同soc支持逻辑 #3880
已合并
jiangjiawei创建于 7月7日
1 个文件变更+124-119
Mmath/real_div/op_api/realdiv.cpp+124-119
@@ -27,155 +27,160 @@ OP_TYPE_REGISTER(RealDiv);
27static const int MODE_REAL_DIV = 0;27static const int MODE_REAL_DIV = 0;
28static const int MODE_TRUNC_DIV = 1;28static const int MODE_TRUNC_DIV = 1;
29 29 
30static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT,30static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST = {
31 op::DataType::DT_FLOAT16, op::DataType::DT_BF16, op::DataType::DT_BOOL};31 op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_BF16, op::DataType::DT_BOOL};
32 32 
33static const std::initializer_list<op::DataType> ASCEND910B_AICORE_DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT,33static const std::initializer_list<op::DataType> ASCEND910B_AICORE_DTYPE_SUPPORT_LIST = {
34 op::DataType::DT_FLOAT16, op::DataType::DT_BF16, op::DataType::DT_BOOL, op::DataType::DT_INT32};34 op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_BF16, op::DataType::DT_BOOL,
35 op::DataType::DT_INT32};
35 36 
36static const std::initializer_list<op::DataType> ASCEND610LITE_DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT,37static const std::initializer_list<op::DataType> ASCEND610LITE_DTYPE_SUPPORT_LIST = {
37 op::DataType::DT_FLOAT16, op::DataType::DT_INT8, op::DataType::DT_UINT8, op::DataType::DT_INT32};38 op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_INT8, op::DataType::DT_UINT8,
39 op::DataType::DT_INT32};
38 40 
39static const std::initializer_list<op::DataType> ASCEND950_DTYPE_SUPPORT_LIST = {op::DataType::DT_FLOAT,41static const std::initializer_list<op::DataType> ASCEND950_DTYPE_SUPPORT_LIST = {
40 op::DataType::DT_FLOAT16, op::DataType::DT_BF16, op::DataType::DT_BOOL, op::DataType::DT_INT32,42 op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_BF16,
41 op::DataType::DT_INT64};43 op::DataType::DT_BOOL, op::DataType::DT_INT32, op::DataType::DT_INT64};
42 
43// 判断当前芯片是否支持int32精度的RealDiv kernel(仅910B/910C支持)
44static bool IsInt32PrecisionSupported() {
45 auto socVersion = GetCurrentPlatformInfo().GetSocVersion();
46 return socVersion == SocVersion::ASCEND910B || socVersion == SocVersion::ASCEND910_93;
47}
48 44 
49// 根据芯片类型、dtype判断算子是否支持走aicore45// 根据芯片类型、dtype判断算子是否支持走aicore
50static bool IsAiCoreSupport(const aclTensor* self) {46static bool IsAiCoreSupport(const aclTensor* self)
51 // 根据dtype返回决定是否走aicore:true则走aicore47{
52 auto socVersion = GetCurrentPlatformInfo().GetSocVersion();48 // 根据dtype返回决定是否走aicore:true则走aicore
53 if (IsRegBase()) {49 auto socVersion = GetCurrentPlatformInfo().GetSocVersion();
54 return CheckType(self->GetDataType(), ASCEND950_DTYPE_SUPPORT_LIST);50 if (IsRegBase()) {
55 }51 return CheckType(self->GetDataType(), ASCEND950_DTYPE_SUPPORT_LIST);
56 if (socVersion == SocVersion::ASCEND610LITE) {52 }
57 return CheckType(self->GetDataType(), ASCEND610LITE_DTYPE_SUPPORT_LIST);53 if (socVersion == SocVersion::ASCEND610LITE) {
58 }54 return CheckType(self->GetDataType(), ASCEND610LITE_DTYPE_SUPPORT_LIST);
59 if (socVersion == SocVersion::ASCEND910B || socVersion == SocVersion::ASCEND910_93) {55 }
60 return CheckType(self->GetDataType(), ASCEND910B_AICORE_DTYPE_SUPPORT_LIST);56 if (socVersion == SocVersion::ASCEND910B || socVersion == SocVersion::ASCEND910_93) {
61 }57 return CheckType(self->GetDataType(), ASCEND910B_AICORE_DTYPE_SUPPORT_LIST);
62 return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST);58 }
59 return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST);
63}60}
64 61 
65bool IsRealDivSupportNonContiguous(const aclTensor* self) {62static bool is910BInt32Supported(const aclTensor* self, const aclTensor* other)
66 bool isSupportNonContiguous = IsRegBase();63{
67 return isSupportNonContiguous && IsAiCoreSupport(self);64 auto socVersion = GetCurrentPlatformInfo().GetSocVersion();
65 return (socVersion == SocVersion::ASCEND910B || socVersion == SocVersion::ASCEND910_93) &&
66 self->GetDataType() == op::DataType::DT_INT32 && other->GetDataType() == op::DataType::DT_INT32;
67}
68 
69bool IsRealDivSupportNonContiguous(const aclTensor* self)
70{
71 bool isSupportNonContiguous = IsRegBase();
72 return isSupportNonContiguous && IsAiCoreSupport(self);
68}73}
69 74 
70// AICORE算子kernel75// AICORE算子kernel
71static const aclTensor* RealDivAiCore(const aclTensor* self, const aclTensor* other, aclTensor* divOut,76static const aclTensor* RealDivAiCore(const aclTensor* self, const aclTensor* other, aclTensor* divOut,
72 aclOpExecutor* executor) {77 aclOpExecutor* executor)
73 L0_DFX(RealDivAiCore, self, other, divOut);78{
74 // 使用框架宏ADD_TO_LAUNCHER_LIST_AICORE,将AiCore RealDiv算子加入任务队列79 L0_DFX(RealDivAiCore, self, other, divOut);
75 // RealDiv算子的OpType,self、other是算子的输,divOut是算子的输出80 // 使用框架宏ADD_TO_LAUNCHER_LIST_AICORE,将AiCore RealDiv算子任务队列
76 ADD_TO_LAUNCHER_LIST_AICORE(RealDiv, OP_INPUT(self, other), OP_OUTPUT(divOut));81 // RealDiv是算子的OpType,selfother是算子的输入,divOut是算子的输出
77 return divOut;82 ADD_TO_LAUNCHER_LIST_AICORE(RealDiv, OP_INPUT(self, other), OP_OUTPUT(divOut));
83 return divOut;
78}84}
79 85 
80// AICPU算子kernel86// AICPU算子kernel
81static const aclTensor *RealDivAiCpu(const aclTensor *self, const aclTensor *other, aclTensor *divOut,87static const aclTensor* RealDivAiCpu(const aclTensor* self, const aclTensor* other, aclTensor* divOut,
82 aclOpExecutor *executor) {88 aclOpExecutor* executor)
83 L0_DFX(RealDivAiCpu);89{
84 static internal::AicpuTaskSpace space("RealDiv");90 L0_DFX(RealDivAiCpu);
85 auto ret = ADD_TO_LAUNCHER_LIST_AICPU(RealDiv, OP_ATTR_NAMES(), OP_INPUT(self, other), OP_OUTPUT(divOut));91 static internal::AicpuTaskSpace space("RealDiv");
86 CHECK_RET(ret == ACLNN_SUCCESS, nullptr);92 auto ret = ADD_TO_LAUNCHER_LIST_AICPU(RealDiv, OP_ATTR_NAMES(), OP_INPUT(self, other), OP_OUTPUT(divOut));
87 return divOut;93 CHECK_RET(ret == ACLNN_SUCCESS, nullptr);
94 return divOut;
88}95}
89 96 
90const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, aclOpExecutor* executor) {97const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, aclOpExecutor* executor)
91 op::Shape broadcastShape;98{
92 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {99 op::Shape broadcastShape;
93 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),100 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {
94 op::ToString(other->GetViewShape()).GetString());101 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),
95 return nullptr;102 op::ToString(other->GetViewShape()).GetString());
96 }103 return nullptr;
104 }
97 105 
98 aclTensor* divOut;106 aclTensor* divOut;
99 if (self->GetDataType() == op::DataType::DT_BOOL ||107 if (self->GetDataType() == op::DataType::DT_BOOL || is910BInt32Supported(self, other)) {
100 (self->GetDataType() == op::DataType::DT_INT32 && other->GetDataType() == op::DataType::DT_INT32 &&108 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);
101 IsInt32PrecisionSupported())) {109 } else {
102 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);110 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());
103 } else {111 }
104 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());
105 }
106 112 
107 if (IsAiCoreSupport(self)) {113 if (IsAiCoreSupport(self)) {
108 return RealDivAiCore(self, other, divOut, executor);114 return RealDivAiCore(self, other, divOut, executor);
109 } else {115 } else {
110 return RealDivAiCpu(self, other, divOut, executor);116 return RealDivAiCpu(self, other, divOut, executor);
111 }117 }
112 return divOut;118 return divOut;
113}119}
114 120 
115const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, const int mode, aclOpExecutor* executor) {121const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, const int mode, aclOpExecutor* executor)
116 op::Shape broadcastShape;122{
117 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {123 op::Shape broadcastShape;
118 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),124 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {
119 op::ToString(other->GetViewShape()).GetString());125 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),
120 return nullptr;126 op::ToString(other->GetViewShape()).GetString());
121 }127 return nullptr;
128 }
122 129 
123 bool isOutDtypeFloat = false;130 bool isOutDtypeFloat = false;
124 if (mode == MODE_REAL_DIV &&131 if (mode == MODE_REAL_DIV &&
125 (self->GetDataType() == op::DataType::DT_BOOL ||132 (self->GetDataType() == op::DataType::DT_BOOL || self->GetDataType() == op::DataType::DT_INT32)) {
126 (self->GetDataType() == op::DataType::DT_INT32 && other->GetDataType() == op::DataType::DT_INT32 &&133 isOutDtypeFloat = true;
127 IsInt32PrecisionSupported()))) {134 }
atomgit-bot
atomgit-botatomgit-bot7月8日

🟠 High Priority

变更行: 第 133–134 行的 MODE_REAL_DIV 条件。

问题: 旧代码为: if (mode == MODE_REAL_DIV && (DT_BOOL || (DT_INT32 && DT_INT32 && IsInt32PrecisionSupported()))) IsInt32PrecisionSupported() 仅在 910B/910_93 上返回 true。因此旧代码仅在 910B 上对 INT32+INT32 输出 DT_FLOAT。

新代码为: if (mode == MODE_REAL_DIV && (DT_BOOL || DT_INT32)) 无条件对任何芯片上的 self = DT_INT32 输出 DT_FLOAT,不再检查芯片是否支持 INT32 精度,也不再要求 other 也是 INT32。

受影响芯片及路径:

  • 其他芯片(默认路径):若绕过 CompatibleInferDivDtype 直接以 INT32 输入调用此 API,AICORE_DTYPE_SUPPORT_LIST 不含 INT32 → IsAiCoreSupport 返回 false → 走 AICPU 路径(RealDivAiCpu)。AICPU kernel 收到 INT32 输入 + DT_FLOAT 输出缓冲区的行为需确认。

额外问题: 条件中还移除了 other->GetDataType() == DT_INT32 检查。如果 API 被外部以 (INT32, FLOAT16) 调用 MODE_REAL_DIV,会错误输出 DT_FLOAT(旧代码输出 self 的 dtype = INT32)。

likedislike
128 isOutDtypeFloat = true;
129 }
130 135 
131 if (mode == MODE_TRUNC_DIV && self->GetDataType() == op::DataType::DT_BOOL) {136 if (mode == MODE_TRUNC_DIV && self->GetDataType() == op::DataType::DT_BOOL) {
132 isOutDtypeFloat = true;137 isOutDtypeFloat = true;
133 }138 }
134 139 
135 aclTensor* divOut;140 aclTensor* divOut;
136 if (isOutDtypeFloat) {141 if (isOutDtypeFloat) {
137 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);142 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);
138 } else {143 } else {
139 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());144 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());
140 }145 }
141 146 
142 if (IsAiCoreSupport(self)) {147 if (IsAiCoreSupport(self)) {
143 return RealDivAiCore(self, other, divOut, executor);148 return RealDivAiCore(self, other, divOut, executor);
144 } else {149 } else {
145 return RealDivAiCpu(self, other, divOut, executor);150 return RealDivAiCpu(self, other, divOut, executor);
146 }151 }
147 return divOut;152 return divOut;
148}153}
149 154 
150static const aclTensor* RealDivKernel(const aclTensor* self, const aclTensor* other, aclTensor* divOut,155static const aclTensor* RealDivKernel(const aclTensor* self, const aclTensor* other, aclTensor* divOut,
151 aclOpExecutor* executor) {156 aclOpExecutor* executor)
152 if (IsAiCoreSupport(self)) {157{
153 return RealDivAiCore(self, other, divOut, executor);158 if (IsAiCoreSupport(self)) {
154 } else {159 return RealDivAiCore(self, other, divOut, executor);
155 return RealDivAiCpu(self, other, divOut, executor);160 } else {
156 }161 return RealDivAiCpu(self, other, divOut, executor);
162 }
157}163}
158 164 
159const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, bool isScalar, aclOpExecutor* executor) {165const aclTensor* RealDiv(const aclTensor* self, const aclTensor* other, bool isScalar, aclOpExecutor* executor)
160 op::Shape broadcastShape;166{
161 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {167 op::Shape broadcastShape;
162 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),168 if (!BroadcastInferShape(self->GetViewShape(), other->GetViewShape(), broadcastShape)) {
163 op::ToString(other->GetViewShape()).GetString());169 OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Broadcast %s and %s failed.", op::ToString(self->GetViewShape()).GetString(),
164 return nullptr;170 op::ToString(other->GetViewShape()).GetString());
165 }171 return nullptr;
172 }
166 173 
167 aclTensor* divOut;174 aclTensor* divOut;
168 bool isInt32Precision = self->GetDataType() == op::DataType::DT_INT32 &&
169 other->GetDataType() == op::DataType::DT_INT32 && IsInt32PrecisionSupported();
170 if ((isScalar && self->GetDataType() != op::DataType::DT_BOOL && !isInt32Precision) ||
171 ((!isScalar) && self->GetDataType() == other->GetDataType() && self->GetDataType() != op::DataType::DT_BOOL &&
172 !isInt32Precision)) {
173 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());
174 } else {
175 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);
176 }
177 175 
178 return RealDivKernel(self, other, divOut, executor);176 if ((isScalar && self->GetDataType() != op::DataType::DT_BOOL) ||
177 ((!isScalar) && self->GetDataType() == other->GetDataType() && self->GetDataType() != op::DataType::DT_BOOL)) {
178 divOut = executor->AllocTensor(broadcastShape, self->GetDataType());
179 } else {
180 divOut = executor->AllocTensor(broadcastShape, op::DataType::DT_FLOAT);
181 }
182 
183 return RealDivKernel(self, other, divOut, executor);
179}184}
180 185 
181} // namespace l0op186} // namespace l0op