已合并
feat: 9个迁移算子适配unknown shape/rank InferShape并补UT及入口日志 #4811
xuejinghui创建于 8月17日
feat: 9个迁移算子适配unknown shape/rank InferShape并补UT及入口日志 #4811
已合并
xuejinghui创建于 8月17日
27 个文件变更+1006-333
@@ -16,6 +16,7 @@
16#include <climits>16#include <climits>
17#include "log/log.h"17#include "log/log.h"
18#include "register/op_impl_registry.h"18#include "register/op_impl_registry.h"
19+#include "util/shape_util.h"
19#include <algorithm>20#include <algorithm>
20 21 
21using namespace ge;22using namespace ge;
@@ -25,12 +26,20 @@ static constexpr int64_t IDX_0 = 0;
25 26 
26static ge::graphStatus InferShapeMatrixDiagPart(gert::InferShapeContext* context)27static ge::graphStatus InferShapeMatrixDiagPart(gert::InferShapeContext* context)
27{28{
29+ OP_LOGD(context->GetNodeName(), "Enter InferShapeMatrixDiagPart");
30+ 
28 const gert::Shape* xShape = context->GetInputShape(IDX_0);31 const gert::Shape* xShape = context->GetInputShape(IDX_0);
29 OP_CHECK_NULL_WITH_CONTEXT(context, xShape);32 OP_CHECK_NULL_WITH_CONTEXT(context, xShape);
30 33 
31 gert::Shape* yShape = context->GetOutputShape(IDX_0);34 gert::Shape* yShape = context->GetOutputShape(IDX_0);
32 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);35 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);
33 36 
37+ // Unknown rank (-2): rank is unknown, cannot infer the diag shape; pass through as unknown rank
38+ if (Ops::Base::IsUnknownRank(*xShape)) {
39+ Ops::Base::SetUnknownRank(*yShape);
40+ return GRAPH_SUCCESS;
41+ }
42+ 
34 auto xShapeSize = xShape->GetDimNum();43 auto xShapeSize = xShape->GetDimNum();
35 if (xShapeSize < 2) {44 if (xShapeSize < 2) {
36 OP_LOGE_FOR_INVALID_SHAPESIZE_WITH_REASON(context->GetNodeName(), "x", std::to_string(xShapeSize).c_str(),45 OP_LOGE_FOR_INVALID_SHAPESIZE_WITH_REASON(context->GetNodeName(), "x", std::to_string(xShapeSize).c_str(),
@@ -43,13 +43,9 @@ static ge::graphStatus GetPlatformInfo(gert::TilingContext* context, uint64_t& u
43 return ge::GRAPH_SUCCESS;43 return ge::GRAPH_SUCCESS;
44}44}
45 45 
46-static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)46+static ge::graphStatus ValidateInputAndComputeDims(gert::TilingContext* context, int64_t& d, int64_t& n,
47+ int64_t& matrixSize, int64_t& totalOutputElements)
47{48{
48- uint64_t ubSize;
49- int64_t coreNum;
50- OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,
51- OP_LOGE(context, "GetPlatformInfo error"), return ge::GRAPH_FAILED);
52- 
53 auto inputX = context->GetInputShape(0);49 auto inputX = context->GetInputShape(0);
54 OP_CHECK_NULL_WITH_CONTEXT(context, inputX);50 OP_CHECK_NULL_WITH_CONTEXT(context, inputX);
55 auto inputShapeX = Ops::Base::EnsureNotScalar(inputX->GetStorageShape());51 auto inputShapeX = Ops::Base::EnsureNotScalar(inputX->GetStorageShape());
@@ -68,19 +64,23 @@ static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)
68 }64 }
69 65 
70 int64_t M = inputShapeX.GetDim(rank - 2);66 int64_t M = inputShapeX.GetDim(rank - 2);
71- int64_t N = inputShapeX.GetDim(rank - 1);67+ n = inputShapeX.GetDim(rank - 1);
72- int64_t d = std::min(M, N);68+ d = std::min(M, n);
73- int64_t matrixSize = M * N;69+ matrixSize = M * n;
74 int64_t totalInputElements = inputShapeX.GetShapeSize();70 int64_t totalInputElements = inputShapeX.GetShapeSize();
75 int64_t batchTotal = (matrixSize > 0) ? (totalInputElements / matrixSize) : 0;71 int64_t batchTotal = (matrixSize > 0) ? (totalInputElements / matrixSize) : 0;
76- int64_t totalOutputElements = batchTotal * d;72+ totalOutputElements = batchTotal * d;
77 73 
78 if (d < 0) {74 if (d < 0) {
79 OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context->GetNodeName(), "diagLen", std::to_string(d).c_str(),75 OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context->GetNodeName(), "diagLen", std::to_string(d).c_str(),
80 "diagLen must be greater than or equal to 0");76 "diagLen must be greater than or equal to 0");
81 return ge::GRAPH_FAILED;77 return ge::GRAPH_FAILED;
82 }78 }
79+ return ge::GRAPH_SUCCESS;
80+}
83 81 
82+static ge::graphStatus CheckDtype(gert::TilingContext* context)
83+{
84 const std::set<ge::DataType> supportedDtype = {ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_INT32, ge::DT_INT8,84 const std::set<ge::DataType> supportedDtype = {ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_INT32, ge::DT_INT8,
85 ge::DT_UINT8};85 ge::DT_UINT8};
86 auto inputDesc = context->GetInputDesc(0);86 auto inputDesc = context->GetInputDesc(0);
@@ -91,6 +91,41 @@ static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)
91 "only support float16, float32, int32, int8, uint8");91 "only support float16, float32, int32, int8, uint8");
92 return ge::GRAPH_FAILED;92 return ge::GRAPH_FAILED;
93 }93 }
94+ return ge::GRAPH_SUCCESS;
95+}
96+ 
97+static ge::graphStatus SetupMemoryAndWorkspace(gert::TilingContext* context, uint64_t ubSize)
98+{
99+ auto res = context->SetLocalMemorySize(static_cast<uint32_t>(ubSize - DCACHE_SIZE - STATIC_UB_ESTIMATE));
100+ OP_CHECK_IF((res != ge::GRAPH_SUCCESS),
101+ OP_LOGE(context, "SetLocalMemorySize failed, ubSize=%lu, DCACHE_SIZE=%u, STATIC_UB_ESTIMATE=%u", ubSize,
102+ DCACHE_SIZE, STATIC_UB_ESTIMATE),
103+ return ge::GRAPH_FAILED);
104+ 
105+ auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
106+ uint64_t sysWorkspaceSize = ascendcPlatform.GetLibApiWorkSpaceSize();
107+ size_t* currentWorkspace = context->GetWorkspaceSizes(1);
108+ OP_CHECK_NULL_WITH_CONTEXT(context, currentWorkspace);
109+ currentWorkspace[0] = static_cast<size_t>(sysWorkspaceSize);
110+ return ge::GRAPH_SUCCESS;
111+}
112+ 
113+static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)
114+{
115+ OP_LOGD(context, "Enter TilingMatrixDiagPart");
116+ uint64_t ubSize;
117+ int64_t coreNum;
118+ OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,
119+ OP_LOGE(context, "GetPlatformInfo error"), return ge::GRAPH_FAILED);
120+ 
121+ int64_t d = 0;
122+ int64_t n = 0;
123+ int64_t matrixSize = 0;
124+ int64_t totalOutputElements = 0;
125+ OP_CHECK_IF(ValidateInputAndComputeDims(context, d, n, matrixSize, totalOutputElements) != ge::GRAPH_SUCCESS,
126+ OP_LOGE(context, "ValidateInputAndComputeDims error"), return ge::GRAPH_FAILED);
127+ OP_CHECK_IF(CheckDtype(context) != ge::GRAPH_SUCCESS, OP_LOGE(context, "CheckDtype error"),
128+ return ge::GRAPH_FAILED);
94 129 
95 MatrixDiagPartTilingData* tiling = context->GetTilingData<MatrixDiagPartTilingData>();130 MatrixDiagPartTilingData* tiling = context->GetTilingData<MatrixDiagPartTilingData>();
96 OP_CHECK_NULL_WITH_CONTEXT(context, tiling);131 OP_CHECK_NULL_WITH_CONTEXT(context, tiling);
@@ -98,7 +133,7 @@ static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)
98 OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED);133 OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED);
99 tiling->totalOutputElements = totalOutputElements;134 tiling->totalOutputElements = totalOutputElements;
100 tiling->diagLen = d;135 tiling->diagLen = d;
101- tiling->inputRowStride = N + 1;136+ tiling->inputRowStride = n + 1;
102 tiling->matrixSize = matrixSize;137 tiling->matrixSize = matrixSize;
103 138 
104 int64_t perCoreElements = Ops::Base::CeilDiv(totalOutputElements, coreNum);139 int64_t perCoreElements = Ops::Base::CeilDiv(totalOutputElements, coreNum);
@@ -108,21 +143,12 @@ static ge::graphStatus MatrixDiagPartTilingFunc(gert::TilingContext* context)
108 int64_t needCoreNum = (totalOutputElements == 0) ? 1 : Ops::Base::CeilDiv(totalOutputElements, perCoreElements);143 int64_t needCoreNum = (totalOutputElements == 0) ? 1 : Ops::Base::CeilDiv(totalOutputElements, perCoreElements);
109 context->SetBlockDim(needCoreNum);144 context->SetBlockDim(needCoreNum);
110 145 
111- auto res = context->SetLocalMemorySize(static_cast<uint32_t>(ubSize - DCACHE_SIZE - STATIC_UB_ESTIMATE));146+ OP_CHECK_IF(SetupMemoryAndWorkspace(context, ubSize) != ge::GRAPH_SUCCESS,
112- OP_CHECK_IF((res != ge::GRAPH_SUCCESS),147+ OP_LOGE(context, "SetupMemoryAndWorkspace error"), return ge::GRAPH_FAILED);
113- OP_LOGE(context, "SetLocalMemorySize failed, ubSize=%lu, DCACHE_SIZE=%u, STATIC_UB_ESTIMATE=%u", ubSize,
114- DCACHE_SIZE, STATIC_UB_ESTIMATE),
115- return ge::GRAPH_FAILED);
116 148 
117 uint64_t tilingKey = GET_TPL_TILING_KEY(MODE_DEFAULT);149 uint64_t tilingKey = GET_TPL_TILING_KEY(MODE_DEFAULT);
118 context->SetTilingKey(tilingKey);150 context->SetTilingKey(tilingKey);
119 151 
120- auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
121- uint64_t sysWorkspaceSize = ascendcPlatform.GetLibApiWorkSpaceSize();
122- size_t* currentWorkspace = context->GetWorkspaceSizes(1);
123- OP_CHECK_NULL_WITH_CONTEXT(context, currentWorkspace);
124- currentWorkspace[0] = static_cast<size_t>(sysWorkspaceSize);
125- 
126 return ge::GRAPH_SUCCESS;152 return ge::GRAPH_SUCCESS;
127}153}
128 154 
@@ -112,3 +112,67 @@ TEST_F(MatrixDiagPartInfershape, matrix_diag_part_infershape_dynamic_shape)
112 };112 };
113 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);113 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
114}114}
115+ 
116+TEST_F(MatrixDiagPartInfershape, matrix_diag_part_infershape_unknown_shape)
117+{
118+ // Unknown shape (-1): input shape {-1, -1, -1}, output shape {-1, -1}
119+ gert::InfershapeContextPara infershapeContextPara("MatrixDiagPart",
120+ {
121+ {{{-1, -1, -1}, {-1, -1, -1}}, ge::DT_FLOAT16, ge::FORMAT_ND},
122+ },
123+ {
124+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
125+ });
126+ std::vector<std::vector<int64_t>> expectOutputShape = {
127+ {-1, -1},
128+ };
129+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
130+}
131+ 
132+TEST_F(MatrixDiagPartInfershape, matrix_diag_part_infershape_unknown_shape_mixed)
133+{
134+ // Mixed unknown dim (-1) with known dims: input shape {4, -1, 3}, min(-1, 3) = -1, output shape {4, -1}
135+ gert::InfershapeContextPara infershapeContextPara("MatrixDiagPart",
136+ {
137+ {{{4, -1, 3}, {4, -1, 3}}, ge::DT_FLOAT16, ge::FORMAT_ND},
138+ },
139+ {
140+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
141+ });
142+ std::vector<std::vector<int64_t>> expectOutputShape = {
143+ {4, -1},
144+ };
145+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
146+}
147+ 
148+TEST_F(MatrixDiagPartInfershape, matrix_diag_part_infershape_unknown_shape_rank_mixed)
149+{
150+ // Mixed: origin shape {-1, 2, 3} with unknown rank shape range {-2}, min(2, 3) = 2, output shape {-1, 2}
151+ gert::InfershapeContextPara infershapeContextPara("MatrixDiagPart",
152+ {
153+ {{{-1, 2, 3}, {-2}}, ge::DT_FLOAT16, ge::FORMAT_ND},
154+ },
155+ {
156+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
157+ });
158+ std::vector<std::vector<int64_t>> expectOutputShape = {
159+ {-1, 2},
160+ };
161+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
162+}
163+ 
164+TEST_F(MatrixDiagPartInfershape, matrix_diag_part_infershape_unknown_rank)
165+{
166+ // Unknown rank (-2): input shape {-2}, output shape {-2}
167+ gert::InfershapeContextPara infershapeContextPara("MatrixDiagPart",
168+ {
169+ {{{-2}, {-2}}, ge::DT_FLOAT16, ge::FORMAT_ND},
170+ },
171+ {
172+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
173+ });
174+ std::vector<std::vector<int64_t>> expectOutputShape = {
175+ {-2},
176+ };
177+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
178+}
@@ -26,7 +26,7 @@ protected:
26 static void TearDownTestCase() { std::cout << "MatrixDiagPartTiling TearDown" << std::endl; }26 static void TearDownTestCase() { std::cout << "MatrixDiagPartTiling TearDown" << std::endl; }
27};27};
28 28 
29-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};29+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};
30 30 
31TEST_F(MatrixDiagPartTiling, matrix_diag_part_tiling_float16)31TEST_F(MatrixDiagPartTiling, matrix_diag_part_tiling_float16)
32{32{
@@ -32,41 +32,36 @@ constexpr int64_t PER_CORE_MIN = 1024;
32constexpr uint32_t DCACHE_SIZE = 128 * 1024;32constexpr uint32_t DCACHE_SIZE = 128 * 1024;
33constexpr uint32_t STATIC_UB_ESTIMATE = 0;33constexpr uint32_t STATIC_UB_ESTIMATE = 0;
34 34 
35-static ge::graphStatus GetPlatformInfo(gert::TilingContext* context,35+static ge::graphStatus GetPlatformInfo(gert::TilingContext* context, uint64_t& ubSize, int64_t& coreNum)
36- uint64_t& ubSize, int64_t& coreNum)
37{36{
38 fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo();37 fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo();
39 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr);38 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr);
40 auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfoPtr);39 auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfoPtr);
41 coreNum = ascendcPlatform.GetCoreNumAiv();40 coreNum = ascendcPlatform.GetCoreNumAiv();
42- OP_CHECK_IF(coreNum == 0,41+ OP_CHECK_IF(coreNum == 0, OP_LOGE(context, "coreNum is 0"), return ge::GRAPH_FAILED);
43- OP_LOGE(context, "coreNum is 0"), return ge::GRAPH_FAILED);
44 ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);42 ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
45- OP_CHECK_IF(ubSize == 0,43+ OP_CHECK_IF(ubSize == 0, OP_LOGE(context, "ubSize is 0"), return ge::GRAPH_FAILED);
46- OP_LOGE(context, "ubSize is 0"), return ge::GRAPH_FAILED);
47 return ge::GRAPH_SUCCESS;44 return ge::GRAPH_SUCCESS;
48}45}
49 46 
50// Read tensor data values as int64, handling both int32 and int64 dtypes47// Read tensor data values as int64, handling both int32 and int64 dtypes
51-static ge::graphStatus ReadTensorData(gert::TilingContext* context,48+static ge::graphStatus ReadTensorData(gert::TilingContext* context, int32_t inputIdx, int64_t* outData,
52- int32_t inputIdx, int64_t* outData, int64_t dataSize)49+ int64_t dataSize)
53{50{
54 auto inputTensor = context->GetInputTensor(inputIdx);51 auto inputTensor = context->GetInputTensor(inputIdx);
55 OP_CHECK_NULL_WITH_CONTEXT(context, inputTensor);52 OP_CHECK_NULL_WITH_CONTEXT(context, inputTensor);
56 auto dtype = inputTensor->GetDataType();53 auto dtype = inputTensor->GetDataType();
57 if (dtype == ge::DT_INT64) {54 if (dtype == ge::DT_INT64) {
58 const int64_t* srcData = inputTensor->GetData<int64_t>();55 const int64_t* srcData = inputTensor->GetData<int64_t>();
59- OP_CHECK_IF(srcData == nullptr,56+ OP_CHECK_IF(srcData == nullptr, OP_LOGE(context, "GetData<int64_t> failed for input %d", inputIdx),
60- OP_LOGE(context, "GetData<int64_t> failed for input %d", inputIdx),57+ return ge::GRAPH_FAILED);
61- return ge::GRAPH_FAILED);
62 for (int64_t i = 0; i < dataSize; i++) {58 for (int64_t i = 0; i < dataSize; i++) {
63 outData[i] = srcData[i];59 outData[i] = srcData[i];
64 }60 }
65 } else {61 } else {
66 const int32_t* srcData = inputTensor->GetData<int32_t>();62 const int32_t* srcData = inputTensor->GetData<int32_t>();
67- OP_CHECK_IF(srcData == nullptr,63+ OP_CHECK_IF(srcData == nullptr, OP_LOGE(context, "GetData<int32_t> failed for input %d", inputIdx),
68- OP_LOGE(context, "GetData<int32_t> failed for input %d", inputIdx),64+ return ge::GRAPH_FAILED);
69- return ge::GRAPH_FAILED);
70 for (int64_t i = 0; i < dataSize; i++) {65 for (int64_t i = 0; i < dataSize; i++) {
71 outData[i] = static_cast<int64_t>(srcData[i]);66 outData[i] = static_cast<int64_t>(srcData[i]);
72 }67 }
@@ -75,9 +70,8 @@ static ge::graphStatus ReadTensorData(gert::TilingContext* context,
75}70}
76 71 
77// Resolve -1 dimension in new_shape72// Resolve -1 dimension in new_shape
78-static ge::graphStatus ResolveMinusOne(gert::TilingContext* context,73+static ge::graphStatus ResolveMinusOne(gert::TilingContext* context, const int64_t* shapeData, int32_t inputRank,
79- const int64_t* shapeData, int32_t inputRank,74+ int64_t* resolvedShape, int32_t outputRank)
80- int64_t* resolvedShape, int32_t outputRank)
81{75{
82 int64_t denseSize = 1;76 int64_t denseSize = 1;
83 for (int32_t d = 0; d < inputRank; d++) {77 for (int32_t d = 0; d < inputRank; d++) {
@@ -87,21 +81,16 @@ static ge::graphStatus ResolveMinusOne(gert::TilingContext* context,
87 int32_t unknownIdx = -1;81 int32_t unknownIdx = -1;
88 for (int32_t d = 0; d < outputRank; d++) {82 for (int32_t d = 0; d < outputRank; d++) {
89 if (resolvedShape[d] == -1) {83 if (resolvedShape[d] == -1) {
90- OP_CHECK_IF(unknownIdx != -1,84+ OP_CHECK_IF(unknownIdx != -1, OP_LOGE(context, "At most one -1 dimension allowed"),
91- OP_LOGE(context, "At most one -1 dimension allowed"),85+ return ge::GRAPH_FAILED);
92- return ge::GRAPH_FAILED);
93 unknownIdx = d;86 unknownIdx = d;
94 } else {87 } else {
95- OP_CHECK_IF(resolvedShape[d] <= 0,88+ OP_CHECK_IF(resolvedShape[d] <= 0, OP_LOGE(context, "input dimension is error"), return ge::GRAPH_FAILED);
96- OP_LOGE(context, "input dimension is error"),
97- return ge::GRAPH_FAILED);
98 product *= resolvedShape[d];89 product *= resolvedShape[d];
99 }90 }
100 }91 }
101 if (unknownIdx != -1) {92 if (unknownIdx != -1) {
102- OP_CHECK_IF(product == 0,93+ OP_CHECK_IF(product == 0, OP_LOGE(context, "Cannot infer -1 dim with zero product"), return ge::GRAPH_FAILED);
103- OP_LOGE(context, "Cannot infer -1 dim with zero product"),
104- return ge::GRAPH_FAILED);
105 resolvedShape[unknownIdx] = denseSize / product;94 resolvedShape[unknownIdx] = denseSize / product;
106 }95 }
107 return ge::GRAPH_SUCCESS;96 return ge::GRAPH_SUCCESS;
@@ -110,7 +99,9 @@ static ge::graphStatus ResolveMinusOne(gert::TilingContext* context,
110// Compute strides (row-major, last dim stride = 1)99// Compute strides (row-major, last dim stride = 1)
111static void ComputeStrides(const int64_t* shape, int32_t rank, int64_t* strides)100static void ComputeStrides(const int64_t* shape, int32_t rank, int64_t* strides)
112{101{
113- if (rank <= 0) { return; }102+ if (rank <= 0) {
103+ return;
104+ }
114 strides[rank - 1] = 1;105 strides[rank - 1] = 1;
115 for (int32_t d = rank - 2; d >= 0; d--) {106 for (int32_t d = rank - 2; d >= 0; d--) {
116 strides[d] = strides[d + 1] * shape[d + 1];107 strides[d] = strides[d + 1] * shape[d + 1];
@@ -118,18 +109,58 @@ static void ComputeStrides(const int64_t* shape, int32_t rank, int64_t* strides)
118}109}
119 110 
120// Detect identity reshape (input_shape == output_shape)111// Detect identity reshape (input_shape == output_shape)
121-static int32_t DetectIdentityReshape(const int64_t* shapeData,112+static int32_t DetectIdentityReshape(const int64_t* shapeData, const int64_t* resolvedShape, int32_t inputRank,
122- const int64_t* resolvedShape, int32_t inputRank, int32_t outputRank)113+ int32_t outputRank)
123{114{
124- if (inputRank != outputRank) { return 0; }115+ if (inputRank != outputRank) {
116+ return 0;
117+ }
125 for (int32_t d = 0; d < inputRank; d++) {118 for (int32_t d = 0; d < inputRank; d++) {
126- if (shapeData[d] != resolvedShape[d]) { return 0; }119+ if (shapeData[d] != resolvedShape[d]) {
120+ return 0;
121+ }
127 }122 }
128 return 1;123 return 1;
129}124}
130 125 
131-static ge::graphStatus ComputeSparseReshapeTiling(gert::TilingContext* context,126+// Read shape/new_shape tensor data and resolve -1 dimension
132- SparseReshapeTilingData* tiling, int64_t coreNum)127+static ge::graphStatus ReadAndResolveShapes(gert::TilingContext* context, int32_t inputRank, int32_t outputRank,
128+ int64_t* shapeData, int64_t* resolvedShape)
129+{
130+ int64_t newShapeData[MAX_RANK] = {};
131+ OP_CHECK_IF(ReadTensorData(context, IDX_SHAPE, shapeData, inputRank) != ge::GRAPH_SUCCESS,
132+ OP_LOGE(context, "ReadTensorData(shape) failed"), return ge::GRAPH_FAILED);
133+ OP_CHECK_IF(ReadTensorData(context, IDX_NEW_SHAPE, newShapeData, outputRank) != ge::GRAPH_SUCCESS,
134+ OP_LOGE(context, "ReadTensorData(new_shape) failed"), return ge::GRAPH_FAILED);
135+ for (int32_t d = 0; d < outputRank; d++) {
136+ resolvedShape[d] = newShapeData[d];
137+ }
138+ OP_CHECK_IF(ResolveMinusOne(context, shapeData, inputRank, resolvedShape, outputRank) != ge::GRAPH_SUCCESS,
139+ OP_LOGE(context, "ResolveMinusOne failed"), return ge::GRAPH_FAILED);
140+ return ge::GRAPH_SUCCESS;
141+}
142+ 
143+// 校验 input shape 与 resolved new_shape 总元素数一致 (SE §1.4)
144+static ge::graphStatus ValidateTotalElements(gert::TilingContext* context, const int64_t* shapeData, int32_t inputRank,
145+ const int64_t* resolvedShape, int32_t outputRank)
146+{
147+ int64_t inputTotalElements = 1;
148+ for (int32_t d = 0; d < inputRank; d++) {
149+ inputTotalElements *= shapeData[d];
150+ }
151+ int64_t outputTotalElements = 1;
152+ for (int32_t d = 0; d < outputRank; d++) {
153+ outputTotalElements *= resolvedShape[d];
154+ }
155+ OP_CHECK_IF(
156+ inputTotalElements != outputTotalElements,
157+ OP_LOGE(context, "Total elements mismatch: input=%ld vs output=%ld", inputTotalElements, outputTotalElements),
158+ return ge::GRAPH_FAILED);
159+ return ge::GRAPH_SUCCESS;
160+}
161+ 
162+static ge::graphStatus ComputeSparseReshapeTiling(gert::TilingContext* context, SparseReshapeTilingData* tiling,
163+ int64_t coreNum)
133{164{
134 auto indicesShape = context->GetInputShape(IDX_INDICES);165 auto indicesShape = context->GetInputShape(IDX_INDICES);
135 OP_CHECK_NULL_WITH_CONTEXT(context, indicesShape);166 OP_CHECK_NULL_WITH_CONTEXT(context, indicesShape);
@@ -138,35 +169,19 @@ static ge::graphStatus ComputeSparseReshapeTiling(gert::TilingContext* context,
138 int64_t nnz = indicesShape->GetShape().GetDim(0);169 int64_t nnz = indicesShape->GetShape().GetDim(0);
139 int32_t inputRank = static_cast<int32_t>(indicesShape->GetShape().GetDim(1));170 int32_t inputRank = static_cast<int32_t>(indicesShape->GetShape().GetDim(1));
140 int32_t outputRank = static_cast<int32_t>(newShapeShape->GetShape().GetDim(0));171 int32_t outputRank = static_cast<int32_t>(newShapeShape->GetShape().GetDim(0));
141- OP_CHECK_IF(inputRank > MAX_RANK || outputRank > MAX_RANK,172+ OP_CHECK_IF(inputRank > MAX_RANK || outputRank > MAX_RANK, OP_LOGE(context, "rank exceeds MAX_RANK=%d", MAX_RANK),
142- OP_LOGE(context, "rank exceeds MAX_RANK=%d", MAX_RANK),173+ return ge::GRAPH_FAILED);
143- return ge::GRAPH_FAILED);
144 int64_t shapeData[MAX_RANK] = {};174 int64_t shapeData[MAX_RANK] = {};
145- int64_t newShapeData[MAX_RANK] = {};
146- OP_CHECK_IF(ReadTensorData(context, IDX_SHAPE, shapeData, inputRank) != ge::GRAPH_SUCCESS,
147- OP_LOGE(context, "ReadTensorData(shape) failed"), return ge::GRAPH_FAILED);
148- OP_CHECK_IF(ReadTensorData(context, IDX_NEW_SHAPE, newShapeData, outputRank) != ge::GRAPH_SUCCESS,
149- OP_LOGE(context, "ReadTensorData(new_shape) failed"), return ge::GRAPH_FAILED);
150 int64_t resolvedShape[MAX_RANK] = {};175 int64_t resolvedShape[MAX_RANK] = {};
151- for (int32_t d = 0; d < outputRank; d++) { resolvedShape[d] = newShapeData[d]; }176+ OP_CHECK_IF(ReadAndResolveShapes(context, inputRank, outputRank, shapeData, resolvedShape) != ge::GRAPH_SUCCESS,
152- OP_CHECK_IF(ResolveMinusOne(context, shapeData, inputRank, resolvedShape, outputRank)177+ OP_LOGE(context, "ReadAndResolveShapes failed"), return ge::GRAPH_FAILED);
153- != ge::GRAPH_SUCCESS, OP_LOGE(context, "ResolveMinusOne failed"),178+ OP_CHECK_IF(ValidateTotalElements(context, shapeData, inputRank, resolvedShape, outputRank) != ge::GRAPH_SUCCESS,
154- return ge::GRAPH_FAILED);179+ OP_LOGE(context, "ValidateTotalElements failed"), return ge::GRAPH_FAILED);
155- // 校验 input shape 与 resolved new_shape 总元素数一致 (SE §1.4)
156- int64_t inputTotalElements = 1;
157- for (int32_t d = 0; d < inputRank; d++) { inputTotalElements *= shapeData[d]; }
158- int64_t outputTotalElements = 1;
159- for (int32_t d = 0; d < outputRank; d++) { outputTotalElements *= resolvedShape[d]; }
160- OP_CHECK_IF(inputTotalElements != outputTotalElements,
161- OP_LOGE(context, "Total elements mismatch: input=%ld vs output=%ld",
162- inputTotalElements, outputTotalElements),
163- return ge::GRAPH_FAILED);
164 int64_t inputStrides[MAX_RANK] = {};180 int64_t inputStrides[MAX_RANK] = {};
165 int64_t outputStrides[MAX_RANK] = {};181 int64_t outputStrides[MAX_RANK] = {};
166 ComputeStrides(shapeData, inputRank, inputStrides);182 ComputeStrides(shapeData, inputRank, inputStrides);
167 ComputeStrides(resolvedShape, outputRank, outputStrides);183 ComputeStrides(resolvedShape, outputRank, outputStrides);
168- int32_t isIdentity = DetectIdentityReshape(shapeData, resolvedShape,184+ int32_t isIdentity = DetectIdentityReshape(shapeData, resolvedShape, inputRank, outputRank);
169- inputRank, outputRank);
170 tiling->nnz = nnz;185 tiling->nnz = nnz;
171 tiling->inputRank = inputRank;186 tiling->inputRank = inputRank;
172 tiling->outputRank = outputRank;187 tiling->outputRank = outputRank;
@@ -177,7 +192,9 @@ static ge::graphStatus ComputeSparseReshapeTiling(gert::TilingContext* context,
177 tiling->outputShape[d] = resolvedShape[d];192 tiling->outputShape[d] = resolvedShape[d];
178 }193 }
179 int64_t perCore = (nnz > 0) ? Ops::Base::CeilDiv(nnz, coreNum) : 0;194 int64_t perCore = (nnz > 0) ? Ops::Base::CeilDiv(nnz, coreNum) : 0;
180- if (perCore > 0 && perCore < PER_CORE_MIN) { perCore = PER_CORE_MIN; }195+ if (perCore > 0 && perCore < PER_CORE_MIN) {
196+ perCore = PER_CORE_MIN;
197+ }
181 int64_t needCoreNum = (nnz > 0) ? Ops::Base::CeilDiv(nnz, perCore) : 1;198 int64_t needCoreNum = (nnz > 0) ? Ops::Base::CeilDiv(nnz, perCore) : 1;
182 context->SetBlockDim(static_cast<uint32_t>(needCoreNum));199 context->SetBlockDim(static_cast<uint32_t>(needCoreNum));
183 return ge::GRAPH_SUCCESS;200 return ge::GRAPH_SUCCESS;
@@ -185,37 +202,32 @@ static ge::graphStatus ComputeSparseReshapeTiling(gert::TilingContext* context,
185 202 
186static ge::graphStatus SparseReshapeTilingFunc(gert::TilingContext* context)203static ge::graphStatus SparseReshapeTilingFunc(gert::TilingContext* context)
187{204{
205+ OP_LOGD(context, "Enter TilingSparseReshape");
188 uint64_t ubSize = 0;206 uint64_t ubSize = 0;
189 int64_t coreNum = 0;207 int64_t coreNum = 0;
190 OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,208 OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,
191- OP_LOGE(context, "GetPlatformInfo error"), return ge::GRAPH_FAILED);209+ OP_LOGE(context, "GetPlatformInfo error"), return ge::GRAPH_FAILED);
192 SparseReshapeTilingData* tiling = context->GetTilingData<SparseReshapeTilingData>();210 SparseReshapeTilingData* tiling = context->GetTilingData<SparseReshapeTilingData>();
193 OP_CHECK_NULL_WITH_CONTEXT(context, tiling);211 OP_CHECK_NULL_WITH_CONTEXT(context, tiling);
194- OP_CHECK_IF(memset_s(tiling, sizeof(SparseReshapeTilingData), 0,212+ OP_CHECK_IF(memset_s(tiling, sizeof(SparseReshapeTilingData), 0, sizeof(SparseReshapeTilingData)) != EOK,
195- sizeof(SparseReshapeTilingData)) != EOK,213+ OP_LOGE(context, "memset tiling data error"), return ge::GRAPH_FAILED);
196- OP_LOGE(context, "memset tiling data error"), return ge::GRAPH_FAILED);214+ OP_CHECK_IF(ComputeSparseReshapeTiling(context, tiling, coreNum) != ge::GRAPH_SUCCESS,
197- OP_CHECK_IF(ComputeSparseReshapeTiling(context, tiling, coreNum)215+ OP_LOGE(context, "ComputeSparseReshapeTiling error"), return ge::GRAPH_FAILED);
198- != ge::GRAPH_SUCCESS, OP_LOGE(context, "ComputeSparseReshapeTiling error"),
199- return ge::GRAPH_FAILED);
200 auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());216 auto ascendcPlatform = platform_ascendc::PlatformAscendC(context->GetPlatformInfo());
201 uint64_t sysWS = ascendcPlatform.GetLibApiWorkSpaceSize();217 uint64_t sysWS = ascendcPlatform.GetLibApiWorkSpaceSize();
202 size_t* ws = context->GetWorkspaceSizes(1);218 size_t* ws = context->GetWorkspaceSizes(1);
203 OP_CHECK_NULL_WITH_CONTEXT(context, ws);219 OP_CHECK_NULL_WITH_CONTEXT(context, ws);
204 ws[0] = static_cast<size_t>(static_cast<int64_t>(sysWS));220 ws[0] = static_cast<size_t>(static_cast<int64_t>(sysWS));
205 OP_CHECK_IF((ubSize <= DCACHE_SIZE + STATIC_UB_ESTIMATE),221 OP_CHECK_IF((ubSize <= DCACHE_SIZE + STATIC_UB_ESTIMATE),
206- OP_LOGE(context, "ubSize %lu <= DCACHE_SIZE + STATIC_UB_ESTIMATE", ubSize),222+ OP_LOGE(context, "ubSize %lu <= DCACHE_SIZE + STATIC_UB_ESTIMATE", ubSize), return ge::GRAPH_FAILED);
207- return ge::GRAPH_FAILED);223+ auto res = context->SetLocalMemorySize(static_cast<uint32_t>(ubSize - DCACHE_SIZE - STATIC_UB_ESTIMATE));
208- auto res = context->SetLocalMemorySize(224+ OP_CHECK_IF((res != ge::GRAPH_SUCCESS), OP_LOGE(context, "SetLocalMemorySize failed"), return ge::GRAPH_FAILED);
209- static_cast<uint32_t>(ubSize - DCACHE_SIZE - STATIC_UB_ESTIMATE));
210- OP_CHECK_IF((res != ge::GRAPH_SUCCESS),
211- OP_LOGE(context, "SetLocalMemorySize failed"), return ge::GRAPH_FAILED);
212 uint64_t tilingKey = GET_TPL_TILING_KEY(SPARSE_RESHAPE_TPL_SCH_MODE_DEFAULT);225 uint64_t tilingKey = GET_TPL_TILING_KEY(SPARSE_RESHAPE_TPL_SCH_MODE_DEFAULT);
213 context->SetTilingKey(tilingKey);226 context->SetTilingKey(tilingKey);
214 return ge::GRAPH_SUCCESS;227 return ge::GRAPH_SUCCESS;
215}228}
216 229 
217-static ge::graphStatus TilingParseForSparseReshape(230+static ge::graphStatus TilingParseForSparseReshape([[maybe_unused]] gert::TilingParseContext* context)
218- [[maybe_unused]] gert::TilingParseContext* context)
219{231{
220 return ge::GRAPH_SUCCESS;232 return ge::GRAPH_SUCCESS;
221}233}
@@ -225,4 +237,4 @@ IMPL_OP_OPTILING(SparseReshape)
225 .TilingParse<SparseReshapeCompileInfo>(TilingParseForSparseReshape)237 .TilingParse<SparseReshapeCompileInfo>(TilingParseForSparseReshape)
226 .TilingInputsDataDependency({1, 2});238 .TilingInputsDataDependency({1, 2});
227 239 
228-} // namespace optiling240+} // namespace optiling
@@ -15,6 +15,7 @@
15 */15 */
16#include "register/op_impl_registry.h"16#include "register/op_impl_registry.h"
17#include "log/log.h"17#include "log/log.h"
18+#include "util/shape_util.h"
18 19 
19using namespace ge;20using namespace ge;
20 21 
@@ -25,31 +26,29 @@ static constexpr int64_t IDX_2 = 2;
25static constexpr int64_t MAX_RANK = 8;26static constexpr int64_t MAX_RANK = 8;
26static constexpr int64_t INDICES_TENSOR_RANK = 2;27static constexpr int64_t INDICES_TENSOR_RANK = 2;
27 28 
28-static ge::graphStatus ValidateInputs(gert::InferShapeContext* context,29+static ge::graphStatus ValidateInputs(gert::InferShapeContext* context, const gert::Shape* indicesShape,
29- const gert::Shape* indicesShape, const gert::Shape* shapeShape,30+ const gert::Shape* shapeShape, const gert::Shape* newShapeShape)
30- const gert::Shape* newShapeShape)
31{31{
32 OP_CHECK_IF(indicesShape->GetDimNum() != INDICES_TENSOR_RANK,32 OP_CHECK_IF(indicesShape->GetDimNum() != INDICES_TENSOR_RANK,
33- OP_LOGE(context, "indices must be a matrix, got rank %zu",33+ OP_LOGE(context, "indices must be a matrix, got rank %zu", indicesShape->GetDimNum()),
34- indicesShape->GetDimNum()), return GRAPH_FAILED);34+ return GRAPH_FAILED);
35 OP_CHECK_IF(shapeShape->GetDimNum() != 1,35 OP_CHECK_IF(shapeShape->GetDimNum() != 1,
36- OP_LOGE(context, "shape must be a vector, got rank %zu",36+ OP_LOGE(context, "shape must be a vector, got rank %zu", shapeShape->GetDimNum()), return GRAPH_FAILED);
37- shapeShape->GetDimNum()), return GRAPH_FAILED);
38 OP_CHECK_IF(newShapeShape->GetDimNum() != 1,37 OP_CHECK_IF(newShapeShape->GetDimNum() != 1,
39- OP_LOGE(context, "new_shape must be a vector, got rank %zu",38+ OP_LOGE(context, "new_shape must be a vector, got rank %zu", newShapeShape->GetDimNum()),
40- newShapeShape->GetDimNum()), return GRAPH_FAILED);39+ return GRAPH_FAILED);
41 int64_t inputRank = indicesShape->GetDim(1);40 int64_t inputRank = indicesShape->GetDim(1);
42 int64_t outputRank = newShapeShape->GetDim(0);41 int64_t outputRank = newShapeShape->GetDim(0);
43 int64_t shapeRank = shapeShape->GetDim(0);42 int64_t shapeRank = shapeShape->GetDim(0);
44- OP_CHECK_IF(inputRank > MAX_RANK,43+ OP_CHECK_IF(inputRank > MAX_RANK, OP_LOGE(context, "input_rank %ld > MAX_RANK %ld", inputRank, MAX_RANK),
45- OP_LOGE(context, "input_rank %ld > MAX_RANK %ld", inputRank, MAX_RANK),44+ return GRAPH_FAILED);
46- return GRAPH_FAILED);45+ OP_CHECK_IF(outputRank > MAX_RANK, OP_LOGE(context, "output_rank %ld > MAX_RANK %ld", outputRank, MAX_RANK),
47- OP_CHECK_IF(outputRank > MAX_RANK,46+ return GRAPH_FAILED);
48- OP_LOGE(context, "output_rank %ld > MAX_RANK %ld", outputRank, MAX_RANK),47+ // 维度值未知(-1) 时跳过该维一致性校验
49- return GRAPH_FAILED);48+ constexpr int64_t UNKNOWN_DIM = -1;
50- OP_CHECK_IF(inputRank != shapeRank,49+ OP_CHECK_IF(inputRank != UNKNOWN_DIM && shapeRank != UNKNOWN_DIM && inputRank != shapeRank,
51- OP_LOGE(context, "indices.shape[1] (%ld) != shape.shape[0] (%ld)",50+ OP_LOGE(context, "indices.shape[1] (%ld) != shape.shape[0] (%ld)", inputRank, shapeRank),
52- inputRank, shapeRank), return GRAPH_FAILED);51+ return GRAPH_FAILED);
53 return GRAPH_SUCCESS;52 return GRAPH_SUCCESS;
54}53}
55 54 
@@ -62,9 +61,27 @@ static ge::graphStatus InferShapeSparseReshape(gert::InferShapeContext* context)
62 OP_CHECK_NULL_WITH_CONTEXT(context, shapeShape);61 OP_CHECK_NULL_WITH_CONTEXT(context, shapeShape);
63 const gert::Shape* newShapeShape = context->GetInputShape(IDX_2);62 const gert::Shape* newShapeShape = context->GetInputShape(IDX_2);
64 OP_CHECK_NULL_WITH_CONTEXT(context, newShapeShape);63 OP_CHECK_NULL_WITH_CONTEXT(context, newShapeShape);
65- OP_CHECK_IF(ValidateInputs(context, indicesShape, shapeShape, newShapeShape)64+ 
66- != GRAPH_SUCCESS, OP_LOGE(context, "ValidateInputs failed"),65+ // Unknown rank(-2) 处理:与 canndev 原始实现对齐,
67- return GRAPH_FAILED);66+ // y_indices 为 {-1, -1}(固定 rank 2,维度未知),y_shape 为 {-1}(固定 rank 1,维度未知)
67+ if (Ops::Base::IsUnknownRank(*indicesShape) || Ops::Base::IsUnknownRank(*shapeShape) ||
68+ Ops::Base::IsUnknownRank(*newShapeShape)) {
69+ constexpr int64_t UNKNOWN_DIM = -1;
70+ gert::Shape* yIndicesShape = context->GetOutputShape(IDX_0);
71+ OP_CHECK_NULL_WITH_CONTEXT(context, yIndicesShape);
72+ yIndicesShape->SetDimNum(INDICES_TENSOR_RANK);
73+ yIndicesShape->SetDim(IDX_0, UNKNOWN_DIM);
74+ yIndicesShape->SetDim(IDX_1, UNKNOWN_DIM);
75+ gert::Shape* yShapeShape = context->GetOutputShape(IDX_1);
76+ OP_CHECK_NULL_WITH_CONTEXT(context, yShapeShape);
77+ yShapeShape->SetDimNum(1);
78+ yShapeShape->SetDim(IDX_0, UNKNOWN_DIM);
79+ OP_LOGD(context->GetNodeName(), "Input is unknown rank, set outputs to unknown dims");
80+ return GRAPH_SUCCESS;
81+ }
82+ 
83+ OP_CHECK_IF(ValidateInputs(context, indicesShape, shapeShape, newShapeShape) != GRAPH_SUCCESS,
84+ OP_LOGE(context, "ValidateInputs failed"), return GRAPH_FAILED);
68 int64_t nnz = indicesShape->GetDim(0);85 int64_t nnz = indicesShape->GetDim(0);
69 int64_t outputRank = newShapeShape->GetDim(0);86 int64_t outputRank = newShapeShape->GetDim(0);
70 gert::Shape* yIndicesShape = context->GetOutputShape(IDX_0);87 gert::Shape* yIndicesShape = context->GetOutputShape(IDX_0);
@@ -83,7 +100,5 @@ static ge::graphStatus InferShapeSparseReshape(gert::InferShapeContext* context)
83 return GRAPH_SUCCESS;100 return GRAPH_SUCCESS;
84}101}
85 102 
86-IMPL_OP_INFERSHAPE(SparseReshape)103+IMPL_OP_INFERSHAPE(SparseReshape).InferShape(InferShapeSparseReshape).InputsDataDependency({1, 2});
87- .InferShape(InferShapeSparseReshape)104+} // namespace ops
88- .InputsDataDependency({1, 2});
89-} // namespace ops
@@ -26,18 +26,12 @@ using namespace ge;
26 26 
27class SparseReshapeTiling : public testing::Test {27class SparseReshapeTiling : public testing::Test {
28protected:28protected:
29- static void SetUpTestCase()29+ static void SetUpTestCase() { std::cout << "SparseReshapeTiling SetUp" << std::endl; }
30- {
31- std::cout << "SparseReshapeTiling SetUp" << std::endl;
32- }
33 30 
34- static void TearDownTestCase()31+ static void TearDownTestCase() { std::cout << "SparseReshapeTiling TearDown" << std::endl; }
35- {
36- std::cout << "SparseReshapeTiling TearDown" << std::endl;
37- }
38};32};
39 33 
40-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950PR"}};34+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950PR"}};
41 35 
42// Test case 1: reshape [2,3] -> [3,2], nnz=4, int6436// Test case 1: reshape [2,3] -> [3,2], nnz=4, int64
43TEST_F(SparseReshapeTiling, sparse_reshape_int64)37TEST_F(SparseReshapeTiling, sparse_reshape_int64)
@@ -51,7 +45,8 @@ TEST_F(SparseReshapeTiling, sparse_reshape_int64)
51 {45 {
52 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),46 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),
53 gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),47 gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),
54- gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)newShapeData),48+ gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
49+ (void*)newShapeData),
55 },50 },
56 {51 {
57 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),52 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),
@@ -88,8 +83,10 @@ TEST_F(SparseReshapeTiling, sparse_reshape_int32)
88 "SparseReshape",83 "SparseReshape",
89 {84 {
90 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND),85 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND),
91- gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND, true, (void*)shapeData32),86+ gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND, true,
92- gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND, true, (void*)newShapeData32),87+ (void*)shapeData32),
88+ gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND, true,
89+ (void*)newShapeData32),
93 },90 },
94 {91 {
95 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND),92 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND),
@@ -115,13 +112,14 @@ TEST_F(SparseReshapeTiling, sparse_reshape_identity)
115 struct SparseReshapeCompileInfo {112 struct SparseReshapeCompileInfo {
116 } compileInfo;113 } compileInfo;
117 int64_t shapeData[] = {2, 3};114 int64_t shapeData[] = {2, 3};
118- int64_t newShapeData[] = {2, 3}; // same as input shape -> identity115+ int64_t newShapeData[] = {2, 3}; // same as input shape -> identity
119 gert::TilingContextPara tilingContextPara(116 gert::TilingContextPara tilingContextPara(
120 "SparseReshape",117 "SparseReshape",
121 {118 {
122 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),119 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),
123 gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),120 gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),
124- gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)newShapeData),121+ gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
122+ (void*)newShapeData),
125 },123 },
126 {124 {
127 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),125 gert::TilingContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND),
@@ -154,7 +152,8 @@ TEST_F(SparseReshapeTiling, sparse_reshape_rank_change)
154 {152 {
155 gert::TilingContextPara::TensorDescription({{10, 3}, {10, 3}}, ge::DT_INT64, ge::FORMAT_ND),153 gert::TilingContextPara::TensorDescription({{10, 3}, {10, 3}}, ge::DT_INT64, ge::FORMAT_ND),
156 gert::TilingContextPara::TensorDescription({{3}, {3}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),154 gert::TilingContextPara::TensorDescription({{3}, {3}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)shapeData),
157- gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, (void*)newShapeData),155+ gert::TilingContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
156+ (void*)newShapeData),
158 },157 },
159 {158 {
160 gert::TilingContextPara::TensorDescription({{10, 2}, {10, 2}}, ge::DT_INT64, ge::FORMAT_ND),159 gert::TilingContextPara::TensorDescription({{10, 2}, {10, 2}}, ge::DT_INT64, ge::FORMAT_ND),
@@ -20,18 +20,11 @@
20#include "infershape_context_faker.h"20#include "infershape_context_faker.h"
21#include "infershape_case_executor.h"21#include "infershape_case_executor.h"
22 22 
23-class SparseReshapeInfershape : public testing::Test23+class SparseReshapeInfershape : public testing::Test {
24-{
25protected:24protected:
26- static void SetUpTestCase()25+ static void SetUpTestCase() { std::cout << "SparseReshapeInfershape SetUp" << std::endl; }
27- {
28- std::cout << "SparseReshapeInfershape SetUp" << std::endl;
29- }
30 26 
31- static void TearDownTestCase()27+ static void TearDownTestCase() { std::cout << "SparseReshapeInfershape TearDown" << std::endl; }
32- {
33- std::cout << "SparseReshapeInfershape TearDown" << std::endl;
34- }
35};28};
36 29 
37// Test case 1: reshape [2,3] -> [3,2], nnz=4, int6430// Test case 1: reshape [2,3] -> [3,2], nnz=4, int64
@@ -42,13 +35,13 @@ TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_test1)
42 gert::InfershapeContextPara infershapeContextPara(35 gert::InfershapeContextPara infershapeContextPara(
43 "SparseReshape",36 "SparseReshape",
44 {37 {
45- {{{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND}, // indices: (nnz=4, input_rank=2)38+ {{{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND}, // indices: (nnz=4, input_rank=2)
46- {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // shape: (input_rank=2,)39+ {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // shape: (input_rank=2,)
47- {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape: (output_rank=2,)40+ {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape: (output_rank=2,)
48 },41 },
49 {42 {
50- {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices: shape inferred43+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices: shape inferred
51- {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape: shape inferred44+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape: shape inferred
52 });45 });
53 std::vector<std::vector<int64_t>> expectOutputShape = {46 std::vector<std::vector<int64_t>> expectOutputShape = {
54 {4, 2},47 {4, 2},
@@ -64,13 +57,13 @@ TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_test2)
64 gert::InfershapeContextPara infershapeContextPara(57 gert::InfershapeContextPara infershapeContextPara(
65 "SparseReshape",58 "SparseReshape",
66 {59 {
67- {{{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND}, // indices: (nnz=4, input_rank=2)60+ {{{4, 2}, {4, 2}}, ge::DT_INT32, ge::FORMAT_ND}, // indices: (nnz=4, input_rank=2)
68- {{{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND}, // shape: (input_rank=2,)61+ {{{2}, {2}}, ge::DT_INT32, ge::FORMAT_ND}, // shape: (input_rank=2,)
69- {{{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND}, // new_shape: (output_rank=1,)62+ {{{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND}, // new_shape: (output_rank=1,)
70 },63 },
71 {64 {
72- {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_indices65+ {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_indices
73- {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_shape66+ {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_shape
74 });67 });
75 std::vector<std::vector<int64_t>> expectOutputShape = {68 std::vector<std::vector<int64_t>> expectOutputShape = {
76 {4, 1},69 {4, 1},
@@ -87,12 +80,12 @@ TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_test3)
87 "SparseReshape",80 "SparseReshape",
88 {81 {
89 {{{10, 3}, {10, 3}}, ge::DT_INT64, ge::FORMAT_ND}, // indices: (nnz=10, input_rank=3)82 {{{10, 3}, {10, 3}}, ge::DT_INT64, ge::FORMAT_ND}, // indices: (nnz=10, input_rank=3)
90- {{{3}, {3}}, ge::DT_INT64, ge::FORMAT_ND}, // shape: (input_rank=3,)83+ {{{3}, {3}}, ge::DT_INT64, ge::FORMAT_ND}, // shape: (input_rank=3,)
91- {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape: (output_rank=2,)84+ {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape: (output_rank=2,)
92 },85 },
93 {86 {
94- {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices87+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices
95- {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape88+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape
96 });89 });
97 std::vector<std::vector<int64_t>> expectOutputShape = {90 std::vector<std::vector<int64_t>> expectOutputShape = {
98 {10, 2},91 {10, 2},
@@ -100,3 +93,93 @@ TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_test3)
100 };93 };
101 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);94 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
102}95}
96+ 
97+// Test case 4: Unknown shape (-1)
98+// indices: {-1, -1}, shape: {-1}, new_shape: {-1}
99+// y_indices = {-1, -1}, y_shape = {-1}
100+TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_unknown_shape)
101+{
102+ gert::InfershapeContextPara infershapeContextPara(
103+ "SparseReshape",
104+ {
105+ {{{-1, -1}, {-1, -1}}, ge::DT_INT64, ge::FORMAT_ND}, // indices
106+ {{{-1}, {-1}}, ge::DT_INT64, ge::FORMAT_ND}, // shape
107+ {{{-1}, {-1}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape
108+ },
109+ {
110+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices
111+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape
112+ });
113+ std::vector<std::vector<int64_t>> expectOutputShape = {
114+ {-1, -1},
115+ {-1},
116+ };
117+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
118+}
119+ 
120+// Test case 5: Unknown rank (-2)
121+// All inputs unknown rank, y_indices = {-1, -1}, y_shape = {-1}
122+TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_unknown_rank)
123+{
124+ gert::InfershapeContextPara infershapeContextPara("SparseReshape",
125+ {
126+ {{{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND}, // indices
127+ {{{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND}, // shape
128+ {{{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape
129+ },
130+ {
131+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices
132+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape
133+ });
134+ std::vector<std::vector<int64_t>> expectOutputShape = {
135+ {-1, -1},
136+ {-1},
137+ };
138+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
139+}
140+ 
141+// Test case 6: Mixed unknown dim (-1) with known dims
142+// indices: {-1, 2}(nnz 未知,input_rank=2 已知), shape: {2}, new_shape: {-1}(output_rank 未知)
143+// input_rank(2) == shape.shape[0](2) 校验通过,output_rank=-1 逐维透传
144+// y_indices = {-1, -1}, y_shape = {-1}
145+TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_unknown_shape_mixed)
146+{
147+ gert::InfershapeContextPara infershapeContextPara("SparseReshape",
148+ {
149+ {{{-1, 2}, {-1, 2}}, ge::DT_INT64, ge::FORMAT_ND}, // indices
150+ {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // shape
151+ {{{-1}, {-1}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape
152+ },
153+ {
154+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices
155+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape
156+ });
157+ std::vector<std::vector<int64_t>> expectOutputShape = {
158+ {-1, -1},
159+ {-1},
160+ };
161+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
162+}
163+ 
164+// Test case 7: Mixed unknown rank (-2) with partial unknown shape
165+// indices: {-1, -1} 部分未知, shape: {-2} unknown rank, new_shape: {2}
166+// 任一输入 unknown rank -> y_indices = {-1, -1}, y_shape = {-1}
167+TEST_F(SparseReshapeInfershape, sparse_reshape_infershape_unknown_rank_mixed)
168+{
169+ gert::InfershapeContextPara infershapeContextPara(
170+ "SparseReshape",
171+ {
172+ {{{-1, -1}, {-1, -1}}, ge::DT_INT64, ge::FORMAT_ND}, // indices
173+ {{{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND}, // shape
174+ {{{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND}, // new_shape
175+ },
176+ {
177+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices
178+ {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape
179+ });
180+ std::vector<std::vector<int64_t>> expectOutputShape = {
181+ {-1, -1},
182+ {-1},
183+ };
184+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
185+}
@@ -21,6 +21,7 @@
21#include <string>21#include <string>
22 22 
23#include "conversion/triu/op_host/arch35/triu_tiling.h"23#include "conversion/triu/op_host/arch35/triu_tiling.h"
24+#include "log/log.h"
24#include "register/op_impl_registry.h"25#include "register/op_impl_registry.h"
25#include "register/tilingdata_base.h"26#include "register/tilingdata_base.h"
26 27 
@@ -119,6 +120,7 @@ static ge::graphStatus ValidateDtypes(gert::TilingContext* context)
119 120 
120static ge::graphStatus TriluTilingFunc(gert::TilingContext* context)121static ge::graphStatus TriluTilingFunc(gert::TilingContext* context)
121{122{
123+ OP_LOGD(context, "Enter TilingTrilu");
122 if (ValidateDtypes(context) != ge::GRAPH_SUCCESS) {124 if (ValidateDtypes(context) != ge::GRAPH_SUCCESS) {
123 return ge::GRAPH_FAILED;125 return ge::GRAPH_FAILED;
124 }126 }
@@ -22,6 +22,7 @@ using namespace ge;
22namespace ops {22namespace ops {
23static ge::graphStatus InferShapeTrilu(gert::InferShapeContext* context)23static ge::graphStatus InferShapeTrilu(gert::InferShapeContext* context)
24{24{
25+ OP_LOGD(context->GetNodeName(), "Enter InferShapeTrilu");
25 const gert::Shape* xShape = context->GetInputShape(0);26 const gert::Shape* xShape = context->GetInputShape(0);
26 gert::Shape* yShape = context->GetOutputShape(0);27 gert::Shape* yShape = context->GetOutputShape(0);
27 28 
@@ -38,4 +39,4 @@ static ge::graphStatus InferShapeTrilu(gert::InferShapeContext* context)
38 return GRAPH_SUCCESS;39 return GRAPH_SUCCESS;
39}40}
40IMPL_OP_INFERSHAPE(Trilu).InferShape(InferShapeTrilu);41IMPL_OP_INFERSHAPE(Trilu).InferShape(InferShapeTrilu);
41-} // namespace ops42+} // namespace ops
@@ -20,18 +20,11 @@
20#include "infershape_context_faker.h"20#include "infershape_context_faker.h"
21#include "infershape_case_executor.h"21#include "infershape_case_executor.h"
22 22 
23-class TriluInfershape : public testing::Test23+class TriluInfershape : public testing::Test {
24-{
25protected:24protected:
26- static void SetUpTestCase()25+ static void SetUpTestCase() { std::cout << "TriluInfershape SetUp" << std::endl; }
27- {
28- std::cout << "TriluInfershape SetUp" << std::endl;
29- }
30 26 
31- static void TearDownTestCase()27+ static void TearDownTestCase() { std::cout << "TriluInfershape TearDown" << std::endl; }
32- {
33- std::cout << "TriluInfershape TearDown" << std::endl;
34- }
35};28};
36 29 
37TEST_F(TriluInfershape, trilu_infershape_test1)30TEST_F(TriluInfershape, trilu_infershape_test1)
@@ -49,3 +42,52 @@ TEST_F(TriluInfershape, trilu_infershape_test1)
49 };42 };
50 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);43 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
51}44}
45+ 
46+TEST_F(TriluInfershape, trilu_infershape_unknown_shape)
47+{
48+ // Unknown shape (-1): {-1, -1, -1} -> shape passthrough {-1, -1, -1}
49+ gert::InfershapeContextPara infershapeContextPara("Trilu",
50+ {
51+ {{{-1, -1, -1}, {-1, -1, -1}}, ge::DT_FLOAT16, ge::FORMAT_ND},
52+ },
53+ {
54+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
55+ });
56+ std::vector<std::vector<int64_t>> expectOutputShape = {
57+ {-1, -1, -1},
58+ };
59+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
60+}
61+ 
62+TEST_F(TriluInfershape, trilu_infershape_unknown_shape_mixed)
63+{
64+ // Mixed unknown dim (-1) with known dims: {-1, 2, 4, -1} -> shape passthrough {-1, 2, 4, -1}
65+ gert::InfershapeContextPara infershapeContextPara(
66+ "Trilu",
67+ {
68+ {{{-1, 2, 4, -1}, {-1, 2, 4, -1}}, ge::DT_FLOAT16, ge::FORMAT_ND},
69+ },
70+ {
71+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
72+ });
73+ std::vector<std::vector<int64_t>> expectOutputShape = {
74+ {-1, 2, 4, -1},
75+ };
76+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
77+}
78+ 
79+TEST_F(TriluInfershape, trilu_infershape_unknown_rank)
80+{
81+ // Unknown rank (-2): {-2} -> shape passthrough {-2}
82+ gert::InfershapeContextPara infershapeContextPara("Trilu",
83+ {
84+ {{{-2}, {-2}}, ge::DT_FLOAT16, ge::FORMAT_ND},
85+ },
86+ {
87+ {{{}, {}}, ge::DT_FLOAT16, ge::FORMAT_ND},
88+ });
89+ std::vector<std::vector<int64_t>> expectOutputShape = {
90+ {-2},
91+ };
92+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
93+}
@@ -24,7 +24,7 @@ protected:
24 static void TearDownTestCase() { std::cout << "AddExampleTiling TearDown" << std::endl; }24 static void TearDownTestCase() { std::cout << "AddExampleTiling TearDown" << std::endl; }
25};25};
26 26 
27-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend910B"}};27+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend910B"}};
28 28 
29TEST_F(AddExampleTiling, add_example_0)29TEST_F(AddExampleTiling, add_example_0)
30{30{
@@ -74,4 +74,4 @@ TEST_F(AddExampleTiling, add_example_1)
74 string expectTilingData = "2048 32 10912 ";74 string expectTilingData = "2048 32 10912 ";
75 std::vector<size_t> expectWorkspaces = {0};75 std::vector<size_t> expectWorkspaces = {0};
76 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);76 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);
77-}77+}
@@ -25,7 +25,7 @@ protected:
25 static void TearDownTestCase() { std::cout << "ExpandvTiling TearDown" << std::endl; }25 static void TearDownTestCase() { std::cout << "ExpandvTiling TearDown" << std::endl; }
26};26};
27 27 
28-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend910B"}};28+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend910B"}};
29 29 
30TEST_F(ExpandvTiling, expandv_example_0)30TEST_F(ExpandvTiling, expandv_example_0)
31{31{
@@ -44,8 +44,8 @@ TEST_F(ExpandvTiling, expandv_example_0)
44 },44 },
45 &compileInfo); // 已修正原始笔误(删除多余的attrs,)45 &compileInfo); // 已修正原始笔误(删除多余的attrs,)
46 uint64_t expectTilingKey = 0;46 uint64_t expectTilingKey = 0;
47- std::string expectTilingData =47+ std::string expectTilingData = "64 72 1 1 8184 64 72 0 3 3 4 1 3 0 0 0 0 0 0 0 4 5 3 0 0 0 0 0 0 0 3 3 1 0 0 0 0 0 "
48- "64 72 1 1 8184 64 72 0 3 3 4 1 3 0 0 0 0 0 0 0 4 5 3 0 0 0 0 0 0 0 3 3 1 0 0 0 0 0 0 0 15 3 1 0 0 0 0 0 0 0 ";48+ "0 0 15 3 1 0 0 0 0 0 0 0 ";
49 std::vector<size_t> expectWorkspaces = {1024 * 1024 * 16};49 std::vector<size_t> expectWorkspaces = {1024 * 1024 * 16};
50 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);50 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);
51}51}
@@ -67,8 +67,8 @@ TEST_F(ExpandvTiling, expandv_example_1)
67 },67 },
68 &compileInfo);68 &compileInfo);
69 uint64_t expectTilingKey = 2;69 uint64_t expectTilingKey = 2;
70- std::string expectTilingData =70+ std::string expectTilingData = "64 80 1 1 16368 64 80 0 3 3 4 1 3 0 0 0 0 0 0 0 4 5 3 0 0 0 0 0 0 0 3 3 1 0 0 0 0 "
71- "64 80 1 1 16368 64 80 0 3 3 4 1 3 0 0 0 0 0 0 0 4 5 3 0 0 0 0 0 0 0 3 3 1 0 0 0 0 0 0 0 15 3 1 0 0 0 0 0 0 0 ";71+ "0 0 0 15 3 1 0 0 0 0 0 0 0 ";
72 std::vector<size_t> expectWorkspaces = {1024 * 1024 * 16};72 std::vector<size_t> expectWorkspaces = {1024 * 1024 * 16};
73 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);73 ExecuteTestCase(tilingContextPara, ge::GRAPH_SUCCESS, expectTilingKey, expectTilingData, expectWorkspaces);
74-}74+}
@@ -21,18 +21,12 @@ using namespace ge;
21 21 
22class RadixSortTiling : public testing::Test {22class RadixSortTiling : public testing::Test {
23protected:23protected:
24- static void SetUpTestCase()24+ static void SetUpTestCase() { std::cout << "RadixSortTiling SetUp" << std::endl; }
25- {
26- std::cout << "RadixSortTiling SetUp" << std::endl;
27- }
28 25 
29- static void TearDownTestCase()26+ static void TearDownTestCase() { std::cout << "RadixSortTiling TearDown" << std::endl; }
30- {
31- std::cout << "RadixSortTiling TearDown" << std::endl;
32- }
33};27};
34 28 
35-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};29+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};
36 30 
37TEST_F(RadixSortTiling, radix_sort_int32_ascending_2048)31TEST_F(RadixSortTiling, radix_sort_int32_ascending_2048)
38{32{
@@ -188,6 +188,7 @@ static ge::graphStatus GetWorkspaceSize(gert::TilingContext* context)
188 188 
189static ge::graphStatus CosineSimilarityTilingFunc(gert::TilingContext* context)189static ge::graphStatus CosineSimilarityTilingFunc(gert::TilingContext* context)
190{190{
191+ OP_LOGD(context, "Enter TilingCosineSimilarity");
191 OP_CHECK_IF(ValidateDtypes(context) != ge::GRAPH_SUCCESS, OP_LOGE(context, "ValidateDtypes error"),192 OP_CHECK_IF(ValidateDtypes(context) != ge::GRAPH_SUCCESS, OP_LOGE(context, "ValidateDtypes error"),
192 return ge::GRAPH_FAILED);193 return ge::GRAPH_FAILED);
193 194 
@@ -12,6 +12,7 @@
12 12 
13#include "register/op_impl_registry.h"13#include "register/op_impl_registry.h"
14#include "log/log.h"14#include "log/log.h"
15+#include "util/shape_util.h"
15 16 
16using namespace ge;17using namespace ge;
17 18 
@@ -19,6 +20,7 @@ namespace ops {
19static constexpr int64_t IDX_0 = 0;20static constexpr int64_t IDX_0 = 0;
20static constexpr int64_t IDX_1 = 1;21static constexpr int64_t IDX_1 = 1;
21static constexpr int32_t MAX_DIMS = 8;22static constexpr int32_t MAX_DIMS = 8;
23+static constexpr int64_t UNKNOWN_DIM = -1;
22 24 
23static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* context)25static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* context)
24{26{
@@ -32,16 +34,21 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
32 gert::Shape* yShape = context->GetOutputShape(IDX_0);34 gert::Shape* yShape = context->GetOutputShape(IDX_0);
33 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);35 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);
34 36 
37+ // Unknown rank (-2): rank is unknown, cannot infer the reduced shape; pass through as unknown rank
38+ if (Ops::Base::IsUnknownRank(*x1Shape) || Ops::Base::IsUnknownRank(*x2Shape)) {
39+ Ops::Base::SetUnknownRank(*yShape);
40+ return GRAPH_SUCCESS;
41+ }
42+ 
35 // Get input dimensions43 // Get input dimensions
36 size_t x1Dims = x1Shape->GetDimNum();44 size_t x1Dims = x1Shape->GetDimNum();
37 size_t x2Dims = x2Shape->GetDimNum();45 size_t x2Dims = x2Shape->GetDimNum();
38 size_t ndim = (x1Dims > x2Dims) ? x1Dims : x2Dims;46 size_t ndim = (x1Dims > x2Dims) ? x1Dims : x2Dims;
39 47 
40 if (ndim > static_cast<size_t>(MAX_DIMS)) {48 if (ndim > static_cast<size_t>(MAX_DIMS)) {
41- OP_LOGE_FOR_INVALID_SHAPEDIMS_WITH_REASON(49+ OP_LOGE_FOR_INVALID_SHAPEDIMS_WITH_REASON(context->GetNodeName(), "x1 and x2",
42- context->GetNodeName(), "x1 and x2",50+ (std::to_string(x1Dims) + " and " + std::to_string(x2Dims)).c_str(),
43- (std::to_string(x1Dims) + " and " + std::to_string(x2Dims)).c_str(),51+ "broadcast ndim must not exceed 8");
44- "broadcast ndim must not exceed 8");
45 return GRAPH_FAILED;52 return GRAPH_FAILED;
46 }53 }
47 54 
@@ -65,11 +72,13 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
65 x2Padded[x2Offset + i] = x2Shape->GetDim(i);72 x2Padded[x2Offset + i] = x2Shape->GetDim(i);
66 }73 }
67 74 
68- // Compute broadcast shape75+ // Compute broadcast shape (unknown dim(-1) 逐维通配:任一侧未知则该维结果为 -1)
69 for (int32_t d = 0; d < static_cast<int32_t>(ndim); d++) {76 for (int32_t d = 0; d < static_cast<int32_t>(ndim); d++) {
70 int64_t s1 = x1Padded[d];77 int64_t s1 = x1Padded[d];
71 int64_t s2 = x2Padded[d];78 int64_t s2 = x2Padded[d];
72- if (s1 == s2) {79+ if (s1 == UNKNOWN_DIM || s2 == UNKNOWN_DIM) {
80+ bcastShape[d] = UNKNOWN_DIM;
81+ } else if (s1 == s2) {
73 bcastShape[d] = s1;82 bcastShape[d] = s1;
74 } else if (s1 == 1) {83 } else if (s1 == 1) {
75 bcastShape[d] = s2;84 bcastShape[d] = s2;
@@ -77,9 +86,8 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
77 bcastShape[d] = s1;86 bcastShape[d] = s1;
78 } else {87 } else {
79 std::string shapeMsg = std::to_string(s1) + " and " + std::to_string(s2);88 std::string shapeMsg = std::to_string(s1) + " and " + std::to_string(s2);
80- OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(89+ OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(context->GetNodeName(), "x1 and x2", shapeMsg.c_str(),
81- context->GetNodeName(), "x1 and x2", shapeMsg.c_str(),90+ ("shapes not broadcastable at dim " + std::to_string(d)).c_str());
82- ("shapes not broadcastable at dim " + std::to_string(d)).c_str());
83 return GRAPH_FAILED;91 return GRAPH_FAILED;
84 }92 }
85 }93 }
@@ -97,9 +105,8 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
97 dim += static_cast<int32_t>(ndim);105 dim += static_cast<int32_t>(ndim);
98 }106 }
99 if (dim < 0 || dim >= static_cast<int32_t>(ndim)) {107 if (dim < 0 || dim >= static_cast<int32_t>(ndim)) {
100- OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(108+ OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context->GetNodeName(), "dim", std::to_string(dim).c_str(),
101- context->GetNodeName(), "dim", std::to_string(dim).c_str(),109+ ("dim must be in range [0, " + std::to_string(ndim) + ")").c_str());
102- ("dim must be in range [0, " + std::to_string(ndim) + ")").c_str());
103 return GRAPH_FAILED;110 return GRAPH_FAILED;
104 }111 }
105 112 
@@ -117,7 +124,8 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
117 yShape->SetDimNum(outDims);124 yShape->SetDimNum(outDims);
118 size_t outIdx = 0;125 size_t outIdx = 0;
119 for (int32_t d = 0; d < static_cast<int32_t>(ndim); d++) {126 for (int32_t d = 0; d < static_cast<int32_t>(ndim); d++) {
120- if (d == dim) continue;127+ if (d == dim)
128+ continue;
121 yShape->SetDim(outIdx++, bcastShape[d]);129 yShape->SetDim(outIdx++, bcastShape[d]);
122 }130 }
123 }131 }
@@ -130,4 +138,4 @@ static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* conte
130}138}
131 139 
132IMPL_OP_INFERSHAPE(CosineSimilarity).InferShape(InferShapeCosineSimilarity);140IMPL_OP_INFERSHAPE(CosineSimilarity).InferShape(InferShapeCosineSimilarity);
133-} // namespace ops141+} // namespace ops
@@ -15,32 +15,24 @@
15#include "infershape_context_faker.h"15#include "infershape_context_faker.h"
16#include "infershape_case_executor.h"16#include "infershape_case_executor.h"
17 17 
18-class CosineSimilarityInfershape : public testing::Test18+class CosineSimilarityInfershape : public testing::Test {
19-{
20protected:19protected:
21- static void SetUpTestCase()20+ static void SetUpTestCase() { std::cout << "CosineSimilarityInfershape SetUp" << std::endl; }
22- {
23- std::cout << "CosineSimilarityInfershape SetUp" << std::endl;
24- }
25 21 
26- static void TearDownTestCase()22+ static void TearDownTestCase() { std::cout << "CosineSimilarityInfershape TearDown" << std::endl; }
27- {
28- std::cout << "CosineSimilarityInfershape TearDown" << std::endl;
29- }
30};23};
31 24 
32TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test1)25TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test1)
33{26{
34 // Input shape: (4, 8), reduce along dim=1, output shape: (4,)27 // Input shape: (4, 8), reduce along dim=1, output shape: (4,)
35- gert::InfershapeContextPara infershapeContextPara(28+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
36- "CosineSimilarity",29+ {
37- {30+ {{{4, 8}, {4, 8}}, ge::DT_FLOAT, ge::FORMAT_ND},
38- {{{4, 8}, {4, 8}}, ge::DT_FLOAT, ge::FORMAT_ND},31+ {{{4, 8}, {4, 8}}, ge::DT_FLOAT, ge::FORMAT_ND},
39- {{{4, 8}, {4, 8}}, ge::DT_FLOAT, ge::FORMAT_ND},32+ },
40- },33+ {
41- {34+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
42- {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},35+ });
43- });
44 std::vector<std::vector<int64_t>> expectOutputShape = {36 std::vector<std::vector<int64_t>> expectOutputShape = {
45 {4},37 {4},
46 };38 };
@@ -50,17 +42,102 @@ TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test1)
50TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test2)42TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test2)
51{43{
52 // Input shape: (2, 3, 4), default dim=1, output shape: (2, 4)44 // Input shape: (2, 3, 4), default dim=1, output shape: (2, 4)
53- gert::InfershapeContextPara infershapeContextPara(45+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
54- "CosineSimilarity",46+ {
55- {47+ {{{2, 3, 4}, {2, 3, 4}}, ge::DT_FLOAT, ge::FORMAT_ND},
56- {{{2, 3, 4}, {2, 3, 4}}, ge::DT_FLOAT, ge::FORMAT_ND},48+ {{{2, 3, 4}, {2, 3, 4}}, ge::DT_FLOAT, ge::FORMAT_ND},
57- {{{2, 3, 4}, {2, 3, 4}}, ge::DT_FLOAT, ge::FORMAT_ND},49+ },
58- },50+ {
59- {51+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
60- {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},52+ });
61- });
62 std::vector<std::vector<int64_t>> expectOutputShape = {53 std::vector<std::vector<int64_t>> expectOutputShape = {
63 {2, 4},54 {2, 4},
64 };55 };
65 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);56 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
66}57}
58+ 
59+TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_unknown_shape)
60+{
61+ // Unknown shape (-1): input shape {-1, -1, -1}, default dim=1, output shape {-1, -1}
62+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
63+ {
64+ {{{-1, -1, -1}, {-1, -1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
65+ {{{-1, -1, -1}, {-1, -1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
66+ },
67+ {
68+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
69+ });
70+ std::vector<std::vector<int64_t>> expectOutputShape = {
71+ {-1, -1},
72+ };
73+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
74+}
75+ 
76+TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_unknown_shape_mixed)
77+{
78+ // Mixed unknown dim (-1) with known dims: input shape {4, -1, 3}, default dim=1, output shape {4, 3}
79+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
80+ {
81+ {{{4, -1, 3}, {4, -1, 3}}, ge::DT_FLOAT, ge::FORMAT_ND},
82+ {{{4, -1, 3}, {4, -1, 3}}, ge::DT_FLOAT, ge::FORMAT_ND},
83+ },
84+ {
85+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
86+ });
87+ std::vector<std::vector<int64_t>> expectOutputShape = {
88+ {4, 3},
89+ };
90+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
91+}
92+ 
93+TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_unknown_shape_rank_mixed)
94+{
95+ // Mixed: origin shape {-1, 2, 3} with unknown rank shape range {-2}, default dim=1, output shape {-1, 3}
96+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
97+ {
98+ {{{-1, 2, 3}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
99+ {{{-1, 2, 3}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
100+ },
101+ {
102+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
103+ });
104+ std::vector<std::vector<int64_t>> expectOutputShape = {
105+ {-1, 3},
106+ };
107+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
108+}
109+ 
110+TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_unknown_shape_broadcast_mixed)
111+{
112+ // Mixed broadcast with one-sided unknown dim (-1): x1 {-1, 3}, x2 {2, -1}, default dim=1
113+ // 逐维通配:dim0 -1 vs 2 -> -1,dim1 3 vs -1 -> -1,broadcast {-1, -1},reduce dim=1 -> output {-1}
114+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
115+ {
116+ {{{-1, 3}, {-1, 3}}, ge::DT_FLOAT, ge::FORMAT_ND},
117+ {{{2, -1}, {2, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
118+ },
119+ {
120+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
121+ });
122+ std::vector<std::vector<int64_t>> expectOutputShape = {
123+ {-1},
124+ };
125+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
126+}
127+ 
128+TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_unknown_rank)
129+{
130+ // Unknown rank (-2): input shape {-2}, output shape {-2}
131+ gert::InfershapeContextPara infershapeContextPara("CosineSimilarity",
132+ {
133+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
134+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
135+ },
136+ {
137+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
138+ });
139+ std::vector<std::vector<int64_t>> expectOutputShape = {
140+ {-2},
141+ };
142+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
143+}
@@ -290,6 +290,7 @@ static ge::graphStatus SetTilingDataAndConfig(gert::TilingContext* context, int3
290 290 
291static ge::graphStatus ProdForceSeATilingFunc(gert::TilingContext* context)291static ge::graphStatus ProdForceSeATilingFunc(gert::TilingContext* context)
292{292{
293+ OP_LOGD(context, "Enter TilingProdForceSeA");
293 uint64_t ubCapacity;294 uint64_t ubCapacity;
294 int64_t aivCoreNum;295 int64_t aivCoreNum;
295 if (GetPlatformInfo(context, ubCapacity, aivCoreNum) != ge::GRAPH_SUCCESS) {296 if (GetPlatformInfo(context, ubCapacity, aivCoreNum) != ge::GRAPH_SUCCESS) {
@@ -40,6 +40,102 @@ static constexpr int64_t ATTR_INDEX_N_A_SEL = 0; // n_a_sel 属性索引
40static constexpr int64_t ATTR_INDEX_N_R_SEL = 1; // n_r_sel 属性索引40static constexpr int64_t ATTR_INDEX_N_R_SEL = 1; // n_r_sel 属性索引
41static constexpr int64_t OUTPUT_DIM_NUM = 3; // 输出维度数41static constexpr int64_t OUTPUT_DIM_NUM = 3; // 输出维度数
42static constexpr int64_t COORD_DIM_SIZE = 3; // 坐标维度大小 (x,y,z)42static constexpr int64_t COORD_DIM_SIZE = 3; // 坐标维度大小 (x,y,z)
43+static constexpr int64_t UNKNOWN_DIM = -1; // unknown dim 值
44+ 
45+// 帧数一致性校验 (SE 1.4),unknown dim(-1) 时跳过对应校验
46+static ge::graphStatus CheckFramesConsistency(const char* opName, const gert::Shape* netDerivShape,
47+ const gert::Shape* inDerivShape, const gert::Shape* nlistShape,
48+ int64_t& nframes)
49+{
50+ nframes = netDerivShape->GetDim(IDX_0);
51+ int64_t inDerivFrames = inDerivShape->GetDim(IDX_0);
52+ int64_t nlistFrames = nlistShape->GetDim(IDX_0);
53+ if (nframes != UNKNOWN_DIM && inDerivFrames != UNKNOWN_DIM && nframes != inDerivFrames) {
54+ std::string shapeMsg = std::to_string(nframes) + " and " + std::to_string(inDerivFrames);
55+ OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(opName, "net_deriv and in_deriv", shapeMsg.c_str(),
56+ "net_deriv.shape[0] and in_deriv.shape[0] should be same");
57+ return GRAPH_FAILED;
58+ }
59+ if (nframes != UNKNOWN_DIM && nlistFrames != UNKNOWN_DIM && nframes != nlistFrames) {
60+ std::string shapeMsg = std::to_string(nlistFrames) + " and " + std::to_string(nframes);
61+ OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(opName, "net_deriv and nlist", shapeMsg.c_str(),
62+ "net_deriv.shape[0] and nlist.shape[0] should be same");
63+ return GRAPH_FAILED;
64+ }
65+ return GRAPH_SUCCESS;
66+}
67+ 
68+// dtype 一致性校验 (SE 1.4)
69+static ge::graphStatus CheckDtypeConsistency(gert::InferShapeContext* context, const char* opName)
70+{
71+ const auto* netDerivDesc = context->GetInputDesc(IDX_0);
72+ OP_CHECK_NULL_WITH_CONTEXT(context, netDerivDesc);
73+ const auto* inDerivDesc = context->GetInputDesc(IDX_1);
74+ OP_CHECK_NULL_WITH_CONTEXT(context, inDerivDesc);
75+ if (netDerivDesc->GetDataType() != inDerivDesc->GetDataType()) {
76+ std::string dtypeMsg = Ops::Base::ToString(netDerivDesc->GetDataType()) + " and " +
77+ Ops::Base::ToString(inDerivDesc->GetDataType());
78+ OP_LOGE_FOR_INVALID_DTYPES_WITH_REASON(opName, "net_deriv and in_deriv", dtypeMsg.c_str(),
79+ "dtype of net_deriv and in_deriv should be same");
80+ return GRAPH_FAILED;
81+ }
82+ return GRAPH_SUCCESS;
83+}
84+ 
85+// natoms 值依赖读取与校验 (SE 1.4)
86+// natoms 为 unknown shape(-1) 时无法读取尺寸与值,nall 按 unknown dim(-1) 处理
87+static ge::graphStatus ReadAndValidateNatoms(gert::InferShapeContext* context, const gert::Shape* natomsShape,
88+ const char* opName, int64_t& nall)
89+{
90+ nall = UNKNOWN_DIM;
91+ if (Ops::Base::IsUnknownShape(*natomsShape)) {
92+ return GRAPH_SUCCESS;
93+ }
94+ const gert::Tensor* natomsTensor = context->GetInputTensor(IDX_3);
95+ OP_CHECK_NULL_WITH_CONTEXT(context, natomsTensor);
96+ int64_t natomsNum = natomsTensor->GetStorageShape().GetShapeSize();
97+ if (natomsNum < MIN_NATOMS_SIZE) {
98+ OP_LOGE_FOR_INVALID_SHAPESIZE(opName, "natoms", std::to_string(natomsNum).c_str(), ">= 3");
99+ return GRAPH_FAILED;
100+ }
101+ const int32_t* natomsData = natomsTensor->GetData<int32_t>();
102+ OP_CHECK_NULL_WITH_CONTEXT(context, natomsData);
103+ int64_t nloc = static_cast<int64_t>(natomsData[0]);
104+ nall = static_cast<int64_t>(natomsData[1]);
105+ if (nloc < 0) {
106+ OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nloc", std::to_string(nloc).c_str(),
107+ "nloc should be greater than or equal to 0");
108+ return GRAPH_FAILED;
109+ }
110+ if (nall < nloc) {
111+ OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nall", std::to_string(nall).c_str(),
112+ "nall should be greater than or equal to nloc");
113+ return GRAPH_FAILED;
114+ }
115+ return GRAPH_SUCCESS;
116+}
117+ 
118+// 属性校验 (SE 1.4)
119+static ge::graphStatus ValidateAttrs(gert::InferShapeContext* context, const char* opName)
120+{
121+ const gert::RuntimeAttrs* attrs = context->GetAttrs();
122+ OP_CHECK_NULL_WITH_CONTEXT(context, attrs);
123+ int32_t nASel = *(attrs->GetAttrPointer<int32_t>(ATTR_INDEX_N_A_SEL));
124+ int32_t nRSel = *(attrs->GetAttrPointer<int32_t>(ATTR_INDEX_N_R_SEL));
125+ if (nASel < 0 || nRSel < 0) {
126+ std::string valMsg = std::to_string(nASel) + " and " + std::to_string(nRSel);
127+ OP_LOGE_FOR_INVALID_VALUES_WITH_REASON(opName, "n_a_sel and n_r_sel", valMsg.c_str(),
128+ "n_a_sel and n_r_sel should be greater than or equal to 0");
129+ return GRAPH_FAILED;
130+ }
131+ int32_t nnei = nASel + nRSel;
132+ if (nnei == 0) {
133+ OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nnei", std::to_string(nnei).c_str(),
134+ "nnei should be greater than 0");
135+ return GRAPH_FAILED;
136+ }
137+ return GRAPH_SUCCESS;
138+}
43 139 
44static ge::graphStatus InferShapeProdForceSeA(gert::InferShapeContext* context)140static ge::graphStatus InferShapeProdForceSeA(gert::InferShapeContext* context)
45{141{
@@ -65,83 +161,24 @@ static ge::graphStatus InferShapeProdForceSeA(gert::InferShapeContext* context)
65 OP_LOGD(opName, "Input is unknown rank, set output to unknown rank");161 OP_LOGD(opName, "Input is unknown rank, set output to unknown rank");
66 return GRAPH_SUCCESS;162 return GRAPH_SUCCESS;
67 }163 }
68- if (Ops::Base::IsUnknownShape(*netDerivShape) || Ops::Base::IsUnknownShape(*inDerivShape) ||
69- Ops::Base::IsUnknownShape(*nlistShape) || Ops::Base::IsUnknownShape(*natomsShape)) {
70- Ops::Base::SetUnknownShape(OUTPUT_DIM_NUM, *forceShape);
71- OP_LOGD(opName, "Input is unknown shape, set output to unknown shape");
72- return GRAPH_SUCCESS;
73- }
74 164 
75- // ===== 3. 帧数一致性校验 (SE 1.4) =====165+ // ===== 3. 帧数一致性校验 =====
76- int64_t nframes = netDerivShape->GetDim(IDX_0);166+ int64_t nframes = 0;
77- int64_t inDerivFrames = inDerivShape->GetDim(IDX_0);167+ OP_CHECK_IF(CheckFramesConsistency(opName, netDerivShape, inDerivShape, nlistShape, nframes) != GRAPH_SUCCESS,
78- int64_t nlistFrames = nlistShape->GetDim(IDX_0);168+ OP_LOGE(opName, "CheckFramesConsistency failed"), return GRAPH_FAILED);
79- if (nframes != inDerivFrames) {
80- std::string shapeMsg = std::to_string(nframes) + " and " + std::to_string(inDerivFrames);
81- OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(opName, "net_deriv and in_deriv", shapeMsg.c_str(),
82- "net_deriv.shape[0] and in_deriv.shape[0] should be same");
83- return GRAPH_FAILED;
84- }
85- if (nframes != nlistFrames) {
86- std::string shapeMsg = std::to_string(nlistFrames) + " and " + std::to_string(nframes);
87- OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(opName, "net_deriv and nlist", shapeMsg.c_str(),
88- "net_deriv.shape[0] and nlist.shape[0] should be same");
89- return GRAPH_FAILED;
90- }
91 169 
92- // ===== 4. dtype 一致性校验 (SE 1.4) =====170+ // ===== 4. dtype 一致性校验 =====
93- const auto* netDerivDesc = context->GetInputDesc(IDX_0);171+ OP_CHECK_IF(CheckDtypeConsistency(context, opName) != GRAPH_SUCCESS,
94- OP_CHECK_NULL_WITH_CONTEXT(context, netDerivDesc);172+ OP_LOGE(opName, "CheckDtypeConsistency failed"), return GRAPH_FAILED);
95- const auto* inDerivDesc = context->GetInputDesc(IDX_1);
96- OP_CHECK_NULL_WITH_CONTEXT(context, inDerivDesc);
97- if (netDerivDesc->GetDataType() != inDerivDesc->GetDataType()) {
98- std::string dtypeMsg = Ops::Base::ToString(netDerivDesc->GetDataType()) + " and " +
99- Ops::Base::ToString(inDerivDesc->GetDataType());
100- OP_LOGE_FOR_INVALID_DTYPES_WITH_REASON(opName, "net_deriv and in_deriv", dtypeMsg.c_str(),
101- "dtype of net_deriv and in_deriv should be same");
102- return GRAPH_FAILED;
103- }
104 173 
105- // ===== 5. natoms 值依赖读取与校验 (SE 1.4) =====174+ // ===== 5. natoms 值依赖读取与校验 =====
106- const gert::Tensor* natomsTensor = context->GetInputTensor(IDX_3);175+ int64_t nall = UNKNOWN_DIM;
107- OP_CHECK_NULL_WITH_CONTEXT(context, natomsTensor);176+ OP_CHECK_IF(ReadAndValidateNatoms(context, natomsShape, opName, nall) != GRAPH_SUCCESS,
108- int64_t natomsNum = natomsTensor->GetStorageShape().GetShapeSize();177+ OP_LOGE(opName, "ReadAndValidateNatoms failed"), return GRAPH_FAILED);
109- if (natomsNum < MIN_NATOMS_SIZE) {
110- OP_LOGE_FOR_INVALID_SHAPESIZE(opName, "natoms", std::to_string(natomsNum).c_str(), ">= 3");
111- return GRAPH_FAILED;
112- }
113- const int32_t* natomsData = natomsTensor->GetData<int32_t>();
114- OP_CHECK_NULL_WITH_CONTEXT(context, natomsData);
115- int64_t nloc = static_cast<int64_t>(natomsData[0]);
116- int64_t nall = static_cast<int64_t>(natomsData[1]);
117- if (nloc < 0) {
118- OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nloc", std::to_string(nloc).c_str(),
119- "nloc should be greater than or equal to 0");
120- return GRAPH_FAILED;
121- }
122- if (nall < nloc) {
123- OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nall", std::to_string(nall).c_str(),
124- "nall should be greater than or equal to nloc");
125- return GRAPH_FAILED;
126- }
127 178 
128- // ===== 6. 属性校验 (SE 1.4) =====179+ // ===== 6. 属性校验 =====
129- const gert::RuntimeAttrs* attrs = context->GetAttrs();180+ OP_CHECK_IF(ValidateAttrs(context, opName) != GRAPH_SUCCESS, OP_LOGE(opName, "ValidateAttrs failed"),
130- OP_CHECK_NULL_WITH_CONTEXT(context, attrs);181+ return GRAPH_FAILED);
131- int32_t nASel = *(attrs->GetAttrPointer<int32_t>(ATTR_INDEX_N_A_SEL));
132- int32_t nRSel = *(attrs->GetAttrPointer<int32_t>(ATTR_INDEX_N_R_SEL));
133- if (nASel < 0 || nRSel < 0) {
134- std::string valMsg = std::to_string(nASel) + " and " + std::to_string(nRSel);
135- OP_LOGE_FOR_INVALID_VALUES_WITH_REASON(opName, "n_a_sel and n_r_sel", valMsg.c_str(),
136- "n_a_sel and n_r_sel should be greater than or equal to 0");
137- return GRAPH_FAILED;
138- }
139- int32_t nnei = nASel + nRSel;
140- if (nnei == 0) {
141- OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(opName, "nnei", std::to_string(nnei).c_str(),
142- "nnei should be greater than 0");
143- return GRAPH_FAILED;
144- }
145 182 
146 // ===== 7. 设置输出 shape: [nframes, nall, 3] =====183 // ===== 7. 设置输出 shape: [nframes, nall, 3] =====
147 forceShape->SetDimNum(OUTPUT_DIM_NUM);184 forceShape->SetDimNum(OUTPUT_DIM_NUM);
@@ -53,3 +53,106 @@ TEST_F(ProdForceSeAInfershape, prod_force_se_a_infershape_test1)
53 };53 };
54 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);54 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
55}55}
56+ 
57+TEST_F(ProdForceSeAInfershape, prod_force_se_a_infershape_unknown_shape)
58+{
59+ // Unknown shape (-1): all inputs unknown shape,
60+ // natoms 尺寸/值不可读 -> nall=-1,已知维保留(坐标维固定为 3),output shape {-1, -1, 3}
61+ int64_t nASel = 2;
62+ int64_t nRSel = 1;
63+ gert::InfershapeContextPara infershapeContextPara("ProdForceSeA",
64+ {
65+ {{{-1, -1}, {-1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
66+ {{{-1, -1}, {-1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
67+ {{{-1, -1}, {-1, -1}}, ge::DT_INT32, ge::FORMAT_ND},
68+ {{{-1}, {-1}}, ge::DT_INT32, ge::FORMAT_ND},
69+ },
70+ {
71+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
72+ },
73+ {
74+ {"n_a_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nASel)},
75+ {"n_r_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nRSel)},
76+ });
77+ std::vector<std::vector<int64_t>> expectOutputShape = {
78+ {-1, -1, 3},
79+ };
80+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
81+}
82+ 
83+TEST_F(ProdForceSeAInfershape, prod_force_se_a_infershape_unknown_shape_mixed)
84+{
85+ // Mixed unknown dim (-1) with known dims: net_deriv {-1, 36}、in_deriv {2, -1}、nlist {2, 9},
86+ // 帧数一致性校验遇 -1 跳过;natoms const [3, 5, 2] -> nall=5,output shape {-1, 5, 3}
87+ static int32_t natomsData[] = {3, 5, 2};
88+ int64_t nASel = 2;
89+ int64_t nRSel = 1;
90+ gert::InfershapeContextPara infershapeContextPara("ProdForceSeA",
91+ {
92+ {{{-1, 36}, {-1, 36}}, ge::DT_FLOAT, ge::FORMAT_ND},
93+ {{{2, -1}, {2, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
94+ {{{2, 9}, {2, 9}}, ge::DT_INT32, ge::FORMAT_ND},
95+ {{{3}, {3}}, ge::DT_INT32, ge::FORMAT_ND, true, natomsData},
96+ },
97+ {
98+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
99+ },
100+ {
101+ {"n_a_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nASel)},
102+ {"n_r_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nRSel)},
103+ });
104+ std::vector<std::vector<int64_t>> expectOutputShape = {
105+ {-1, 5, 3},
106+ };
107+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
108+}
109+ 
110+TEST_F(ProdForceSeAInfershape, prod_force_se_a_infershape_unknown_rank_mixed)
111+{
112+ // Mixed: natoms unknown rank {-2},其余输入已知 shape,输出透传为 unknown rank {-2}
113+ int64_t nASel = 2;
114+ int64_t nRSel = 1;
115+ gert::InfershapeContextPara infershapeContextPara("ProdForceSeA",
116+ {
117+ {{{2, 36}, {2, 36}}, ge::DT_FLOAT, ge::FORMAT_ND},
118+ {{{2, 108}, {2, 108}}, ge::DT_FLOAT, ge::FORMAT_ND},
119+ {{{2, 9}, {2, 9}}, ge::DT_INT32, ge::FORMAT_ND},
120+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
121+ },
122+ {
123+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
124+ },
125+ {
126+ {"n_a_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nASel)},
127+ {"n_r_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nRSel)},
128+ });
129+ std::vector<std::vector<int64_t>> expectOutputShape = {
130+ {-2},
131+ };
132+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
133+}
134+ 
135+TEST_F(ProdForceSeAInfershape, prod_force_se_a_infershape_unknown_rank)
136+{
137+ // Unknown rank (-2): all inputs unknown rank, output shape {-2}
138+ int64_t nASel = 2;
139+ int64_t nRSel = 1;
140+ gert::InfershapeContextPara infershapeContextPara("ProdForceSeA",
141+ {
142+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
143+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
144+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
145+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
146+ },
147+ {
148+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
149+ },
150+ {
151+ {"n_a_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nASel)},
152+ {"n_r_sel", Ops::Math::AnyValue::CreateFrom<int64_t>(nRSel)},
153+ });
154+ std::vector<std::vector<int64_t>> expectOutputShape = {
155+ {-2},
156+ };
157+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
158+}
@@ -221,6 +221,7 @@ static ge::graphStatus GetWorkspaceSize(gert::TilingContext* context)
221 221 
222static ge::graphStatus ProdVirialSeATilingFunc(gert::TilingContext* context)222static ge::graphStatus ProdVirialSeATilingFunc(gert::TilingContext* context)
223{223{
224+ OP_LOGD(context, "Enter TilingProdVirialSeA");
224 uint64_t ubSize = 0;225 uint64_t ubSize = 0;
225 int64_t coreNum = 0;226 int64_t coreNum = 0;
226 OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,227 OP_CHECK_IF(GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS,
@@ -25,6 +25,7 @@
25 25 
26#include "register/op_impl_registry.h"26#include "register/op_impl_registry.h"
27#include "log/log.h"27#include "log/log.h"
28+#include "util/shape_util.h"
28 29 
29namespace ops {30namespace ops {
30static constexpr int64_t IDX_NET_DERIV = 0;31static constexpr int64_t IDX_NET_DERIV = 0;
@@ -54,6 +55,16 @@ static ge::graphStatus SetAtomVirialShape(gert::InferShapeContext* context, int6
54 // 校验 natoms shape size >= 3(910b 兼容)55 // 校验 natoms shape size >= 3(910b 兼容)
55 const auto* natomsShape = context->GetInputShape(IDX_NATOMS);56 const auto* natomsShape = context->GetInputShape(IDX_NATOMS);
56 OP_CHECK_NULL_WITH_CONTEXT(context, natomsShape);57 OP_CHECK_NULL_WITH_CONTEXT(context, natomsShape);
58+ 
59+ // natoms 为 unknown rank(-2) / unknown shape(-1) 时无法读取尺寸,
60+ // 按动态 shape 处理:atom_virial shape[1] = -1
61+ if (Ops::Base::IsUnknownRank(*natomsShape) || Ops::Base::IsUnknownShape(*natomsShape)) {
62+ atomVirialShape->SetDimNum(2);
63+ atomVirialShape->SetDim(0, nframes);
64+ atomVirialShape->SetDim(1, -1);
65+ return ge::GRAPH_SUCCESS;
66+ }
67+ 
57 OP_CHECK_IF(natomsShape->GetShapeSize() < 3,68 OP_CHECK_IF(natomsShape->GetShapeSize() < 3,
58 OP_LOGE(context, "natoms size must be >= 3, got %ld", natomsShape->GetShapeSize()),69 OP_LOGE(context, "natoms size must be >= 3, got %ld", natomsShape->GetShapeSize()),
59 return ge::GRAPH_FAILED);70 return ge::GRAPH_FAILED);
@@ -105,6 +116,18 @@ static ge::graphStatus InferShapeProdVirialSeA(gert::InferShapeContext* context)
105 // 1. 获取输入 shape116 // 1. 获取输入 shape
106 const auto* netDerivShape = context->GetInputShape(IDX_NET_DERIV);117 const auto* netDerivShape = context->GetInputShape(IDX_NET_DERIV);
107 OP_CHECK_NULL_WITH_CONTEXT(context, netDerivShape);118 OP_CHECK_NULL_WITH_CONTEXT(context, netDerivShape);
119+ 
120+ // net_deriv 为 unknown rank(-2) 时无法推导,两个输出均透传为 unknown rank
121+ if (Ops::Base::IsUnknownRank(*netDerivShape)) {
122+ auto* virialShape = context->GetOutputShape(IDX_VIRIAL);
123+ OP_CHECK_NULL_WITH_CONTEXT(context, virialShape);
124+ Ops::Base::SetUnknownRank(*virialShape);
125+ auto* atomVirialShape = context->GetOutputShape(IDX_ATOM_VIRIAL);
126+ OP_CHECK_NULL_WITH_CONTEXT(context, atomVirialShape);
127+ Ops::Base::SetUnknownRank(*atomVirialShape);
128+ return ge::GRAPH_SUCCESS;
129+ }
130+ 
108 int64_t nframes = netDerivShape->GetDim(0);131 int64_t nframes = netDerivShape->GetDim(0);
109 132 
110 // 2. 设置 virial shape = [nframes, 9]133 // 2. 设置 virial shape = [nframes, 9]
@@ -43,6 +43,98 @@ TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_float32)
43 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);43 ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
44}44}
45 45 
46+TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_unknown_shape)
47+{
48+ // Unknown shape (-1): all inputs unknown shape,
49+ // virial -> {-1, 9}, atom_virial -> {-1, -1}
50+ gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",
51+ {
52+ {{{-1, -1}, {-1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
53+ {{{-1, -1}, {-1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
54+ {{{-1, -1}, {-1, -1}}, ge::DT_FLOAT, ge::FORMAT_ND},
55+ {{{-1, -1}, {-1, -1}}, ge::DT_INT32, ge::FORMAT_ND},
56+ {{{-1}, {-1}}, ge::DT_INT32, ge::FORMAT_ND},
57+ },
58+ {
59+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
60+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
61+ });
62+ std::vector<std::vector<int64_t>> expectOutputShape = {
63+ {-1, 9},
64+ {-1, -1},
65+ };
66+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
67+}
68+ 
69+TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_unknown_rank)
70+{
71+ // Unknown rank (-2): all inputs unknown rank, outputs {-2}
72+ gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",
73+ {
74+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
75+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
76+ {{{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND},
77+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
78+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
79+ },
80+ {
81+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
82+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
83+ });
84+ std::vector<std::vector<int64_t>> expectOutputShape = {
85+ {-2},
86+ {-2},
87+ };
88+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
89+}
90+ 
91+TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_unknown_shape_mixed)
92+{
93+ // Mixed unknown dim (-1) with known dims: net_deriv {-1, 72},其余输入已知,
94+ // nframes=-1 逐维透传,natoms 非 const -> atom_virial shape[1] = -1
95+ // virial -> {-1, 9}, atom_virial -> {-1, -1}
96+ gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",
97+ {
98+ {{{-1, 72}, {-1, 72}}, ge::DT_FLOAT, ge::FORMAT_ND},
99+ {{{2, 72}, {2, 72}}, ge::DT_FLOAT, ge::FORMAT_ND},
100+ {{{2, 18}, {2, 18}}, ge::DT_FLOAT, ge::FORMAT_ND},
101+ {{{2, 18}, {2, 18}}, ge::DT_INT32, ge::FORMAT_ND},
102+ {{{3}, {3}}, ge::DT_INT32, ge::FORMAT_ND},
103+ },
104+ {
105+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
106+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
107+ });
108+ std::vector<std::vector<int64_t>> expectOutputShape = {
109+ {-1, 9},
110+ {-1, -1},
111+ };
112+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
113+}
114+ 
115+TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_unknown_rank_mixed)
116+{
117+ // Mixed: natoms unknown rank {-2},其余输入已知 shape,
118+ // virial 不依赖 natoms -> {2, 9},atom_virial 依赖 natoms -> {2, -1}
119+ gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",
120+ {
121+ {{{2, 72}, {2, 72}}, ge::DT_FLOAT, ge::FORMAT_ND},
122+ {{{2, 72}, {2, 72}}, ge::DT_FLOAT, ge::FORMAT_ND},
123+ {{{2, 18}, {2, 18}}, ge::DT_FLOAT, ge::FORMAT_ND},
124+ {{{2, 18}, {2, 18}}, ge::DT_INT32, ge::FORMAT_ND},
125+ {{{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND},
126+ },
127+ {
128+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
129+ {{{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND},
130+ });
131+ std::vector<std::vector<int64_t>> expectOutputShape = {
132+ {2, 9},
133+ {2, -1},
134+ };
135+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
136+}
137+ 
46TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_float16)138TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_float16)
47{139{
48 gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",140 gert::InfershapeContextPara infershapeContextPara("ProdVirialSeA",
@@ -62,6 +62,7 @@ struct SparseBincountCompileInfo {};
62 62 
63static ge::graphStatus SparseBincountTilingFunc(gert::TilingContext* context)63static ge::graphStatus SparseBincountTilingFunc(gert::TilingContext* context)
64{64{
65+ OP_LOGD(context, "Enter TilingSparseBincount");
65 // 1. Get platform info66 // 1. Get platform info
66 fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo();67 fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo();
67 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr);68 OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr);
@@ -20,6 +20,7 @@
20 20 
21#include "register/op_impl_registry.h"21#include "register/op_impl_registry.h"
22#include "log/log.h"22#include "log/log.h"
23+#include "util/shape_util.h"
23 24 
24using namespace ge;25using namespace ge;
25 26 
@@ -49,6 +50,14 @@ static ge::graphStatus InferShapeSparseBincount(gert::InferShapeContext* context
49 gert::Shape* yShape = context->GetOutputShape(IDX_OUTPUT);50 gert::Shape* yShape = context->GetOutputShape(IDX_OUTPUT);
50 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);51 OP_CHECK_NULL_WITH_CONTEXT(context, yShape);
51 52 
53+ // dense_shape 为 unknown rank(-2) / unknown shape(-1) 时无法判断输出是 1D 还是 multi-dim,
54+ // 输出透传为 unknown rank
55+ if (Ops::Base::IsUnknownRank(*denseShapeShape) || Ops::Base::IsUnknownShape(*denseShapeShape)) {
56+ Ops::Base::SetUnknownRank(*yShape);
57+ OP_LOGD(context->GetNodeName(), "dense_shape is unknown rank/shape, set output to unknown rank");
58+ return GRAPH_SUCCESS;
59+ }
60+ 
52 // Read size tensor value61 // Read size tensor value
53 const auto* sizeTensor = context->GetInputTensor(IDX_SIZE);62 const auto* sizeTensor = context->GetInputTensor(IDX_SIZE);
54 OP_CHECK_NULL_WITH_CONTEXT(context, sizeTensor);63 OP_CHECK_NULL_WITH_CONTEXT(context, sizeTensor);
@@ -61,13 +70,11 @@ static ge::graphStatus InferShapeSparseBincount(gert::InferShapeContext* context
61 int64_t sizeValue = 0;70 int64_t sizeValue = 0;
62 if (sizeDtype == DT_INT32) {71 if (sizeDtype == DT_INT32) {
63 const int32_t* sizeData = sizeTensor->GetData<int32_t>();72 const int32_t* sizeData = sizeTensor->GetData<int32_t>();
64- OP_CHECK_IF(sizeData == nullptr,73+ OP_CHECK_IF(sizeData == nullptr, OP_LOGE(context, "size data is null"), return GRAPH_FAILED);
65- OP_LOGE(context, "size data is null"), return GRAPH_FAILED);
66 sizeValue = static_cast<int64_t>(sizeData[0]);74 sizeValue = static_cast<int64_t>(sizeData[0]);
67 } else {75 } else {
68 const int64_t* sizeData = sizeTensor->GetData<int64_t>();76 const int64_t* sizeData = sizeTensor->GetData<int64_t>();
69- OP_CHECK_IF(sizeData == nullptr,77+ OP_CHECK_IF(sizeData == nullptr, OP_LOGE(context, "size data is null"), return GRAPH_FAILED);
70- OP_LOGE(context, "size data is null"), return GRAPH_FAILED);
71 sizeValue = sizeData[0];78 sizeValue = sizeData[0];
72 }79 }
73 80 
@@ -80,8 +87,7 @@ static ge::graphStatus InferShapeSparseBincount(gert::InferShapeContext* context
80 const auto* denseShapeTensor = context->GetInputTensor(IDX_DENSE_SHAPE);87 const auto* denseShapeTensor = context->GetInputTensor(IDX_DENSE_SHAPE);
81 OP_CHECK_NULL_WITH_CONTEXT(context, denseShapeTensor);88 OP_CHECK_NULL_WITH_CONTEXT(context, denseShapeTensor);
82 const int64_t* denseShapeData = denseShapeTensor->GetData<int64_t>();89 const int64_t* denseShapeData = denseShapeTensor->GetData<int64_t>();
83- OP_CHECK_IF(denseShapeData == nullptr,90+ OP_CHECK_IF(denseShapeData == nullptr, OP_LOGE(context, "dense_shape data is null"), return GRAPH_FAILED);
84- OP_LOGE(context, "dense_shape data is null"), return GRAPH_FAILED);
85 int64_t denseShapeRows = denseShapeData[0];91 int64_t denseShapeRows = denseShapeData[0];
86 92 
87 yShape->SetDimNum(2);93 yShape->SetDimNum(2);
@@ -96,4 +102,4 @@ static ge::graphStatus InferShapeSparseBincount(gert::InferShapeContext* context
96}102}
97 103 
98IMPL_OP_INFERSHAPE(SparseBincount).InferShape(InferShapeSparseBincount);104IMPL_OP_INFERSHAPE(SparseBincount).InferShape(InferShapeSparseBincount);
99-} // namespace ops105+} // namespace ops
@@ -31,7 +31,7 @@ protected:
31 static void TearDownTestCase() { std::cout << "SparseBincountTiling TearDown" << std::endl; }31 static void TearDownTestCase() { std::cout << "SparseBincountTiling TearDown" << std::endl; }
32};32};
33 33 
34-std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};34+static std::map<std::string, std::string> soc_version_infos = {{"Short_SoC_version", "Ascend950"}};
35 35 
36// Test case 1: 1D mode, values=int32, size=int32, with weights36// Test case 1: 1D mode, values=int32, size=int32, with weights
37// indices: [4, 1] int64, values: [4] int32, dense_shape: [1] int64,37// indices: [4, 1] int64, values: [4] int32, dense_shape: [1] int64,
@@ -15,18 +15,11 @@
15#include "infershape_context_faker.h"15#include "infershape_context_faker.h"
16#include "infershape_case_executor.h"16#include "infershape_case_executor.h"
17 17 
18-class SparseBincountInfershape : public testing::Test18+class SparseBincountInfershape : public testing::Test {
19-{
20protected:19protected:
21- static void SetUpTestCase()20+ static void SetUpTestCase() { std::cout << "SparseBincountInfershape SetUp" << std::endl; }
22- {
23- std::cout << "SparseBincountInfershape SetUp" << std::endl;
24- }
25 21 
26- static void TearDownTestCase()22+ static void TearDownTestCase() { std::cout << "SparseBincountInfershape TearDown" << std::endl; }
27- {
28- std::cout << "SparseBincountInfershape TearDown" << std::endl;
29- }
30};23};
31 24 
32// Test case 1: 1D mode25// Test case 1: 1D mode
@@ -43,14 +36,16 @@ TEST_F(SparseBincountInfershape, sparse_bincount_1d_test)
43 gert::InfershapeContextPara infershapeContextPara(36 gert::InfershapeContextPara infershapeContextPara(
44 "SparseBincount",37 "SparseBincount",
45 {38 {
46- gert::InfershapeContextPara::TensorDescription({{4, 1}, {4, 1}}, ge::DT_INT64, ge::FORMAT_ND), // indices39+ gert::InfershapeContextPara::TensorDescription({{4, 1}, {4, 1}}, ge::DT_INT64, ge::FORMAT_ND), // indices
47- gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_INT32, ge::FORMAT_ND), // values40+ gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_INT32, ge::FORMAT_ND), // values
48- gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT64, ge::FORMAT_ND, true, denseShapeData), // dense_shape (const)41+ gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT64, ge::FORMAT_ND, true,
49- gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true, sizeData), // size (const)42+ denseShapeData), // dense_shape (const)
50- gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights43+ gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true,
44+ sizeData), // size (const)
45+ gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights
51 },46 },
52 {47 {
53- gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output48+ gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output
54 });49 });
55 std::vector<std::vector<int64_t>> expectOutputShape = {50 std::vector<std::vector<int64_t>> expectOutputShape = {
56 {8},51 {8},
@@ -72,14 +67,95 @@ TEST_F(SparseBincountInfershape, sparse_bincount_nd_test)
72 gert::InfershapeContextPara infershapeContextPara(67 gert::InfershapeContextPara infershapeContextPara(
73 "SparseBincount",68 "SparseBincount",
74 {69 {
75- gert::InfershapeContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND), // indices70+ gert::InfershapeContextPara::TensorDescription({{4, 2}, {4, 2}}, ge::DT_INT64, ge::FORMAT_ND), // indices
76- gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_INT64, ge::FORMAT_ND), // values71+ gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_INT64, ge::FORMAT_ND), // values
77- gert::InfershapeContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true, denseShapeData), // dense_shape (const)72+ gert::InfershapeContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
78- gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true, sizeData), // size (const)73+ denseShapeData), // dense_shape (const)
79- gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights74+ gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true,
75+ sizeData), // size (const)
76+ gert::InfershapeContextPara::TensorDescription({{4}, {4}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights
80 },77 },
81 {78 {
82- gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output79+ gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output
80+ });
81+ std::vector<std::vector<int64_t>> expectOutputShape = {
82+ {4, 8},
83+ };
84+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
85+}
86+ 
87+// Test case 3: Unknown shape (-1)
88+// indices/values/weights are unknown shape; dense_shape and size are const (value dependency)
89+// Expected output shape: [dense_shape[0], size] = [4, 8]
90+TEST_F(SparseBincountInfershape, sparse_bincount_unknown_shape_test)
91+{
92+ int32_t sizeData[1] = {8};
93+ int64_t denseShapeData[2] = {4, 5};
94+ 
95+ gert::InfershapeContextPara infershapeContextPara(
96+ "SparseBincount",
97+ {
98+ gert::InfershapeContextPara::TensorDescription({{-1, -1}, {-1, -1}}, ge::DT_INT64,
99+ ge::FORMAT_ND), // indices
100+ gert::InfershapeContextPara::TensorDescription({{-1}, {-1}}, ge::DT_INT32, ge::FORMAT_ND), // values
101+ gert::InfershapeContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
102+ denseShapeData), // dense_shape (const)
103+ gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true,
104+ sizeData), // size (const)
105+ gert::InfershapeContextPara::TensorDescription({{-1}, {-1}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights
106+ },
107+ {
108+ gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output
109+ });
110+ std::vector<std::vector<int64_t>> expectOutputShape = {
111+ {4, 8},
112+ };
113+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
114+}
115+ 
116+// Test case 4: Unknown rank (-2)
117+// dense_shape is unknown rank, output rank cannot be decided -> {-2}
118+TEST_F(SparseBincountInfershape, sparse_bincount_unknown_rank_test)
119+{
120+ gert::InfershapeContextPara infershapeContextPara(
121+ "SparseBincount",
122+ {
123+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND), // indices
124+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND), // values
125+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND), // dense_shape
126+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_INT32, ge::FORMAT_ND), // size
127+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights
128+ },
129+ {
130+ gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output
131+ });
132+ std::vector<std::vector<int64_t>> expectOutputShape = {
133+ {-2},
134+ };
135+ ExecuteTestCase(infershapeContextPara, ge::GRAPH_SUCCESS, expectOutputShape);
136+}
137+ 
138+// Test case 5: Mixed unknown rank/shape
139+// indices unknown rank {-2}、values/weights 部分未知 {-1},dense_shape/size 为 const(值依赖)
140+// 输出仅依赖 dense_shape 与 size,其余输入 shape 不参与推导 -> [4, 8]
141+TEST_F(SparseBincountInfershape, sparse_bincount_mixed_unknown_test)
142+{
143+ int32_t sizeData[1] = {8};
144+ int64_t denseShapeData[2] = {4, 5};
145+ 
146+ gert::InfershapeContextPara infershapeContextPara(
147+ "SparseBincount",
148+ {
149+ gert::InfershapeContextPara::TensorDescription({{-2}, {-2}}, ge::DT_INT64, ge::FORMAT_ND), // indices
150+ gert::InfershapeContextPara::TensorDescription({{-1}, {-1}}, ge::DT_INT32, ge::FORMAT_ND), // values
151+ gert::InfershapeContextPara::TensorDescription({{2}, {2}}, ge::DT_INT64, ge::FORMAT_ND, true,
152+ denseShapeData), // dense_shape (const)
153+ gert::InfershapeContextPara::TensorDescription({{1}, {1}}, ge::DT_INT32, ge::FORMAT_ND, true,
154+ sizeData), // size (const)
155+ gert::InfershapeContextPara::TensorDescription({{-1}, {-1}}, ge::DT_FLOAT, ge::FORMAT_ND), // weights
156+ },
157+ {
158+ gert::InfershapeContextPara::TensorDescription({{}, {}}, ge::DT_FLOAT, ge::FORMAT_ND), // output
83 });159 });
84 std::vector<std::vector<int64_t>> expectOutputShape = {160 std::vector<std::vector<int64_t>> expectOutputShape = {
85 {4, 8},161 {4, 8},