已合并
【PR】: fix: 调整 tensor layout 工具归属和搬运模式 #1932
Phl17创建于 9月2日
【PR】: fix: 调整 tensor layout 工具归属和搬运模式 #1932
已合并
共 14 个文件变更+142-35
| @@ -15,9 +15,8 @@ | |||
| 15 | #include "ascgen_log.h" | 15 | #include "ascgen_log.h" |
| 16 | #include "ascir_ops.h" | 16 | #include "ascir_ops.h" |
| 17 | #include "common_utils.h" | 17 | #include "common_utils.h" |
| 18 | -#include "schedule_utils.h" | ||
| 19 | 18 | ||
| 20 | -namespace optimize { | 19 | +namespace ascgen_utils { |
| 21 | af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info) { | 20 | af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info) { |
| 22 | const auto &axis = attr.axis; | 21 | const auto &axis = attr.axis; |
| 23 | const auto &repeats = attr.repeats; | 22 | const auto &repeats = attr.repeats; |
| @@ -64,4 +63,4 @@ af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr & | |||
| 64 | 63 | ||
| 65 | return af::SUCCESS; | 64 | return af::SUCCESS; |
| 66 | } | 65 | } |
| 67 | -} // namespace optimize | 66 | +} // namespace ascgen_utils |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include "ascendc_ir/ascendc_ir_core/ascendc_ir_def.h" | 14 | #include "ascendc_ir/ascendc_ir_core/ascendc_ir_def.h" |
| 15 | 15 | ||
| 16 | -namespace optimize { | 16 | +namespace ascgen_utils { |
| 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 optimize | 25 | +} // namespace ascgen_utils |
| 26 | 26 | ||
| 27 | #endif // OPTIMIZE_TENSOR_LAYOUT_UTILS_H_ | 27 | #endif // OPTIMIZE_TENSOR_LAYOUT_UTILS_H_ |
| @@ -0,0 +1,94 @@ | |||
| 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 | +#include <gtest/gtest.h> | ||
| 12 | + | ||
| 13 | +#include <vector> | ||
| 14 | + | ||
| 15 | +#include "tensor_layout_utils.h" | ||
| 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::Normal>"), std::string::npos); | 52 | + EXPECT_NE(kernel.find("DataCopyPadExtend<int32_t, AscendC::PaddingMode::Compact>"), std::string::npos); |
| 53 | }); | 53 | }); |
| 54 | } | 54 | } |
| @@ -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::Normal>(global_1"), std::string::npos); | 55 | + EXPECT_NE(kernel.find("DataCopyPadExtend<float, AscendC::PaddingMode::Compact>(global_1"), std::string::npos); |
| 56 | }); | 56 | }); |
| 57 | } | 57 | } |
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <gtest/gtest.h> | 1 | #include <gtest/gtest.h> |
| 2 | +#include <algorithm> | ||
| 2 | #include "tikicpulib.h" | 3 | #include "tikicpulib.h" |
| 3 | 4 | ||
| 4 | #include "autofuse_tiling_data.h" | 5 | #include "autofuse_tiling_data.h" |
| @@ -17,6 +18,7 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 17 | float *input = (float *)AscendC::GmAlloc(test_size * sizeof(float) + 32); | 18 | float *input = (float *)AscendC::GmAlloc(test_size * sizeof(float) + 32); |
| 18 | uint8_t *y = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); | 19 | uint8_t *y = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); |
| 19 | uint8_t *expect = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); | 20 | uint8_t *expect = (uint8_t *)AscendC::GmAlloc(test_size * sizeof(uint8_t) + 32); |
| 21 | + std::fill_n(y, test_size, uint8_t{0}); | ||
| 20 | 22 | ||
| 21 | // Prepare test and expect data | 23 | // Prepare test and expect data |
| 22 | srand(1); | 24 | srand(1); |
| @@ -32,6 +34,8 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 32 | tiling_data.s2 = test_shape[2]; | 34 | tiling_data.s2 = test_shape[2]; |
| 33 | tiling_data.tiling_key = 0; | 35 | tiling_data.tiling_key = 0; |
| 34 | GetTiling(tiling_data); | 36 | 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; | ||
| 35 | 39 | ||
| 36 | AscendC::SetKernelMode(KernelMode::AIV_MODE); | 40 | AscendC::SetKernelMode(KernelMode::AIV_MODE); |
| 37 | ICPU_RUN_KF(load_nan_out_for_store, tiling_data.block_dim, (uint8_t *)input, (uint8_t *)y, nullptr, | 41 | ICPU_RUN_KF(load_nan_out_for_store, tiling_data.block_dim, (uint8_t *)input, (uint8_t *)y, nullptr, |
| @@ -53,5 +57,5 @@ TEST_P(E2E_LoadNanOutForStore_Code, CalculateCorrect_Nan) { | |||
| 53 | } | 57 | } |
| 54 | 58 | ||
| 55 | INSTANTIATE_TEST_SUITE_P(CalcWithDifferentShape, E2E_LoadNanOutForStore_Code, | 59 | INSTANTIATE_TEST_SUITE_P(CalcWithDifferentShape, E2E_LoadNanOutForStore_Code, |
| 56 | - ::testing::Values(std::vector<int>{2, 8, 8}, std::vector<int>{8, 16, 16}, | 60 | + ::testing::Values(std::vector<int>{2, 8, 32}, std::vector<int>{8, 16, 32}, |
| 57 | - std::vector<int>{96, 16, 16})); | 61 | + std::vector<int>{96, 16, 32})); |
| @@ -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::Compact>(local_0[0], local_0[0 + 0], 4, 2, 2, (2 " | 299 | + std::string{"DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(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::Compact>(local_0[outer_for_0 * " | 388 | + "AscendC::PaddingMode::Normal>(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"}); |
| @@ -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::Compact>(local_1[0 + 0], local_0[0], 4, 2, (2 - 2), 2, " | 452 | + "DataCopyPadExtend<float, AscendC::PaddingMode::Normal>(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::Compact>(local_1[(0 + 0 + " | 556 | + "AscendC::PaddingMode::Normal>(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,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include "reg_api_call_utils.h" | 11 | #include "reg_api_call_utils.h" |
| 12 | #include "graph/symbolizer/symbolic_utils.h" | 12 | #include "graph/symbolizer/symbolic_utils.h" |
| 13 | +#include "tensor_layout_utils.h" | ||
| 13 | 14 | ||
| 14 | namespace { | 15 | namespace { |
| 15 | constexpr size_t kDmaMaxLen = 2U; | 16 | constexpr size_t kDmaMaxLen = 2U; |
| @@ -98,23 +99,29 @@ void SetLoopModeParamsExpr(const DataCopyParams &data_copy_param, LoopModeParams | |||
| 98 | } | 99 | } |
| 99 | } | 100 | } |
| 100 | 101 | ||
| 101 | -// 根据ub上最后一维的对齐信息以及切分轴信息判断,是否使用Compact模式,如果能明确判断出来,stride与repeat相同且ub切分轴是首轴,则使用compact模式,否则使用normal模式 | 102 | +std::string GetPaddingMode(const Tensor &ub_tensor, const DataCopyParams &data_copy_param) { |
| 102 | -std::string GetPaddingMode(const TPipe &tpipe, const Tensor &ub_tensor, const DataCopyParams &data_copy_param) { | 103 | + af::AscTensorAttr attr; |
| 103 | - for (auto axis_pos : ub_tensor.vectorized_axis_pos) { | 104 | + attr.axis = ub_tensor.axis; |
| 104 | - ascir::AxisId axis_id = ub_tensor.axis[axis_pos]; | 105 | + attr.repeats = ub_tensor.axis_size; |
| 105 | - const Axis &axis = tpipe.tiler.GetAxis(axis_id); | 106 | + attr.strides = ub_tensor.axis_strides; |
| 106 | - if (axis.type == ascir::Axis::Type::kAxisTypeTileInner && ub_tensor.vectorized_axis[0] != axis_id) { | 107 | + attr.vectorized_axis = ub_tensor.vectorized_axis; |
| 107 | - GELOGD("The TileInner axis is not the first axis, use normal mode."); | 108 | + |
| 108 | - return kNormalPddingMode; | ||
| 109 | - } | ||
| 110 | - } | ||
| 111 | if (data_copy_param.repeats.size() <= 1) { | 109 | if (data_copy_param.repeats.size() <= 1) { |
| 112 | return kNormalPddingMode; | 110 | return kNormalPddingMode; |
| 113 | } | 111 | } |
| 114 | ascir::SizeExpr repeat = data_copy_param.repeats.back(); | 112 | ascir::SizeExpr repeat = data_copy_param.repeats.back(); |
| 115 | ascir::SizeExpr stride = data_copy_param.ub_strides[data_copy_param.ub_strides.size() - kDmaMaxLen]; | 113 | 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; | 114 | bool status = af::SymbolicUtils::StaticCheckEq(repeat, stride) == af::TriBool::kTrue; |
| 117 | - return status ? kCompactPddingMode : kNormalPddingMode; | 115 | + |
| 116 | + ascgen_utils::DiscontinuityInfo info; | ||
| 117 | + auto analyze_success = ascgen_utils::TensorLayoutUtils::AnalyzeLoadDiscontinuity(attr, info) == af::SUCCESS; | ||
| 118 | + auto no_multiple_discontinuities = !info.has_multiple_discontinuities; | ||
| 119 | + GELOGD("GetPaddingMode conditions: analyze_success=%d, no_multiple_discontinuities=%d", analyze_success, | ||
| 120 | + no_multiple_discontinuities); | ||
| 121 | + if (analyze_success && no_multiple_discontinuities && status) { | ||
| 122 | + return kCompactPddingMode; | ||
| 123 | + } | ||
| 124 | + return kNormalPddingMode; | ||
| 118 | } | 125 | } |
| 119 | 126 | ||
| 120 | std::string GenLoopModeParams(const LoopModeParams &loop_mode_param, int64_t input_dtype_size, | 127 | std::string GenLoopModeParams(const LoopModeParams &loop_mode_param, int64_t input_dtype_size, |
| @@ -170,7 +177,7 @@ void CreateEnhanceDmaCall(const TPipe &tpipe, const Tensor &input, const Tensor | |||
| 170 | LoopModeParams loop_mode_param; | 177 | LoopModeParams loop_mode_param; |
| 171 | SetLoopModeParams(tpipe, data_copy_param, loop_mode_param, copy_in); | 178 | SetLoopModeParams(tpipe, data_copy_param, loop_mode_param, copy_in); |
| 172 | const Tensor &ub_tensor = copy_in ? output : input; | 179 | const Tensor &ub_tensor = copy_in ? output : input; |
| 173 | - std::string padding_mode = GetPaddingMode(tpipe, ub_tensor, data_copy_param); | 180 | + std::string padding_mode = GetPaddingMode(ub_tensor, data_copy_param); |
| 174 | if (total_len <= kDmaMaxLen) { | 181 | if (total_len <= kDmaMaxLen) { |
| 175 | CreateBaseDmaCall(input, output, dma_param, padding_mode, ss, copy_in); | 182 | CreateBaseDmaCall(input, output, dma_param, padding_mode, ss, copy_in); |
| 176 | return; | 183 | return; |
| @@ -349,7 +356,7 @@ Status BuildDataCopyApiParamInNormal(const TPipe &tpipe, CodegenApiParam &api_pa | |||
| 349 | GE_ASSERT_TRUE(CalculateDmaParams(tpipe, dst, dst, data_copy_param), "CalculateDmaParams failed"); | 356 | GE_ASSERT_TRUE(CalculateDmaParams(tpipe, dst, dst, data_copy_param), "CalculateDmaParams failed"); |
| 350 | size_t total_len = data_copy_param.repeats.size(); | 357 | size_t total_len = data_copy_param.repeats.size(); |
| 351 | const Tensor &ub_tensor = copy_in ? dst : src; | 358 | const Tensor &ub_tensor = copy_in ? dst : src; |
| 352 | - std::string padding_mode = GetPaddingMode(tpipe, ub_tensor, data_copy_param); | 359 | + std::string padding_mode = GetPaddingMode(ub_tensor, data_copy_param); |
| 353 | api_param.template_params.emplace_back(padding_mode); | 360 | api_param.template_params.emplace_back(padding_mode); |
| 354 | 361 | ||
| 355 | BuildDataCopyBaseParams(tpipe, data_copy_param, dma_specific_params, copy_in); | 362 | 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 TPipe &tpipe, const Tensor &ub_tensor, const DataCopyParams &data_copy_param); | 87 | +std::string GetPaddingMode(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,7 +27,10 @@ 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 | - | 30 | + DataCopyParams data_copy_param; |
| 31 | + (void)CalculateDmaParams(tpipe, output, output, data_copy_param); | ||
| 32 | + constexpr char kCompactPddingMode[] = "AscendC::PaddingMode::Compact"; | ||
| 33 | + std::string padding_mode = GetPaddingMode(output, data_copy_param); | ||
| 31 | ss << "const uint32_t " << shape_prefix << input.id << "_brc_to_" << output.id << "[" << vectorized_axis_size | 34 | ss << "const uint32_t " << shape_prefix << input.id << "_brc_to_" << output.id << "[" << vectorized_axis_size |
| 32 | << "] = {"; | 35 | << "] = {"; |
| 33 | const char *sep = ""; | 36 | const char *sep = ""; |
| @@ -65,7 +68,7 @@ static void GenParams(const TPipe &tpipe, const Tensor &input, const Tensor &out | |||
| 65 | ascir::AxisId axis_id = output.vectorized_axis[pos]; | 68 | ascir::AxisId axis_id = output.vectorized_axis[pos]; |
| 66 | auto last_dim_size = output.vectorized_strides[pre_pos]; | 69 | auto last_dim_size = output.vectorized_strides[pre_pos]; |
| 67 | if (tpipe.tiler.GetAxis(axis_id).type != ascir::Axis::Type::kAxisTypeTileInner || | 70 | if (tpipe.tiler.GetAxis(axis_id).type != ascir::Axis::Type::kAxisTypeTileInner || |
| 68 | - output.vectorized_axis[0] == axis_id) { | 71 | + output.vectorized_axis[0] == axis_id || padding_mode == kCompactPddingMode) { |
| 69 | ss << tpipe.tiler.ActualSize(last_dim_size); | 72 | ss << tpipe.tiler.ActualSize(last_dim_size); |
| 70 | } else { | 73 | } else { |
| 71 | ss << tpipe.tiler.Size(last_dim_size); | 74 | 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 | - DiscontinuityInfo info; | 45 | + ascgen_utils::DiscontinuityInfo info; |
| 46 | - GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), | 46 | + GE_ASSERT_SUCCESS(ascgen_utils::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 | - DiscontinuityInfo info; | 274 | + ascgen_utils::DiscontinuityInfo info; |
| 275 | - GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(node->outputs[0].attr, info), | 275 | + GE_ASSERT_SUCCESS(ascgen_utils::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 | - DiscontinuityInfo info; | 39 | + ascgen_utils::DiscontinuityInfo info; |
| 40 | - GE_ASSERT_SUCCESS(TensorLayoutUtils::AnalyzeLoadDiscontinuity(output_attr, info), | 40 | + GE_ASSERT_SUCCESS(ascgen_utils::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模式搬运 |