您好,感谢反馈!
问题分析
核对 cann/ops-math 提交 5f717513abcb6a6b94a4ae61a8151e4ba65e9eb3,第一段入口会检查 repeats 长度、负值、输入维度等,但没有检查“首轴参与 repeat 时最多 4 个非 1 参数,首轴不参与时最多 3 个”的组合限制;随后调用 Tile 构建计算流程。第二段直接返回执行器的运行状态,因此您报告的 0 / 561103 应区分为第一段通过、第二段调用返回内部异常,不能由此推定异常一定到 stream 同步才可见。入口检查与执行路径
还有一处文档口径需要澄清:当前错误码表已将“同时对超过 4 个维度做 repeat”列为 561103,并非明确承诺该项返回 161002;但该表又放在“第一段接口完成入参校验”的说明之后,与您在 Ascend 910B2、CANN 9.2.0 上报告的实际失败阶段不符,约束说明中的“校验报错”也未说明阶段。现有错误码表、两种首轴约束
本轮未重新上板,当前公开入口不足以确定对应交付库中第二段 561103 的内部传播细节。
调整方向
可考虑对适用该限制的产品在第一段检查组合条件,返回便于调用方定位的 161002,并同步更新错误码和阶段说明;这属于校验前移及错误分类的调整,需要评估现有返回码兼容性。检查逻辑还需与首轴、输入扩维、空输出等实际分支一致,避免把某一产品内核的限制直接套用于所有产品。我们会继续评估这一报错时机与分类。


您好,感谢反馈。最终处理结论如下。
代码处理
已在 math/tile/op_api/aclnn_repeat.cpp 的第一段接口增加 A2/A3 路径门控:
- 仅对
ASCEND910B、ASCEND910_93生效; - 首轴参与 repeat(
repeats[0] != 1)时,非 1 维度最多 4 个; - 首轴不参与 repeat(
repeats[0] == 1)时,非 1 维度最多 3 个; - 超过限制时
aclnnRepeatGetWorkspaceSize返回ACLNN_ERR_PARAM_INVALID(161002); - 空 Tensor、repeats 含 0 等不进入 Tile kernel 的既有 no-op 分支保持原行为。
A5 兼容性结论
A5 使用 DAV_3510 路径,实测与 A2/A3 不同:
- 两个超限场景在 A5 上第一段、第二段均成功,输出校验通过;
- 因此该限制是 A2/A3 的内部 broadcast kernel 限制,不能在公共第一段无条件拦截;
- 本次未修改 A5 行为。
实测覆盖
- A2、A3:fp32/fp16/bf16/int32 × 两个超限场景,8/8 均在第一段返回 161002;
- A2、A3:合法边界场景 8/8 成功,负值控制项 4/4 返回 161002;
- A5:两个超限场景 8/8 成功且输出正确,合法边界 8/8 成功;
- A2、A3、A5 的
tileop_api UT 各 12/12 通过。
资料已同步为:A2/A3 第一段返回 161002,A5 支持超过 4 个非 1 维度。


现象
aclnnRepeat的repeats违反资料「限制1/限制2」(同时 repeat 的非 1 维度个数超限)时,第一段
GetWorkspaceSize返回 0 放行、第二段执行才返回 561103(ACLNN_ERR_INNER_NULLPTR,内部异常);而同一张错误码表里其它
repeats入参约束全部由第一段返回 161002(ACLNN_ERR_PARAM_INVALID)。同机逐项实测(FLOAT32):self/repeatsret(gws)ret(exec)[2,2,2,2,2]/[2,2,2,2,2](首维非1,5 个非1)[2,2,2,2,2]/[1,2,2,2,2](首维=1,4 个非1)[2,2]/[2,-1]、[2,2,2]/[2,2]、rank=9[2,2,2,2,2]/[2,2,2,2,1]、/ [1,2,2,2,1]期望
资料
math/tile/docs/aclnnRepeat.md「约束说明」原文:资料自己写明这是 「校验报错」 的入参约束,且文中示例正是本次缺陷组 → 应在第一段拦截并返回
161002。环境
npu-smi26.1.1;CANN 9.2.0,Linux aarch64,g++ 11.4cann/ops-mathcf5f38c7(git fetch后的 origin/master,2026-10-26 复现)复现步骤
repro.cpp,编译:g++ -std=c++17 -O2 repro.cpp -o repro -I$ASCEND_HOME_PATH/aarch64-linux/include -L$ASCEND_HOME_PATH/aarch64-linux/lib64 -lascendcl -lnnopbase -lopapi_math -lopapi./repro:缺陷组GetWorkspaceSize = 0且Execute = 561103;同表对照GetWorkspaceSize = 161002复现脚本
// aclnnRepeat: 超 4 维限制报 561103(内部异常)而非 161002(参数非法),且延迟到第二段 #include <cstdio> #include <cstdint> #include <vector> #include <cmath> #include "acl/acl.h" #include "aclnnop/aclnn_repeat.h" static aclTensor* Mk(const std::vector<int64_t>& sh, void** dev, bool fill) { int64_t n = 1; for (auto d : sh) { n *= d; } size_t b = static_cast<size_t>(n) * sizeof(float); if (b == 0) { b = 1; } if (aclrtMalloc(dev, b, ACL_MEM_MALLOC_HUGE_FIRST) != ACL_SUCCESS) { return nullptr; } std::vector<float> h(n > 0 ? n : 1, 0.0f); for (int64_t i = 0; i < n; ++i) { h[i] = fill ? static_cast<float>(i + 1) : std::nanf(""); } aclrtMemcpy(*dev, b, h.data(), b, ACL_MEMCPY_HOST_TO_DEVICE); std::vector<int64_t> st(sh.size(), 1); for (int64_t i = static_cast<int64_t>(sh.size()) - 2; i >= 0; --i) { st[i] = sh[i + 1] * st[i + 1]; } return aclCreateTensor(sh.data(), sh.size(), ACL_FLOAT, st.data(), 0, ACL_FORMAT_ND, sh.data(), sh.size(), *dev); } static void Run(const char* tag, const std::vector<int64_t>& ss, const std::vector<int64_t>& rep, const std::vector<int64_t>& os, aclrtStream stream) { void* sA = nullptr; void* oA = nullptr; aclTensor* self = Mk(ss, &sA, true); aclTensor* out = Mk(os, &oA, false); aclIntArray* r = aclCreateIntArray(rep.data(), rep.size()); uint64_t ws = 0; aclOpExecutor* ex = nullptr; int ret1 = static_cast<int>(aclnnRepeatGetWorkspaceSize(self, r, out, &ws, &ex)); printf("%s GetWorkspaceSize = %d\n", tag, ret1); if (ret1 == 0) { void* wA = nullptr; if (ws > 0) { aclrtMalloc(&wA, ws, ACL_MEM_MALLOC_HUGE_FIRST); } int ret2 = static_cast<int>(aclnnRepeat(wA, ws, ex, stream)); printf("%s Execute = %d\n", tag, ret2); if (wA != nullptr) { aclrtFree(wA); } } aclDestroyTensor(self); aclDestroyTensor(out); aclDestroyIntArray(r); aclrtFree(sA); aclrtFree(oA); } int main() { aclInit(nullptr); aclrtSetDevice(0); aclrtStream s = nullptr; aclrtCreateStream(&s); Run("[缺陷组-超4维 首维非1]", {2,2,2,2,2}, {2,2,2,2,2}, {4,4,4,4,4}, s); Run("[缺陷组-超3维 首维=1]", {2,2,2,2,2}, {1,2,2,2,2}, {2,4,4,4,4}, s); Run("[对照组-含负值]", {2,2}, {2,-1}, {4,2}, s); Run("[对照组-个数不足]", {2,2,2}, {2,2}, {4,4,2}, s); Run("[对照组-rank9]", {1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1}, s); Run("[对照组-合法边界4个非1]", {2,2,2,2,2}, {2,2,2,2,1}, {4,4,4,4,2}, s); Run("[对照组-合法边界3个非1]", {2,2,2,2,2}, {1,2,2,2,1}, {2,4,4,4,2}, s); aclrtDestroyStream(s); aclrtResetDevice(0); aclFinalize(); return 0; }实测输出(完整 7 组见上表):
影响
而实际只需把
repeats的非 1 维度减到 4(或 3)个以内。建议
math/tile/op_api/aclnn_repeat.cpp的CheckParams补「非 1 维度个数」校验(按
repeats首元素是否为 1 分别判 4 / 3 上限),失败返回ACLNN_ERR_PARAM_INVALID,与
CheckRepeatsSize/CheckRepeatsValue同级;并同步把资料错误码表该条从ACLNN_ERR_INNER_NULLPTR(561103) 移入ACLNN_ERR_PARAM_INVALID(161002)。