已合并
bug fix: experimental 构建报错 'multiple definition of `ops::op_impl_register_infershape_ZerosLike` + gen_compile_option.sh awk 重复告警 #3516
zhaohujie创建于 6月24日
bug fix: experimental 构建报错 'multiple definition of `ops::op_impl_register_infershape_ZerosLike` + gen_compile_option.sh awk 重复告警 #3516
已合并
共 3 个文件变更+52-107
| @@ -12,7 +12,6 @@ | |||
| 12 | add_all_modules_sources( | 12 | add_all_modules_sources( |
| 13 | OPTYPE isin_part_v1 | 13 | OPTYPE isin_part_v1 |
| 14 | ACLNNTYPE aclnn | 14 | ACLNNTYPE aclnn |
| 15 | - DEPENDENCIES concat_d sort zeros_like zero_op cast | ||
| 16 | COMPUTE_UNIT ascend950 | 15 | COMPUTE_UNIT ascend950 |
| 17 | TILING_DIR arch35 | 16 | TILING_DIR arch35 |
| 18 | DISABLE_IN_OPP TRUE | 17 | DISABLE_IN_OPP TRUE |
| @@ -1,19 +1,15 @@ | |||
| 1 | /** | 1 | /** |
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. |
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, |
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. |
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | 8 | + * See LICENSE in the root of the software repository for the full text of the License. |
| 9 | - */ | 9 | + */ |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | - | ||
| 13 | 12 | ||
| 14 | - | ||
| 15 | - | ||
| 16 | - | ||
| 17 | 13 | ||
| 18 | 14 | ||
| 19 | 15 | ||
| @@ -107,76 +103,35 @@ int main() | |||
| 107 | CHECK_RET(aclrtCreateContext(&context, deviceId) == ACL_SUCCESS, return -1); | 103 | CHECK_RET(aclrtCreateContext(&context, deviceId) == ACL_SUCCESS, return -1); |
| 108 | CHECK_RET(aclrtCreateStream(&stream) == ACL_SUCCESS, return -1); | 104 | CHECK_RET(aclrtCreateStream(&stream) == ACL_SUCCESS, return -1); |
| 109 | 105 | ||
| 110 | - // 2. 原始输入数据 | 106 | + // 2. 直接构造 IsinPartV1 的三个输入,仅校验本算子(不依赖 Cat/Sort/Cast 等其它算子)。 |
| 111 | - std::vector<float> h_elements = {1.0, 1.0, 4.0, 1.0, 1.0}; | 107 | + // 语义等价于 isin(elements=[1,1,4,1,1], test_elements=[0,1,2,3]): |
| 112 | - std::vector<float> h_test_elements = {0.0, 1.0, 2.0, 3.0}; | 108 | + // - 将 elements 与 test_elements 拼接后按值排序,相等值相邻; |
| 113 | - int64_t elementsNum = h_elements.size(); | 109 | + // - value 为排序后的值,index 为其在拼接序列中的原始位置(0..elementsNum-1 为待判定元素); |
| 114 | - int64_t totalSize = h_elements.size() + h_test_elements.size(); | 110 | + // - elementsNum 为待判定元素个数(单元素 INT32 张量); |
| 111 | + // - 输出 z[i] 表示第 i 个待判定元素是否出现在 test_elements 中。 | ||
| 112 | + std::vector<float> h_value = {0, 1, 1, 1, 1, 1, 2, 3, 4}; // 排序后的值 | ||
| 113 | + std::vector<int32_t> h_index = {5, 0, 1, 3, 4, 6, 7, 8, 2}; // 对应的原始位置 | ||
| 114 | + int32_t elementsNum = 5; | ||
| 115 | + std::vector<int32_t> h_elementsNum = {elementsNum}; | ||
| 116 | + int64_t totalSize = static_cast<int64_t>(h_value.size()); | ||
| 115 | 117 | ||
| 116 | std::vector<int64_t> totalShape = {totalSize}; | 118 | std::vector<int64_t> totalShape = {totalSize}; |
| 117 | std::vector<int64_t> outShape = {elementsNum}; | 119 | std::vector<int64_t> outShape = {elementsNum}; |
| 118 | 120 | ||
| 119 | // 3. 资源准备 | 121 | // 3. 资源准备 |
| 120 | - void *elAddr = nullptr, *teAddr = nullptr, *catAddr = nullptr; | 122 | + void *valueAddr = nullptr, *indexAddr = nullptr, *elementsNumAddr = nullptr, *outAddr = nullptr; |
| 121 | - void *sortVAddr = nullptr, *sortI64Addr = nullptr, *sortI32Addr = nullptr, *outAddr = nullptr; | 123 | + aclTensor *valueTensor = nullptr, *indexTensor = nullptr, *elementsNumTensor = nullptr, *outTensor = nullptr; |
| 122 | - aclTensor *elTensor = nullptr, *teTensor = nullptr, *catTensor = nullptr; | 124 | + CHECK_RET(CreateAclTensor(h_value, totalShape, &valueAddr, ACL_FLOAT, &valueTensor) == 0, return -1); |
| 123 | - aclTensor *sortVTensor = nullptr, *sortI64Tensor = nullptr, *sortI32Tensor = nullptr, *outTensor = nullptr; | 125 | + CHECK_RET(CreateAclTensor(h_index, totalShape, &indexAddr, ACL_INT32, &indexTensor) == 0, return -1); |
| 124 | - | 126 | + CHECK_RET(CreateAclTensor(h_elementsNum, {1}, &elementsNumAddr, ACL_INT32, &elementsNumTensor) == 0, return -1); |
| 125 | - CHECK_RET(CreateAclTensor(h_elements, {elementsNum}, &elAddr, ACL_FLOAT, &elTensor) == 0, return -1); | ||
| 126 | - CHECK_RET( | ||
| 127 | - CreateAclTensor(h_test_elements, {(int64_t)h_test_elements.size()}, &teAddr, ACL_FLOAT, &teTensor) == 0, | ||
| 128 | - return -1); | ||
| 129 | - | ||
| 130 | - // 创建输入 Tensor | ||
| 131 | - CHECK_RET(CreateEmptyTensor(totalShape, ACL_FLOAT, &catAddr, &catTensor) == 0, return -1); | ||
| 132 | - CHECK_RET(CreateEmptyTensor(totalShape, ACL_FLOAT, &sortVAddr, &sortVTensor) == 0, return -1); | ||
| 133 | - CHECK_RET(CreateEmptyTensor(totalShape, ACL_INT64, &sortI64Addr, &sortI64Tensor) == 0, return -1); | ||
| 134 | - CHECK_RET(CreateEmptyTensor(totalShape, ACL_INT32, &sortI32Addr, &sortI32Tensor) == 0, return -1); | ||
| 135 | CHECK_RET(CreateEmptyTensor(outShape, ACL_BOOL, &outAddr, &outTensor) == 0, return -1); | 127 | CHECK_RET(CreateEmptyTensor(outShape, ACL_BOOL, &outAddr, &outTensor) == 0, return -1); |
| 136 | 128 | ||
| 137 | - // 4. 调用 aclnnCat | 129 | + // 4. 调用自定义算子 aclnnIsinPartV1 |
| 138 | - LOG_PRINT("[Process] Step A: aclnnCat\n"); | 130 | + LOG_PRINT("[Process] aclnnIsinPartV1\n"); |
| 139 | - std::vector<aclTensor*> catListVec = {elTensor, teTensor}; | ||
| 140 | - aclTensorList* catList = aclCreateTensorList(catListVec.data(), catListVec.size()); | ||
| 141 | - uint64_t wsCat = 0; | ||
| 142 | - aclOpExecutor* execCat = nullptr; | ||
| 143 | - CHECK_RET(aclnnCatGetWorkspaceSize(catList, 0, catTensor, &wsCat, &execCat) == ACL_SUCCESS, return -1); | ||
| 144 | - void* wsCatAddr = nullptr; | ||
| 145 | - if (wsCat > 0) | ||
| 146 | - aclrtMalloc(&wsCatAddr, wsCat, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 147 | - CHECK_RET(aclnnCat(wsCatAddr, wsCat, execCat, stream) == ACL_SUCCESS, return -1); | ||
| 148 | - | ||
| 149 | - // 5. 调用 aclnnSort (输出为 INT64) | ||
| 150 | - LOG_PRINT("[Process] Step B: aclnnSort (INT64 Indices)\n"); | ||
| 151 | - uint64_t wsSort = 0; | ||
| 152 | - aclOpExecutor* execSort = nullptr; | ||
| 153 | - CHECK_RET( | ||
| 154 | - aclnnSortGetWorkspaceSize(catTensor, false, 0, false, sortVTensor, sortI64Tensor, &wsSort, &execSort) == | ||
| 155 | - ACL_SUCCESS, | ||
| 156 | - return -1); | ||
| 157 | - void* wsSortAddr = nullptr; | ||
| 158 | - if (wsSort > 0) | ||
| 159 | - aclrtMalloc(&wsSortAddr, wsSort, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 160 | - CHECK_RET(aclnnSort(wsSortAddr, wsSort, execSort, stream) == ACL_SUCCESS, return -1); | ||
| 161 | - | ||
| 162 | - // 6. 调用 aclnnCast (INT64 -> INT32) | ||
| 163 | - LOG_PRINT("[Process] Step C: aclnnCast (INT64 -> INT32)\n"); | ||
| 164 | - uint64_t wsCast = 0; | ||
| 165 | - aclOpExecutor* execCast = nullptr; | ||
| 166 | - CHECK_RET( | ||
| 167 | - aclnnCastGetWorkspaceSize(sortI64Tensor, ACL_INT32, sortI32Tensor, &wsCast, &execCast) == ACL_SUCCESS, | ||
| 168 | - return -1); | ||
| 169 | - void* wsCastAddr = nullptr; | ||
| 170 | - if (wsCast > 0) | ||
| 171 | - aclrtMalloc(&wsCastAddr, wsCast, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| 172 | - CHECK_RET(aclnnCast(wsCastAddr, wsCast, execCast, stream) == ACL_SUCCESS, return -1); | ||
| 173 | - | ||
| 174 | - // 7. 调用自定义算子 aclnnIsinPartV1 | ||
| 175 | - LOG_PRINT("[Process] Step D: aclnnIsinPartV1\n"); | ||
| 176 | uint64_t wsIsin = 0; | 131 | uint64_t wsIsin = 0; |
| 177 | aclOpExecutor* execIsin = nullptr; | 132 | aclOpExecutor* execIsin = nullptr; |
| 178 | CHECK_RET( | 133 | CHECK_RET( |
| 179 | - aclnnIsinPartV1GetWorkspaceSize(sortVTensor, sortI32Tensor, elementsNum, outTensor, &wsIsin, &execIsin) == | 134 | + aclnnIsinPartV1GetWorkspaceSize(valueTensor, indexTensor, elementsNumTensor, outTensor, &wsIsin, &execIsin) == |
| 180 | ACL_SUCCESS, | 135 | ACL_SUCCESS, |
| 181 | return -1); | 136 | return -1); |
| 182 | void* wsIsinAddr = nullptr; | 137 | void* wsIsinAddr = nullptr; |
| @@ -184,38 +139,21 @@ int main() | |||
| 184 | aclrtMalloc(&wsIsinAddr, wsIsin, ACL_MEM_MALLOC_HUGE_FIRST); | 139 | aclrtMalloc(&wsIsinAddr, wsIsin, ACL_MEM_MALLOC_HUGE_FIRST); |
| 185 | CHECK_RET(aclnnIsinPartV1(wsIsinAddr, wsIsin, execIsin, stream) == ACL_SUCCESS, return -1); | 140 | CHECK_RET(aclnnIsinPartV1(wsIsinAddr, wsIsin, execIsin, stream) == ACL_SUCCESS, return -1); |
| 186 | 141 | ||
| 187 | - // 8. 同步并获取结果 | 142 | + // 5. 同步并获取结果(期望 [1, 1, 0, 1, 1],即 1 在测试集中、4 不在) |
| 188 | CHECK_RET(aclrtSynchronizeStream(stream) == ACL_SUCCESS, return -1); | 143 | CHECK_RET(aclrtSynchronizeStream(stream) == ACL_SUCCESS, return -1); |
| 189 | - std::vector<uint8_t> h_out(elementsNum, 0); // Bool 在 Host 用 uint8_t 接收 | ||
| 190 | - aclrtMemcpy(h_out.data(), elementsNum, outAddr, elementsNum, ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 191 | - | ||
| 192 | LOG_PRINT("--- Final Result ---\n"); | 144 | LOG_PRINT("--- Final Result ---\n"); |
| 193 | PrintOutResult(outShape, elementsNum, &outAddr); | 145 | PrintOutResult(outShape, elementsNum, &outAddr); |
| 194 | 146 | ||
| 195 | - // 9. 资源清理 | 147 | + // 6. 资源清理 |
| 196 | - aclDestroyTensorList(catList); | 148 | + aclDestroyTensor(valueTensor); |
| 197 | - aclDestroyTensor(elTensor); | 149 | + aclDestroyTensor(indexTensor); |
| 198 | - aclDestroyTensor(teTensor); | 150 | + aclDestroyTensor(elementsNumTensor); |
| 199 | - aclDestroyTensor(catTensor); | ||
| 200 | - aclDestroyTensor(sortVTensor); | ||
| 201 | - aclDestroyTensor(sortI64Tensor); | ||
| 202 | - aclDestroyTensor(sortI32Tensor); | ||
| 203 | aclDestroyTensor(outTensor); | 151 | aclDestroyTensor(outTensor); |
| 204 | 152 | ||
| 205 | - aclrtFree(elAddr); | 153 | + aclrtFree(valueAddr); |
| 206 | - aclrtFree(teAddr); | 154 | + aclrtFree(indexAddr); |
| 207 | - aclrtFree(catAddr); | 155 | + aclrtFree(elementsNumAddr); |
| 208 | - aclrtFree(sortVAddr); | ||
| 209 | - aclrtFree(sortI64Addr); | ||
| 210 | - aclrtFree(sortI32Addr); | ||
| 211 | aclrtFree(outAddr); | 156 | aclrtFree(outAddr); |
| 212 | - | ||
| 213 | - if (wsCatAddr) | ||
| 214 | - aclrtFree(wsCatAddr); | ||
| 215 | - if (wsSortAddr) | ||
| 216 | - aclrtFree(wsSortAddr); | ||
| 217 | - if (wsCastAddr) | ||
| 218 | - aclrtFree(wsCastAddr); | ||
| 219 | if (wsIsinAddr) | 157 | if (wsIsinAddr) |
| 220 | aclrtFree(wsIsinAddr); | 158 | aclrtFree(wsIsinAddr); |
| 221 | 159 | ||
| @@ -224,4 +162,4 @@ int main() | |||
| 224 | aclFinalize(); | 162 | aclFinalize(); |
| 225 | 163 | ||
| 226 | return 0; | 164 | return 0; |
| 227 | -} | 165 | +} |
| @@ -185,18 +185,26 @@ main() { | |||
| 185 | fi | 185 | fi |
| 186 | 186 | ||
| 187 | compute_units=$(echo "$json_line" | awk ' | 187 | compute_units=$(echo "$json_line" | awk ' |
| 188 | - match($0, /"compute_units"[[:space:]]*:[[:space:]]*\[([^]]*)\]/, arr) { | 188 | + { |
| 189 | - str = arr[1] | 189 | + if (match($0, /"compute_units"[[:space:]]*:[[:space:]]*\[[^]]*\]/)) { |
| 190 | - gsub(/"/, "", str) | 190 | + str = substr($0, RSTART, RLENGTH) |
| 191 | - gsub(/^[[:space:]]+|[[:space:]]+$/, "", str) | 191 | + sub(/^"compute_units"[[:space:]]*:[[:space:]]*\[/, "", str) |
| 192 | - gsub(/,[[:space:]]*/, " ", str) | 192 | + sub(/\][[:space:]]*$/, "", str) |
| 193 | - print str | 193 | + gsub(/"/, "", str) |
| 194 | + gsub(/^[[:space:]]+|[[:space:]]+$/, "", str) | ||
| 195 | + gsub(/,[[:space:]]*/, " ", str) | ||
| 196 | + print str | ||
| 197 | + } | ||
| 194 | }') | 198 | }') |
| 195 | 199 | ||
| 196 | if [ -z "$compile_options" ]; then | 200 | if [ -z "$compile_options" ]; then |
| 197 | compile_options=$(echo "$json_line" | awk ' | 201 | compile_options=$(echo "$json_line" | awk ' |
| 198 | - match($0, /"compile_options"[[:space:]]*:[[:space:]]*(\{[^}]*\})/, arr) { | 202 | + { |
| 199 | - print arr[1] | 203 | + if (match($0, /"compile_options"[[:space:]]*:[[:space:]]*\{[^}]*\}/)) { |
| 204 | + s = substr($0, RSTART, RLENGTH) | ||
| 205 | + sub(/^"compile_options"[[:space:]]*:[[:space:]]*/, "", s) | ||
| 206 | + print s | ||
| 207 | + } | ||
| 200 | }') | 208 | }') |
| 201 | fi | 209 | fi |
| 202 | 210 | ||