Closed
[Bug-Report|缺陷反馈]: [CircularPad2d/CircularPad3d] padding 边界与资料不符:pad==dim 被接受、pad>dim 返回 561103 而非 161002 #3923
liuhanwen8Add on  16 days agoClosed at  11 days ago
liuhanwen8
liuhanwen8
16 days ago Create

现象

aclnnCircularPad2d / aclnnCircularPad3d 对 padding 的上界校验与资料不一致:padding == self 对应维度 被接受并算出正确结果,padding > 维度 返回 561103(内部 tiling 错),而资料要求两者都返回 161002。

aclnnCircularPad2d(self=float32[1,2,4,4]):

组别 padding 观测
对照组 CTRL [1,1,1,1] ret_gws=0 ret_exec=0
对照/边界 [3,3,3,3](dim-1) ret_gws=0 ret_exec=0
缺陷组 DEFECT [4,4,4,4](==dim) ret_gws=0 ret_exec=0,输出与循环填充逐元素一致(288/288)
缺陷组 DEFECT [5,5,5,5](>dim) ret_gws=561103
缺陷组 DEFECT [3,0,0,0](单侧==dim,self 末维 3) ret_gws=0 ret_exec=0

aclnnCircularPad3d(self=float32[1,2,4,4,4])同款:[4,4,4,4,4,4] 返回 0 且输出正确(3456/3456),[5,5,5,5,5,5] 返回 561103,[3,0,0,0,0,0] 返回 0。

期望

资料《aclnnCircularPad2d》《aclnnCircularPad3d》错误码表 161002 子项写明:"padding的数值大于等于self对应维度的大小。" 即 padding >= dim(含相等)应返回 161002。参数表对 Ascend 950(Arch35)另注"允许等于",但同时写明"其他产品以对应版本约束为准";本复现的 910B2 属"其他产品",应按错误码表返回 161002。

环境

  • 硬件:Ascend 910B2(单卡)
  • CANN:9.2.0(Ascend-cann-toolkit 9.2.0 + ops 9.2.0)
  • 仓:cann/ops-math,master 最新提交 584b2ea6(复现前 git fetch 核对,SafePadSum 仍只有下界/溢出校验)
  • 操作系统:Linux aarch64(glibc 2.35)

复现步骤

  1. 把下方代码保存为 repro_circpad.cpp。
  2. 编译:g++ -std=c++17 -O2 repro_circpad.cpp -o repro_circpad -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 -lascendcl -lopapi -lnnopbase
  3. 跑对照:./repro_circpad lt,打印 ret_gws=0 ret_exec=0。
  4. 跑缺陷一:./repro_circpad eq(padding=4 == dim=4),打印 ret_gws=0 ret_exec=0(应为 161002)。
  5. 跑缺陷二:./repro_circpad gt(padding=5 > dim=4),打印 ret_gws=561103(应为 161002)。

复现脚本

// aclnnCircularPad2d: padding>=self 维度未被 host 校验(资料要求 161002)
// build: g++ -std=c++17 -O2 repro_circpad.cpp -o repro_circpad \
//          -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 -lascendcl -lopapi -lnnopbase
// run:   ./repro_circpad lt ; ./repro_circpad eq ; ./repro_circpad gt
#include <acl/acl.h>
#include <aclnnop/aclnn_circular_pad2d.h>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <vector>

static aclTensor* mk(void* d, std::vector<int64_t> sh, aclDataType dt) {
    std::vector<int64_t> st(sh.size());
    int64_t acc = 1;
    for (int i = (int)sh.size() - 1; i >= 0; --i) { st[i] = acc; acc *= (sh[i] ? sh[i] : 1); }
    return aclCreateTensor(sh.data(), sh.size(), dt, st.data(), 0, ACL_FORMAT_ND,
                           sh.data(), sh.size(), d);
}

int main(int argc, char** argv) {
    aclInit(nullptr);
    aclrtSetDevice(0);
    aclrtStream stream = nullptr;
    aclrtCreateStream(&stream);
    int64_t H = 4, W = 4;
    std::vector<int64_t> pads = {1, 1, 1, 1};
    const char* tag = "[对照组 CTRL]   pad=1 < dim=4";
    if (argc > 1 && std::strcmp(argv[1], "eq") == 0) { pads = {4, 4, 4, 4}; tag = "[缺陷组 DEFECT] pad=4 == dim=4"; }
    if (argc > 1 && std::strcmp(argv[1], "gt") == 0) { pads = {5, 5, 5, 5}; tag = "[缺陷组 DEFECT] pad=5 > dim=4"; }
    std::vector<int64_t> sh = {1, 2, H, W};
    std::vector<int64_t> outSh = {1, 2, H + pads[2] + pads[3], W + pads[0] + pads[1]};
    int64_t n = 1, on = 1;
    for (auto v : sh) n *= v;
    for (auto v : outSh) on *= v;
    std::vector<float> h(n);
    for (int64_t i = 0; i < n; ++i) h[i] = (float)(i * 3 + 1);
    void *dIn = nullptr, *dOut = nullptr;
    aclrtMalloc(&dIn, n * 4, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMalloc(&dOut, on * 4, ACL_MEM_MALLOC_HUGE_FIRST);
    aclrtMemcpy(dIn, n * 4, h.data(), n * 4, ACL_MEMCPY_HOST_TO_DEVICE);
    aclTensor* self = mk(dIn, sh, ACL_FLOAT);
    aclTensor* out = mk(dOut, outSh, ACL_FLOAT);
    aclIntArray* pa = aclCreateIntArray(pads.data(), (uint64_t)pads.size());
    uint64_t ws = 0;
    aclOpExecutor* ex = nullptr;
    printf("%s self=[1,2,4,4] out=[1,2,%lld,%lld] -> ", tag, (long long)outSh[2], (long long)outSh[3]);
    fflush(stdout);
    int r1 = (int)aclnnCircularPad2dGetWorkspaceSize(self, pa, out, &ws, &ex);
    int r2 = -1;
    if (r1 == 0) {
        void* dWs = nullptr;
        if (ws) aclrtMalloc(&dWs, ws, ACL_MEM_MALLOC_HUGE_FIRST);
        r2 = (int)aclnnCircularPad2d(dWs, ws, ex, stream);
        aclrtSynchronizeStream(stream);
        if (dWs) aclrtFree(dWs);
    }
    std::vector<float> got(on, -1.0f);
    if (r1 == 0 && r2 == 0) aclrtMemcpy(got.data(), on * 4, dOut, on * 4, ACL_MEMCPY_DEVICE_TO_HOST);
    printf("ret_gws=%d ret_exec=%d out[0..3]=%.0f,%.0f,%.0f,%.0f\n", r1, r2, got[0], got[1], got[2], got[3]);
    aclDestroyIntArray(pa);
    aclDestroyTensor(self);
    aclDestroyTensor(out);
    aclrtFree(dIn);
    aclrtFree(dOut);
    aclrtDestroyStream(stream);
    aclFinalize();
    return 0;
}

影响

调用方按资料会在 host 侧放过 padding >= dim 的配置,实际拿到两种不一致结果:等于维度时被静默接受(输出正确但违反契约),大于维度时拿到 561103(tiling 内部错)。561103 在上层通常被当成"内部错误/环境问题"而不是"参数非法",排障会走偏;对自动调优/参数扫描,等于把非法配置当合法配置继续执行。

建议

在 circular_pad_common.h 的 SafePadSum 之外补一条 host 侧上界校验:对每个 pad 维度,pad_front >= dim || pad_back >= dim(按资料口径含相等)直接返回 ACLNN_ERR_PARAM_INVALID(161002),不要留到 tiling。2D/3D 共用同一模板,一处修改即可覆盖两个接口。

likedislike
liuhanwen8liuhanwen8
16 days ago Added label: bug-report
陈思
陈思Collaborators
15 days ago Comments:

您好,感谢反馈!按您报告的 cann/ops-math@584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核查,这里需要分别看“等于维度的边界口径”和“大于维度时的前置错误码”。

问题分析

共享 API 的 SafePadSum 负责溢出、负向裁剪及输出尺寸校验,没有正 padding 上界检查。进入 A2 对应的 arch22 tiling 后,各空间轴对正 padding 的拒绝条件实际是 pad > inputDim,并非 pad >= inputDim。因此,本条非负 padding 中 pad==dim 被接受,与该版本 A2 的比较逻辑一致,不能直接按“漏掉等号检查”处理。共享检查、A2 上界比较

资料中 950 参数说明“允许等于”,而两个接口的错误表又统一写“大于等于”,确有需要对齐的边界表述。对于 A2,仍应对应其实际版本说明支持范围,不能只根据这条通用错误项就新增等号拒绝。2d 资料、3d 错误项

pad>dim 则会在现有 A2 tiling 检查中返回失败,而前面的 aclnn 参数校验没有提前识别。您报告的 ret_gws=561103 发生在第一段准备阶段;当前源码能够确认这条前置检查缺口,具体运行时错误码映射仍需对应核实。

处理方向

可考虑在 2d/3d 共用的参数检查中,按该平台实际支持范围提前返回 ACLNN_ERR_PARAM_INVALID(161002),同时修正文档的等号边界与产品条件。直接按建议统一加入 >=dim 会改变当前可执行的等号调用,需要先确认正式支持策略及兼容影响。

调整还需保留溢出防护、输出 shape 关系和已有正负混合 padding 约束;正负混合时的可用范围不能只看原始维度。直接相关的验证可覆盖各轴的 dim-1/dim/dim+1 及单侧、混合情形。我们会继续确认边界说明与前置返回码的一致性。

likedislike
陈思陈思Collaborators
15 days ago Assign chen_0715 as responsible person
陈思陈思Collaborators
15 days ago Added label: pending-confirmation
陈思陈思Collaborators
15 days ago Removed label: pending-confirmation
CchenyifengCollaborators
12 days ago Assign Anthony0331 as responsible person
CchenyifengCollaborators
12 days ago Removed responsible person chen_0715
WangJinChengWangJinChengCollaborators
11 days ago Associated pull request
CANN-robotCANN-robotCollaborators
11 days ago Close issue
CANN-robotCANN-robotCollaborators
11 days ago Added label: resolved