已合并
【PR】: fix: 调整 tensor layout 工具归属和搬运模式 #1932
【PR】: fix: 调整 tensor layout 工具归属和搬运模式 #1932
已合并
Phl17创建于 9月2日
共 14 个文件变更+142-35
Rautofuse/optimize/tensor_layout_utils.cpp→autofuse/common/tensor_layout_utils.cpp+2-3
@@ -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 {
21af::Status TensorLayoutUtils::AnalyzeLoadDiscontinuity(const af::AscTensorAttr &attr, DiscontinuityInfo &info) {20af::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 optimize66+} // namespace ascgen_utils
Rautofuse/optimize/tensor_layout_utils.h→autofuse/common/tensor_layout_utils.h+2-2
@@ -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 {
17struct DiscontinuityInfo {17struct 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 optimize25+} // 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
@@ -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 data23 // 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 
55INSTANTIATE_TEST_SUITE_P(CalcWithDifferentShape, E2E_LoadNanOutForStore_Code,59INSTANTIATE_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 
14namespace {15namespace {
15constexpr size_t kDmaMaxLen = 2U;16constexpr 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 
120std::string GenLoopModeParams(const LoopModeParams &loop_mode_param, int64_t input_dtype_size,127std::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
84void SetLoopModeParams(const TPipe &tpipe, const DataCopyParams &data_copy_param, LoopModeParams &loop_mode_param,84void SetLoopModeParams(const TPipe &tpipe, const DataCopyParams &data_copy_param, LoopModeParams &loop_mode_param,
85 bool copy_in);85 bool copy_in);
86void SetLoopModeParamsExpr(const DataCopyParams &data_copy_param, LoopModeParamsExpr &loop_mode_param, bool copy_in);86void 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);
88void BuildDataCopyApiParamInCVFusion(const TPipe &tpipe, CodegenApiParam &api_param,88void 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_size34 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模式搬运