您好,感谢反馈!
问题分析
按您提供的 cann/ops-math@584b2ea6 核查,三接口的 Host 检查要求各侧 padding 小于对应原维度,并通过 SafePadSum 检查溢出、裁剪范围和输出尺寸;它没有统一拒绝负值。因此长度 5、[-1,2]、输出长度 6 这样的输入可以通过第一段检查。SafePadSum 只验证尺寸,并未实现负值裁剪。形状检查、SafePadSum。
对报告中的 FLOAT32,实际走的是 ProcessMirrorPad,负值保留符号后传给 MirrorPad;A2 的 FLOAT32 分派到 AI Core。复数类型另走 PadV3,不能据此认为所有类型具有相同负 padding 能力。接口分支、padding 传递、后端选择。当前公开构建列出的 MirrorPad 实现平台为 arch35,尚不能仅凭这部分代码确认您所用 A2 包内第二段返回 561103 的具体触发位置。构建配置。
处理方向
现有资料确实只给出了 padding 上界及输出尺寸加和,没有明确负值的语义。资料约束。一个可行方向是结合平台和数据类型明确能力边界:若对应路径不支持负 padding,可在现有 Host 参数检查中提前返回 161002;若支持,则需同时明确裁剪与反射的索引语义,并匹配可执行实现。正负混合时反射参考范围也需明确,不能只按输出尺寸合法就认定可执行,或直接假定先裁剪再反射对所有边界等价。
这些调整需保留正 padding 上界、裁剪范围、溢出与输出形状检查,并评估其他类型和平台已可用行为的兼容性。我们会继续确认该路径的能力与错误码处理。


已提交修复:反射填充(ReflectionPad1d/2d/3d)在 CheckShape 中增加 padding 非负校验,负值第一段返回 161002。
真机(910B / CANN 8.5.1):修复前 padding=-1,1,1,1 为 rc1=0 / rc2=561103;修复后 rc1=161002;正 padding 对照仍为 0。


MR:!6828


现象
aclnnReflectionPad1d/2d/3d在padding含负值(裁剪)时,第一段GetWorkspaceSize返回 0 放行,第二段执行返回 561103(
ACLNN_ERR_INNER_NULLPTR)—— 两段口径不一致,且把内部错误码外泄给调用方。FLOAT32、值 1..7,同机逐项对照:
self=[2,5] pad=1,2:ret(gws)=0 ret(exec)=0,输出[2,8]正常self=[2,5] pad=-1,2:ret(gws)=0 ret(exec)=561103(输出[2,6])self=[1,4,4] pad=1,1,1,1:ret(gws)=0 ret(exec)=0,输出[1,6,6]正常self=[1,4,4] pad=-1,1,1,1:ret(gws)=0 ret(exec)=561103(输出[1,6,4])3d 同样命中(
self=[1,1,4,5,6] pad=-1,1,0,2,1,0]→ret(exec)=561103),说明是mirror_pad一族共用的 host 路径问题,不是单个接口的偶发。期望
资料
conversion/mirror_pad/docs/aclnnReflectionPad{1,2,3}d.md没有声明负 padding 的语义(既没写「支持裁剪」,也没写「负值报错」),因此本 issue 不主张「应当支持裁剪」。
主张的是两段一致:若不支持,应在第一段返回
161002(ACLNN_ERR_PARAM_INVALID);padding是aclIntArray属性,host 侧判负是零成本校验。影响
失败发生在第二段/执行期而非参数校验期:调用方拿到
561103(内部错误)而不是161002(参数错误),会倾向重试或按环境故障上报,掩盖真实的入参问题;异步/图模式下更难定位到「padding 为负」。无数据正确性问题(直接失败,不产脏数据)。建议
两种修法都可以,但两段必须一致:
op_api的 check 或 tiling 前置)判负并返回161002;F.pad(mode='reflect')支持负值)。环境
cann/ops-math@584b2ea6(master,2026-10-24 fetch)复现步骤
repro_refpad_negpad.cpp;LF 换行g++ -std=c++17 -O2 repro_refpad_negpad.cpp -o repro -I"$ASCEND_HOME_PATH/include" -L"$ASCEND_HOME_PATH/lib64" -lascendcl -lopapi -lnnopbaseASCEND_LAUNCH_BLOCKING=1 ./reproCTRL-*应ret(gws)=0 ret(exec)=0;两组CASE-*-negative应ret(gws)=0 ret(exec)=561103复现脚本
#include <cstdio> #include <vector> #include "acl/acl.h" #include "aclnnop/aclnn_reflection_pad1d.h" #include "aclnnop/aclnn_reflection_pad2d.h" static aclTensor* Make(std::vector<float>& h, std::vector<int64_t>& sh, void** dev) { int64_t n = 1; for (auto d : sh) n *= d; size_t b = size_t(n > 0 ? n : 1) * sizeof(float); aclrtMalloc(dev, b, ACL_MEM_MALLOC_HUGE_FIRST); if (n > 0) aclrtMemcpy(*dev, b, h.data(), b, ACL_MEMCPY_HOST_TO_DEVICE); std::vector<int64_t> st(sh.size(), 1); for (int64_t i = 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 std::vector<int64_t> Padded(const std::vector<int64_t>& s, const std::vector<int64_t>& p) { std::vector<int64_t> o = s; int r = int(o.size()); for (int k = r - 1; k >= 0; --k) { int i = 2 * (r - 1 - k); if (i + 1 < int(p.size())) o[k] += p[i] + p[i + 1]; } return o; } // 对照组 CTRL(正 padding)/ 缺陷组 DEFECT(负 padding) static void Run(const char* tag, int dim, std::vector<int64_t> in, std::vector<int64_t> pads, aclrtStream stream) { std::vector<int64_t> out = Padded(in, pads); int64_t nIn = 1, nOut = 1; for (auto d : in) nIn *= d; for (auto d : out) nOut *= d; std::vector<float> sh(size_t(nIn > 0 ? nIn : 1)); for (int64_t i = 0; i < nIn; ++i) sh[size_t(i)] = float(i % 7 + 1); std::vector<float> oh(size_t(nOut > 0 ? nOut : 1), -7.0f); void* sd = nullptr; void* od = nullptr; aclTensor* self = Make(sh, in, &sd); aclTensor* ot = Make(oh, out, &od); aclIntArray* pa = aclCreateIntArray(pads.data(), int64_t(pads.size())); uint64_t ws = 0; aclOpExecutor* ex = nullptr; aclnnStatus r1 = (dim == 1) ? aclnnReflectionPad1dGetWorkspaceSize(self, pa, ot, &ws, &ex) : aclnnReflectionPad2dGetWorkspaceSize(self, pa, ot, &ws, &ex); void* w = nullptr; if (r1 == 0 && ws > 0) aclrtMalloc(&w, ws, ACL_MEM_MALLOC_HUGE_FIRST); aclnnStatus r2 = (aclnnStatus)-1; if (r1 == 0) r2 = (dim == 1) ? aclnnReflectionPad1d(w, ws, ex, stream) : aclnnReflectionPad2d(w, ws, ex, stream); aclnnStatus r3 = (r1 == 0 && r2 == 0) ? aclrtSynchronizeStream(stream) : -1; printf("[%-18s] pad=[", tag); for (size_t i = 0; i < pads.size(); ++i) printf("%s%ld", i ? "," : "", long(pads[i])); printf("] ret(gws)=%d ret(exec)=%d sync=%d\n", int(r1), int(r2), int(r3)); aclDestroyTensor(self); aclDestroyTensor(ot); aclDestroyIntArray(pa); if (w) aclrtFree(w); aclrtFree(sd); aclrtFree(od); } int main() { aclInit(nullptr); aclrtSetDevice(0); aclrtStream s = nullptr; aclrtCreateStream(&s); // 对照组 CTRL Run("CTRL-1d", 1, {2, 5}, {1, 2}, s); // 缺陷组 DEFECT Run("CASE-1d-negative", 1, {2, 5}, {-1, 2}, s); Run("CTRL-2d", 2, {1, 4, 4}, {1, 1, 1, 1}, s); Run("CASE-2d-negative", 2, {1, 4, 4}, {-1, 1, 1, 1}, s); aclrtDestroyStream(s); aclrtResetDevice(0); aclFinalize(); return 0; }实测输出:
[CTRL-1d] ret(gws)=0 ret(exec)=0、[CASE-1d-negative] ret(gws)=0 ret(exec)=561103、[CTRL-2d] ret(gws)=0 ret(exec)=0、[CASE-2d-negative] ret(gws)=0 ret(exec)=561103。