During the runtime verification of operators on the NPU, the actual data is inconsistent with the truth value, indicating an operator precision problem.
Generally, the precision of the operator is incorrect because of the incorrect implementation logic.
Ascend C provides the twin debugging function to locate the implementation logic problem of an operator through function verification in the CPU, GDB step-by-step debugging, and printf value printing. This example shows only the possible scenarios to facilitate the demonstration of the fault locating procedure. During actual use, debug the code based on the actual situation.
Refer to Kernel Launch Based on a Sample Project to compile the runtime verification code on the CPU and perform running and verification. The CPU results also show precision inconsistencies.
Check whether an error is reported in the log. You can search for the keyword failed. For example, the following is an error example, which indicates that the error occurs where the LeakyReLU API is called in the code.
1 | leakyrelu_custom_cpu: /usr/local/Ascend/CANN-7.0/x86_64-linux/tikcpp/tikcfw/interface/kernel_operator_vec_binary_scalar_intf.h:447: void AscendC::LeakyRelu(const AscendC::LocalTensor<T>&, const AscendC::LocalTensor<T>&, const T&, const int32_t&) [with T = float16::Fp16T; int32_t = int]: Assertion `false && "check vlrelu instr failed"' failed |
Generally, only the code line where the error is reported instead of the specific error can be located based on the preceding error logs. Use the GDB debugging mode or printf printing mode to further locate the fault.
gdb leakyrelu_custom_cpu
(gdb) set follow-fork-mode child
(gdb) r
(gdb) bt
(gdb) f 5
#5 0x000055555555d364 in KernelLeakyRelu::Compute (this=0x7fffffffd7d0, progress=0) at /root/AscendC_DemoCode-master/precision-error/vector/leakyrelu_custom.cpp:59
59 LeakyRelu(yLocal, xLocal, scalar, tileLength);
(gdb) p tileLength
$1 = 1024
(gdb) p xLocal
$1 = {<AscendC::BaseTensor<float16::Fp16T>> = {<No data fields>}, address_ = {logicPos = 9 '\t', bufferHandle = 0x7fffffffd930 "\003\005\377\377", dataLen = 1024,bufferAddr = 0,absAddr = ...}
1 2 | printf("xLocal size: %d\n", xLocal.GetSize()); printf("tileLength: %d\n", tileLength); |
In the following log, tileLength is 1024. In this program, 1024 half-type numbers need to be processed. The size of Tensor xLocal is 512, indicating that only 512 half-type numbers can be computed. The preceding information indicates that the lengths of the two parameters do not match. Therefore, the fault can be located.
1 2 | xLocal size: 512 tileLength: 1024 |