已合并
【PR】: revert reorganize tensor layout utilities and update codegen #1898
Phl17创建于 14 天前
【PR】: revert reorganize tensor layout utilities and update codegen #1898
已合并
共 16 个文件变更+61-157
| @@ -15,8 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 18 | 19 | ||
| 19 | -namespace ascgen_utils { | 20 | +namespace optimize { |
| 20 | af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info) { | 21 | af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info) { |
| 21 | const auto &axis = attr.axis; | 22 | const auto &axis = attr.axis; |
| 22 | const auto &repeats = attr.repeats; | 23 | const auto &repeats = attr.repeats; |
| @@ -63,4 +64,4 @@ af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr & | |||
| 63 | 64 | ||
| 64 | return af::SUCCESS; | 65 | return af::SUCCESS; |
| 65 | } | 66 | } |
| 66 | -} // namespace ascgen_utils | 67 | +} // namespace optimize |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | -namespace ascgen_utils { | 16 | +namespace optimize { |
| 17 | struct DiscontinuityInfo { | 17 | struct DiscontinuityInfo { |
| 18 | bool is_tail_axis_discontinuous{false}; // 最后一根有效轴不连续 | 18 | bool is_tail_axis_discontinuous{false}; // 最后一根有效轴不连续 |
| 19 | bool has_multiple_discontinuities{false}; // 多根轴不连续场景 | 19 | bool has_multiple_discontinuities{false}; // 多根轴不连续场景 |
| @@ -22,6 +22,6 @@ class TensorLayoutUtils { | |||
| 22 | public: | 22 | public: |
| 23 | static af::Status AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info); | 23 | static af::Status AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info); |
| 24 | }; | 24 | }; |
| 25 | -} // namespace ascgen_utils | 25 | +} // namespace optimize |
| 26 | 26 | ||
| 27 | 27 | ||
| @@ -1,94 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | - | ||
| 12 | - | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | - | ||
| 17 | -namespace ascgen_utils { | ||
| 18 | -namespace { | ||
| 19 | -af::AscTensorAttr CreateAttr(const std::vector<int64_t> &axis, const std::vector<int64_t> &repeats, | ||
| 20 | - const std::vector<int64_t> &strides, const std::vector<int64_t> &vectorized_axis) { | ||
| 21 | - af::AscTensorAttr attr; | ||
| 22 | - for (const auto value : axis) { | ||
| 23 | - attr.axis.emplace_back(value); | ||
| 24 | - } | ||
| 25 | - for (const auto value : repeats) { | ||
| 26 | - attr.repeats.emplace_back(af::Symbol(value)); | ||
| 27 | - } | ||
| 28 | - for (const auto value : strides) { | ||
| 29 | - attr.strides.emplace_back(af::Symbol(value)); | ||
| 30 | - } | ||
| 31 | - attr.vectorized_axis = vectorized_axis; | ||
| 32 | - return attr; | ||
| 33 | -} | ||
| 34 | -} // namespace | ||
| 35 | - | ||
| 36 | -TEST(TensorLayoutUtilsTest, AnalyzeContinuousLayout) { | ||
| 37 | - const auto attr = CreateAttr({0, 1}, {2, 4}, {4, 1}, {0, 1}); | ||
| 38 | - DiscontinuityInfo info; | ||
| 39 | - | ||
| 40 | - EXPECT_EQ(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 41 | - EXPECT_FALSE(info.is_tail_axis_discontinuous); | ||
| 42 | - EXPECT_FALSE(info.has_multiple_discontinuities); | ||
| 43 | -} | ||
| 44 | - | ||
| 45 | -TEST(TensorLayoutUtilsTest, AnalyzeSingleDiscontinuity) { | ||
| 46 | - const auto attr = CreateAttr({0, 1}, {2, 4}, {8, 1}, {0, 1}); | ||
| 47 | - DiscontinuityInfo info; | ||
| 48 | - | ||
| 49 | - EXPECT_EQ(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 50 | - EXPECT_FALSE(info.is_tail_axis_discontinuous); | ||
| 51 | - EXPECT_FALSE(info.has_multiple_discontinuities); | ||
| 52 | -} | ||
| 53 | - | ||
| 54 | -TEST(TensorLayoutUtilsTest, AnalyzeMultipleDiscontinuities) { | ||
| 55 | - const auto attr = CreateAttr({0, 1, 2}, {2, 2, 4}, {16, 3, 1}, {0, 1, 2}); | ||
| 56 | - DiscontinuityInfo info; | ||
| 57 | - | ||
| 58 | - EXPECT_EQ(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 59 | - EXPECT_FALSE(info.is_tail_axis_discontinuous); | ||
| 60 | - EXPECT_TRUE(info.has_multiple_discontinuities); | ||
| 61 | -} | ||
| 62 | - | ||
| 63 | -TEST(TensorLayoutUtilsTest, AnalyzeTailAxisDiscontinuity) { | ||
| 64 | - const auto attr = CreateAttr({0, 1}, {2, 4}, {4, 2}, {1}); | ||
| 65 | - DiscontinuityInfo info; | ||
| 66 | - | ||
| 67 | - EXPECT_EQ(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 68 | - EXPECT_TRUE(info.is_tail_axis_discontinuous); | ||
| 69 | - EXPECT_FALSE(info.has_multiple_discontinuities); | ||
| 70 | -} | ||
| 71 | - | ||
| 72 | -TEST(TensorLayoutUtilsTest, IgnoreBroadcastAxisWhenAnalyzingDiscontinuity) { | ||
| 73 | - const auto attr = CreateAttr({0, 1, 2}, {2, 3, 4}, {12, 0, 1}, {0, 1, 2}); | ||
| 74 | - DiscontinuityInfo info; | ||
| 75 | - | ||
| 76 | - EXPECT_EQ(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 77 | - EXPECT_FALSE(info.is_tail_axis_discontinuous); | ||
| 78 | - EXPECT_FALSE(info.has_multiple_discontinuities); | ||
| 79 | -} | ||
| 80 | - | ||
| 81 | -TEST(TensorLayoutUtilsTest, ReturnFailureWhenVectorizedAxisIsMissing) { | ||
| 82 | - const auto attr = CreateAttr({0, 1}, {2, 4}, {4, 1}, {2}); | ||
| 83 | - DiscontinuityInfo info; | ||
| 84 | - | ||
| 85 | - EXPECT_NE(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 86 | -} | ||
| 87 | - | ||
| 88 | -TEST(TensorLayoutUtilsTest, ReturnFailureWhenLayoutAttributeLengthsAreInsufficient) { | ||
| 89 | - const auto attr = CreateAttr({0, 1}, {2}, {4}, {0, 1}); | ||
| 90 | - DiscontinuityInfo info; | ||
| 91 | - | ||
| 92 | - EXPECT_NE(TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info), af::SUCCESS); | ||
| 93 | -} | ||
| 94 | -} // namespace ascgen_utils | ||
Mautofuse/tests/v35/st/backend_e2e_v2/floortoint_float_test/floortoint_float_backend_generate.cpp+1-1
| @@ -49,6 +49,6 @@ TEST_F(TestBackendFloortointFloatE2e, FloortointFloatE2eCodegen) { | |||
| 49 | EXPECT_NE(kernel.find("AscendC::Cast(local_3[0], local_2[0], AscendC::RoundMode::CAST_FLOOR, " | 49 | EXPECT_NE(kernel.find("AscendC::Cast(local_3[0], local_2[0], AscendC::RoundMode::CAST_FLOOR, " |
| 50 | "local_2_actual_size);"), | 50 | "local_2_actual_size);"), |
| 51 | std::string::npos); | 51 | std::string::npos); |
| 52 | - EXPECT_NE(kernel.find("DataCopyPadExtend<int32_t, AscendC::PaddingMode::Compact>"), std::string::npos); | 52 | + EXPECT_NE(kernel.find("DataCopyPadExtend<int32_t, AscendC::PaddingMode::Normal>"), std::string::npos); |
| 53 | }); | 53 | }); |
| 54 | } | 54 | } |
| @@ -4174,10 +4174,10 @@ constexpr int64_t kOutputDim1 = 16; | |||
| 4174 | constexpr int64_t kDim2 = 5; | 4174 | constexpr int64_t kDim2 = 5; |
| 4175 | 4175 | ||
| 4176 | constexpr int64_t kInputStride0 = IL_INPUT_STRIDE0; | 4176 | constexpr int64_t kInputStride0 = IL_INPUT_STRIDE0; |
| 4177 | -constexpr int64_t kInputStride1 = (!kExpectSimt && !kExpectSk && IL_INPUT_STRIDE1 == 10) ? 5 : IL_INPUT_STRIDE1; | 4177 | +constexpr int64_t kInputStride1 = IL_INPUT_STRIDE1; |
| 4178 | constexpr int64_t kInputStride2 = IL_INPUT_STRIDE2; | 4178 | constexpr int64_t kInputStride2 = IL_INPUT_STRIDE2; |
| 4179 | constexpr int64_t kIndexStride0 = IL_INDEX_STRIDE0; | 4179 | constexpr int64_t kIndexStride0 = IL_INDEX_STRIDE0; |
| 4180 | -constexpr int64_t kIndexStride1 = (!kExpectSimt && !kExpectSk && IL_INDEX_STRIDE1 == 10) ? 5 : IL_INDEX_STRIDE1; | 4180 | +constexpr int64_t kIndexStride1 = IL_INDEX_STRIDE1; |
| 4181 | constexpr int64_t kIndexStride2 = IL_INDEX_STRIDE2; | 4181 | constexpr int64_t kIndexStride2 = IL_INDEX_STRIDE2; |
| 4182 | 4182 | ||
| 4183 | constexpr int64_t kEffectiveInputStride0 = kInputStride0; | 4183 | constexpr int64_t kEffectiveInputStride0 = kInputStride0; |
| @@ -4369,8 +4369,8 @@ std::shared_ptr<af::AscGraph> CreateSubGraph() { | |||
| 4369 | const std::vector<af::AxisId> output_axes = {view.output_row_axis, view.output_inner_axis}; | 4369 | const std::vector<af::AxisId> output_axes = {view.output_row_axis, view.output_inner_axis}; |
| 4370 | const std::vector<af::Expression> output_repeats = {view.index_rows, view.embedding_size}; | 4370 | const std::vector<af::Expression> output_repeats = {view.index_rows, view.embedding_size}; |
| 4371 | const std::vector<af::Expression> output_strides = {view.embedding_size, af::ops::One}; | 4371 | const std::vector<af::Expression> output_strides = {view.embedding_size, af::ops::One}; |
| 4372 | - const std::vector<af::Expression> index_repeats = {view.index_rows, view.embedding_size}; | 4372 | + const std::vector<af::Expression> index_repeats = {view.index_rows, af::ops::One}; |
| 4373 | - const std::vector<af::Expression> index_strides = {view.embedding_size, af::ops::One}; | 4373 | + const std::vector<af::Expression> index_strides = {af::ops::One, af::ops::Zero}; |
| 4374 | const std::vector<af::Expression> reduce_repeats = {view.index_rows, af::ops::One}; | 4374 | const std::vector<af::Expression> reduce_repeats = {view.index_rows, af::ops::One}; |
| 4375 | const std::vector<af::Expression> reduce_strides = {af::ops::One, af::ops::Zero}; | 4375 | const std::vector<af::Expression> reduce_strides = {af::ops::One, af::ops::Zero}; |
| 4376 | 4376 | ||
| @@ -4388,11 +4388,16 @@ std::shared_ptr<af::AscGraph> CreateSubGraph() { | |||
| 4388 | index_load.x = index.y; | 4388 | index_load.x = index.y; |
| 4389 | SetView(index_load, output_axes, index_repeats, index_strides, af::DT_INT32); | 4389 | SetView(index_load, output_axes, index_repeats, index_strides, af::DT_INT32); |
| 4390 | 4390 | ||
| 4391 | + af::ascir_op::Cast index_cast("index_cast"); | ||
| 4392 | + view.graph->AddNode(index_cast); | ||
| 4393 | + index_cast.x = index_load.y; | ||
| 4394 | + SetView(index_cast, output_axes, index_repeats, index_strides, af::DT_INT64); | ||
| 4395 | + | ||
| 4391 | af::ascir_op::Broadcast index_broadcast("index_broadcast"); | 4396 | af::ascir_op::Broadcast index_broadcast("index_broadcast"); |
| 4392 | view.graph->AddNode(index_broadcast); | 4397 | view.graph->AddNode(index_broadcast); |
| 4393 | index_broadcast.attr.api.compute_type = af::ComputeType::kComputeBroadcast; | 4398 | index_broadcast.attr.api.compute_type = af::ComputeType::kComputeBroadcast; |
| 4394 | - index_broadcast.x = index_load.y; | 4399 | + index_broadcast.x = index_cast.y; |
| 4395 | - SetView(index_broadcast, output_axes, output_repeats, output_strides, af::DT_INT32); | 4400 | + SetView(index_broadcast, output_axes, output_repeats, output_strides, af::DT_INT64); |
| 4396 | 4401 | ||
| 4397 | af::ascir_op::IndirectLoad indirect_load("indirect_load"); | 4402 | af::ascir_op::IndirectLoad indirect_load("indirect_load"); |
| 4398 | view.graph->AddNode(indirect_load); | 4403 | view.graph->AddNode(indirect_load); |
| @@ -1682,10 +1682,10 @@ extern "C" int64_t AutofuseTiling(AutofuseTilingData *, uint32_t *, uint32_t *, | |||
| 1682 | 1682 | ||
| 1683 | namespace { | 1683 | namespace { |
| 1684 | constexpr int32_t kInputStride0 = IL_INPUT_STRIDE0; | 1684 | constexpr int32_t kInputStride0 = IL_INPUT_STRIDE0; |
| 1685 | -constexpr int32_t kInputStride1 = (!IL_EXPECT_SIMT && !IL_EXPECT_SK && IL_INPUT_STRIDE1 == 10) ? 5 : IL_INPUT_STRIDE1; | 1685 | +constexpr int32_t kInputStride1 = IL_INPUT_STRIDE1; |
| 1686 | constexpr int32_t kInputStride2 = IL_INPUT_STRIDE2; | 1686 | constexpr int32_t kInputStride2 = IL_INPUT_STRIDE2; |
| 1687 | constexpr int32_t kIndexStride0 = IL_INDEX_STRIDE0; | 1687 | constexpr int32_t kIndexStride0 = IL_INDEX_STRIDE0; |
| 1688 | -constexpr int32_t kIndexStride1 = (!IL_EXPECT_SIMT && !IL_EXPECT_SK && IL_INDEX_STRIDE1 == 10) ? 5 : IL_INDEX_STRIDE1; | 1688 | +constexpr int32_t kIndexStride1 = IL_INDEX_STRIDE1; |
| 1689 | constexpr int32_t kIndexStride2 = IL_INDEX_STRIDE2; | 1689 | constexpr int32_t kIndexStride2 = IL_INDEX_STRIDE2; |
| 1690 | 1690 | ||
| 1691 | constexpr int32_t kEffectiveInputStride0 = 138; | 1691 | constexpr int32_t kEffectiveInputStride0 = 138; |
| @@ -1827,13 +1827,10 @@ void InitializeData(float *input, int32_t *index, float *expected) { | |||
| 1827 | } | 1827 | } |
| 1828 | } | 1828 | } |
| 1829 | for (int32_t row = 0; row < kIndexRows; ++row) { | 1829 | for (int32_t row = 0; row < kIndexRows; ++row) { |
| 1830 | - const int32_t index_value = static_cast<int32_t>((row * 7 + 3) % kInputRows); | 1830 | + index[row] = static_cast<int32_t>((row * 7 + 3) % kInputRows); |
| 1831 | - for (int32_t col = 0; col < kEmbeddingSize; ++col) { | ||
| 1832 | - index[row * kEmbeddingSize + col] = index_value; | ||
| 1833 | - } | ||
| 1834 | float sum = 0.0F; | 1831 | float sum = 0.0F; |
| 1835 | for (int32_t col = 0; col < kEmbeddingSize; ++col) { | 1832 | for (int32_t col = 0; col < kEmbeddingSize; ++col) { |
| 1836 | - sum += 2.0F * (input[index[row * kEmbeddingSize] * kEmbeddingSize + col] + 0.1F); | 1833 | + sum += 2.0F * (input[index[row] * kEmbeddingSize + col] + 0.1F); |
| 1837 | } | 1834 | } |
| 1838 | expected[row] = sum; | 1835 | expected[row] = sum; |
| 1839 | } | 1836 | } |
| @@ -1842,7 +1839,7 @@ void InitializeData(float *input, int32_t *index, float *expected) { | |||
| 1842 | 1839 | ||
| 1843 | TEST(E2EIndirectLoadEmbedding, GeneratedKernelMatchesReference) { | 1840 | TEST(E2EIndirectLoadEmbedding, GeneratedKernelMatchesReference) { |
| 1844 | constexpr int64_t input_count = static_cast<int64_t>(kInputRows) * kEmbeddingSize; | 1841 | constexpr int64_t input_count = static_cast<int64_t>(kInputRows) * kEmbeddingSize; |
| 1845 | - constexpr int64_t index_count = static_cast<int64_t>(kIndexRows) * kEmbeddingSize; | 1842 | + constexpr int64_t index_count = kIndexRows; |
| 1846 | constexpr int64_t output_count = kIndexRows; | 1843 | constexpr int64_t output_count = kIndexRows; |
| 1847 | indirect_load_test::KernelData<float, int32_t> buffers(input_count, index_count, output_count); | 1844 | indirect_load_test::KernelData<float, int32_t> buffers(input_count, index_count, output_count); |
| 1848 | ASSERT_TRUE(buffers.IsValid()); | 1845 | ASSERT_TRUE(buffers.IsValid()); |
| @@ -52,6 +52,6 @@ TEST_F(TestBackendLoadWhereX2X3IsUbscalarStoreE2e, LoadWhereX2X3IsUbscalarStoreE | |||
| 52 | EXPECT_NE(kernel.find("Duplicate(local_blk_tensor_of_scalar_2[0], static_cast<float>(100), " | 52 | EXPECT_NE(kernel.find("Duplicate(local_blk_tensor_of_scalar_2[0], static_cast<float>(100), " |
| 53 | "static_cast<uint64_t>(32/sizeof(float)));"), | 53 | "static_cast<uint64_t>(32/sizeof(float)));"), |
| 54 | std::string::npos); | 54 | std::string::npos); |
| 55 | - EXPECT_NE(kernel.find("DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(global_1"), std::string::npos); | 55 | + EXPECT_NE(kernel.find("DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(global_1"), std::string::npos); |
| 56 | }); | 56 | }); |
| 57 | } | 57 | } |
| @@ -1,5 +1,4 @@ | |||
| 1 | 1 | ||
| 2 | - | ||
| 3 | 2 | ||
| 4 | 3 | ||
| 5 | 4 | ||
| @@ -18,7 +17,6 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 18 | float *input = (float *)AscendC::GmAlloc(test_size * sizeof(float) + 32); | 17 | float *input = (float *)AscendC::GmAlloc(test_size * sizeof(float) + 32); |
| 19 | uint8_t *y = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); | 18 | uint8_t *y = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); |
| 20 | uint8_t *expect = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); | 19 | uint8_t *expect = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); |
| 21 | - std::fill_n(y, test_size, uint8_t{0}); | ||
| 22 | 20 | ||
| 23 | // Prepare test and expect data | 21 | // Prepare test and expect data |
| 24 | srand(1); | 22 | srand(1); |
| @@ -34,8 +32,6 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 34 | tiling_data.s2 = test_shape[2]; | 32 | tiling_data.s2 = test_shape[2]; |
| 35 | tiling_data.tiling_key = 0; | 33 | tiling_data.tiling_key = 0; |
| 36 | GetTiling(tiling_data); | 34 | GetTiling(tiling_data); |
| 37 | - // This generated test kernel iterates all z0 slices and does not partition them by block index. | ||
| 38 | - tiling_data.block_dim = 1; | ||
| 39 | 35 | ||
| 40 | AscendC::SetKernelMode(KernelMode::AIV_MODE); | 36 | AscendC::SetKernelMode(KernelMode::AIV_MODE); |
| 41 | ICPU_RUN_KF(load_nan_out_for_store, tiling_data.block_dim, (uint8_t *)input, (uint8_t *)y, nullptr, | 37 | ICPU_RUN_KF(load_nan_out_for_store, tiling_data.block_dim, (uint8_t *)input, (uint8_t *)y, nullptr, |
| @@ -57,5 +53,5 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 57 | } | 53 | } |
| 58 | 54 | ||
| 59 | INSTANTIATE_TEST_SUITE_P(CalcWithDifferentShape, E2E_LoadNanOutForStore_Code, | 55 | INSTANTIATE_TEST_SUITE_P(CalcWithDifferentShape, E2E_LoadNanOutForStore_Code, |
| 60 | - ::testing::Values(std::vector<int>{2, 8, 32}, std::vector<int>{8, 16, 32}, | 56 | + ::testing::Values(std::vector<int>{2, 8, 8}, std::vector<int>{8, 16, 16}, |
| 61 | - std::vector<int>{96, 16, 32})); | 57 | + std::vector<int>{96, 16, 16})); |
| @@ -84,9 +84,9 @@ TEST(CodegenKernel, LoadRegApiCall_OneDimLoad) { | |||
| 84 | 84 | ||
| 85 | std::string result; | 85 | std::string result; |
| 86 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); | 86 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); |
| 87 | - EXPECT_EQ(result, | 87 | + EXPECT_EQ( |
| 88 | - std::string{ | 88 | + result, |
| 89 | - "DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_0[0], local_0[0 + 0], 1, 8, 0, 0);\n"}); | 89 | + std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_0[0], local_0[0 + 0], 1, 8, 0, 0);\n"}); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | TEST(CodegenKernel, LoadRegApiCall_CvUbFuseUsesDtypeAwareStrides) { | 92 | TEST(CodegenKernel, LoadRegApiCall_CvUbFuseUsesDtypeAwareStrides) { |
| @@ -296,7 +296,7 @@ TEST(CodegenKernel, LoadRegApiCall_ThreeDimLoad) { | |||
| 296 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); | 296 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); |
| 297 | EXPECT_EQ( | 297 | EXPECT_EQ( |
| 298 | result, | 298 | result, |
| 299 | - std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_0[0], local_0[0 + 0], 4, 2, 2, (2 " | 299 | + std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_0[0], local_0[0 + 0], 4, 2, 2, (2 " |
| 300 | "- 2), {static_cast<uint32_t>(8), " | 300 | "- 2), {static_cast<uint32_t>(8), " |
| 301 | "static_cast<uint32_t>(1), static_cast<uint64_t>(24 * 4), static_cast<uint64_t>(8 * 4), " | 301 | "static_cast<uint32_t>(1), static_cast<uint64_t>(24 * 4), static_cast<uint64_t>(8 * 4), " |
| 302 | "static_cast<uint64_t>(0 * 4), static_cast<uint64_t>(0 * 4)});\n"}); | 302 | "static_cast<uint64_t>(0 * 4), static_cast<uint64_t>(0 * 4)});\n"}); |
| @@ -385,7 +385,7 @@ TEST(CodegenKernel, LoadRegApiCall_FiveDimLoad) { | |||
| 385 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); | 385 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); |
| 386 | EXPECT_EQ(result, | 386 | EXPECT_EQ(result, |
| 387 | std::string{"for (int outer_for_0 = 0; outer_for_0 < 8; outer_for_0++) {\nDataCopyPadExtend<float, " | 387 | std::string{"for (int outer_for_0 = 0; outer_for_0 < 8; outer_for_0++) {\nDataCopyPadExtend<float, " |
| 388 | - "AscendC::PaddingMode::Normal>(local_0[outer_for_0 * " | 388 | + "AscendC::PaddingMode::Compact>(local_0[outer_for_0 * " |
| 389 | "32], local_0[(0 + 0 + outer_for_0 * 160)], 2, 2, 2, (2 - 2), {static_cast<uint32_t>(2), " | 389 | "32], local_0[(0 + 0 + outer_for_0 * 160)], 2, 2, 2, (2 - 2), {static_cast<uint32_t>(2), " |
| 390 | "static_cast<uint32_t>(4), static_cast<uint64_t>(12 * 4), static_cast<uint64_t>(4 * 4), " | 390 | "static_cast<uint32_t>(4), static_cast<uint64_t>(12 * 4), static_cast<uint64_t>(4 * 4), " |
| 391 | "static_cast<uint64_t>(32 * 4), static_cast<uint64_t>(8 * 4)});\n}\n"}); | 391 | "static_cast<uint64_t>(32 * 4), static_cast<uint64_t>(8 * 4)});\n}\n"}); |
| @@ -130,13 +130,13 @@ TEST(CodegenKernel, StoreRegApiCall_TwoStoreOneOutput) { | |||
| 130 | EXPECT_EQ( | 130 | EXPECT_EQ( |
| 131 | result, | 131 | result, |
| 132 | std::string{ | 132 | std::string{ |
| 133 | - "DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_1[0 + 0], local_0[0], 1, 1, (16 - 1), 0);\n"}); | 133 | + "DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_1[0 + 0], local_0[0], 1, 1, (16 - 1), 0);\n"}); |
| 134 | 134 | ||
| 135 | codegen::StoreRegApiCall call_1("DataCopyPadExtend"); | 135 | codegen::StoreRegApiCall call_1("DataCopyPadExtend"); |
| 136 | EXPECT_EQ(call_1.Init(store_1), 0); | 136 | EXPECT_EQ(call_1.Init(store_1), 0); |
| 137 | call_1.inputs.push_back(&x1); | 137 | call_1.inputs.push_back(&x1); |
| 138 | call_1.Generate(tpipe, vector<af::AxisId>{}, result); | 138 | call_1.Generate(tpipe, vector<af::AxisId>{}, result); |
| 139 | - EXPECT_EQ(result, std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_1[0 + 1], local_0[0], " | 139 | + EXPECT_EQ(result, std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_1[0 + 1], local_0[0], " |
| 140 | "z0_t_size, 1, (16 - 1), 0);\n"}); | 140 | "z0_t_size, 1, (16 - 1), 0);\n"}); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| @@ -352,7 +352,7 @@ TEST(CodegenKernel, StoreRegApiCall_NeetMte3SyncMte2) { | |||
| 352 | EXPECT_EQ( | 352 | EXPECT_EQ( |
| 353 | result, | 353 | result, |
| 354 | std::string{ | 354 | std::string{ |
| 355 | - "DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_1[0 + 0], local_0[0], 1, 1, (16 - 1), 0);\n" | 355 | + "DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_1[0 + 0], local_0[0], 1, 1, (16 - 1), 0);\n" |
| 356 | "auto local_0_e_mte3_2_mte2_t_0 = tpipe.AllocEventID<HardEvent::MTE3_MTE2>();\n" | 356 | "auto local_0_e_mte3_2_mte2_t_0 = tpipe.AllocEventID<HardEvent::MTE3_MTE2>();\n" |
| 357 | "TQueSync<PIPE_MTE3, PIPE_MTE2> local_0_s_mte3_2_mte2_t_0;\n" | 357 | "TQueSync<PIPE_MTE3, PIPE_MTE2> local_0_s_mte3_2_mte2_t_0;\n" |
| 358 | "local_0_s_mte3_2_mte2_t_0.SetFlag(local_0_e_mte3_2_mte2_t_0);\n" | 358 | "local_0_s_mte3_2_mte2_t_0.SetFlag(local_0_e_mte3_2_mte2_t_0);\n" |
| @@ -449,7 +449,7 @@ TEST(CodegenKernel, StoreRegApiCall_ThreeDimStore) { | |||
| 449 | EXPECT_EQ( | 449 | EXPECT_EQ( |
| 450 | result, | 450 | result, |
| 451 | std::string{ | 451 | std::string{ |
| 452 | - "DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(local_1[0 + 0], local_0[0], 4, 2, (2 - 2), 2, " | 452 | + "DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(local_1[0 + 0], local_0[0], 4, 2, (2 - 2), 2, " |
| 453 | "{static_cast<uint32_t>(8), static_cast<uint32_t>(1), static_cast<uint64_t>(8 * 4), static_cast<uint64_t>(24 " | 453 | "{static_cast<uint32_t>(8), static_cast<uint32_t>(1), static_cast<uint64_t>(8 * 4), static_cast<uint64_t>(24 " |
| 454 | "* 4), static_cast<uint64_t>(0 * 4), static_cast<uint64_t>(0 * 4)});\n"}); | 454 | "* 4), static_cast<uint64_t>(0 * 4), static_cast<uint64_t>(0 * 4)});\n"}); |
| 455 | } | 455 | } |
| @@ -553,7 +553,7 @@ TEST(CodegenKernel, StoreRegApiCall_FiveDimStore) { | |||
| 553 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); | 553 | call_0.Generate(tpipe, vector<af::AxisId>{}, result); |
| 554 | EXPECT_EQ(result, | 554 | EXPECT_EQ(result, |
| 555 | std::string{"for (int outer_for_0 = 0; outer_for_0 < 8; outer_for_0++) {\nDataCopyPadExtend<float, " | 555 | std::string{"for (int outer_for_0 = 0; outer_for_0 < 8; outer_for_0++) {\nDataCopyPadExtend<float, " |
| 556 | - "AscendC::PaddingMode::Normal>(local_1[(0 + 0 + " | 556 | + "AscendC::PaddingMode::Compact>(local_1[(0 + 0 + " |
| 557 | "outer_for_0 * 160)], local_0[outer_for_0 * 32], 2, 2, (2 - 2), 2, {static_cast<uint32_t>(2), " | 557 | "outer_for_0 * 160)], local_0[outer_for_0 * 32], 2, 2, (2 - 2), 2, {static_cast<uint32_t>(2), " |
| 558 | "static_cast<uint32_t>(4), static_cast<uint64_t>(4 * 4), static_cast<uint64_t>(12 * 4), " | 558 | "static_cast<uint32_t>(4), static_cast<uint64_t>(4 * 4), static_cast<uint64_t>(12 * 4), " |
| 559 | "static_cast<uint64_t>(8 * 4), " | 559 | "static_cast<uint64_t>(8 * 4), " |
| @@ -10,7 +10,6 @@ | |||
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | - | ||
| 14 | 13 | ||
| 15 | namespace { | 14 | namespace { |
| 16 | constexpr size_t kDmaMaxLen = 2U; | 15 | constexpr size_t kDmaMaxLen = 2U; |
| @@ -99,21 +98,23 @@ void SetLoopModeParamsExpr(const DataCopyParams &data_copy_param, LoopModeParams | |||
| 99 | } | 98 | } |
| 100 | } | 99 | } |
| 101 | 100 | ||
| 102 | -std::string GetPaddingMode(const Tensor &ub_tensor) { | 101 | +// 根据ub上最后一维的对齐信息以及切分轴信息判断,是否使用Compact模式,如果能明确判断出来,stride与repeat相同且ub切分轴是首轴,则使用compact模式,否则使用normal模式 |
| 103 | - af::AscTensorAttr attr; | 102 | +std::string GetPaddingMode(const TPipe &tpipe, const Tensor &ub_tensor, const DataCopyParams &data_copy_param) { |
| 104 | - attr.axis = ub_tensor.axis; | 103 | + for (auto axis_pos : ub_tensor.vectorized_axis_pos) { |
| 105 | - attr.repeats = ub_tensor.axis_size; | 104 | + ascir::AxisId axis_id = ub_tensor.axis[axis_pos]; |
| 106 | - attr.strides = ub_tensor.axis_strides; | 105 | + const Axis &axis = tpipe.tiler.GetAxis(axis_id); |
| 107 | - attr.vectorized_axis = ub_tensor.vectorized_axis; | 106 | + if (axis.type == ascir::Axis::Type::kAxisTypeTileInner && ub_tensor.vectorized_axis[0] != axis_id) { |
| 108 | - ascgen_utils::DiscontinuityInfo info; | 107 | + GELOGD("The TileInner axis is not the first axis, use normal mode."); |
| 109 | - auto analyze_success = ascgen_utils::TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info) == af::SUCCESS; | 108 | + return kNormalPddingMode; |
| 110 | - auto no_multiple_discontinuities = !info.has_multiple_discontinuities; | 109 | + } |
| 111 | - GELOGD("GetPaddingMode conditions: analyze_success=%d, no_multiple_discontinuities=%d", analyze_success, | ||
| 112 | - no_multiple_discontinuities); | ||
| 113 | - if (analyze_success && no_multiple_discontinuities) { | ||
| 114 | - return kCompactPddingMode; | ||
| 115 | } | 110 | } |
| 116 | - return kNormalPddingMode; | 111 | + if (data_copy_param.repeats.size() <= 1) { |
| 112 | + return kNormalPddingMode; | ||
| 113 | + } | ||
| 114 | + ascir::SizeExpr repeat = data_copy_param.repeats.back(); | ||
| 115 | + ascir::SizeExpr stride = data_copy_param.ub_strides[data_copy_param.ub_strides.size() - kDmaMaxLen]; | ||
| 116 | + bool status = af::SymbolicUtils::StaticCheckEq(repeat, stride) == af::TriBool::kTrue; | ||
| 117 | + return status ? kCompactPddingMode : kNormalPddingMode; | ||
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | std::string GenLoopModeParams(const LoopModeParams &loop_mode_param, int64_t input_dtype_size, | 120 | std::string GenLoopModeParams(const LoopModeParams &loop_mode_param, int64_t input_dtype_size, |
| @@ -169,7 +170,7 @@ void CreateEnhanceDmaCall(const TPipe &tpipe, const Tensor &input, const Tensor | |||
| 169 | LoopModeParams loop_mode_param; | 170 | LoopModeParams loop_mode_param; |
| 170 | SetLoopModeParams(tpipe, data_copy_param, loop_mode_param, copy_in); | 171 | SetLoopModeParams(tpipe, data_copy_param, loop_mode_param, copy_in); |
| 171 | const Tensor &ub_tensor = copy_in ? output : input; | 172 | const Tensor &ub_tensor = copy_in ? output : input; |
| 172 | - std::string padding_mode = GetPaddingMode(ub_tensor); | 173 | + std::string padding_mode = GetPaddingMode(tpipe, ub_tensor, data_copy_param); |
| 173 | if (total_len <= kDmaMaxLen) { | 174 | if (total_len <= kDmaMaxLen) { |
| 174 | CreateBaseDmaCall(input, output, dma_param, padding_mode, ss, copy_in); | 175 | CreateBaseDmaCall(input, output, dma_param, padding_mode, ss, copy_in); |
| 175 | return; | 176 | return; |
| @@ -348,7 +349,7 @@ Status BuildDataCopyApiParamInNormal(const TPipe &tpipe, CodegenApiParam &api_pa | |||
| 348 | GE_ASSERT_TRUE(CalculateDmaParams(tpipe, dst, dst, data_copy_param), "CalculateDmaParams failed"); | 349 | GE_ASSERT_TRUE(CalculateDmaParams(tpipe, dst, dst, data_copy_param), "CalculateDmaParams failed"); |
| 349 | size_t total_len = data_copy_param.repeats.size(); | 350 | size_t total_len = data_copy_param.repeats.size(); |
| 350 | const Tensor &ub_tensor = copy_in ? dst : src; | 351 | const Tensor &ub_tensor = copy_in ? dst : src; |
| 351 | - std::string padding_mode = GetPaddingMode(ub_tensor); | 352 | + std::string padding_mode = GetPaddingMode(tpipe, ub_tensor, data_copy_param); |
| 352 | api_param.template_params.emplace_back(padding_mode); | 353 | api_param.template_params.emplace_back(padding_mode); |
| 353 | 354 | ||
| 354 | BuildDataCopyBaseParams(tpipe, data_copy_param, dma_specific_params, copy_in); | 355 | BuildDataCopyBaseParams(tpipe, data_copy_param, dma_specific_params, copy_in); |
| @@ -84,7 +84,7 @@ void SetNddmaParams(const TPipe &tpipe, const DataCopyParams &data_copy_param, N | |||
| 84 | void SetLoopModeParams(const TPipe &tpipe, const DataCopyParams &data_copy_param, LoopModeParams &loop_mode_param, | 84 | void SetLoopModeParams(const TPipe &tpipe, const DataCopyParams &data_copy_param, LoopModeParams &loop_mode_param, |
| 85 | bool copy_in); | 85 | bool copy_in); |
| 86 | void SetLoopModeParamsExpr(const DataCopyParams &data_copy_param, LoopModeParamsExpr &loop_mode_param, bool copy_in); | 86 | void SetLoopModeParamsExpr(const DataCopyParams &data_copy_param, LoopModeParamsExpr &loop_mode_param, bool copy_in); |
| 87 | -std::string GetPaddingMode(const Tensor &ub_tensor); | 87 | +std::string GetPaddingMode(const TPipe &tpipe, const Tensor &ub_tensor, const DataCopyParams &data_copy_param); |
| 88 | void BuildDataCopyApiParamInCVFusion(const TPipe &tpipe, CodegenApiParam &api_param, | 88 | void BuildDataCopyApiParamInCVFusion(const TPipe &tpipe, CodegenApiParam &api_param, |
| 89 | DmaSpecificParams &dma_specific_params, const Tensor &gm, const Tensor &ub, | 89 | DmaSpecificParams &dma_specific_params, const Tensor &gm, const Tensor &ub, |
| 90 | std::string &dtype_name, bool copy_in); | 90 | std::string &dtype_name, bool copy_in); |
| @@ -27,8 +27,6 @@ static void GenParams(const TPipe &tpipe, const Tensor &input, const Tensor &out | |||
| 27 | // 只保证在仅对张量尾轴做32B对齐的场景下有效,若对中间轴做了对齐,则还需要增加处理逻辑 | 27 | // 只保证在仅对张量尾轴做32B对齐的场景下有效,若对中间轴做了对齐,则还需要增加处理逻辑 |
| 28 | auto vectorized_axis_size = input.vectorized_axis.size(); | 28 | auto vectorized_axis_size = input.vectorized_axis.size(); |
| 29 | const char *shape_prefix = is_src ? "src_shape_" : "dst_shape_"; | 29 | const char *shape_prefix = is_src ? "src_shape_" : "dst_shape_"; |
| 30 | - constexpr char kCompactPddingMode[] = "AscendC::PaddingMode::Compact"; | ||
| 31 | - std::string padding_mode = GetPaddingMode(output); | ||
| 32 | 30 | ||
| 33 | ss << "const uint32_t " << shape_prefix << input.id << "_brc_to_" << output.id << "[" << vectorized_axis_size | 31 | ss << "const uint32_t " << shape_prefix << input.id << "_brc_to_" << output.id << "[" << vectorized_axis_size |
| 34 | << "] = {"; | 32 | << "] = {"; |
| @@ -67,7 +65,7 @@ static void GenParams(const TPipe &tpipe, const Tensor &input, const Tensor &out | |||
| 67 | ascir::AxisId axis_id = output.vectorized_axis[pos]; | 65 | ascir::AxisId axis_id = output.vectorized_axis[pos]; |
| 68 | auto last_dim_size = output.vectorized_strides[pre_pos]; | 66 | auto last_dim_size = output.vectorized_strides[pre_pos]; |
| 69 | if (tpipe.tiler.GetAxis(axis_id).type != ascir::Axis::Type::kAxisTypeTileInner || | 67 | if (tpipe.tiler.GetAxis(axis_id).type != ascir::Axis::Type::kAxisTypeTileInner || |
| 70 | - output.vectorized_axis[0] == axis_id || padding_mode == kCompactPddingMode) { | 68 | + output.vectorized_axis[0] == axis_id) { |
| 71 | ss << tpipe.tiler.ActualSize(last_dim_size); | 69 | ss << tpipe.tiler.ActualSize(last_dim_size); |
| 72 | } else { | 70 | } else { |
| 73 | ss << tpipe.tiler.Size(last_dim_size); | 71 | ss << tpipe.tiler.Size(last_dim_size); |
| @@ -42,8 +42,8 @@ af::Status LoadToNddmaTemplate::Generate(const af::AscGraph &origin_graph, | |||
| 42 | if (ascgen_utils::indirect_load::GetTemplateBehavior(node).uses_direct_gm_pipeline) { | 42 | if (ascgen_utils::indirect_load::GetTemplateBehavior(node).uses_direct_gm_pipeline) { |
| 43 | continue; | 43 | continue; |
| 44 | } | 44 | } |
| 45 | - ascgen_utils::DiscontinuityInfo info; | 45 | + DiscontinuityInfo info; |
| 46 | - GE_ASSERT_SUCCESS(ascgen_utils::TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), | 46 | + GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), |
| 47 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); | 47 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); |
| 48 | bool need_align_at_repeat1 = info.has_multiple_discontinuities && info.is_tail_axis_discontinuous; | 48 | bool need_align_at_repeat1 = info.has_multiple_discontinuities && info.is_tail_axis_discontinuous; |
| 49 | if (IsLoadNeedAlign(node) || need_align_at_repeat1) { | 49 | if (IsLoadNeedAlign(node) || need_align_at_repeat1) { |
| @@ -271,8 +271,8 @@ af::Status NddmaTemplate::Generate([[maybe_unused]] const af::AscGraph &origin_g | |||
| 271 | } | 271 | } |
| 272 | GE_ASSERT_SUCCESS(ProcessSliceToNddma(node, is_nddma_generated_cur)); | 272 | GE_ASSERT_SUCCESS(ProcessSliceToNddma(node, is_nddma_generated_cur)); |
| 273 | is_nddma_generated = is_nddma_generated || is_nddma_generated_cur; | 273 | is_nddma_generated = is_nddma_generated || is_nddma_generated_cur; |
| 274 | - ascgen_utils::DiscontinuityInfo info; | 274 | + DiscontinuityInfo info; |
| 275 | - GE_ASSERT_SUCCESS(ascgen_utils::TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), | 275 | + GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), |
| 276 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); | 276 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); |
| 277 | bool need_align_at_repeat1 = info.has_multiple_discontinuities && info.is_tail_axis_discontinuous; | 277 | bool need_align_at_repeat1 = info.has_multiple_discontinuities && info.is_tail_axis_discontinuous; |
| 278 | if (!is_nddma_generated_cur && (IsLoadNeedAlign(node) || need_align_at_repeat1)) { | 278 | if (!is_nddma_generated_cur && (IsLoadNeedAlign(node) || need_align_at_repeat1)) { |
| @@ -36,8 +36,8 @@ af::Status UnAlignmentStrategy::LoadAlignmentInferFunc(const af::AscNodePtr &nod | |||
| 36 | tensor_to_align_type_[&output_attr] = {AlignmentType::kNotAligned}; | 36 | tensor_to_align_type_[&output_attr] = {AlignmentType::kNotAligned}; |
| 37 | return af::SUCCESS; | 37 | return af::SUCCESS; |
| 38 | } | 38 | } |
| 39 | - ascgen_utils::DiscontinuityInfo info; | 39 | + DiscontinuityInfo info; |
| 40 | - GE_ASSERT_SUCCESS(ascgen_utils::TensorLayoutUtils::AnalyzeLoadDiscontinuity(output_attr, info), | 40 | + GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(output_attr, info), |
| 41 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); | 41 | "Failed to analyze discontinuity info for node:[%s].", node->GetNamePtr()); |
| 42 | if (!info.has_multiple_discontinuities) { | 42 | if (!info.has_multiple_discontinuities) { |
| 43 | // 走compat模式搬运 | 43 | // 走compat模式搬运 |
🔴 Critical
changed line:
autofuse/optimize/tensor_layout_utils.cpp第 18 行新增的include "schedule_utils.h"缺少预处理指令前缀#(diff 中为+include "schedule_utils.h",工作区文件内容经 read_file 与 grep 双重确认均为include "schedule_utils.h",而同一文件第 11~17 行的#include均正常带#)。affected behavior/contract: 该行位于文件作用域,
include会被当作未声明标识符解析,紧随其后的字符串字面量构成非法声明,整个翻译单元出现语法错误。failure mode: tensor_layout_utils.cpp 无法通过编译,
optimize库构建失败;由于AnalyzeLoadDiscontinuity/TensorLayoutUtils被un_alignment_strategy.cpp、load_to_nddma_template.cpp、nddma_template.cpp等生产代码引用,将连带导致依赖该库的整个 autofuse 组件(以及涉及本文件的回归测试)编译失败,属 P0 级构建故障。suggested fix: 将行首补上
#恢复为#include "schedule_utils.h"(该头文件存在于 autofuse/optimize/schedule_utils.h,修复后可用;若本文件实际并不需要它,也可直接删除此行)。建议:把第 18 行改为
#include "schedule_utils.h"(或确认本文件未使用 schedule_utils 中的符号时直接删除该 include)。