已合并
feat: 9个迁移算子适配unknown shape/rank InferShape并补UT及入口日志 #4811
xuejinghui创建于 8月17日
feat: 9个迁移算子适配unknown shape/rank InferShape并补UT及入口日志 #4811
已合并
共 27 个文件变更+1006-333
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | using namespace ge; | 22 | using namespace ge; |
| @@ -25,12 +26,20 @@ static constexpr int64_t IDX_0 = 0; | |||
| 25 | 26 | ||
| 26 | static ge::graphStatus InferShapeMatrixDiagPart(gert::InferShapeContext* context) | 27 | static 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 | ||
| 31 | TEST_F(MatrixDiagPartTiling, matrix_diag_part_tiling_float16) | 31 | TEST_F(MatrixDiagPartTiling, matrix_diag_part_tiling_float16) |
| 32 | { | 32 | { |
| @@ -32,41 +32,36 @@ constexpr int64_t PER_CORE_MIN = 1024; | |||
| 32 | constexpr uint32_t DCACHE_SIZE = 128 * 1024; | 32 | constexpr uint32_t DCACHE_SIZE = 128 * 1024; |
| 33 | constexpr uint32_t STATIC_UB_ESTIMATE = 0; | 33 | constexpr 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 dtypes | 47 | // 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_shape | 72 | // 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) |
| 111 | static void ComputeStrides(const int64_t* shape, int32_t rank, int64_t* strides) | 100 | static 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 | ||
| 186 | static ge::graphStatus SparseReshapeTilingFunc(gert::TilingContext* context) | 203 | static 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 optiling | 240 | +} // namespace optiling |
| @@ -15,6 +15,7 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 18 | 19 | ||
| 19 | using namespace ge; | 20 | using namespace ge; |
| 20 | 21 | ||
| @@ -25,31 +26,29 @@ static constexpr int64_t IDX_2 = 2; | |||
| 25 | static constexpr int64_t MAX_RANK = 8; | 26 | static constexpr int64_t MAX_RANK = 8; |
| 26 | static constexpr int64_t INDICES_TENSOR_RANK = 2; | 27 | static 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 | ||
| 27 | class SparseReshapeTiling : public testing::Test { | 27 | class SparseReshapeTiling : public testing::Test { |
| 28 | protected: | 28 | protected: |
| 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, int64 | 36 | // Test case 1: reshape [2,3] -> [3,2], nnz=4, int64 |
| 43 | TEST_F(SparseReshapeTiling, sparse_reshape_int64) | 37 | TEST_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 -> identity | 115 | + 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 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | -class SparseReshapeInfershape : public testing::Test | 23 | +class SparseReshapeInfershape : public testing::Test { |
| 24 | -{ | ||
| 25 | protected: | 24 | protected: |
| 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, int64 | 30 | // 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 inferred | 43 | + {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices: shape inferred |
| 51 | - {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape: shape inferred | 44 | + {{{}, {}}, 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_indices | 65 | + {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_indices |
| 73 | - {{{}, {}}, ge::DT_INT32, ge::FORMAT_ND}, // y_shape | 66 | + {{{}, {}}, 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_indices | 87 | + {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_indices |
| 95 | - {{{}, {}}, ge::DT_INT64, ge::FORMAT_ND}, // y_shape | 88 | + {{{}, {}}, 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 | 21 | ||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | + | ||
| 24 | 25 | ||
| 25 | 26 | ||
| 26 | 27 | ||
| @@ -119,6 +120,7 @@ static ge::graphStatus ValidateDtypes(gert::TilingContext* context) | |||
| 119 | 120 | ||
| 120 | static ge::graphStatus TriluTilingFunc(gert::TilingContext* context) | 121 | static 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; | |||
| 22 | namespace ops { | 22 | namespace ops { |
| 23 | static ge::graphStatus InferShapeTrilu(gert::InferShapeContext* context) | 23 | static 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 | } |
| 40 | IMPL_OP_INFERSHAPE(Trilu).InferShape(InferShapeTrilu); | 41 | IMPL_OP_INFERSHAPE(Trilu).InferShape(InferShapeTrilu); |
| 41 | -} // namespace ops | 42 | +} // namespace ops |
| @@ -20,18 +20,11 @@ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | -class TriluInfershape : public testing::Test | 23 | +class TriluInfershape : public testing::Test { |
| 24 | -{ | ||
| 25 | protected: | 24 | protected: |
| 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 | ||
| 37 | TEST_F(TriluInfershape, trilu_infershape_test1) | 30 | TEST_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 | ||
| 29 | TEST_F(AddExampleTiling, add_example_0) | 29 | TEST_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 | ||
| 30 | TEST_F(ExpandvTiling, expandv_example_0) | 30 | TEST_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 | ||
| 22 | class RadixSortTiling : public testing::Test { | 22 | class RadixSortTiling : public testing::Test { |
| 23 | protected: | 23 | protected: |
| 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 | ||
| 37 | TEST_F(RadixSortTiling, radix_sort_int32_ascending_2048) | 31 | TEST_F(RadixSortTiling, radix_sort_int32_ascending_2048) |
| 38 | { | 32 | { |
| @@ -188,6 +188,7 @@ static ge::graphStatus GetWorkspaceSize(gert::TilingContext* context) | |||
| 188 | 188 | ||
| 189 | static ge::graphStatus CosineSimilarityTilingFunc(gert::TilingContext* context) | 189 | static 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 | 13 | ||
| 14 | 14 | ||
| 15 | + | ||
| 15 | 16 | ||
| 16 | using namespace ge; | 17 | using namespace ge; |
| 17 | 18 | ||
| @@ -19,6 +20,7 @@ namespace ops { | |||
| 19 | static constexpr int64_t IDX_0 = 0; | 20 | static constexpr int64_t IDX_0 = 0; |
| 20 | static constexpr int64_t IDX_1 = 1; | 21 | static constexpr int64_t IDX_1 = 1; |
| 21 | static constexpr int32_t MAX_DIMS = 8; | 22 | static constexpr int32_t MAX_DIMS = 8; |
| 23 | +static constexpr int64_t UNKNOWN_DIM = -1; | ||
| 22 | 24 | ||
| 23 | static ge::graphStatus InferShapeCosineSimilarity(gert::InferShapeContext* context) | 25 | static 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 dimensions | 43 | // 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 shape | 75 | + // 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 | ||
| 132 | IMPL_OP_INFERSHAPE(CosineSimilarity).InferShape(InferShapeCosineSimilarity); | 140 | IMPL_OP_INFERSHAPE(CosineSimilarity).InferShape(InferShapeCosineSimilarity); |
| 133 | -} // namespace ops | 141 | +} // namespace ops |
| @@ -15,32 +15,24 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | -class CosineSimilarityInfershape : public testing::Test | 18 | +class CosineSimilarityInfershape : public testing::Test { |
| 19 | -{ | ||
| 20 | protected: | 19 | protected: |
| 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 | ||
| 32 | TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test1) | 25 | TEST_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) | |||
| 50 | TEST_F(CosineSimilarityInfershape, cosine_similarity_infershape_test2) | 42 | TEST_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 | ||
| 291 | static ge::graphStatus ProdForceSeATilingFunc(gert::TilingContext* context) | 291 | static 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 属性索引 | |||
| 40 | static constexpr int64_t ATTR_INDEX_N_R_SEL = 1; // n_r_sel 属性索引 | 40 | static constexpr int64_t ATTR_INDEX_N_R_SEL = 1; // n_r_sel 属性索引 |
| 41 | static constexpr int64_t OUTPUT_DIM_NUM = 3; // 输出维度数 | 41 | static constexpr int64_t OUTPUT_DIM_NUM = 3; // 输出维度数 |
| 42 | static constexpr int64_t COORD_DIM_SIZE = 3; // 坐标维度大小 (x,y,z) | 42 | static 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 | ||
| 44 | static ge::graphStatus InferShapeProdForceSeA(gert::InferShapeContext* context) | 140 | static 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 | ||
| 222 | static ge::graphStatus ProdVirialSeATilingFunc(gert::TilingContext* context) | 222 | static 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 | 26 | ||
| 27 | 27 | ||
| 28 | + | ||
| 28 | 29 | ||
| 29 | namespace ops { | 30 | namespace ops { |
| 30 | static constexpr int64_t IDX_NET_DERIV = 0; | 31 | static 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. 获取输入 shape | 116 | // 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 | + | ||
| 46 | TEST_F(ProdVirialSeAInfershapeTest, prod_virial_se_a_infershape_float16) | 138 | TEST_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 | ||
| 63 | static ge::graphStatus SparseBincountTilingFunc(gert::TilingContext* context) | 63 | static ge::graphStatus SparseBincountTilingFunc(gert::TilingContext* context) |
| 64 | { | 64 | { |
| 65 | + OP_LOGD(context, "Enter TilingSparseBincount"); | ||
| 65 | // 1. Get platform info | 66 | // 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 | 21 | ||
| 22 | 22 | ||
| 23 | + | ||
| 23 | 24 | ||
| 24 | using namespace ge; | 25 | using 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 value | 61 | // 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 | ||
| 98 | IMPL_OP_INFERSHAPE(SparseBincount).InferShape(InferShapeSparseBincount); | 104 | IMPL_OP_INFERSHAPE(SparseBincount).InferShape(InferShapeSparseBincount); |
| 99 | -} // namespace ops | 105 | +} // 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 weights | 36 | // 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 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | -class SparseBincountInfershape : public testing::Test | 18 | +class SparseBincountInfershape : public testing::Test { |
| 19 | -{ | ||
| 20 | protected: | 19 | protected: |
| 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 mode | 25 | // 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), // indices | 39 | + 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), // values | 40 | + 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), // weights | 43 | + 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), // output | 48 | + 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), // indices | 70 | + 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), // values | 71 | + 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), // weights | 74 | + 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), // output | 79 | + 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}, |