运行验证时AllocTensor/FreeTensor失败
现象描述
通过NPU进行核函数的运行验证时,出现挂死现象;通过CPU进行核函数的运行验证时,出现AllocTensor/FreeTensor失败的报错,日志报错和调用栈打印如下:
[ERROR][Core_0][/usr/local/Ascend/latest/x86_64-linux/tikcpp/tikcfw/interface/kernel_tpipe.h:730][AllocEventID][321678] current size is 4, max buffer number in same queue position is 4 [ERROR][CORE_0][pid 321674] error happened! ========= SIGABRT Signal (Abort Signal from abort) catched, backtrace info: [#0] 0x000000000001e7c0: handler(int) at /usr/local/Ascend/latest/tools/tikicpulib/lib/include/kern_fwk.h:105 [#1] 0x0000000000017c4f: signed char AscendC::TPipe::AllocEventID<(AscendC::HardEvent)5>() at /usr/local/Ascend/latest/x86_64-linux/tikcpp/tikcfw/interface/kernel_tpipe.h:733 [#2] 0x000000000001426d: AscendC::TQueBind<(AscendC::TPosition)0, (AscendC::TPosition)9, 4, 0>::FreeBuffer(unsigned char*) at /usr/local/Ascend/latest/x86_64-linux/tikcpp/tikcfw/interface/kernel_tpipe.h:1217 [#3] 0x0000000000011058: void AscendC::TQueBind<(AscendC::TPosition)0, (AscendC::TPosition)9, 4, 0>::FreeTensor<float16::Fp16T>(AscendC::LocalTensor<float16::Fp16T>&) at /usr/local/Ascend/latest/x86_64-linux/tikcpp/tikcfw/interface/kernel_tpipe.h:1237 [#4] 0x000000000000dfde: KernelAdd::Compute(int) at /home/xxxx/xxxx.cpp:59 [#5] 0x000000000000dd1c: KernelAdd::Process() at /home/xxxx/xxxx.cpp:37 (discriminator 2) ...
问题根因
根据日志信息“current size is 4, max buffer number in same queue position is 4”可以明确该问题是因为同一个TPosition上QUE Buffer的数量超出限制导致。
同一个TPosition上QUE Buffer的数量根据AI处理器型号的不同,有数量约束。申请Buffer时,需要满足该约束。
Atlas 训练系列产品、Atlas推理系列产品AI Core不超过4块。
Atlas A2训练系列产品/Atlas 800I A2推理产品不超过8块。
不满足该约束,在后续使用AllocTensor/FreeTensor可能会出现分配资源失败。比如:
TQue<TPosition::VECIN, 1> que0; TQue<TPosition::VECIN, 1> que1; // 不建议: // 比如,算子有6个输入,需要申请6块buffer // 通过2个队列为其申请内存,分别为que0、que1分配3块,申请VECIN position上的buffer总数为6 // 针对Atlas 训练系列产品、Atlas推理系列产品AI Core同一个TPosition上QUE Buffer的数量限制为4,超出该限制,在后续使用AllocTensor/FreeTensor可能会出现分配资源失败。 pipe.InitBuffer(que0, 3, len); pipe.InitBuffer(que1, 3, len);
处理步骤
如果确实有多块buffer使用,可以将多个buffer合并到一块buffer,通过偏移使用。样例如下:
// 此时建议通过以下方法解决: // 如果确实有多块buffer使用,可以将多个buffer合并到一块buffer,通过偏移使用 pipe.InitBuffer(que0, 1, len * 3) pipe.Initbuffer(que1, 1, len * 3) /* * 分配出3块内存大小的LocalTensor,local1的地址为que0中buffer的起始地址, * local2的地址为local1的地址偏移len后的地址,local3的地址为local1的地址偏移 * len * 2的地址 */ int32_t offset1 = len; int32_t offset2 = len * 2; LocalTensor<T> local1 = que0.AllocTensor<T>(); LocalTensor<T> local2 = local1[offset1]; LocalTensor<T> local3 = local1[offset2];
父主题: FAQ