| @@ -0,0 +1,204 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 3 | + * MindIE is licensed under Mulan PSL v2. | ||
| 4 | + * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 5 | + * You may obtain a copy of Mulan PSL v2 at: | ||
| 6 | + * http://license.coscl.org.cn/MulanPSL2 | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 8 | + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 9 | + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 10 | + * See the Mulan PSL v2 for more details. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +using namespace op; | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +extern "C" { | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +namespace { | ||
| 29 | +/** | ||
| 30 | + * @brief for acl graph calculates the max workspace size based on the specific calculation process. | ||
| 31 | + * declaration here for testcase to use by extern the interface | ||
| 32 | + * @domain aclnn_ops_infer | ||
| 33 | + */ | ||
| 34 | +__attribute__((visibility("default"))) aclnnStatus aclnnFusedInferAttentionScoreV4GetMaxWorkspaceSize( | ||
| 35 | + const aclTensor *query, const aclTensorList *tensorListKey, const aclTensorList *tensorListValue, | ||
| 36 | + const aclTensor *pseShiftOptional, const aclTensor *attenMaskOptional, const aclIntArray *actualSeqLengthsOptional, | ||
| 37 | + const aclIntArray *actualSeqLengthsKvOptional, const aclTensor *deqScale1Optional, | ||
| 38 | + const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, const aclTensor *quantScale2Optional, | ||
| 39 | + const aclTensor *quantOffset2Optional, const aclTensor *antiquantScaleOptional, | ||
| 40 | + const aclTensor *antiquantOffsetOptional, const aclTensor *blockTableOptional, | ||
| 41 | + const aclTensor *queryPaddingSizeOptional, const aclTensor *kvPaddingSizeOptional, | ||
| 42 | + const aclTensor *keyAntiquantScaleOptional, const aclTensor *keyAntiquantOffsetOptional, | ||
| 43 | + const aclTensor *valueAntiquantScaleOptional, const aclTensor *valueAntiquantOffsetOptional, | ||
| 44 | + const aclTensor *tensorKeySharedPrefixOptional, const aclTensor *tensorValueSharedPrefixOptional, | ||
| 45 | + const aclIntArray *actualSharedPrefixLenOptional, const aclTensor *queryRopeOptional, | ||
| 46 | + const aclTensor *keyRopeOptional, const aclTensor *keyRopeAntiquantScaleOptional, | ||
| 47 | + const aclTensor *dequantScaleQueryOptional, const aclTensor *learnableSinkOptional, int64_t numHeads, | ||
| 48 | + double scaleValue, int64_t preTokens, int64_t nextTokens, char *inputLayout, int64_t numKeyValueHeads, | ||
| 49 | + int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, bool softmaxLseFlag, | ||
| 50 | + int64_t keyAntiquantMode, int64_t valueAntiquantMode, int64_t queryQuantMode, const aclTensor *attentionOut, | ||
| 51 | + const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor); | ||
| 52 | + | ||
| 53 | +extern "C" aclnnStatus __attribute__((weak)) NnopbaseDisableOptionalInput(void *executor, const size_t irIndex); | ||
| 54 | + | ||
| 55 | +aclnnStatus aclnnFusedInferAttentionScoreV4GetMaxWorkspaceSize(const aclTensor *query, | ||
| 56 | + const aclTensorList *tensorListKey, const aclTensorList *tensorListValue, const aclTensor *pseShiftOptional, | ||
| 57 | + const aclTensor *attenMaskOptional, const aclIntArray *actualSeqLengthsOptional, | ||
| 58 | + const aclIntArray *actualSeqLengthsKvOptional, const aclTensor *deqScale1Optional, | ||
| 59 | + const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, const aclTensor *quantScale2Optional, | ||
| 60 | + const aclTensor *quantOffset2Optional, const aclTensor *antiquantScaleOptional, | ||
| 61 | + const aclTensor *antiquantOffsetOptional, const aclTensor *blockTableOptional, | ||
| 62 | + const aclTensor *queryPaddingSizeOptional, const aclTensor *kvPaddingSizeOptional, | ||
| 63 | + const aclTensor *keyAntiquantScaleOptional, const aclTensor *keyAntiquantOffsetOptional, | ||
| 64 | + const aclTensor *valueAntiquantScaleOptional, const aclTensor *valueAntiquantOffsetOptional, | ||
| 65 | + const aclTensor *tensorKeySharedPrefixOptional, const aclTensor *tensorValueSharedPrefixOptional, | ||
| 66 | + const aclIntArray *actualSharedPrefixLenOptional, const aclTensor *queryRopeOptional, | ||
| 67 | + const aclTensor *keyRopeOptional, const aclTensor *keyRopeAntiquantScaleOptional, | ||
| 68 | + const aclTensor *dequantScaleQueryOptional, const aclTensor *learnableSinkOptional, int64_t numHeads, | ||
| 69 | + double scaleValue, int64_t preTokens, int64_t nextTokens, char *inputLayout, int64_t numKeyValueHeads, | ||
| 70 | + int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, bool softmaxLseFlag, | ||
| 71 | + int64_t keyAntiquantMode, int64_t valueAntiquantMode, int64_t queryQuantMode, const aclTensor *attentionOut, | ||
| 72 | + const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor) { | ||
| 73 | + if (op::GetCurrentPlatformInfo().GetCurNpuArch() == NpuArch::DAV_3510) { | ||
| 74 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, | ||
| 75 | + "Interface aclnnFusedInferAttentionScore versions V1 to V4 are no longer supported on Ascend950."); | ||
| 76 | + return ACLNN_ERR_RUNTIME_ERROR; | ||
| 77 | + } | ||
| 78 | + OP_LOGD("start aclnnFusedInferAttentionScoreV4GetMaxWorkspaceSize"); | ||
| 79 | + TensorPreProcess(tensorListKey, tensorListValue); | ||
| 80 | + PrefixTensorPreProcess(tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional); | ||
| 81 | + | ||
| 82 | + aclTensor *fakeActualSeqLengthsOptional{nullptr}; | ||
| 83 | + aclTensor *fakeActualSeqLengthsKvOptional{nullptr}; | ||
| 84 | + aclTensor *fakeActualSharedPrefixLenOptional{nullptr}; | ||
| 85 | + | ||
| 86 | + // nullptr不处理, nullptr是空指针,这样不会影响原来就不传入actual seq length为空的逻辑 | ||
| 87 | + aclnnStatus ret = FakeArray(actualSeqLengthsOptional, fakeActualSeqLengthsOptional); | ||
| 88 | + CHECK_RET_CODE(ret, "Try alloc fake actualSeqLengthsOptional failed"); | ||
| 89 | + | ||
| 90 | + ret = FakeArray(actualSeqLengthsKvOptional, fakeActualSeqLengthsKvOptional); | ||
| 91 | + if (ret != ACLNN_SUCCESS) { | ||
| 92 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake actualSeqLengthsKvOptional failed"); | ||
| 93 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 94 | + return ret; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + ret = FakeArray(actualSharedPrefixLenOptional, fakeActualSharedPrefixLenOptional); | ||
| 98 | + if (ret != ACLNN_SUCCESS) { | ||
| 99 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake actualSharedPrefixLenOptional failed"); | ||
| 100 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 101 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 102 | + return ret; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + const aclTensor *placeHolder = nullptr; | ||
| 106 | + const aclTensor *tempTensor = nullptr; | ||
| 107 | + FusedInferAttentionScoreProcessSoftmaxLse(softmaxLseFlag, softmaxLse, tempTensor, placeHolder); | ||
| 108 | + | ||
| 109 | + ret = aclnnInnerEagleFusedInferAttentionScoreTensorGetWorkspaceSize(query, tensorListKey, tensorListValue, | ||
| 110 | + pseShiftOptional, attenMaskOptional, fakeActualSeqLengthsOptional, fakeActualSeqLengthsKvOptional, | ||
| 111 | + deqScale1Optional, quantScale1Optional, deqScale2Optional, quantScale2Optional, quantOffset2Optional, | ||
| 112 | + antiquantScaleOptional, antiquantOffsetOptional, blockTableOptional, queryPaddingSizeOptional, | ||
| 113 | + kvPaddingSizeOptional, keyAntiquantScaleOptional, keyAntiquantOffsetOptional, valueAntiquantScaleOptional, | ||
| 114 | + valueAntiquantOffsetOptional, tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional, | ||
| 115 | + fakeActualSharedPrefixLenOptional, queryRopeOptional, keyRopeOptional, keyRopeAntiquantScaleOptional, | ||
| 116 | + dequantScaleQueryOptional, learnableSinkOptional, nullptr, nullptr, numHeads, scaleValue, preTokens, nextTokens, | ||
| 117 | + inputLayout, numKeyValueHeads, sparseMode, innerPrecise, blockSize, antiquantMode, softmaxLseFlag, | ||
| 118 | + keyAntiquantMode, valueAntiquantMode, queryQuantMode, 0, 0, attentionOut, placeHolder, workspaceSize, executor); | ||
| 119 | + if (softmaxLseFlag == false) { | ||
| 120 | + aclDestroyTensor(tempTensor); | ||
| 121 | + } | ||
| 122 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 只会成功,无需校验 | ||
| 123 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 124 | + aclDestroyTensor(fakeActualSharedPrefixLenOptional); | ||
| 125 | + return ret; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +aclnnStatus aclnnFusedInferAttentionScoreV4GetWorkspaceSize(const aclTensor *query, const aclTensorList *key, | ||
| 129 | + const aclTensorList *value, const aclTensor *pseShiftOptional, const aclTensor *attenMaskOptional, | ||
| 130 | + const aclIntArray *actualSeqLengthsOptional, const aclIntArray *actualSeqLengthsKvOptional, | ||
| 131 | + const aclTensor *deqScale1Optional, const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, | ||
| 132 | + const aclTensor *quantScale2Optional, const aclTensor *quantOffset2Optional, | ||
| 133 | + const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, | ||
| 134 | + const aclTensor *blockTableOptional, const aclTensor *queryPaddingSizeOptional, | ||
| 135 | + const aclTensor *kvPaddingSizeOptional, const aclTensor *keyAntiquantScaleOptional, | ||
| 136 | + const aclTensor *keyAntiquantOffsetOptional, const aclTensor *valueAntiquantScaleOptional, | ||
| 137 | + const aclTensor *valueAntiquantOffsetOptional, const aclTensor *keySharedPrefixOptional, | ||
| 138 | + const aclTensor *valueSharedPrefixOptional, const aclIntArray *actualSharedPrefixLenOptional, | ||
| 139 | + const aclTensor *queryRopeOptional, const aclTensor *keyRopeOptional, | ||
| 140 | + const aclTensor *keyRopeAntiquantScaleOptional, const aclTensor *dequantScaleQueryOptional, | ||
| 141 | + const aclTensor *learnableSinkOptional, int64_t numHeads, double scaleValue, int64_t preTokens, int64_t nextTokens, | ||
| 142 | + char *inputLayout, int64_t numKeyValueHeads, int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, | ||
| 143 | + int64_t antiquantMode, bool softmaxLseFlag, int64_t keyAntiquantMode, int64_t valueAntiquantMode, | ||
| 144 | + int64_t queryQuantMode, const aclTensor *attentionOut, const aclTensor *softmaxLse, uint64_t *workspaceSize, | ||
| 145 | + aclOpExecutor **executor) { | ||
| 146 | + if (op::GetCurrentPlatformInfo().GetCurNpuArch() == NpuArch::DAV_3510) { | ||
| 147 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, | ||
| 148 | + "Interface aclnnFusedInferAttentionScore versions V1 to V4 are no longer supported on Ascend950."); | ||
| 149 | + return ACLNN_ERR_RUNTIME_ERROR; | ||
| 150 | + } | ||
| 151 | + const aclTensorList *tensorListKey = key; | ||
| 152 | + const aclTensorList *tensorListValue = value; | ||
| 153 | + TensorPreProcess(tensorListKey, tensorListValue); | ||
| 154 | + | ||
| 155 | + const aclTensor *tensorKeySharedPrefixOptional = keySharedPrefixOptional; | ||
| 156 | + const aclTensor *tensorValueSharedPrefixOptional = valueSharedPrefixOptional; | ||
| 157 | + PrefixTensorPreProcess(tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional); | ||
| 158 | + | ||
| 159 | + aclnnStatus ret = CheckKVContiguous(key, value); | ||
| 160 | + if (ret != ACLNN_SUCCESS && NnopbaseSupportTensorV2 == nullptr) { | ||
| 161 | + return ret; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + const aclTensor *placeHolder = nullptr; | ||
| 165 | + const aclTensor *tempTensor = nullptr; | ||
| 166 | + FusedInferAttentionScoreProcessSoftmaxLse(softmaxLseFlag, softmaxLse, tempTensor, placeHolder); | ||
| 167 | + | ||
| 168 | + ret = aclnnInnerEagleFusedInferAttentionScoreGetWorkspaceSize(query, tensorListKey, tensorListValue, | ||
| 169 | + pseShiftOptional, attenMaskOptional, actualSeqLengthsOptional, actualSeqLengthsKvOptional, deqScale1Optional, | ||
| 170 | + quantScale1Optional, deqScale2Optional, quantScale2Optional, quantOffset2Optional, antiquantScaleOptional, | ||
| 171 | + antiquantOffsetOptional, blockTableOptional, queryPaddingSizeOptional, kvPaddingSizeOptional, | ||
| 172 | + keyAntiquantScaleOptional, keyAntiquantOffsetOptional, valueAntiquantScaleOptional, | ||
| 173 | + valueAntiquantOffsetOptional, tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional, | ||
| 174 | + actualSharedPrefixLenOptional, queryRopeOptional, keyRopeOptional, keyRopeAntiquantScaleOptional, | ||
| 175 | + dequantScaleQueryOptional, learnableSinkOptional, nullptr, nullptr, numHeads, scaleValue, preTokens, nextTokens, | ||
| 176 | + inputLayout, numKeyValueHeads, sparseMode, innerPrecise, blockSize, antiquantMode, softmaxLseFlag, | ||
| 177 | + keyAntiquantMode, valueAntiquantMode, queryQuantMode, 0, 0, attentionOut, placeHolder, workspaceSize, executor); | ||
| 178 | + if (softmaxLseFlag == false) { | ||
| 179 | + aclDestroyTensor(tempTensor); | ||
| 180 | + } | ||
| 181 | + if (ret == 0) { | ||
| 182 | + if (NnopbaseDisableOptionalInput != nullptr) { | ||
| 183 | + NnopbaseDisableOptionalInput(*executor, 29U); // 29 is input irIndex,占位符 | ||
| 184 | + NnopbaseDisableOptionalInput(*executor, 30U); // 30 is input irIndex,占位符 | ||
| 185 | + } | ||
| 186 | + } | ||
| 187 | + return ret; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +aclnnStatus aclnnFusedInferAttentionScoreV4( | ||
| 191 | + void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, const aclrtStream stream) { | ||
| 192 | + if (op::GetCurrentPlatformInfo().GetCurNpuArch() == NpuArch::DAV_3510) { | ||
| 193 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, | ||
| 194 | + "Interface aclnnFusedInferAttentionScore versions V1 to V4 are no longer supported on Ascend950."); | ||
| 195 | + return ACLNN_ERR_RUNTIME_ERROR; | ||
| 196 | + } | ||
| 197 | + return aclnnInnerEagleFusedInferAttentionScore(workspace, workspaceSize, executor, stream); | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +} // namespace | ||
| 201 | + | ||
| 202 | + | ||
| 203 | +} | ||
| 204 | + | ||
| @@ -0,0 +1,54 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 3 | + * MindIE is licensed under Mulan PSL v2. | ||
| 4 | + * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 5 | + * You may obtain a copy of Mulan PSL v2 at: | ||
| 6 | + * http://license.coscl.org.cn/MulanPSL2 | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 8 | + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 9 | + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 10 | + * See the Mulan PSL v2 for more details. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +extern "C" { | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * @brief The first interface of aclnnFusedInferAttentionScoreV4 calculates the workspace size based on the specific calculation process. | ||
| 23 | + * @domain aclnn_ops_infer | ||
| 24 | + */ | ||
| 25 | +__attribute__((visibility("default"))) aclnnStatus aclnnFusedInferAttentionScoreV4GetWorkspaceSize( | ||
| 26 | + const aclTensor *query, const aclTensorList *key, const aclTensorList *value, const aclTensor *pseShiftOptional, | ||
| 27 | + const aclTensor *attenMaskOptional, const aclIntArray *actualSeqLengthsOptional, | ||
| 28 | + const aclIntArray *actualSeqLengthsKvOptional, const aclTensor *deqScale1Optional, | ||
| 29 | + const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, const aclTensor *quantScale2Optional, | ||
| 30 | + const aclTensor *quantOffset2Optional, const aclTensor *antiquantScaleOptional, | ||
| 31 | + const aclTensor *antiquantOffsetOptional, const aclTensor *blockTableOptional, | ||
| 32 | + const aclTensor *queryPaddingSizeOptional, const aclTensor *kvPaddingSizeOptional, | ||
| 33 | + const aclTensor *keyAntiquantScaleOptional, const aclTensor *keyAntiquantOffsetOptional, | ||
| 34 | + const aclTensor *valueAntiquantScaleOptional, const aclTensor *valueAntiquantOffsetOptional, | ||
| 35 | + const aclTensor *keySharedPrefixOptional, const aclTensor *valueSharedPrefixOptional, | ||
| 36 | + const aclIntArray *actualSharedPrefixLenOptional, const aclTensor *queryRopeOptional, | ||
| 37 | + const aclTensor *keyRopeOptional, const aclTensor *keyRopeAntiquantScaleOptional, | ||
| 38 | + const aclTensor *dequantScaleQueryOptional, const aclTensor *learnableSinkOptional, int64_t numHeads, | ||
| 39 | + double scaleValue, int64_t preTokens, int64_t nextTokens, char *inputLayout, int64_t numKeyValueHeads, | ||
| 40 | + int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, bool softmaxLseFlag, | ||
| 41 | + int64_t keyAntiquantMode, int64_t valueAntiquantMode, int64_t queryQuantMode, const aclTensor *attentionOut, | ||
| 42 | + const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor); | ||
| 43 | + | ||
| 44 | +/** | ||
| 45 | + * @brief The second interface of aclnnFusedInferAttentionScoreV4 is used to perform calculations. | ||
| 46 | + */ | ||
| 47 | +__attribute__((visibility("default"))) aclnnStatus aclnnFusedInferAttentionScoreV4( | ||
| 48 | + void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, const aclrtStream stream); | ||
| 49 | + | ||
| 50 | + | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | + | ||
| 54 | + | ||
| @@ -0,0 +1,250 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 3 | + * MindIE is licensed under Mulan PSL v2. | ||
| 4 | + * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 5 | + * You may obtain a copy of Mulan PSL v2 at: | ||
| 6 | + * http://license.coscl.org.cn/MulanPSL2 | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 8 | + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 9 | + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 10 | + * See the Mulan PSL v2 for more details. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
🔴 Critical aclnn_fused_infer_attention_score_v5.cpp 第 13 行和 fallback_fused_infer_attention_score.cpp 第 22 行均 #include "aclnn_fused_infer_attention_score_v5.h",但该头文件在整个仓库中不存在(glob 搜索无结果)。PR 描述中也明确注明 v5 "未引入头文件",然而 .cpp 文件又引用了它,这是一个矛盾。没有该头文件,编译必定失败——v5.cpp 中定义的对外 API 函数(如 aclnnEagleFusedInferAttentionScoreV5、aclnnEagleFusedInferAttentionScoreV5GetWorkspaceSize 等)的外部调用者(包括 fallback.cpp 中的 EXEC_OPAPI_CMD 宏需要通过函数指针调用 GetWorkspaceSize 和执行函数)无法找到声明。类比 v4 版本,v4.h 提供了对应的公开声明,v5 需要同等的头文件。 建议:参照 aclnn_fused_infer_attention_score_v4.h 的模式,创建 aclnn_fused_infer_attention_score_v5.h,在其中声明 aclnnEagleFusedInferAttentionScoreV5、aclnnEagleFusedInferAttentionScoreV5GetWorkspaceSize、CheckTensorContiguous、NnopbaseSupportTensorV2 等公开符号。同时确保该头文件被 v5.cpp 和 fallback_fused_infer_attention_score.cpp 正确包含。 ![]() ![]() | |||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +using namespace op; | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +extern "C" { | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * @brief for acl graph calculates the max workspace size based on the specific calculation process. | ||
| 31 | + * declaration here for testcase to use by extern the interface | ||
| 32 | + * @domain aclnn_ops_infer | ||
| 33 | + */ | ||
| 34 | +__attribute__((visibility("default"))) aclnnStatus aclnnEagleFusedInferAttentionScoreV5GetMaxWorkspaceSize( | ||
| 35 | + const aclTensor *query, const aclTensorList *key, const aclTensorList *value, const aclTensor *pseShiftOptional, | ||
| 36 | + const aclTensor *attenMaskOptional, const aclIntArray *actualSeqLengthsOptional, | ||
| 37 | + const aclIntArray *actualSeqLengthsKvOptional, const aclTensor *deqScale1Optional, | ||
| 38 | + const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, const aclTensor *quantScale2Optional, | ||
| 39 | + const aclTensor *quantOffset2Optional, const aclTensor *antiquantScaleOptional, | ||
| 40 | + const aclTensor *antiquantOffsetOptional, const aclTensor *blockTableOptional, | ||
| 41 | + const aclTensor *queryPaddingSizeOptional, const aclTensor *kvPaddingSizeOptional, | ||
| 42 | + const aclTensor *keyAntiquantScaleOptional, const aclTensor *keyAntiquantOffsetOptional, | ||
| 43 | + const aclTensor *valueAntiquantScaleOptional, const aclTensor *valueAntiquantOffsetOptional, | ||
| 44 | + const aclTensor *keySharedPrefixOptional, const aclTensor *valueSharedPrefixOptional, | ||
| 45 | + const aclIntArray *actualSharedPrefixLenOptional, const aclTensor *queryRopeOptional, | ||
| 46 | + const aclTensor *keyRopeOptional, const aclTensor *keyRopeAntiquantScaleOptional, | ||
| 47 | + const aclTensor *dequantScaleQueryOptional, const aclTensor *learnableSinkOptional, | ||
| 48 | + const aclIntArray *qStartIdxOptional, const aclIntArray *kvStartIdxOptional, int64_t numHeads, double scaleValue, | ||
| 49 | + int64_t preTokens, int64_t nextTokens, char *inputLayout, int64_t numKeyValueHeads, int64_t sparseMode, | ||
| 50 | + int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, bool softmaxLseFlag, int64_t keyAntiquantMode, | ||
| 51 | + int64_t valueAntiquantMode, int64_t queryQuantMode, int64_t pseType, const aclTensor *attentionOut, | ||
| 52 | + const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor); | ||
| 53 | + | ||
| 54 | +__attribute__((visibility("default"))) aclnnStatus CheckTensorContiguous(const aclTensorList *key, | ||
| 55 | + const aclTensorList *value, const aclTensor *keyAntiquantScaleOptional, | ||
| 56 | + const aclTensor *valueAntiquantScaleOptional, const aclTensor *keyRopeOptional); | ||
| 57 | + | ||
| 58 | +// 新版本opbase存在TensorV2的新接口,用弱符号判断当前opbase是新版本还是旧版本,旧版本不支持传入非连续tensor | ||
| 59 | +bool NnopbaseSupportTensorV2() __attribute__((weak)); | ||
| 60 | + | ||
| 61 | +aclnnStatus aclnnEagleFusedInferAttentionScoreV5GetMaxWorkspaceSize(const aclTensor *query, const aclTensorList *key, | ||
| 62 | + const aclTensorList *value, const aclTensor *pseShiftOptional, const aclTensor *attenMaskOptional, | ||
| 63 | + const aclIntArray *actualSeqLengthsOptional, const aclIntArray *actualSeqLengthsKvOptional, | ||
| 64 | + const aclTensor *deqScale1Optional, const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, | ||
| 65 | + const aclTensor *quantScale2Optional, const aclTensor *quantOffset2Optional, | ||
| 66 | + const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, | ||
| 67 | + const aclTensor *blockTableOptional, const aclTensor *queryPaddingSizeOptional, | ||
| 68 | + const aclTensor *kvPaddingSizeOptional, const aclTensor *keyAntiquantScaleOptional, | ||
| 69 | + const aclTensor *keyAntiquantOffsetOptional, const aclTensor *valueAntiquantScaleOptional, | ||
| 70 | + const aclTensor *valueAntiquantOffsetOptional, const aclTensor *keySharedPrefixOptional, | ||
| 71 | + const aclTensor *valueSharedPrefixOptional, const aclIntArray *actualSharedPrefixLenOptional, | ||
| 72 | + const aclTensor *queryRopeOptional, const aclTensor *keyRopeOptional, | ||
| 73 | + const aclTensor *keyRopeAntiquantScaleOptional, const aclTensor *dequantScaleQueryOptional, | ||
| 74 | + const aclTensor *learnableSinkOptional, const aclIntArray *qStartIdxOptional, const aclIntArray *kvStartIdxOptional, | ||
| 75 | + int64_t numHeads, double scaleValue, int64_t preTokens, int64_t nextTokens, char *inputLayout, | ||
| 76 | + int64_t numKeyValueHeads, int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, | ||
| 77 | + bool softmaxLseFlag, int64_t keyAntiquantMode, int64_t valueAntiquantMode, int64_t queryQuantMode, int64_t pseType, | ||
| 78 | + const aclTensor *attentionOut, const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor) { | ||
| 79 | + OP_LOGD("start aclnnEagleFusedInferAttentionScoreV5GetMaxWorkspaceSize"); | ||
| 80 | + const aclTensorList *tensorListKey = key; | ||
| 81 | + const aclTensorList *tensorListValue = value; | ||
| 82 | + TensorPreProcess(tensorListKey, tensorListValue); | ||
| 83 | + | ||
| 84 | + const aclTensor *tensorKeySharedPrefixOptional = keySharedPrefixOptional; | ||
| 85 | + const aclTensor *tensorValueSharedPrefixOptional = valueSharedPrefixOptional; | ||
| 86 | + PrefixTensorPreProcess(tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional); | ||
| 87 | + | ||
| 88 | + aclTensor *fakeActualSeqLengthsOptional{nullptr}; | ||
| 89 | + aclTensor *fakeActualSeqLengthsKvOptional{nullptr}; | ||
| 90 | + aclTensor *fakeActualSharedPrefixLenOptional{nullptr}; | ||
| 91 | + aclTensor *fakeQStartIdxOptional{nullptr}; | ||
| 92 | + aclTensor *fakeKVStartIdxOptional{nullptr}; | ||
| 93 | + | ||
| 94 | + // nullptr不处理, nullptr是空指针,这样不会影响原来就不传入actual seq length为空的逻辑 | ||
| 95 | + aclnnStatus ret = FakeArray(actualSeqLengthsOptional, fakeActualSeqLengthsOptional); | ||
| 96 | + CHECK_RET_CODE(ret, "Try alloc fake actualSeqLengthsOptional failed"); | ||
| 97 | + | ||
| 98 | + ret = FakeArray(actualSeqLengthsKvOptional, fakeActualSeqLengthsKvOptional); | ||
| 99 | + if (ret != ACLNN_SUCCESS) { | ||
| 100 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake actualSeqLengthsKvOptional failed"); | ||
| 101 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 102 | + return ret; | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + ret = FakeArray(actualSharedPrefixLenOptional, fakeActualSharedPrefixLenOptional); | ||
| 106 | + if (ret != ACLNN_SUCCESS) { | ||
| 107 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake actualSharedPrefixLenOptional failed"); | ||
| 108 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 109 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 110 | + return ret; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + ret = FakeArray(qStartIdxOptional, fakeQStartIdxOptional); | ||
| 114 | + if (ret != ACLNN_SUCCESS) { | ||
| 115 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake qStartIdxOptional failed"); | ||
| 116 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 117 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 118 | + aclDestroyTensor(fakeActualSharedPrefixLenOptional); | ||
| 119 | + return ret; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + ret = FakeArray(kvStartIdxOptional, fakeKVStartIdxOptional); | ||
| 123 | + if (ret != ACLNN_SUCCESS) { | ||
| 124 | + OP_LOGE(ACLNN_ERR_INNER_NULLPTR, "Try alloc fake kvStartIdxOptional failed"); | ||
| 125 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 没有返回值无需校验 | ||
| 126 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 127 | + aclDestroyTensor(fakeActualSharedPrefixLenOptional); | ||
| 128 | + aclDestroyTensor(fakeQStartIdxOptional); | ||
| 129 | + return ret; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + const aclTensor *placeHolder = nullptr; | ||
| 133 | + const aclTensor *tempTensor = nullptr; | ||
| 134 | + if (softmaxLseFlag == false) { | ||
| 135 | + std::vector<int64_t> shape = {0}; | ||
| 136 | + int64_t addr = 0xff; | ||
| 137 | + tempTensor = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT, shape.data(), 0, ACL_FORMAT_ND, | ||
| 138 | + shape.data(), shape.size(), static_cast<void *>(&addr)); | ||
| 139 | + placeHolder = tempTensor; | ||
| 140 | + } else { | ||
| 141 | + placeHolder = softmaxLse; | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + ret = aclnnInnerEagleFusedInferAttentionScoreTensorGetWorkspaceSize(query, tensorListKey, tensorListValue, | ||
| 145 | + pseShiftOptional, attenMaskOptional, fakeActualSeqLengthsOptional, fakeActualSeqLengthsKvOptional, | ||
| 146 | + deqScale1Optional, quantScale1Optional, deqScale2Optional, quantScale2Optional, quantOffset2Optional, | ||
| 147 | + antiquantScaleOptional, antiquantOffsetOptional, blockTableOptional, queryPaddingSizeOptional, | ||
| 148 | + kvPaddingSizeOptional, keyAntiquantScaleOptional, keyAntiquantOffsetOptional, valueAntiquantScaleOptional, | ||
| 149 | + valueAntiquantOffsetOptional, tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional, | ||
| 150 | + fakeActualSharedPrefixLenOptional, queryRopeOptional, keyRopeOptional, keyRopeAntiquantScaleOptional, | ||
| 151 | + dequantScaleQueryOptional, learnableSinkOptional, fakeQStartIdxOptional, fakeKVStartIdxOptional, numHeads, | ||
| 152 | + scaleValue, preTokens, nextTokens, inputLayout, numKeyValueHeads, sparseMode, innerPrecise, blockSize, | ||
| 153 | + antiquantMode, softmaxLseFlag, keyAntiquantMode, valueAntiquantMode, queryQuantMode, pseType, 0, attentionOut, | ||
| 154 | + placeHolder, workspaceSize, executor); | ||
| 155 | + if (softmaxLseFlag == false) { | ||
| 156 | + aclDestroyTensor(tempTensor); | ||
| 157 | + } | ||
| 158 | + aclDestroyTensor(fakeActualSeqLengthsOptional); // 只会成功,无需校验 | ||
| 159 | + aclDestroyTensor(fakeActualSeqLengthsKvOptional); | ||
| 160 | + aclDestroyTensor(fakeActualSharedPrefixLenOptional); | ||
| 161 | + aclDestroyTensor(fakeQStartIdxOptional); | ||
| 162 | + aclDestroyTensor(fakeKVStartIdxOptional); | ||
| 163 | + return ret; | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +aclnnStatus CheckTensorContiguous(const aclTensorList *key, const aclTensorList *value, | ||
| 167 | + const aclTensor *keyAntiquantScaleOptional, const aclTensor *valueAntiquantScaleOptional, | ||
| 168 | + const aclTensor *keyRopeOptional) { | ||
| 169 | + if (!IsContiguous((*key)[0]) || !IsContiguous((*value)[0])) { | ||
🟡 Medium Priority aclnn_fused_infer_attention_score_v5.cpp 第 193 行,CheckTensorContiguous 函数中直接执行 建议:在解引用 key/value 之前增加空指针检查,若 key 或 value 为 nullptr 则直接返回 ACLNN_ERR_INNER_NULLPTR 或等价错误码。 ![]() ![]() | |||
| 170 | + return ACLNN_ERR_INNER_TILING_ERROR; | ||
| 171 | + } | ||
| 172 | + if (keyRopeOptional != nullptr && !IsContiguous(keyRopeOptional)) { | ||
| 173 | + return ACLNN_ERR_INNER_TILING_ERROR; | ||
| 174 | + } | ||
| 175 | + if ((keyAntiquantScaleOptional != nullptr && !IsContiguous(keyAntiquantScaleOptional)) || | ||
| 176 | + (valueAntiquantScaleOptional != nullptr && !IsContiguous(valueAntiquantScaleOptional))) { | ||
| 177 | + return ACLNN_ERR_INNER_TILING_ERROR; | ||
| 178 | + } | ||
| 179 | + return ACLNN_SUCCESS; | ||
| 180 | +} | ||
| 181 | + | ||
| 182 | +aclnnStatus aclnnEagleFusedInferAttentionScoreV5GetWorkspaceSize(const aclTensor *query, const aclTensorList *key, | ||
| 183 | + const aclTensorList *value, const aclTensor *pseShiftOptional, const aclTensor *attenMaskOptional, | ||
| 184 | + const aclIntArray *actualSeqLengthsOptional, const aclIntArray *actualSeqLengthsKvOptional, | ||
| 185 | + const aclTensor *deqScale1Optional, const aclTensor *quantScale1Optional, const aclTensor *deqScale2Optional, | ||
| 186 | + const aclTensor *quantScale2Optional, const aclTensor *quantOffset2Optional, | ||
| 187 | + const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, | ||
| 188 | + const aclTensor *blockTableOptional, const aclTensor *queryPaddingSizeOptional, | ||
| 189 | + const aclTensor *kvPaddingSizeOptional, const aclTensor *keyAntiquantScaleOptional, | ||
| 190 | + const aclTensor *keyAntiquantOffsetOptional, const aclTensor *valueAntiquantScaleOptional, | ||
| 191 | + const aclTensor *valueAntiquantOffsetOptional, const aclTensor *keySharedPrefixOptional, | ||
| 192 | + const aclTensor *valueSharedPrefixOptional, const aclIntArray *actualSharedPrefixLenOptional, | ||
| 193 | + const aclTensor *queryRopeOptional, const aclTensor *keyRopeOptional, | ||
| 194 | + const aclTensor *keyRopeAntiquantScaleOptional, const aclTensor *dequantScaleQueryOptional, | ||
| 195 | + const aclTensor *learnableSinkOptional, const aclIntArray *qStartIdxOptional, const aclIntArray *kvStartIdxOptional, | ||
| 196 | + int64_t numHeads, double scaleValue, int64_t preTokens, int64_t nextTokens, char *inputLayout, | ||
| 197 | + int64_t numKeyValueHeads, int64_t sparseMode, int64_t innerPrecise, int64_t blockSize, int64_t antiquantMode, | ||
| 198 | + bool softmaxLseFlag, int64_t keyAntiquantMode, int64_t valueAntiquantMode, int64_t queryQuantMode, int64_t pseType, | ||
| 199 | + const aclTensor *attentionOut, const aclTensor *softmaxLse, uint64_t *workspaceSize, aclOpExecutor **executor) { | ||
| 200 | + const aclTensorList *tensorListKey = key; | ||
| 201 | + const aclTensorList *tensorListValue = value; | ||
| 202 | + TensorPreProcess(tensorListKey, tensorListValue); | ||
| 203 | + | ||
| 204 | + const aclTensor *tensorKeySharedPrefixOptional = keySharedPrefixOptional; | ||
| 205 | + const aclTensor *tensorValueSharedPrefixOptional = valueSharedPrefixOptional; | ||
| 206 | + PrefixTensorPreProcess(tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional); | ||
| 207 | + | ||
| 208 | + aclnnStatus ret = | ||
| 209 | + CheckTensorContiguous(key, value, keyAntiquantScaleOptional, valueAntiquantScaleOptional, keyRopeOptional); | ||
| 210 | + if (ret != ACLNN_SUCCESS && NnopbaseSupportTensorV2 == nullptr) { | ||
| 211 | + OP_LOGE(ACLNN_ERR_INNER_TILING_ERROR, "When tensor is not contiguous, opbase package version check failed"); | ||
| 212 | + return ret; | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + const aclTensor *placeHolder = nullptr; | ||
| 216 | + const aclTensor *tempTensor = nullptr; | ||
| 217 | + if (softmaxLseFlag == false) { | ||
| 218 | + std::vector<int64_t> shape = {0}; | ||
| 219 | + int64_t addr = 0xff; | ||
| 220 | + tempTensor = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT, shape.data(), 0, ACL_FORMAT_ND, | ||
| 221 | + shape.data(), shape.size(), static_cast<void *>(&addr)); | ||
| 222 | + placeHolder = tempTensor; | ||
| 223 | + } else { | ||
| 224 | + placeHolder = softmaxLse; | ||
| 225 | + } | ||
| 226 | + ret = aclnnInnerEagleFusedInferAttentionScoreGetWorkspaceSize(query, tensorListKey, tensorListValue, | ||
| 227 | + pseShiftOptional, attenMaskOptional, actualSeqLengthsOptional, actualSeqLengthsKvOptional, deqScale1Optional, | ||
| 228 | + quantScale1Optional, deqScale2Optional, quantScale2Optional, quantOffset2Optional, antiquantScaleOptional, | ||
| 229 | + antiquantOffsetOptional, blockTableOptional, queryPaddingSizeOptional, kvPaddingSizeOptional, | ||
| 230 | + keyAntiquantScaleOptional, keyAntiquantOffsetOptional, valueAntiquantScaleOptional, | ||
| 231 | + valueAntiquantOffsetOptional, tensorKeySharedPrefixOptional, tensorValueSharedPrefixOptional, | ||
| 232 | + actualSharedPrefixLenOptional, queryRopeOptional, keyRopeOptional, keyRopeAntiquantScaleOptional, | ||
| 233 | + dequantScaleQueryOptional, learnableSinkOptional, qStartIdxOptional, kvStartIdxOptional, numHeads, scaleValue, | ||
| 234 | + preTokens, nextTokens, inputLayout, numKeyValueHeads, sparseMode, innerPrecise, blockSize, antiquantMode, | ||
| 235 | + softmaxLseFlag, keyAntiquantMode, valueAntiquantMode, queryQuantMode, pseType, 0, attentionOut, placeHolder, | ||
| 236 | + workspaceSize, executor); | ||
| 237 | + if (softmaxLseFlag == false) { | ||
| 238 | + aclDestroyTensor(tempTensor); | ||
| 239 | + } | ||
| 240 | + return ret; | ||
| 241 | +} | ||
| 242 | + | ||
| 243 | +aclnnStatus aclnnEagleFusedInferAttentionScoreV5( | ||
| 244 | + void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, const aclrtStream stream) { | ||
| 245 | + return aclnnInnerEagleFusedInferAttentionScore(workspace, workspaceSize, executor, stream); | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | + | ||
| 249 | +} | ||
| 250 | + | ||
| @@ -0,0 +1,39 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 3 | + * MindIE is licensed under Mulan PSL v2. | ||
| 4 | + * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 5 | + * You may obtain a copy of Mulan PSL v2 at: | ||
| 6 | + * http://license.coscl.org.cn/MulanPSL2 | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 8 | + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 9 | + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 10 | + * See the Mulan PSL v2 for more details. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +extern "C" { | ||
| 21 | + | ||
| 22 | + | ||
| 23 | +void TensorPreProcess(const aclTensorList *&tensorListKey, const aclTensorList *&tensorListValue); | ||
| 24 | +void PrefixTensorPreProcess(const aclTensor *&tensorKey, const aclTensor *&tensorValue); | ||
| 25 | +aclnnStatus FakeArray(const aclIntArray *inArray, aclTensor *&outArray); | ||
| 26 | + | ||
| 27 | +void FusedInferAttentionScoreProcessSoftmaxLse( | ||
| 28 | + bool softmaxLseFlag, const aclTensor *softmaxLse, const aclTensor *&tempTensor, const aclTensor *&placeHolder); | ||
| 29 | + | ||
| 30 | +aclnnStatus CheckKVContiguous(const aclTensorList *key, const aclTensorList *value); | ||
| 31 | + | ||
| 32 | +// 新版本opbase存在TensorV2的新接口,用弱符号判断当前opbase是新版本还是旧版本,旧版本不支持传入非连续tensor | ||
| 33 | +bool NnopbaseSupportTensorV2() __attribute__((weak)); | ||
| 34 | + | ||
| 35 | + | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| @@ -0,0 +1,13 @@ | |||
| 1 | +# Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 2 | +# MindIE is licensed under Mulan PSL v2. | ||
| 3 | +# You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 4 | +# You may obtain a copy of Mulan PSL v2 at: | ||
| 5 | +# http://license.coscl.org.cn/MulanPSL2 | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 7 | +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 8 | +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 9 | +# See the Mulan PSL v2 for more details. | ||
| 10 | + | ||
| 11 | +if (BUILD_OPEN_PROJECT) | ||
| 12 | + add_graph_plugin_sources() | ||
| 13 | +endif() | ||
| @@ -0,0 +1,355 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved. | ||
| 3 | + * MindIE is licensed under Mulan PSL v2. | ||
| 4 | + * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 5 | + * You may obtain a copy of Mulan PSL v2 at: | ||
| 6 | + * http://license.coscl.org.cn/MulanPSL2 | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 8 | + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 9 | + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 10 | + * See the Mulan PSL v2 for more details. | ||
| 11 | + */ | ||
| 12 | + | ||
| 13 | +/*! | ||
| 14 | + * \file fallback_fused_infer_attention_score.cpp | ||
| 15 | + * \brief | ||
| 16 | + */ | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +extern "C" { | ||
| 26 | + | ||
| 27 | +namespace fallback { | ||
| 28 | + | ||
| 29 | +using namespace ge; | ||
| 30 | +using namespace gert; | ||
| 31 | +static const size_t QUERY_INDEX = 0; | ||
| 32 | +static const size_t KEY_INDEX = 1; | ||
| 33 | +static const size_t VALUE_INDEX = 2; | ||
| 34 | +static const size_t PSE_SHIFT_INDEX = 3; | ||
| 35 | +static const size_t ATTEN_MASK_INDEX = 4; | ||
| 36 | +static const size_t ACTUAL_SEQ_Q_INDEX = 5; | ||
| 37 | +static const size_t ACTUAL_SEQ_KV_INDEX = 6; | ||
| 38 | +static const size_t DEQUANT_SCALE1_INDEX = 7; | ||
| 39 | +static const size_t QUANT_SCALE1_INDEX = 8; | ||
| 40 | +static const size_t DEQUANT_SCALE2_INDEX = 9; | ||
| 41 | +static const size_t QUANT_SCALE2_INDEX = 10; | ||
| 42 | +static const size_t QUANT_OFFSET2_INDEX = 11; | ||
| 43 | +static const size_t ANTIQUANT_SCALE_INDEX = 12; | ||
| 44 | +static const size_t ANTIQUANT_OFFSET_INDEX = 13; | ||
| 45 | +static const size_t BLOCK_TABLE_INDEX = 14; | ||
| 46 | +static const size_t QUERY_PADDING_INDEX = 15; | ||
| 47 | +static const size_t KV_PADDING_INDEX = 16; | ||
| 48 | +static const size_t KEY_ANTIQUANT_SCALE_INDEX = 17; | ||
| 49 | +static const size_t KEY_ANTIQUANT_OFFSET_INDEX = 18; | ||
| 50 | +static const size_t VALUE_ANTIQUANT_SCALE_INDEX = 19; | ||
| 51 | +static const size_t VALUE_ANTIQUANT_OFFSET_INDEX = 20; | ||
| 52 | +static const size_t KEY_SHARED_PREFIX_INDEX = 21; | ||
| 53 | +static const size_t VALUE_SHARED_PREFIX_INDEX = 22; | ||
| 54 | +static const size_t ACTUAL_SHARED_PREFIX_LEN_INDEX = 23; | ||
| 55 | +static const size_t QUERY_ROPE_INDEX = 24; | ||
| 56 | +static const size_t KEY_ROPE_INDEX = 25; | ||
| 57 | +static const size_t KEY_ROPE_ANTIQUANT_SCALE_INDEX = 26; | ||
| 58 | +static const size_t DEQUANT_SCALE_QUERY_INDEX = 27; | ||
| 59 | +static const size_t LEARNABLE_SINK_INDEX = 28; | ||
| 60 | + | ||
| 61 | +static const size_t ATTR_N_INDEX = 0; | ||
| 62 | +static const size_t ATTR_SCALE_INDEX = 1; | ||
| 63 | +static const size_t ATTR_PRE_TOKEN_INDEX = 2; | ||
| 64 | +static const size_t ATTR_NEXT_TOKEN_INDEX = 3; | ||
| 65 | +static const size_t ATTR_INPUT_LAYOUT_INDEX = 4; | ||
| 66 | +static const size_t ATTR_NUM_KV_HEADS_INDEX = 5; | ||
| 67 | +static const size_t ATTR_SPARSE_MODE_INDEX = 6; | ||
| 68 | +static const size_t ATTR_INNER_PRECISE_INDEX = 7; | ||
| 69 | +static const size_t ATTR_BLOCK_SIZE_INDEX = 8; | ||
| 70 | +static const size_t ATTR_ANTIQUANT_MODE_INDEX = 9; | ||
| 71 | +static const size_t ATTR_SOFTMAX_LSE_FLAG_INDEX = 10; | ||
| 72 | +static const size_t ATTR_KEY_ANTIQUANT_MODE_INDEX = 11; | ||
| 73 | +static const size_t ATTR_VALUE_ANTIQUANT_MODE_INDEX = 12; | ||
| 74 | +static const size_t ATTR_QUERY_QUANT_MODE_INDEX = 13; | ||
| 75 | +static const size_t ATTR_PSE_TYPE_INDEX = 14; | ||
| 76 | + | ||
| 77 | +static const size_t ATTENTION_OUT_INDEX = 0; | ||
| 78 | +static const size_t SOFTMAX_LSE_INDEX = 1; | ||
| 79 | + | ||
| 80 | +static constexpr int64_t SPARSE_MODE_INT_MAX = 2147483647; | ||
| 81 | + | ||
| 82 | +struct FusedInferHostTensorParams { | ||
| 83 | + const gert::Tensor *query = nullptr; | ||
| 84 | + const gert::Tensor *key = nullptr; | ||
| 85 | + const gert::Tensor *value = nullptr; | ||
| 86 | + const gert::Tensor *output = nullptr; | ||
| 87 | + const gert::Tensor *softmaxLse = nullptr; | ||
| 88 | + const gert::Tensor *pseShiftGe = nullptr; | ||
| 89 | + const gert::Tensor *attenMaskGe = nullptr; | ||
| 90 | + const gert::Tensor *actualSeqLengthsGe = nullptr; | ||
| 91 | + const gert::Tensor *actualSeqLengthsGeKv = nullptr; | ||
| 92 | + const gert::Tensor *deqScale1 = nullptr; | ||
| 93 | + const gert::Tensor *quantScale1 = nullptr; | ||
| 94 | + const gert::Tensor *deqScale2 = nullptr; | ||
| 95 | + const gert::Tensor *quantScale2 = nullptr; | ||
| 96 | + const gert::Tensor *quantOffset2 = nullptr; | ||
| 97 | + const gert::Tensor *antiquantScaleGe = nullptr; | ||
| 98 | + const gert::Tensor *antiquantOffsetGe = nullptr; | ||
| 99 | + const gert::Tensor *blocktableGe = nullptr; | ||
| 100 | + const gert::Tensor *queryPaddingGe = nullptr; | ||
| 101 | + const gert::Tensor *kvPaddingGe = nullptr; | ||
| 102 | + const gert::Tensor *keyAntiquantScaleGe = nullptr; | ||
| 103 | + const gert::Tensor *keyAntiquantOffsetGe = nullptr; | ||
| 104 | + const gert::Tensor *valueAntiquantScaleGe = nullptr; | ||
| 105 | + const gert::Tensor *valueAntiquantOffsetGe = nullptr; | ||
| 106 | + const gert::Tensor *keySharedPrefixGe = nullptr; | ||
| 107 | + const gert::Tensor *valueSharedPrefixGe = nullptr; | ||
| 108 | + const gert::Tensor *actualSharedPrefixLenGe = nullptr; | ||
| 109 | + const gert::Tensor *queryRopeGe = nullptr; | ||
| 110 | + const gert::Tensor *keyRopeGe = nullptr; | ||
| 111 | + const gert::Tensor *keyRopeAntiquantScaleGe = nullptr; | ||
| 112 | + const gert::Tensor *dequantScaleQueryGe = nullptr; | ||
| 113 | + const gert::Tensor *learnableSinkGe = nullptr; | ||
| 114 | + const gert::Tensor *qStartIdx = nullptr; // not supported in Pytorch interfaces, default nullptr | ||
| 115 | + const gert::Tensor *kvStartIdx = nullptr; // not supported in Pytorch interfaces, default nullptr | ||
| 116 | +}; | ||
| 117 | + | ||
| 118 | +static graphStatus FiaFillTensorParams(const OpExecuteContext *host_api_ctx, FusedInferHostTensorParams &fiaTensors) { | ||
| 119 | + fiaTensors.query = host_api_ctx->GetInputTensor(QUERY_INDEX); | ||
| 120 | + if (fiaTensors.query == nullptr) { | ||
| 121 | + OP_LOGE_WITH_INVALID_INPUT(host_api_ctx->GetNodeName(), "query"); | ||
| 122 | + return GRAPH_FAILED; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + fiaTensors.key = host_api_ctx->GetDynamicInputTensor(KEY_INDEX, 0); | ||
| 126 | + if (fiaTensors.key == nullptr) { | ||
| 127 | + OP_LOGE_WITH_INVALID_INPUT(host_api_ctx->GetNodeName(), "key"); | ||
| 128 | + return GRAPH_FAILED; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + fiaTensors.value = host_api_ctx->GetDynamicInputTensor(VALUE_INDEX, 0); | ||
| 132 | + if (fiaTensors.value == nullptr) { | ||
| 133 | + OP_LOGE_WITH_INVALID_INPUT(host_api_ctx->GetNodeName(), "value"); | ||
| 134 | + return GRAPH_FAILED; | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + fiaTensors.output = host_api_ctx->GetOutputTensor(ATTENTION_OUT_INDEX); | ||
| 138 | + if (fiaTensors.output == nullptr) { | ||
| 139 | + OP_LOGE_WITH_INVALID_INPUT(host_api_ctx->GetNodeName(), "output"); | ||
| 140 | + return GRAPH_FAILED; | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + fiaTensors.softmaxLse = host_api_ctx->GetOutputTensor(SOFTMAX_LSE_INDEX); | ||
| 144 | + if (fiaTensors.softmaxLse == nullptr) { | ||
| 145 | + OP_LOGE_WITH_INVALID_INPUT(host_api_ctx->GetNodeName(), "softmaxLse"); | ||
| 146 | + return GRAPH_FAILED; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + fiaTensors.pseShiftGe = host_api_ctx->GetOptionalInputTensor(PSE_SHIFT_INDEX); | ||
| 150 | + fiaTensors.attenMaskGe = host_api_ctx->GetOptionalInputTensor(ATTEN_MASK_INDEX); | ||
| 151 | + fiaTensors.actualSeqLengthsGe = host_api_ctx->GetOptionalInputTensor(ACTUAL_SEQ_Q_INDEX); | ||
| 152 | + fiaTensors.actualSeqLengthsGeKv = host_api_ctx->GetOptionalInputTensor(ACTUAL_SEQ_KV_INDEX); | ||
| 153 | + fiaTensors.deqScale1 = host_api_ctx->GetOptionalInputTensor(DEQUANT_SCALE1_INDEX); | ||
| 154 | + fiaTensors.quantScale1 = host_api_ctx->GetOptionalInputTensor(QUANT_SCALE1_INDEX); | ||
| 155 | + fiaTensors.deqScale2 = host_api_ctx->GetOptionalInputTensor(DEQUANT_SCALE2_INDEX); | ||
| 156 | + fiaTensors.quantScale2 = host_api_ctx->GetOptionalInputTensor(QUANT_SCALE2_INDEX); | ||
| 157 | + fiaTensors.quantOffset2 = host_api_ctx->GetOptionalInputTensor(QUANT_OFFSET2_INDEX); | ||
| 158 | + fiaTensors.antiquantScaleGe = host_api_ctx->GetOptionalInputTensor(ANTIQUANT_SCALE_INDEX); | ||
| 159 | + fiaTensors.antiquantOffsetGe = host_api_ctx->GetOptionalInputTensor(ANTIQUANT_OFFSET_INDEX); | ||
| 160 | + fiaTensors.blocktableGe = host_api_ctx->GetOptionalInputTensor(BLOCK_TABLE_INDEX); | ||
| 161 | + fiaTensors.queryPaddingGe = host_api_ctx->GetOptionalInputTensor(QUERY_PADDING_INDEX); | ||
| 162 | + fiaTensors.kvPaddingGe = host_api_ctx->GetOptionalInputTensor(KV_PADDING_INDEX); | ||
| 163 | + fiaTensors.keyAntiquantScaleGe = host_api_ctx->GetOptionalInputTensor(KEY_ANTIQUANT_SCALE_INDEX); | ||
| 164 | + fiaTensors.keyAntiquantOffsetGe = host_api_ctx->GetOptionalInputTensor(KEY_ANTIQUANT_OFFSET_INDEX); | ||
| 165 | + fiaTensors.valueAntiquantScaleGe = host_api_ctx->GetOptionalInputTensor(VALUE_ANTIQUANT_SCALE_INDEX); | ||
| 166 | + fiaTensors.valueAntiquantOffsetGe = host_api_ctx->GetOptionalInputTensor(VALUE_ANTIQUANT_OFFSET_INDEX); | ||
| 167 | + fiaTensors.keySharedPrefixGe = host_api_ctx->GetOptionalInputTensor(KEY_SHARED_PREFIX_INDEX); | ||
| 168 | + fiaTensors.valueSharedPrefixGe = host_api_ctx->GetOptionalInputTensor(VALUE_SHARED_PREFIX_INDEX); | ||
| 169 | + fiaTensors.actualSharedPrefixLenGe = host_api_ctx->GetOptionalInputTensor(ACTUAL_SHARED_PREFIX_LEN_INDEX); | ||
| 170 | + fiaTensors.queryRopeGe = host_api_ctx->GetOptionalInputTensor(QUERY_ROPE_INDEX); | ||
| 171 | + fiaTensors.keyRopeGe = host_api_ctx->GetOptionalInputTensor(KEY_ROPE_INDEX); | ||
| 172 | + fiaTensors.keyRopeAntiquantScaleGe = host_api_ctx->GetOptionalInputTensor(KEY_ROPE_ANTIQUANT_SCALE_INDEX); | ||
| 173 | + fiaTensors.dequantScaleQueryGe = host_api_ctx->GetOptionalInputTensor(DEQUANT_SCALE_QUERY_INDEX); | ||
| 174 | + fiaTensors.learnableSinkGe = host_api_ctx->GetOptionalInputTensor(LEARNABLE_SINK_INDEX); | ||
| 175 | + | ||
| 176 | + return GRAPH_SUCCESS; | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +struct ActualSeqInfo { | ||
| 180 | + std::vector<int64_t> actSeqArray; | ||
| 181 | + std::vector<int64_t> actSeqArrayKv; | ||
| 182 | + std::vector<int64_t> actSeqSharedPrefix; | ||
| 183 | +}; | ||
| 184 | + | ||
| 185 | +static void FillActualSeqInfo(const FusedInferHostTensorParams &fiaTensors, ActualSeqInfo &actualSeqInfo) { | ||
| 186 | + if (fiaTensors.actualSeqLengthsGe != nullptr) { | ||
| 187 | + const int64_t *actSeqData = fiaTensors.actualSeqLengthsGe->GetData<int64_t>(); | ||
| 188 | + const size_t len = static_cast<size_t>(fiaTensors.actualSeqLengthsGe->GetShapeSize()); | ||
| 189 | + for (size_t i = 0; i < len; i++) { | ||
| 190 | + actualSeqInfo.actSeqArray.push_back(actSeqData[i]); | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + if (fiaTensors.actualSeqLengthsGeKv != nullptr) { | ||
| 195 | + const int64_t *actSeqData = fiaTensors.actualSeqLengthsGeKv->GetData<int64_t>(); | ||
| 196 | + const size_t len = static_cast<size_t>(fiaTensors.actualSeqLengthsGeKv->GetShapeSize()); | ||
| 197 | + for (size_t i = 0; i < len; i++) { | ||
| 198 | + actualSeqInfo.actSeqArrayKv.push_back(actSeqData[i]); | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + std::vector<int64_t> actSeqSharedPrefix; | ||
| 203 | + if (fiaTensors.actualSharedPrefixLenGe != nullptr) { | ||
| 204 | + const int64_t *actSeqData = fiaTensors.actualSharedPrefixLenGe->GetData<int64_t>(); | ||
| 205 | + const size_t len = static_cast<size_t>(fiaTensors.actualSharedPrefixLenGe->GetShapeSize()); | ||
| 206 | + for (size_t i = 0; i < len; i++) { | ||
| 207 | + actualSeqInfo.actSeqSharedPrefix.push_back(actSeqData[i]); | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | +} | ||
| 211 | + | ||
| 212 | +struct FusedInferHostAttrPtrs { | ||
| 213 | + const uint32_t *getNumHeads = nullptr; | ||
| 214 | + const float *scaleValue = nullptr; | ||
| 215 | + const int64_t *getPreTokens = nullptr; | ||
| 216 | + const int64_t *getNextTokens = nullptr; | ||
| 217 | + const char *layout = nullptr; | ||
| 218 | + const uint32_t *getKVHeadNum = nullptr; | ||
| 219 | + const uint32_t *getSparseMode = nullptr; | ||
| 220 | + const uint32_t *getInnerPrecise = nullptr; | ||
| 221 | + const uint32_t *getBlockSize = nullptr; | ||
| 222 | + const uint32_t *getAntiquantMode = nullptr; | ||
| 223 | + const bool *getSoftmaxLseFlag = nullptr; | ||
| 224 | + const uint32_t *getKeyAntiquantMode = nullptr; | ||
| 225 | + const uint32_t *getValueAntiquantMode = nullptr; | ||
| 226 | + const uint32_t *getQueryQuantMode = nullptr; | ||
| 227 | + const int64_t *getPseType = nullptr; | ||
| 228 | +}; | ||
| 229 | + | ||
| 230 | +static void FillAttrPointers(const gert::RuntimeAttrs *attrs, FusedInferHostAttrPtrs &attrPtrs) { | ||
| 231 | + attrPtrs.getNumHeads = attrs->GetAttrPointer<uint32_t>(ATTR_N_INDEX); | ||
| 232 | + attrPtrs.scaleValue = attrs->GetAttrPointer<float>(ATTR_SCALE_INDEX); | ||
| 233 | + attrPtrs.getPreTokens = attrs->GetAttrPointer<int64_t>(ATTR_PRE_TOKEN_INDEX); | ||
| 234 | + attrPtrs.getNextTokens = attrs->GetAttrPointer<int64_t>(ATTR_NEXT_TOKEN_INDEX); | ||
| 235 | + attrPtrs.layout = attrs->GetAttrPointer<char>(ATTR_INPUT_LAYOUT_INDEX); | ||
| 236 | + attrPtrs.getKVHeadNum = attrs->GetAttrPointer<uint32_t>(ATTR_NUM_KV_HEADS_INDEX); | ||
| 237 | + attrPtrs.getSparseMode = attrs->GetAttrPointer<uint32_t>(ATTR_SPARSE_MODE_INDEX); | ||
| 238 | + attrPtrs.getInnerPrecise = attrs->GetAttrPointer<uint32_t>(ATTR_INNER_PRECISE_INDEX); | ||
| 239 | + attrPtrs.getBlockSize = attrs->GetAttrPointer<uint32_t>(ATTR_BLOCK_SIZE_INDEX); | ||
| 240 | + attrPtrs.getAntiquantMode = attrs->GetAttrPointer<uint32_t>(ATTR_ANTIQUANT_MODE_INDEX); | ||
| 241 | + attrPtrs.getSoftmaxLseFlag = attrs->GetAttrPointer<bool>(ATTR_SOFTMAX_LSE_FLAG_INDEX); | ||
| 242 | + attrPtrs.getKeyAntiquantMode = attrs->GetAttrPointer<uint32_t>(ATTR_KEY_ANTIQUANT_MODE_INDEX); | ||
| 243 | + attrPtrs.getValueAntiquantMode = attrs->GetAttrPointer<uint32_t>(ATTR_VALUE_ANTIQUANT_MODE_INDEX); | ||
| 244 | + attrPtrs.getQueryQuantMode = attrs->GetAttrPointer<uint32_t>(ATTR_QUERY_QUANT_MODE_INDEX); | ||
| 245 | + attrPtrs.getPseType = attrs->GetAttrPointer<int64_t>(ATTR_PSE_TYPE_INDEX); | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +struct FusedInferHostScalarParams { | ||
| 249 | + int64_t numHeads = 1; | ||
| 250 | + double dScaleValue = 1.0f; | ||
| 251 | + int64_t preTokens = SPARSE_MODE_INT_MAX; | ||
| 252 | + int64_t nextTokens = SPARSE_MODE_INT_MAX; | ||
| 253 | + int64_t kvHeadNum = 0; | ||
| 254 | + int64_t sparseMode = 0; | ||
| 255 | + int64_t innerPrecise = 1; | ||
| 256 | + int64_t blockSize = 0; | ||
| 257 | + int64_t antiquantMode = 0; | ||
| 258 | + bool softmaxLseFlag = false; | ||
| 259 | + int64_t keyAntiquantMode = 0; | ||
| 260 | + int64_t valueAntiquantMode = 0; | ||
| 261 | + int64_t queryQuantMode = 0; | ||
| 262 | + int64_t pseType = 0; // not supported in Pytorch interfaces, default 0 | ||
| 263 | +}; | ||
| 264 | + | ||
| 265 | +static void GetFusedInferHostScalarParams( | ||
| 266 | + const FusedInferHostAttrPtrs &attrPointers, FusedInferHostScalarParams ¶ms) { | ||
| 267 | + params.numHeads = *(attrPointers.getNumHeads); | ||
| 268 | + params.dScaleValue = *(attrPointers.scaleValue); | ||
| 269 | + params.preTokens = *(attrPointers.getPreTokens); | ||
| 270 | + params.nextTokens = *(attrPointers.getNextTokens); | ||
| 271 | + params.kvHeadNum = *(attrPointers.getKVHeadNum); | ||
| 272 | + params.sparseMode = *(attrPointers.getSparseMode); | ||
| 273 | + params.innerPrecise = *(attrPointers.getInnerPrecise); | ||
| 274 | + params.blockSize = *(attrPointers.getBlockSize); | ||
| 275 | + params.antiquantMode = *(attrPointers.getAntiquantMode); | ||
| 276 | + params.softmaxLseFlag = *(attrPointers.getSoftmaxLseFlag); | ||
| 277 | + params.keyAntiquantMode = *(attrPointers.getKeyAntiquantMode); | ||
| 278 | + params.valueAntiquantMode = *(attrPointers.getValueAntiquantMode); | ||
| 279 | + params.queryQuantMode = *(attrPointers.getQueryQuantMode); | ||
| 280 | + params.pseType = *(attrPointers.getPseType); | ||
| 281 | +} | ||
🟠 High Priority 在 fallback_fused_infer_attention_score.cpp 中,FillAttrPointers 函数(第 232-249 行)通过 attrs->GetAttrPointer 建议:在 FillAttrPointers 中对每个 GetAttrPointer 返回值做空指针检查,若为 nullptr 则记录错误日志并返回失败(或抛出/返回错误码);或者在 GetFusedInferHostScalarParams 解引用之前逐个判空并提前退出。推荐在 FillAttrPointers 中集中校验,将错误尽早暴露。 ![]() ![]() | |||
| 282 | + | ||
| 283 | +static graphStatus FusedInferHostExecuteFunc(OpExecuteContext *host_api_ctx) { | ||
| 284 | + OP_CHECK_IF(host_api_ctx == nullptr, OP_LOGE("aclnnfallback", "host_api_ctx is null"), return GRAPH_FAILED); | ||
| 285 | + FusedInferHostTensorParams fiaTensors{}; | ||
| 286 | + auto apiRet = FiaFillTensorParams(host_api_ctx, fiaTensors); | ||
| 287 | + OP_CHECK_IF(apiRet != GRAPH_SUCCESS, OP_LOGE("aclnnfallback", "Input Tensors invalid"), return GRAPH_FAILED); | ||
| 288 | + | ||
| 289 | + std::vector<const gert::Tensor *> ge_tenserListKey; | ||
| 290 | + ge_tenserListKey.push_back(fiaTensors.key); | ||
| 291 | + | ||
| 292 | + std::vector<const gert::Tensor *> ge_tenserListValue; | ||
| 293 | + ge_tenserListValue.push_back(fiaTensors.value); | ||
| 294 | + | ||
| 295 | + ActualSeqInfo actualSeqInfo{}; | ||
| 296 | + FillActualSeqInfo(fiaTensors, actualSeqInfo); | ||
| 297 | + | ||
| 298 | + FusedInferHostAttrPtrs attrPointers{}; | ||
| 299 | + auto attrs = host_api_ctx->GetAttrs(); | ||
| 300 | + OP_CHECK_IF(attrs == nullptr, OP_LOGE("aclnnfallback", "host_api_ctx Attrs is null"), return GRAPH_FAILED); | ||
| 301 | + FillAttrPointers(attrs, attrPointers); | ||
| 302 | + | ||
| 303 | + FusedInferHostScalarParams scalarParams{}; | ||
| 304 | + GetFusedInferHostScalarParams(attrPointers, scalarParams); | ||
| 305 | + | ||
| 306 | + if (scalarParams.innerPrecise < 0 || | ||
| 307 | + scalarParams.innerPrecise > | ||
| 308 | + 3) { // innerPrecise=2,3 corresponds to rows with invalid high precision and high performance | ||
| 309 | + std::string reason = "The value of inner_precise must be in 0, 1, 2, 3"; | ||
| 310 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(host_api_ctx->GetNodeName(), "inner_precise", | ||
| 311 | + std::to_string(scalarParams.innerPrecise).c_str(), reason.c_str()); | ||
| 312 | + return GRAPH_FAILED; | ||
| 313 | + } | ||
| 314 | + OP_LOGD(host_api_ctx->GetNodeName(), "FusedInferAttentionScore fallback begin, numHeads = %ld, dScaleValue = %lf", | ||
| 315 | + scalarParams.numHeads, scalarParams.dScaleValue); | ||
| 316 | + OP_LOGD(host_api_ctx->GetNodeName(), | ||
| 317 | + "preTokens = %ld, nextTokens = %ld, kvHeadNum = %ld, sparseMode = %ld, innerPrecise = %ld", | ||
| 318 | + scalarParams.preTokens, scalarParams.nextTokens, scalarParams.kvHeadNum, scalarParams.sparseMode, | ||
| 319 | + scalarParams.innerPrecise); | ||
| 320 | + | ||
| 321 | + if (scalarParams.sparseMode >= 10 && scalarParams.sparseMode <= 14) { // 10: min 14: max | ||
| 322 | + scalarParams.innerPrecise = 0; | ||
| 323 | + scalarParams.sparseMode -= 10; // subtract 10 to modify sparseMode | ||
| 324 | + OP_LOGD(host_api_ctx->GetNodeName(), | ||
| 325 | + "because sparseMode in range [10, 14], after modification, sparseMode = %ld, innerPrecise = %ld.", | ||
| 326 | + scalarParams.sparseMode, scalarParams.innerPrecise); | ||
| 327 | + } | ||
| 328 | + | ||
| 329 | + apiRet = EXEC_OPAPI_CMD(aclnnEagleFusedInferAttentionScoreV5, fiaTensors.query, ge_tenserListKey, | ||
| 330 | + ge_tenserListValue, fiaTensors.pseShiftGe, fiaTensors.attenMaskGe, actualSeqInfo.actSeqArray, | ||
| 331 | + actualSeqInfo.actSeqArrayKv, fiaTensors.deqScale1, fiaTensors.quantScale1, fiaTensors.deqScale2, | ||
| 332 | + fiaTensors.quantScale2, fiaTensors.quantOffset2, fiaTensors.antiquantScaleGe, fiaTensors.antiquantOffsetGe, | ||
| 333 | + fiaTensors.blocktableGe, fiaTensors.queryPaddingGe, fiaTensors.kvPaddingGe, fiaTensors.keyAntiquantScaleGe, | ||
| 334 | + fiaTensors.keyAntiquantOffsetGe, fiaTensors.valueAntiquantScaleGe, fiaTensors.valueAntiquantOffsetGe, | ||
| 335 | + fiaTensors.keySharedPrefixGe, fiaTensors.valueSharedPrefixGe, actualSeqInfo.actSeqSharedPrefix, | ||
| 336 | + fiaTensors.queryRopeGe, fiaTensors.keyRopeGe, fiaTensors.keyRopeAntiquantScaleGe, | ||
| 337 | + fiaTensors.dequantScaleQueryGe, fiaTensors.learnableSinkGe, fiaTensors.qStartIdx, fiaTensors.kvStartIdx, | ||
| 338 | + scalarParams.numHeads, scalarParams.dScaleValue, scalarParams.preTokens, scalarParams.nextTokens, | ||
| 339 | + attrPointers.layout, scalarParams.kvHeadNum, scalarParams.sparseMode, scalarParams.innerPrecise, | ||
| 340 | + scalarParams.blockSize, scalarParams.antiquantMode, scalarParams.softmaxLseFlag, scalarParams.keyAntiquantMode, | ||
| 341 | + scalarParams.valueAntiquantMode, scalarParams.queryQuantMode, scalarParams.pseType, fiaTensors.output, | ||
| 342 | + fiaTensors.softmaxLse); | ||
| 343 | + | ||
| 344 | + OP_CHECK_IF( | ||
| 345 | + apiRet != GRAPH_SUCCESS, OP_LOGE(host_api_ctx->GetNodeName(), "apiRet failed:%u", apiRet), return GRAPH_FAILED); | ||
| 346 | + | ||
| 347 | + return GRAPH_SUCCESS; | ||
| 348 | +} | ||
| 349 | + | ||
| 350 | +IMPL_OP(EagleFusedInferAttentionScore).OpExecuteFunc(FusedInferHostExecuteFunc).HostInputs({5, 6, 23}); | ||
| 351 | +} // namespace fallback | ||
| 352 | + | ||
| 353 | + | ||
| 354 | +} | ||
| 355 | + | ||


🔴 Critical
在 v4.cpp 中,匿名命名空间
namespace {(第28行)包裹了整个文件,包括两个在头文件 v4.h 中声明为外部 API 的函数:aclnnFusedInferAttentionScoreV4GetWorkspaceSize(第145行定义,v4.h 第25行声明)aclnnFusedInferAttentionScoreV4(第224行定义,v4.h 第47行声明)匿名命名空间使这些函数获得 内部链接(internal linkage),与头文件中的外部链接声明不匹配。任何包含
v4.h并调用这两个函数的翻译单元在链接阶段都会因找不到外部符号而产生 undefined reference 链接错误,导致构建失败。对比 v5.cpp:v5.cpp 无匿名命名空间,其同名模式的函数处于
extern "C"块内,具有正确的外部链接。修复:删除 v4.cpp 第28行的
namespace {和第234行的} // namespace,使函数定义与头文件声明保持一致的 C 外部链接。建议:删除匿名命名空间(第28行的
namespace {和第234行的} // namespace),使aclnnFusedInferAttentionScoreV4GetWorkspaceSize和aclnnFusedInferAttentionScoreV4具有与头文件声明一致的外部链接(C linkage)。