Closed
[Bug-Report|缺陷反馈]: aclnnReplicationPad3dBackward 负 padding 在 stream 同步时报设备运行时错误 507035(同族 1d/2d 正常) #3965
liuhanwen8Add on  16 days agoClosed at  8 days ago
liuhanwen8
liuhanwen8
16 days ago Create

现象

aclnnReplicationPad3dBackward 在 padding 含负值(裁剪)时:第一段返回 0、第二段返回 0,
但 aclrtSynchronizeStream 返回 507035(设备侧运行时错误)。同族 1d / 2d 反向的同类负 padding
却正常 PASS,说明裁剪语义本身是被支持的,3d 实现不一致。

同一台 A2 单机逐项对照(FLOAT32,值全 1):

接口 self padding gradOutput 实测 结论
3d 对照组 CTRL [1,1,4,5,6] 1,1,1,1,1,1 [1,1,6,7,8] ret(gws)=0 ret(exec)=0 sync=0 合法对照正常
3d 缺陷组 DEFECT [1,1,4,5,6] -1,1,0,2,1,0 [1,1,5,7,6] ret(gws)=0 ret(exec)=0 **sync=507035** 设备侧运行时错误
1d 反向(同形态负 padding) [2,5] -1,-1 — 精度线 PASS(与 torch autograd 逐元素一致) 支持裁剪
2d 反向(同形态负 padding) [1,4,4] -1,1,1,1 — 精度线 PASS 支持裁剪

期望

要么与 1d/2d 一致地正确完成裁剪(推荐,因为同族已支持),
要么在第一段返回 161002(ACLNN_ERR_PARAM_INVALID)明确拒绝。

当前行为是最差的一种:参数被接受、kernel 被拉起、在 stream 同步时才报设备错误。
异步/图模式下调用方很难把它归因到「padding 为负」,且设备侧错误会污染后续算子。

影响

  • 调用方拿到 507035(运行时错误),无法区分「自己传错参数」与「环境/设备故障」。
  • 错误发生在执行段而非校验段,异步场景下定位成本高;同族 1d/2d 能跑通更会误导使用者以为 3d 也行。

建议

按 1d/2d 的实现路径让 3d 反向也支持负 padding 裁剪;若短期做不到,
在 op_api / tiling 前置判负并返回 161002,不要等到 kernel 阶段失败。

环境

  • 仓:cann/ops-math @ 584b2ea6(master,2026-10-24 fetch)
  • 硬件:Ascend 910B2(A2)单卡;CANN 9.2.0(toolkit);Linux aarch64
  • 实测日期 2026-10-25(4.2 单机,非多会话争用机)

复现步骤

  1. 把下方「复现脚本」存为 repro_rpp3b_negpad.cpp;LF 换行
  2. 编译:g++ -std=c++17 -O2 repro_rpp3b_negpad.cpp -o repro -I"$ASCEND_HOME_PATH/include" -L"$ASCEND_HOME_PATH/lib64" -lascendcl -lopapi -lnnopbase
  3. 运行:ASCEND_LAUNCH_BLOCKING=1 ./repro
  4. CTRL-pospad 应为 ret(gws)=0 ret(exec)=0 sync=0;DEFECT-negpad 实测 ret(gws)=0 ret(exec)=0 sync=507035

复现脚本

#include <cstdio>
#include <vector>
#include "acl/acl.h"
#include "aclnnop/aclnn_replication_pad3d_backward.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;
}

static void Run(const char* tag, std::vector<int64_t> selfShape, std::vector<int64_t> pads,
                aclrtStream stream) {
    std::vector<int64_t> goShape = Padded(selfShape, pads);
    int64_t nSelf = 1, nGo = 1;
    for (auto d : selfShape) nSelf *= d;
    for (auto d : goShape) nGo *= d;
    std::vector<float> selfH(size_t(nSelf > 0 ? nSelf : 1), 1.0f);
    std::vector<float> goH(size_t(nGo > 0 ? nGo : 1), 1.0f);
    std::vector<float> giH(size_t(nSelf > 0 ? nSelf : 1), -7.0f);
    void *sd = nullptr, *gd = nullptr, *id = nullptr;
    aclTensor* self = Make(selfH, selfShape, &sd);
    aclTensor* go = Make(goH, goShape, &gd);
    aclTensor* gi = Make(giH, selfShape, &id);
    aclIntArray* pa = aclCreateIntArray(pads.data(), int64_t(pads.size()));
    uint64_t ws = 0; aclOpExecutor* ex = nullptr;
    auto rc1 = aclnnReplicationPad3dBackwardGetWorkspaceSize(go, self, pa, gi, &ws, &ex);
    void* w = nullptr;
    if (rc1 == 0 && ws > 0) aclrtMalloc(&w, ws, ACL_MEM_MALLOC_HUGE_FIRST);
    aclnnStatus rc2 = (aclnnStatus)-1;
    if (rc1 == 0) rc2 = aclnnReplicationPad3dBackward(w, ws, ex, stream);
    aclnnStatus rc3 = (rc1 == 0 && rc2 == 0) ? aclrtSynchronizeStream(stream) : -1;
    printf("[%-14s] 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(rc1), int(rc2), int(rc3));
    aclDestroyTensor(self); aclDestroyTensor(go); aclDestroyTensor(gi); aclDestroyIntArray(pa);
    if (w) aclrtFree(w);
    aclrtFree(sd); aclrtFree(gd); aclrtFree(id);
}

int main() {
    aclInit(nullptr); aclrtSetDevice(0);
    aclrtStream s = nullptr; aclrtCreateStream(&s);
    Run("CTRL-pospad", {1, 1, 4, 5, 6}, {1, 1, 1, 1, 1, 1}, s);      // 对照组 CTRL
    Run("DEFECT-negpad", {1, 1, 4, 5, 6}, {-1, 1, 0, 2, 1, 0}, s);   // 缺陷组 DEFECT
    aclrtDestroyStream(s); aclrtResetDevice(0); aclFinalize();
    return 0;
}

实测输出:

[CTRL-pospad] pad=[1,1,1,1,1,1] ret(gws)=0 ret(exec)=0 sync=0;
[DEFECT-negpad] pad=[-1,1,0,2,1,0] ret(gws)=0 ret(exec)=0 sync=507035。

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

您好,感谢提供正 padding 对照和同步返回值。按您报告的 584b2ea6cbaeba684a51a74296d82d4d50ab3b0f 核查,本例存在负值进入不适配裁剪处理的 3d AiCore 路径的风险,需要沿该路径核实。

问题分析

输入空间维为 [4,5,6],padding 按左右、上下、前后排列为 [-1,1,0,2,1,0],对应 gradOutput 空间维 [5,7,6],满足当前第一段的形状关系检查。该检查没有因负 padding 拒绝本例。L0 分流对 A2、5 维、FLOAT、edge 模式选择 PadV3GradReplication AiCore,不能因文件中也有 AICPU 分支就把本例归为 AICPU 问题。

A2 tiling将 padding 保存在 uint32_t 数组中,RemapPaddings 直接赋入有符号输入值,没有先拆分裁剪与正向填充。因此 -1 会转换为 4294967295;kernel又将这些值用于边界累计次数。这是明确的危险路径,与负 padding 触发运行时失败的报告相符。不过,单凭 507035 仍不能确定本次是哪条访问或哪项设备检查失败,需结合对应任务的设备错误日志确认,尚未独立设备复验。

1d/2d 的成功对照有助于缩小范围,但它们走不同实现分支,不能单独证明 3d 内核已支持同样的裁剪。当前资料也没有清楚说明负值裁剪及其边界,接口支持口径需要明确。

处理方向

若保留负 padding 裁剪语义,应把裁剪偏移与非负填充次数分开处理,正确映射梯度到原 self,裁掉的位置保持零梯度、复制边缘正确累加;不能只把字段改为有符号类型,或将负值直接钳成 0,这些做法没有完成裁剪语义。

若某条后端暂不支持该配置,可评估入口明确拒绝或转到已验证支持的实现,并说明兼容范围。仅修改 isPadSupport 返回 false 不足以证明已避开问题:当前 3d AiCore 分支并不受 padFlag 条件控制,需要同时核对分流。也不宜未经契约确认就统一拒绝所有负 padding。

回归应分别覆盖六个方向的裁剪、正负混合、4D/5D、裁剪后空间大小边界及不同精度,除两段和同步状态外,还需检查完整梯度数值。我们会继续确认 3d 裁剪支持范围、边界表示和安全分流方案。

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
14 days ago Assign Anthony0331 as responsible person
CchenyifengCollaborators
14 days ago Removed responsible person chen_0715
WangJinChengWangJinChengCollaborators
10 days ago Associated pull request
CANN-robotCANN-robotCollaborators
8 days ago Close issue
CANN-robotCANN-robotCollaborators
8 days ago Added label: resolved