已合并
【fix】: 修复Max/Min两个输入都是scalar的bug #1870
【fix】: 修复Max/Min两个输入都是scalar的bug #1870
已合并
liyuewei创建于 9 天前
7 个文件变更+44-29
@@ -11,10 +11,12 @@
11#ifndef __ASCENDC_API_SCALAR_MAXIMUM_H__11#ifndef __ASCENDC_API_SCALAR_MAXIMUM_H__
12#define __ASCENDC_API_SCALAR_MAXIMUM_H__12#define __ASCENDC_API_SCALAR_MAXIMUM_H__
13 13 
14+namespace AscendC {
14template <typename T>15template <typename T>
15-inline __aicore__ void Maximums(const LocalTensor<T> &dst, const T x, const T y) {16+inline __aicore__ void Maxs(const LocalTensor<T> &dst, const T x, const T y) {
16 T res = x > y ? x : y;17 T res = x > y ? x : y;
17 AscendC::Duplicate(dst, res, dst.GetSize());18 AscendC::Duplicate(dst, res, dst.GetSize());
18}19}
20+} // namespace AscendC
19 21 
20#endif // __ASCENDC_API_SCALAR_MAXIMUM_H__22#endif // __ASCENDC_API_SCALAR_MAXIMUM_H__
@@ -11,10 +11,12 @@
11#ifndef __ASCENDC_API_SCALAR_MINIMUM_H__11#ifndef __ASCENDC_API_SCALAR_MINIMUM_H__
12#define __ASCENDC_API_SCALAR_MINIMUM_H__12#define __ASCENDC_API_SCALAR_MINIMUM_H__
13 13 
14+namespace AscendC {
14template <typename T>15template <typename T>
15-inline __aicore__ void Minimums(const LocalTensor<T> &dst, const T x, const T y) {16+inline __aicore__ void Mins(const LocalTensor<T> &dst, const T x, const T y) {
16 T res = x < y ? x : y;17 T res = x < y ? x : y;
17 AscendC::Duplicate(dst, res, dst.GetSize());18 AscendC::Duplicate(dst, res, dst.GetSize());
18}19}
20+} // namespace AscendC
19 21 
20#endif // __ASCENDC_API_SCALAR_MINIMUM_H__22#endif // __ASCENDC_API_SCALAR_MINIMUM_H__
@@ -236,5 +236,26 @@ bool IsNodeHasScalarInput(const AscNode &node) {
236bool IsNodeFirstInputScalar(const AscNode &node) {236bool IsNodeFirstInputScalar(const AscNode &node) {
237 return IsScalarInputType(node.GetInDataNodes().at(0)->GetType());237 return IsScalarInputType(node.GetInDataNodes().at(0)->GetType());
238}238}
239+ 
240+bool IsScalarInput(const std::vector<af::Expression> &repeats) {
241+ return std::all_of(repeats.begin(), repeats.end(), [](const af::Expression &repeat) {
242+ return SymbolicUtils::StaticCheckEq(repeat, af::Symbol(1)) == TriBool::kTrue;
243+ });
244+}
245+ 
246+bool IsAnyInputNodeScalar(const AscNode &node) {
247+ for (const auto &in_anchor : node.GetAllInDataAnchors()) {
248+ GE_ASSERT_NOTNULL(in_anchor);
249+ GE_ASSERT_NOTNULL(in_anchor->GetPeerOutAnchor());
250+ GE_ASSERT_NOTNULL(in_anchor->GetPeerOutAnchor()->GetOwnerNode());
251+ auto in_node = std::dynamic_pointer_cast<af::AscNode>(in_anchor->GetPeerOutAnchor()->GetOwnerNode());
252+ int32_t output_idx = in_anchor->GetPeerOutAnchor()->GetIdx();
253+ auto repeats = in_node->outputs[output_idx].attr.repeats;
254+ if (IsScalarInputType(in_node->GetType()) || IsScalarInput(repeats)) {
255+ return true;
256+ }
257+ }
258+ return false;
259+}
239} // namespace ascir260} // namespace ascir
240} // namespace af261} // namespace af
@@ -31,6 +31,7 @@ Status ValidateShapeConsistencyWithSingleOutput(const AscNode &node,
31 const BroadcastCapability &broadcast_capability = {false, {}});31 const BroadcastCapability &broadcast_capability = {false, {}});
32bool IsNodeHasScalarInput(const AscNode &node);32bool IsNodeHasScalarInput(const AscNode &node);
33bool IsNodeFirstInputScalar(const AscNode &node);33bool IsNodeFirstInputScalar(const AscNode &node);
34+bool IsAnyInputNodeScalar(const AscNode &node);
34} // namespace ascir35} // namespace ascir
35} // namespace af36} // namespace af
36 37 
@@ -1207,8 +1207,7 @@ class DivAscIrCodegenImpl : public AscIrCodegen {
1207 }1207 }
1208 1208 
1209 bool IsBrcInlineSupported(const AscNode &node) const override {1209 bool IsBrcInlineSupported(const AscNode &node) const override {
1210- (void)node;1210+ return !IsAnyInputNodeScalar(node);
1211- return true;
1212 }1211 }
1213 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {1212 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {
1214 (void)is_scalar_list; // 支持任意输入是scalar1213 (void)is_scalar_list; // 支持任意输入是scalar
@@ -1248,8 +1247,7 @@ class SubAscIrCodegenImpl : public AscIrCodegen {
1248 }1247 }
1249 1248 
1250 bool IsBrcInlineSupported(const AscNode &node) const override {1249 bool IsBrcInlineSupported(const AscNode &node) const override {
1251- (void)node;1250+ return !IsAnyInputNodeScalar(node);
1252- return true;
1253 }1251 }
1254 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {1252 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {
1255 (void)is_scalar_list; // 支持任意输入是scalar1253 (void)is_scalar_list; // 支持任意输入是scalar
@@ -1285,8 +1283,7 @@ class AddAscIrCodegenImpl : public AscIrCodegen {
1285 return {"scalar_add.h"};1283 return {"scalar_add.h"};
1286 }1284 }
1287 bool IsBrcInlineSupported(const AscNode &node) const override {1285 bool IsBrcInlineSupported(const AscNode &node) const override {
1288- (void)node;1286+ return !IsAnyInputNodeScalar(node);
1289- return true;
1290 }1287 }
1291 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {1288 bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {
1292 return OnlySecondInputSupportScalar(is_scalar_list);1289 return OnlySecondInputSupportScalar(is_scalar_list);
@@ -1331,8 +1328,7 @@ class MulAscIrCodegenImpl : public AscIrCodegen {
1331 return OnlySecondInputSupportScalar({is_scalar_list[1], is_scalar_list[0]});1328 return OnlySecondInputSupportScalar({is_scalar_list[1], is_scalar_list[0]});
1332 }1329 }
1333 bool IsBrcInlineSupported(const AscNode &node) const override {1330 bool IsBrcInlineSupported(const AscNode &node) const override {
1334- (void)node;1331+ return !IsAnyInputNodeScalar(node);
1335- return true;
1336 }1332 }
1337 bool IsInplaceSupported(const AscNode &mul_node) const override {1333 bool IsInplaceSupported(const AscNode &mul_node) const override {
1338 (void)mul_node;1334 (void)mul_node;
@@ -1438,8 +1434,7 @@ class MinimumAscIrCodegenImpl : public AscIrCodegen {
1438 return true;1434 return true;
1439 }1435 }
1440 bool IsBrcInlineSupported(const AscNode &node) const override {1436 bool IsBrcInlineSupported(const AscNode &node) const override {
1441- (void)node;1437+ return !IsAnyInputNodeScalar(node);
1442- return true;
1443 }1438 }
1444 std::vector<std::string> IncludeApiHeaderFiles() const override {1439 std::vector<std::string> IncludeApiHeaderFiles() const override {
1445 return {1440 return {
@@ -1469,8 +1464,7 @@ class MaximumAscIrCodegenImpl : public AscIrCodegen {
1469 return OnlySecondInputSupportScalar(is_scalar_list);1464 return OnlySecondInputSupportScalar(is_scalar_list);
1470 }1465 }
1471 bool IsBrcInlineSupported(const AscNode &node) const override {1466 bool IsBrcInlineSupported(const AscNode &node) const override {
1472- (void)node;1467+ return !IsAnyInputNodeScalar(node);
1473- return true;
1474 }1468 }
1475 bool IsScalarInputSupportedIfExchangeInputs(const std::vector<bool> &is_scalar_list) const override {1469 bool IsScalarInputSupportedIfExchangeInputs(const std::vector<bool> &is_scalar_list) const override {
1476 GE_ASSERT_EQ(is_scalar_list.size(), 2UL);1470 GE_ASSERT_EQ(is_scalar_list.size(), 2UL);
@@ -2897,8 +2897,7 @@ class DivAscIrCodegenImplV2 : public AscIrCodegenV2 {
2897 }2897 }
2898 2898 
2899 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {2899 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
2900- (void)node;2900+ return !IsAnyInputNodeScalar(node);
2901- return true;
2902 }2901 }
2903 2902 
2904 [[nodiscard]] bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {2903 [[nodiscard]] bool IsScalarInputSupported(const std::vector<bool> &is_scalar_list) const override {
@@ -2946,8 +2945,7 @@ class SubAscIrCodegenImplV2 : public AscIrCodegenV2 {
2946 }2945 }
2947 2946 
2948 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {2947 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
2949- (void)node;2948+ return !IsAnyInputNodeScalar(node);
2950- return true;
2951 }2949 }
2952 2950 
2953 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {2951 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
@@ -3014,8 +3012,7 @@ class AddAscIrCodegenImplV2 : public AscIrCodegenV2 {
3014 }3012 }
3015 3013 
3016 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {3014 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
3017- (void)node;3015+ return !IsAnyInputNodeScalar(node);
3018- return true;
3019 }3016 }
3020 3017 
3021 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {3018 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
@@ -3077,8 +3074,7 @@ class MulAscIrCodegenImplV2 : public AscIrCodegenV2 {
3077 }3074 }
3078 3075 
3079 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {3076 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
3080- (void)node;3077+ return !IsAnyInputNodeScalar(node);
3081- return true;
3082 }3078 }
3083 3079 
3084 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {3080 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
@@ -3131,8 +3127,7 @@ class TrueDivAscIrCodegenImplV2 : public AscIrCodegenV2 {
3131 }3127 }
3132 3128 
3133 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {3129 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
3134- (void)node;3130+ return !IsAnyInputNodeScalar(node);
3135- return true;
3136 }3131 }
3137 3132 
3138 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {3133 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
@@ -3201,8 +3196,7 @@ class MinimumAscIrCodegenImplV2 : public AscIrCodegenV2 {
3201 }3196 }
3202 3197 
3203 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {3198 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
3204- (void)node;3199+ return !IsAnyInputNodeScalar(node);
3205- return true;
3206 }3200 }
3207 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {3201 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
3208 (void)node;3202 (void)node;
@@ -3263,8 +3257,7 @@ class MaximumAscIrCodegenImplV2 : public AscIrCodegenV2 {
3263 }3257 }
3264 3258 
3265 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {3259 [[nodiscard]] bool IsBrcInlineSupported(const AscNode &node) const override {
3266- (void)node;3260+ return !IsAnyInputNodeScalar(node);
3267- return true;
3268 }3261 }
3269 3262 
3270 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {3263 [[nodiscard]] bool IsVectorFunctionSupported(const AscNode &node) const override {
@@ -411,6 +411,7 @@ af::Status NddmaTemplate::SwapCastBrcAndGenNddma(const af::AscNodePtr &node_cast
411af::Status NddmaTemplate::BroadcastInputNodeIsScalar(const af::AscNodePtr &node, bool &is_scalar) {411af::Status NddmaTemplate::BroadcastInputNodeIsScalar(const af::AscNodePtr &node, bool &is_scalar) {
412 is_scalar = false;412 is_scalar = false;
413 af::AscNodePtr in_node = node;413 af::AscNodePtr in_node = node;
414+ int32_t output_idx = 0;
414 while (af::ops::IsOps<af::ascir_op::Broadcast>(in_node)) {415 while (af::ops::IsOps<af::ascir_op::Broadcast>(in_node)) {
415 auto brc_in_anchor = in_node->GetInDataAnchor(0);416 auto brc_in_anchor = in_node->GetInDataAnchor(0);
416 GE_CHECK_NOTNULL(brc_in_anchor);417 GE_CHECK_NOTNULL(brc_in_anchor);
@@ -418,13 +419,14 @@ af::Status NddmaTemplate::BroadcastInputNodeIsScalar(const af::AscNodePtr &node,
418 GE_CHECK_NOTNULL(peer_out_anchor);419 GE_CHECK_NOTNULL(peer_out_anchor);
419 in_node = std::dynamic_pointer_cast<af::AscNode>(peer_out_anchor->GetOwnerNode());420 in_node = std::dynamic_pointer_cast<af::AscNode>(peer_out_anchor->GetOwnerNode());
420 GE_CHECK_NOTNULL(in_node);421 GE_CHECK_NOTNULL(in_node);
422+ output_idx = peer_out_anchor->GetIdx();
421 }423 }
422 if (af::ops::IsOps<af::ascir_op::Scalar>(in_node) || af::ops::IsOps<af::ascir_op::ScalarData>(in_node)) {424 if (af::ops::IsOps<af::ascir_op::Scalar>(in_node) || af::ops::IsOps<af::ascir_op::ScalarData>(in_node)) {
423 is_scalar = true;425 is_scalar = true;
424 GELOGD("Node [%s] is scalar.", in_node->GetNamePtr());426 GELOGD("Node [%s] is scalar.", in_node->GetNamePtr());
425 return af::SUCCESS;427 return af::SUCCESS;
426 }428 }
427- auto &output_attr = in_node->outputs[0].attr;429+ auto &output_attr = in_node->outputs[output_idx].attr;
428 const auto &output_vec_strides = output_attr.vectorized_strides;430 const auto &output_vec_strides = output_attr.vectorized_strides;
429 GE_ASSERT_TRUE(!output_vec_strides.empty());431 GE_ASSERT_TRUE(!output_vec_strides.empty());
430 is_scalar = std::all_of(output_vec_strides.begin(), output_vec_strides.end(), [](const auto &stride) {432 is_scalar = std::all_of(output_vec_strides.begin(), output_vec_strides.end(), [](const auto &stride) {