LCOV - code coverage report
Current view: top level - src/api_check - kernel_vec_proposal_check.cpp (source / functions) Coverage Total Hit
Test: coverage.info_filtered Lines: 76.0 % 146 111
Test Date: 2026-07-27 14:41:20 Functions: 85.7 % 14 12

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : /*!
      12              :  * \file kernel_vec_proposal_check.cpp
      13              :  * \brief
      14              :  */
      15              : 
      16              : #include "kernel_check_params.h"
      17              : #include "kernel_vec_proposal_check.h"
      18              : 
      19              : namespace AscendC {
      20              : namespace check {
      21              : const uint32_t ONE_REPEAT_CAL_NUM = 16; // 1 repeat = 16 region proposals
      22              : const uint32_t PROPOSAL_SIZE = 8;       // 1 proposal = 8 element
      23              : 
      24           56 : bool TikcppVecProposalCheck::CheckAddrAlign(const std::string& src0Name)
      25              : {
      26           56 :     uint8_t alignByte = ONE_BLK_SIZE;
      27           56 :     bool dstRes = true;
      28           56 :     bool src0Res = true;
      29           56 :     if (apiName == "MrgSort") {
      30            4 :         alignByte = 8; // half and float type align Bytes is 8B
      31            8 :         dstRes = CheckTensorAddrAlign(param_.dstAddr, param_.dstPos, ONE_BLK_SIZE, "dst");
      32            4 :         src0Res = CheckTensorAddrAlign(param_.src0Addr, param_.src0Pos, alignByte, src0Name);
      33            4 :         return dstRes && src0Res;
      34              :     }
      35           52 :     if (apiName == "MrgSort4" && param_.dstDtypeBytes == sizeof(half)) {
      36            0 :         alignByte = 16; // half type align Bytes is 16B
      37              :     }
      38          104 :     dstRes = CheckTensorAddrAlign(param_.dstAddr, param_.dstPos, alignByte, "dst");
      39           52 :     src0Res = CheckTensorAddrAlign(param_.src0Addr, param_.src0Pos, alignByte, src0Name);
      40           52 :     return dstRes && src0Res;
      41              : }
      42              : 
      43              : // validBit to num of proposal lists: 3->2, 7->3, 15->4
      44           12 : uint8_t TikcppVecProposalCheck::CountBit(uint16_t validBit) const
      45              : {
      46           12 :     uint8_t count = 0;
      47           60 :     while (validBit != 0) {
      48           48 :         count += (validBit & 0x1);
      49           48 :         validBit >>= 1;
      50              :     }
      51           12 :     return count;
      52              : }
      53              : 
      54           12 : bool TikcppVecProposalCheck::CheckValidBit(uint16_t validBit) const
      55              : {
      56           12 :     bool validBitRes = validBit == 3 || validBit == 7 || validBit == 15;
      57           12 :     ASCENDC_CHECK_AND_LOG((validBitRes), {
      58              :         CHECK_LOG_ERROR(
      59              :             "Failed to check validBit value in %s, its valid value is "
      60              :             "[3, 7, 15], current value is %u.",
      61              :             apiName.c_str(), validBit);
      62              :     });
      63           12 :     return true;
      64              : }
      65              : 
      66              : // calculate total elements that needs to be sorted per repeatTimes. (1 proposal -> 1 element)
      67           12 : uint64_t TikcppVecProposalCheck::CalSortElemPerRep(uint16_t elementLengths[4], uint8_t count) const
      68              : {
      69           12 :     uint64_t elePerRep = 0;
      70           60 :     for (uint8_t i = 0; i < count; ++i) {
      71           48 :         elePerRep += elementLengths[i];
      72              :     }
      73           12 :     return elePerRep;
      74              : }
      75              : 
      76           12 : bool TikcppVecProposalCheck::NeedRepeatTimes() const
      77              : {
      78              :     // 1. 4 region proposals has same lengths
      79           36 :     bool cond1 = (param_.elementLengths[0] == param_.elementLengths[1]) &&
      80           24 :                  (param_.elementLengths[1] == param_.elementLengths[2]) &&
      81           12 :                  (param_.elementLengths[2] == param_.elementLengths[3]);
      82              :     // 2. continuous stored  3. ifExhaused = false 4. validBit = 15
      83           12 :     return cond1 && param_.isContinuous && (!param_.isExhausted) && (param_.validBit == 15);
      84              : }
      85              : 
      86           12 : bool TikcppVecProposalCheck::Vbs16Check() const
      87              : {
      88              :     // 1 repeat = 16 proposals, 1 proposals = 8 * element. Data are continuously stored.
      89           12 :     uint64_t calCount = param_.repeatTimes * ONE_REPEAT_CAL_NUM * PROPOSAL_SIZE;
      90           36 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, calCount, "dstLocal"));
      91           24 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, calCount, "srcLocal"));
      92            4 :     return true;
      93              : }
      94              : 
      95           12 : bool TikcppVecProposalCheck::Vbs32Check() const
      96              : {
      97           36 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
      98              :         param_.src1Size, GlobalParams::Instance().bufferSizeMap.at(param_.src1Pos),
      99              :         "check src1 tensor buffersize failed"));
     100              : 
     101           12 :     if (param_.dstDtypeBytes == 0) {
     102            0 :         CHECK_LOG_ERROR("dst dtype bytes is zero");
     103            0 :         return false;
     104              :     }
     105              :     // In 1 repeat, dst: 256B   src0: 32 * element   src1: 32 element
     106           12 :     const uint32_t oneCalNumVbs32 = 32; // 1 repeat calculates 32 groups of (score + index)
     107           12 :     uint32_t elemPerRepeat = ONE_REPEAT_BYTE_SIZE / param_.dstDtypeBytes;
     108           36 :     ASCENDC_CHECK(
     109              :         CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, elemPerRepeat * param_.repeatTimes, "dstLocal"));
     110           24 :     ASCENDC_CHECK(CheckTensorOverflowHigh(
     111              :         param_.src0DtypeBytes, param_.src0Size, oneCalNumVbs32 * param_.repeatTimes, "src0Local"));
     112           12 :     ASCENDC_CHECK(CheckTensorOverflowHigh(
     113              :         param_.src1DtypeBytes, param_.src1Size, oneCalNumVbs32 * param_.repeatTimes, "src1Local"));
     114            4 :     return true;
     115              : }
     116              : 
     117            8 : bool TikcppVecProposalCheck::Vms4Check() const
     118              : {
     119            8 :     ASCENDC_CHECK(CheckValidBit(param_.validBit));
     120            8 :     uint8_t count = CountBit(param_.validBit);
     121            8 :     if (param_.srcIndex >= count) {
     122            0 :         return true; // if current list index is large than valid list number, no need to check
     123              :     }
     124              : 
     125            8 :     uint64_t sortElePerRep = CalSortElemPerRep(param_.elementLengths, count);
     126            8 :     uint64_t elemPerRep = sortElePerRep * PROPOSAL_SIZE; // 1 sort element = 1 proposal = 8 elements
     127            8 :     uint64_t validRepeatTimes = 1;
     128            8 :     if (NeedRepeatTimes()) {
     129            0 :         validRepeatTimes = param_.repeatTimes;
     130            0 :         ASCENDC_CHECK_VALUE_RANGE(validRepeatTimes, 1, MAX_REPEAT_TIMES, "repeatTimes", "MrgSort4");
     131              :     }
     132              :     // if exhausted, do not know total size. Thus no check
     133            8 :     if (!param_.isExhausted) {
     134           24 :         ASCENDC_CHECK(
     135              :             CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, elemPerRep * param_.repeatTimes, "dstLocal"));
     136              :     }
     137            4 :     std::string tensorName = "src" + std::to_string(param_.srcIndex) + " in srcLocal";
     138            4 :     uint64_t srcEle = (validRepeatTimes - 1) * elemPerRep + param_.elementLengths[param_.srcIndex] * PROPOSAL_SIZE;
     139            4 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, srcEle, tensorName));
     140            4 :     return true;
     141            4 : }
     142              : 
     143            4 : bool TikcppVecProposalCheck::Vms4v2Check() const
     144              : {
     145            4 :     ASCENDC_CHECK(CheckValidBit(param_.validBit));
     146            4 :     uint8_t count = CountBit(param_.validBit);
     147            4 :     if (param_.srcIndex >= count) {
     148            0 :         return true; // if current list index is large than valid list number, no need to check
     149              :     }
     150              : 
     151            4 :     uint64_t sortElePerRep = CalSortElemPerRep(param_.elementLengths, count);
     152            4 :     uint64_t bytePerRep = sortElePerRep * PROPOSAL_SIZE; // 1 sorted element = 8 Byte
     153            4 :     uint64_t validRepeatTimes = 1;
     154            4 :     if (NeedRepeatTimes()) {
     155            0 :         validRepeatTimes = param_.repeatTimes;
     156            0 :         ASCENDC_CHECK_VALUE_RANGE(validRepeatTimes, 1, MAX_REPEAT_TIMES, "repeatTimes", "MrgSort");
     157              :     }
     158              :     // if exhausted, do not know total size. Thus no check
     159            4 :     if (!param_.isExhausted) {
     160           12 :         ASCENDC_CHECK(CheckTensorOverflowHigh(1, param_.dstSize, bytePerRep * param_.repeatTimes, "dstLocal"));
     161              :     }
     162            0 :     std::string tensorName = "src" + std::to_string(param_.srcIndex) + " in srcLocal";
     163            0 :     uint64_t srcBytes = (validRepeatTimes - 1) * bytePerRep + param_.elementLengths[param_.srcIndex] * PROPOSAL_SIZE;
     164              :     // calcount is set as Bytes, thus set sizeof(dtype) to 1
     165            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(1, param_.src0Size, srcBytes, tensorName));
     166            0 :     return true;
     167            0 : }
     168              : 
     169           12 : bool TikcppVecProposalCheck::VconcatCheck() const
     170              : {
     171              :     // src: repeat * 16 element, dst: repeat * 16 region proposal (16 * 8 element)   both continuously stored
     172           12 :     uint32_t base = param_.repeatTimes * ONE_REPEAT_CAL_NUM;
     173           36 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, base, "srcLocal"));
     174           36 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, base * PROPOSAL_SIZE, "dstLocal"));
     175            8 :     return true;
     176              : }
     177              : 
     178            8 : bool TikcppVecProposalCheck::VextractCheck() const
     179              : {
     180              :     // src: repeat * 16 region proposal (16 * 8 element), dst: repeat * 16 element   both continuously stored
     181            8 :     uint32_t base = param_.repeatTimes * ONE_REPEAT_CAL_NUM;
     182           24 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, base * PROPOSAL_SIZE, "srcLocal"));
     183           12 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, base, "dstLocal"));
     184            4 :     return true;
     185              : }
     186              : 
     187            0 : bool TikcppVecProposalCheck::ConcatCheck() const
     188              : {
     189              :     // src: repeat * 16 element        dst: V220 dst = src, V200:  repeat * 16 region proposal (16 * 8 element)
     190            0 :     uint32_t base = param_.repeatTimes * ONE_REPEAT_CAL_NUM;
     191            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, base, "srcLocal"));
     192              : #if defined(__NPU_ARCH__) && ((__NPU_ARCH__ == 2201) || (__NPU_ARCH__ == 3002) || (__NPU_ARCH__ == 3102) || \
     193              :                               (__NPU_ARCH__ == 3510) || (__NPU_ARCH__ == 5102))
     194              :     // tmpLocal is not used
     195            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, base, "concatLocal"));
     196              : #elif defined(__NPU_ARCH__) && ((__NPU_ARCH__ == 1001) || (__NPU_ARCH__ == 2002))
     197            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src1DtypeBytes, param_.src1Size, base * PROPOSAL_SIZE, "tmpLocal"));
     198            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, base * PROPOSAL_SIZE, "concatLocal"));
     199              : #endif
     200            0 :     return true;
     201              : }
     202              : 
     203            0 : bool TikcppVecProposalCheck::ExtractCheck() const
     204              : {
     205              :     // In extract: dst -> dstValueLocal, src1 -> dstIndexLocal, src0 -> sortedLocal
     206              : #if defined(__NPU_ARCH__) && ((__NPU_ARCH__ == 2201) || (__NPU_ARCH__ == 3002) || (__NPU_ARCH__ == 3102) || \
     207              :                               (__NPU_ARCH__ == 3510) || (__NPU_ARCH__ == 5102))
     208              :     // 1 repeat:  32 groups of (score + index)   sortedLocal: 256B      dst: 32 elements
     209            0 :     uint64_t groupNumPerRep = 32; // 1 sort result is 8 Bytes, thus 1 repeat = 32 groups
     210            0 :     uint64_t totalEleNum = groupNumPerRep * param_.repeatTimes;
     211            0 :     ASCENDC_CHECK(
     212              :         CheckTensorSizeOverflow(param_.repeatTimes * ONE_REPEAT_BYTE_SIZE, param_.src0Size, "sortedLocal", "Extract"));
     213            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src1DtypeBytes, param_.src1Size, totalEleNum, "dstIndexLocal"));
     214            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, totalEleNum, "dstValueLocal"));
     215              : #elif defined(__NPU_ARCH__) && ((__NPU_ARCH__ == 1001) || (__NPU_ARCH__ == 2002))
     216              :     // 1 repeat:  src: 16 region proposal   dst: 16 elements
     217            0 :     uint32_t base = param_.repeatTimes * ONE_REPEAT_CAL_NUM;
     218            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, base * PROPOSAL_SIZE, "sortedLocal"));
     219            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src1DtypeBytes, param_.src1Size, base, "dstIndexLocal"));
     220            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.dstDtypeBytes, param_.dstSize, base, "dstValueLocal"));
     221              : #endif
     222            0 :     return true;
     223              : }
     224              : 
     225           80 : bool TikcppVecProposalCheck::CheckAllHighLevel()
     226              : {
     227           80 :     const std::string supportPos = "VECIN/VECOUT/VECCALC";
     228          240 :     ASCENDC_CHECK(CheckTensorScope(param_.dstLogicPos, static_cast<uint8_t>(HardWareIndex::UB), "dst", supportPos));
     229           56 :     std::string src0Name = "src0";
     230           56 :     if (apiName == "MrgSort" || apiName == "MrgSort4") { // only has src1 ~ src4
     231           12 :         src0Name = "src" + std::to_string(param_.srcIndex) + " in srcLocal";
     232              :     }
     233           56 :     ASCENDC_CHECK(CheckTensorScope(param_.src0LogicPos, static_cast<uint8_t>(HardWareIndex::UB), src0Name, supportPos));
     234           56 :     if (apiName == "Sort32" || apiName == "Concat" || apiName == "Extract") {
     235           36 :         ASCENDC_CHECK(
     236              :             CheckTensorScope(param_.src1LogicPos, static_cast<uint8_t>(HardWareIndex::UB), "src1", supportPos));
     237           36 :         ASCENDC_CHECK(CheckTensorAddrAlign(param_.src1Addr, param_.src1Pos, ONE_BLK_SIZE, "src1"));
     238              :     }
     239              : 
     240           56 :     ASCENDC_CHECK(CheckAddrAlign(src0Name));
     241              : 
     242           56 :     std::string bufferSrc0 = "check " + src0Name + " tensor buffersize failed";
     243          168 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     244              :         param_.dstSize, GlobalParams::Instance().bufferSizeMap.at(param_.dstPos),
     245              :         "check dst tensor buffersize failed"));
     246           56 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     247              :         param_.src0Size, GlobalParams::Instance().bufferSizeMap.at(param_.src0Pos), bufferSrc0));
     248              : 
     249           56 :     if (apiName == "Sort32") {
     250           12 :         return Vbs32Check();
     251           44 :     } else if (apiName == "ProposalConcat") {
     252           12 :         return VconcatCheck();
     253           32 :     } else if (apiName == "Concat") {
     254            0 :         return ConcatCheck();
     255           32 :     } else if (apiName == "ProposalExtract") {
     256            8 :         return VextractCheck();
     257           24 :     } else if (apiName == "Extract") {
     258            0 :         return ExtractCheck();
     259           24 :     } else if (apiName == "RpSort16") {
     260           12 :         return Vbs16Check();
     261           12 :     } else if (apiName == "MrgSort4") {
     262            8 :         return Vms4Check();
     263            4 :     } else if (apiName == "MrgSort") {
     264            4 :         return Vms4v2Check();
     265              :     }
     266            0 :     return true;
     267           80 : }
     268              : } // namespace check
     269              : } // namespace AscendC
        

Generated by: LCOV version 2.0-1