Closed
aclnnCalculateMatmulWeightSizeV2 对不支持的 dtype(FLOAT/INT32/BOOL)未拦截,返回按 4 字节推算的 512 而非 161002 #3939
liuhanwen8Add on 16 days agoClosed at 8 days ago
16 days ago Added label: bug-report
陈思
15 days ago Comments:
15 days ago Comments:
您好,感谢反馈!
问题分析
在本次读取的 cann/ops-math@a11d8785 中,aclnnCalculateMatmulWeightSizeV2 确实没有检查 dataType:完成 SoC、指针和 shape 检查后直接计算并返回成功。资料限定 FLOAT16、BFLOAT16、INT8,并把类型不满足要求列为 161002,两者存在校验缺口。V2 实现、资料约束。这是源码核查结论,尚未核对您商用 9.2.0 包的具体源码对应关系。
其中 512 的来源需要澄清:计算函数将 FLOAT16/BFLOAT16 以外的类型全部放进 INT8 对齐分支,对 [16,16] 计算 Align(16,16)×Align(16,32)=512;这里返回的是元素个数,没有按 dtype 的字节宽度计算。V1 固定传入 FLOAT16,因而得到 256,合法 INT8 在 V2 中得到 512 本身是预期差异。计算与 V1 调用、容量单位与公式。
此外,aclnnTransMatmulWeight 有独立的类型校验,该版本的支持列表不含 FLOAT、INT32、BOOL。因此,容量接口误返回成功可以确认,但不能据此断言后续转换一定发生错误读写。下游类型列表、下游校验。
处理方向
一个可行方向是在 V2 写入容量之前,按该接口正式支持的数据类型和产品范围增加明确校验,不支持时返回 161002,同时保留合法类型的对齐规则和元素单位。若扩大类型支持,则需匹配容量规则、后续转换能力和资料,不能仅凭当前兜底分支视为已支持。
调用方应在返回成功后使用容量;错误时输出是否统一归零也需单独明确约定。我们会继续确认入口校验与支持契约的对齐方式。


15 days ago Assign chen_0715 as responsible person
15 days ago Added label: pending-confirmation
15 days ago Removed label: pending-confirmation
14 days ago Assign Anthony0331 as responsible person
14 days ago Removed responsible person chen_0715
14 days ago Associated pull request
9 days ago Associated pull request
8 days ago changed custom state from 进行中 to 已完成
8 days ago Close issue
aclnnCalculateMatmulWeightSizeV2 对不支持的数据类型未拦截,返回按 4 字节推算的占位大小
1. 环境
2. 现象
资料
aclnnCalculateMatmulWeightSizeV2参数表写明dataType只支持 FLOAT16、BFLOAT16、INT8,错误码表 161002 覆盖「输入的数据类型不满足要求」。
实测传入 ACL_FLOAT / ACL_INT32 / ACL_BOOL 时接口返回 0(成功),并给出
weightTensorSize=512,而不是返回 161002。512 恰好等于「按 4 字节 itemsize 取 C0=32」推算出的元素个数,说明非法 dtype
被当成 4 字节类型静默参与计算。
同一组输入下,
aclnnCalculateMatmulWeightSize(V1,无 dtype 形参)恒返回 256,与 V2 的 512 不一致,调用方无法判断该信哪个。
3. 复现步骤
set_env.sh;repro_calc;4. 复现代码
#include <cstdio> #include <cstdint> #include "acl/acl.h" #include "aclnnop/aclnn_trans_matmul_weight.h" static void run(aclDataType dt, const char *name) { int64_t shape[2] = {16, 16}; aclIntArray *arr = aclCreateIntArray(shape, 2); uint64_t size = 0; aclnnStatus rc = aclnnCalculateMatmulWeightSizeV2(arr, dt, &size); printf("%-8s rc=%d size=%llu\n", name, (int)rc, (unsigned long long)size); aclDestroyIntArray(arr); } int main() { aclInit(nullptr); aclrtSetDevice(0); run(ACL_FLOAT16, "fp16"); // 资料声明支持 run(ACL_BF16, "bf16"); // 资料声明支持 run(ACL_INT8, "int8"); // 资料声明支持 run(ACL_FLOAT, "fp32"); // 资料未声明 → 期望 161002 run(ACL_INT32, "int32"); // 资料未声明 → 期望 161002 run(ACL_BOOL, "bool"); // 资料未声明 → 期望 161002 aclrtResetDevice(0); aclFinalize(); return 0; }编译:
g++ -O0 -o repro_calc repro_calc.cpp -I$ASCEND_HOME_PATH/include -L$ASCEND_HOME_PATH/lib64 -lopapi -lnnopbase -lascendcl5. 期望结果
6. 实际结果
三台 910B2 机器(CANN 9.2.0)结果一致,可稳定复现。
7. 影响与建议
该接口的返回值被调用方直接用来申请 weight 张量空间(常见写法是
aclnnCalculateMatmulWeightSizeV2(...)→aclrtMalloc(size * itemsize))。非法 dtype 被静默受理后,调用方拿到一个「看起来合理」的元素个数,
把 fp32 权重按 2 字节类的块布局去申请和填充,后续
aclnnTransMatmulWeight或 matmul 侧就会按错误的存储布局读写,属于静默错误配置而非立即报错,排查成本高。
建议:
aclnnCalculateMatmulWeightSizeV2入口按资料声明的白名单校验dataType,不在 {FLOAT16, BFLOAT16, INT8} 内时返回
ACLNN_ERR_PARAM_INVALID(161002);但不要「文档说不支持、实现按兜底值算」)。