LCOV - code coverage report
Current view: top level - src/api_check - kernel_vec_reduce_check.cpp (source / functions) Coverage Total Hit
Test: coverage.info_filtered Lines: 74.1 % 143 106
Test Date: 2026-07-27 14:41:20 Functions: 100.0 % 12 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_reduce_check.cpp
      13              :  * \brief
      14              :  */
      15              : 
      16              : #include "kernel_check_params.h"
      17              : #include "kernel_vec_reduce_check.h"
      18              : 
      19              : namespace AscendC {
      20              : namespace check {
      21           16 : uint32_t TikcppVecReduceCheck::AlignStartPos(const uint32_t startPos, const uint32_t byteLen) const
      22              : {
      23           16 :     if (byteLen == 0) {
      24            0 :         CHECK_LOG_ERROR("byteLen is %u, it shoule be greater than 0", byteLen);
      25            0 :         return 0;
      26              :     }
      27           16 :     uint32_t resDiv = DivCeil(startPos * byteLen, static_cast<uint32_t>(PlatFormParams::ONE_BLK_SIZE));
      28              : 
      29           16 :     return resDiv * static_cast<uint32_t>(PlatFormParams::ONE_BLK_SIZE) / byteLen;
      30              : }
      31              : 
      32           40 : bool TikcppVecReduceCheck::CheckAllDtypeBytes(const std::string& errMsg)
      33              : {
      34           40 :     uint32_t dstDtypeBytes = param_.dstDtypeBytes;
      35           40 :     uint32_t srcDtypeBytes = param_.src0DtypeBytes;
      36           40 :     uint32_t workDtypeBytes = param_.src1DtypeBytes;
      37           40 :     if ((dstDtypeBytes != srcDtypeBytes) || (srcDtypeBytes != workDtypeBytes) || (workDtypeBytes != dstDtypeBytes)) {
      38            0 :         CHECK_LOG_ERROR(
      39              :             "%s, "
      40              :             "Reduce need dst data type (%u),dst src type (%u), dst wokr type (%u) should be same",
      41              :             errMsg.c_str(), dstDtypeBytes, srcDtypeBytes, workDtypeBytes);
      42            0 :         return false;
      43              :     }
      44           40 :     return true;
      45              : }
      46              : 
      47            8 : void TikcppVecReduceCheck::ReduceBodyCal(
      48              :     const std::vector<uint32_t>& paramsArray, uint32_t& outputCount, uint32_t& nextStartPos) const
      49              : {
      50              :     enum class ReduceBodyCalIndex {
      51              :         PRE_DATA_COUNT = 0,
      52              :         CUR_START_POS,
      53              :         ELEMENT_NUM_PER_REP,
      54              :         TYPE_SIZE,
      55              :         PER_REP_OUTPUT,
      56              :     };
      57              : 
      58            8 :     uint32_t preDataCount = paramsArray[static_cast<uint32_t>(ReduceBodyCalIndex::PRE_DATA_COUNT)];
      59            8 :     uint32_t curStartPos = paramsArray[static_cast<uint32_t>(ReduceBodyCalIndex::CUR_START_POS)];
      60            8 :     uint32_t elementNumPerRep = paramsArray[static_cast<uint32_t>(ReduceBodyCalIndex::ELEMENT_NUM_PER_REP)];
      61            8 :     uint32_t typeSize = paramsArray[static_cast<uint32_t>(ReduceBodyCalIndex::TYPE_SIZE)];
      62            8 :     uint32_t perRepOutput = paramsArray[static_cast<uint32_t>(ReduceBodyCalIndex::PER_REP_OUTPUT)];
      63              : 
      64              :     uint32_t tailOutputCount;
      65            8 :     uint32_t bodyRepTimes = preDataCount / elementNumPerRep;
      66            8 :     uint32_t bodyOutputCount = perRepOutput * bodyRepTimes;
      67            8 :     bool hasTail = (preDataCount % elementNumPerRep) != 0;
      68            8 :     if (hasTail) {
      69            8 :         tailOutputCount = perRepOutput;
      70              :     } else {
      71            0 :         tailOutputCount = 0;
      72              :     }
      73            8 :     outputCount = bodyOutputCount + tailOutputCount;
      74            8 :     nextStartPos = AlignStartPos(curStartPos + outputCount, typeSize);
      75            8 :     return;
      76              : }
      77              : 
      78            8 : bool TikcppVecReduceCheck::CheckCheckWorkSize(
      79              :     const std::string& errMsg, const uint64_t needElements, const uint32_t byteLen)
      80              : {
      81            8 :     uint64_t needSize = static_cast<uint64_t>(needElements * byteLen);
      82            8 :     if (needSize > param_.src1Size) {
      83            0 :         CHECK_LOG_ERROR(
      84              :             "%s, "
      85              :             "Worktensor's size should be more than %lu, but get %lu",
      86              :             errMsg.c_str(), needSize, param_.src1Size);
      87            0 :         return false;
      88              :     }
      89            8 :     return true;
      90              : }
      91              : 
      92            8 : bool TikcppVecReduceCheck::CheckWorkTensorOffset(const std::string& errMsg)
      93              : {
      94              :     uint32_t resIndex;
      95              :     uint32_t it2OutputCount;
      96              :     uint32_t it3StartPos;
      97            8 :     uint32_t typeSize = param_.src1DtypeBytes;
      98            8 :     uint32_t perRepOutput = static_cast<uint32_t>(ReduceCheckExtParams::VREDUCE_PER_REP_OUTPUT);
      99            8 :     uint32_t it1AlignStart = 0;
     100            8 :     uint32_t it1OutputCount = perRepOutput * param_.repeatTimes; // 2
     101            8 :     uint64_t needElement = static_cast<uint32_t>(perRepOutput * param_.repeatTimes);
     102              : 
     103            8 :     if (!param_.calIndex) {
     104            0 :         return CheckCheckWorkSize(errMsg, needElement, typeSize);
     105              :     }
     106              : 
     107              :     // iteration1
     108            8 :     if (it1OutputCount == perRepOutput) {
     109            0 :         resIndex = it1AlignStart + it1OutputCount;
     110            0 :         needElement = resIndex;
     111            0 :         return CheckCheckWorkSize(errMsg, needElement, typeSize);
     112              :     }
     113              : 
     114            8 :     if (typeSize == 0) {
     115            0 :         CHECK_LOG_ERROR("dtype bytes is zeros");
     116            0 :         return false;
     117              :     }
     118              : 
     119              :     // iteration2
     120            8 :     uint32_t it2AlignStart = AlignStartPos(it1OutputCount, typeSize);
     121            8 :     uint32_t elementNumPerRep = static_cast<uint32_t>(PlatFormParams::ONE_REP_BYTE_SIZE) / typeSize;
     122            8 :     if (elementNumPerRep == 0) {
     123            0 :         CHECK_LOG_ERROR(
     124              :             "%s, "
     125              :             "elementNumPerRep can not be 0.",
     126              :             errMsg.c_str());
     127            0 :         return false;
     128              :     }
     129           16 :     ReduceBodyCal(
     130              :         {it1OutputCount, it2AlignStart, elementNumPerRep, typeSize, perRepOutput}, it2OutputCount, it3StartPos);
     131              : 
     132            8 :     if (it2OutputCount == perRepOutput) {
     133            8 :         it3StartPos = it2AlignStart;
     134            8 :         resIndex = it3StartPos + 1;
     135              :     } else {
     136              :         // iteration3
     137            0 :         resIndex = it3StartPos + 1;
     138            0 :         if (it2OutputCount > elementNumPerRep) {
     139              :             uint32_t tmpVal;
     140              :             uint32_t it4StartPos;
     141            0 :             ReduceBodyCal({it2OutputCount, it3StartPos, elementNumPerRep, typeSize, perRepOutput}, tmpVal, it4StartPos);
     142            0 :             resIndex = it4StartPos + 1;
     143              :         }
     144              :     }
     145            8 :     needElement = resIndex + 1;
     146            8 :     return CheckCheckWorkSize(errMsg, needElement, typeSize);
     147              : }
     148              : 
     149           12 : bool TikcppVecReduceCheck::CheckWorkTensorSizeEqual(const std::string& errMsg)
     150              : {
     151           12 :     uint64_t needSize = static_cast<uint64_t>(param_.repeatTimes * param_.src1DtypeBytes);
     152           12 :     if (needSize > param_.src1Size) {
     153            4 :         CHECK_LOG_ERROR(
     154              :             "%s, "
     155              :             "Need size: %lu, while tensor size is %lu",
     156              :             errMsg.c_str(), needSize, param_.src1Size);
     157            4 :         return false;
     158              :     }
     159              : 
     160            8 :     return true;
     161              : }
     162              : 
     163           40 : bool TikcppVecReduceCheck::CheckDstTensorSizeRange(const std::string& errMsg)
     164              : {
     165           40 :     uint32_t needCount = 1;
     166           40 :     uint64_t needSize = 0;
     167           40 :     if (param_.calIndex) {
     168           24 :         needCount = static_cast<uint32_t>(ReduceCheckExtParams::VREDUCE_CALL_INDEX_COUNT);
     169              :     }
     170           40 :     needSize = static_cast<uint64_t>(needCount * param_.dstDtypeBytes);
     171              : 
     172           40 :     if (needSize > param_.dstSize) {
     173            0 :         CHECK_LOG_ERROR(
     174              :             "%s, "
     175              :             "Need least output size: %lu, while tensor size is %lu",
     176              :             errMsg.c_str(), needSize, param_.dstSize);
     177            0 :         return false;
     178              :     }
     179           40 :     return true;
     180              : }
     181              : 
     182           40 : bool TikcppVecReduceCheck::CheckAddrAlign()
     183              : {
     184           80 :     bool srcRes = CheckTensorAddrAlign(param_.src0Addr, param_.src0Pos, ONE_BLK_SIZE, "src");
     185           80 :     bool dstRes = CheckTensorAddrAlign(param_.dstAddr, param_.dstPos, param_.dstDtypeBytes, "dst");
     186           80 :     bool src1Res = CheckTensorAddrAlign(param_.src1Addr, param_.src1Pos, param_.dstDtypeBytes, "work");
     187           40 :     return srcRes && dstRes && src1Res;
     188              : }
     189              : 
     190           40 : bool TikcppVecReduceCheck::CommonCheck()
     191              : {
     192           80 :     ASCENDC_CHECK(CheckAllDtypeBytes("Check Reduce data type"));
     193           80 :     ASCENDC_CHECK(CheckDstTensorSizeRange("Check Reduce dst data size"));
     194              : 
     195           40 :     const std::string supportPos = "VECIN/VECOUT/VECCALC";
     196          120 :     ASCENDC_CHECK(CheckTensorScope(param_.dstLogicPos, static_cast<uint8_t>(HardWareIndex::UB), "dst", supportPos));
     197          120 :     ASCENDC_CHECK(CheckTensorScope(param_.src0LogicPos, static_cast<uint8_t>(HardWareIndex::UB), "src", supportPos));
     198          120 :     ASCENDC_CHECK(CheckTensorScope(param_.src1LogicPos, static_cast<uint8_t>(HardWareIndex::UB), "work", supportPos));
     199              : 
     200           40 :     ASCENDC_CHECK(CheckAddrAlign());
     201              : 
     202          120 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     203              :         param_.dstSize, GlobalParams::Instance().bufferSizeMap.at(param_.dstPos),
     204              :         "check dst tensor buffersize failed"));
     205          120 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     206              :         param_.src0Size, GlobalParams::Instance().bufferSizeMap.at(param_.src0Pos),
     207              :         "check src tensor buffersize failed"));
     208          120 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     209              :         param_.src1Size, GlobalParams::Instance().bufferSizeMap.at(param_.src1Pos),
     210              :         "check work tensor buffersize failed"));
     211           40 :     return true;
     212           40 : }
     213              : 
     214           32 : bool TikcppVecReduceCheck::CheckAllHighLevel()
     215              : {
     216              :     // Only for reduce interface level 2
     217           32 :     ASCENDC_CHECK(CommonCheck());
     218              : 
     219           96 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, param_.calCount, "src0Local"));
     220           12 :     if (apiName == "ReduceSum") {
     221            8 :         ASCENDC_CHECK(CheckWorkTensorSizeEqual("Check Reduce Sum workLocal tensor size"));
     222            8 :     } else if (apiName == "ReduceMax") {
     223           16 :         ASCENDC_CHECK(CheckWorkTensorOffset("Check Reduce max workLocal tensor size"));
     224              :     } else {
     225            0 :         ASCENDC_CHECK(CheckWorkTensorOffset("Check Reduce min workLocal tensor size"));
     226              :     }
     227           12 :     return true;
     228              : }
     229              : 
     230            4 : bool TikcppVecReduceCheck::CheckAllHighLevelMode2()
     231              : {
     232            4 :     uint32_t dstDtypeBytes = param_.dstDtypeBytes;
     233            4 :     uint32_t srcDtypeBytes = param_.src0DtypeBytes;
     234            4 :     if (dstDtypeBytes != srcDtypeBytes) {
     235            4 :         CHECK_LOG_ERROR(
     236              :             "Check Reduce data type, Reduce need dst data type (%u), src data type (%u) should be same", dstDtypeBytes,
     237              :             srcDtypeBytes);
     238            4 :         return false;
     239              :     }
     240              : 
     241            0 :     ASCENDC_CHECK(CheckDstTensorSizeRange("Check Reduce dst data size"));
     242              : 
     243            0 :     const std::string supportPos = "VECIN/VECOUT/VECCALC";
     244            0 :     ASCENDC_CHECK(CheckTensorScope(param_.dstLogicPos, static_cast<uint8_t>(HardWareIndex::UB), "dst", supportPos));
     245            0 :     ASCENDC_CHECK(CheckTensorScope(param_.src0LogicPos, static_cast<uint8_t>(HardWareIndex::UB), "src", supportPos));
     246              : 
     247            0 :     bool srcRes = CheckTensorAddrAlign(param_.src0Addr, param_.src0Pos, ONE_BLK_SIZE, "src");
     248            0 :     bool dstRes = CheckTensorAddrAlign(param_.dstAddr, param_.dstPos, param_.dstDtypeBytes, "dst");
     249            0 :     ASCENDC_CHECK(srcRes && dstRes);
     250              : 
     251            0 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     252              :         param_.dstSize, GlobalParams::Instance().bufferSizeMap.at(param_.dstPos),
     253              :         "check dst tensor buffersize failed"));
     254            0 :     ASCENDC_CHECK(CheckBufferSizeOverFlow(
     255              :         param_.src0Size, GlobalParams::Instance().bufferSizeMap.at(param_.src0Pos),
     256              :         "check src tensor buffersize failed"));
     257            0 :     ASCENDC_CHECK(CheckTensorOverflowHigh(param_.src0DtypeBytes, param_.src0Size, param_.calCount, "src0Local"));
     258              : 
     259            0 :     return true;
     260            0 : }
     261              : 
     262            8 : bool TikcppVecReduceCheck::CheckAllLowLevel(std::vector<uint64_t> maskArray)
     263              : {
     264            8 :     uint32_t maxByteLen = param_.dstDtypeBytes;
     265            8 :     ASCENDC_CHECK(UpdateMaskArrayAndCheck(maskArray, maxByteLen));
     266            8 :     ASCENDC_CHECK(CommonCheck());
     267              : 
     268              :     TensorOverflowParams params = {
     269            8 :         param_.src0Size,
     270            8 :         param_.src0DtypeBytes,
     271            8 :         static_cast<uint64_t>(param_.repeatTimes),
     272            8 :         static_cast<uint64_t>(param_.src0BlockStride),
     273            8 :         static_cast<uint64_t>(param_.src0RepeatStride),
     274            8 :         false};
     275           24 :     ASCENDC_CHECK(CheckTensorOverflowLow(maskArray, params, "src0Local"));
     276            8 :     if (apiName == "ReduceSum") {
     277           16 :         ASCENDC_CHECK(CheckWorkTensorSizeEqual("Check Reduce sum workLocal tensor size"));
     278            0 :     } else if (apiName == "ReduceMax") {
     279            0 :         ASCENDC_CHECK(CheckWorkTensorOffset("Check Reduce max workLocal tensor size"));
     280              :     } else {
     281            0 :         ASCENDC_CHECK(CheckWorkTensorOffset("Check Reduce min workLocal tensor size"));
     282              :     }
     283            4 :     return true;
     284              : }
     285              : } // namespace check
     286              : } // namespace AscendC
        

Generated by: LCOV version 2.0-1