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_other_whl_check.cpp
13 : * \brief
14 : */
15 :
16 : #include "kernel_check_params.h"
17 : #include "model/model_factory_mask.h"
18 : #include "kernel_vec_reduce_other_whl_check.h"
19 :
20 : namespace AscendC {
21 : namespace check {
22 :
23 32 : bool TikcppVecReduceOtherWhlCheck::CheckWholeReduceDtypeBytes(const std::string& errMsg)
24 : {
25 32 : uint32_t dstDtypeBytes = params_.dstDtypeBytes;
26 32 : uint32_t srcDtypeBytes = params_.src0DtypeBytes;
27 32 : if (dstDtypeBytes != srcDtypeBytes) {
28 4 : CHECK_LOG_ERROR(
29 : "%s, "
30 : "Reduce need dst data type (%u),dst src type (%u), should be same",
31 : errMsg.c_str(), dstDtypeBytes, srcDtypeBytes);
32 4 : return false;
33 : }
34 28 : return true;
35 : }
36 :
37 20 : bool TikcppVecReduceOtherWhlCheck::CheckAddrAlign()
38 : {
39 20 : uint8_t alignByte = 4; // float type align Bytes is 4B
40 20 : if (params_.dstDtypeBytes == sizeof(half)) {
41 16 : alignByte = 2; // half type align Bytes is 2B
42 : }
43 60 : return CheckTensorAddrAlign(params_.dstAddr, params_.dstPos, alignByte, "dst");
44 : }
45 :
46 0 : static bool CheckTensorWhlOverflowLowCounter(
47 : std::vector<uint64_t>& maskArray, const VecReduceWhlApiParams& param, const uint64_t unit,
48 : const std::string& tensorName, const std::string& apiName)
49 : {
50 0 : uint32_t oneRepeatNum = ONE_REPEAT_BYTE_SIZE / param.dstDtypeBytes; // when counter mode, always full mask
51 0 : uint64_t elementNum = (maskArray.size() == 1) ? maskArray[0] : maskArray[1]; // maskLow means element num
52 0 : int32_t repeatTimes = (elementNum + oneRepeatNum - 1) / oneRepeatNum;
53 0 : uint32_t needSize = (repeatTimes - 1) * param.dstRepeatStride * unit + unit;
54 0 : ASCENDC_CHECK(CheckTensorSizeOverflow(needSize, param.dstSize, tensorName, apiName, ModeType::COUNTER_MODE));
55 0 : return true;
56 : }
57 :
58 28 : static bool CheckTensorWhlOverflowLowNorm(
59 : const VecReduceWhlApiParams& param, const uint64_t unit, const std::string& tensorName, const std::string& apiName)
60 : {
61 28 : uint32_t needSize = (param.repeatTimes - 1) * param.dstRepeatStride * unit;
62 28 : if (param.order == ReduceOrder::ORDER_VALUE_INDEX || param.order == ReduceOrder::ORDER_INDEX_VALUE) {
63 12 : needSize = needSize + param.dstDtypeBytes * 2; // the DtypeBytes of index
64 16 : } else if (param.order == ReduceOrder::ORDER_ONLY_VALUE) {
65 8 : needSize = needSize + param.dstDtypeBytes;
66 8 : } else if (param.order == ReduceOrder::ORDER_ONLY_INDEX) {
67 8 : needSize = needSize + sizeof(uint32_t);
68 : }
69 28 : ASCENDC_CHECK(CheckTensorSizeOverflow(needSize, param.dstSize, tensorName, apiName, ModeType::NORM_MODE));
70 16 : return true;
71 : }
72 :
73 : // the unit of dstRepStride is Byte
74 28 : bool TikcppVecReduceOtherWhlCheck::CheckTensorWhlOverflowLow(
75 : std::vector<uint64_t>& maskArray, const uint64_t unit, const std::string& tensorName)
76 : {
77 28 : if (ModelFactoryGetMaskMode() == 1) { // counter mode
78 0 : return CheckTensorWhlOverflowLowCounter(maskArray, params_, unit, tensorName, apiName);
79 : }
80 28 : return CheckTensorWhlOverflowLowNorm(params_, unit, tensorName, apiName);
81 : }
82 :
83 32 : bool TikcppVecReduceOtherWhlCheck::CheckAllLowLevel(std::vector<uint64_t> maskArray)
84 : {
85 32 : uint32_t maxByteLen = std::max(params_.dstDtypeBytes, params_.src0DtypeBytes);
86 32 : ASCENDC_CHECK(UpdateMaskArrayAndCheck(maskArray, maxByteLen));
87 :
88 32 : if ((apiName == "WholeReduceMax") || (apiName == "WholeReduceMin")) {
89 64 : ASCENDC_CHECK(CheckWholeReduceDtypeBytes("Check Whole Reduce data type"));
90 28 : if (params_.order == ReduceOrder::ORDER_VALUE_INDEX || params_.order == ReduceOrder::ORDER_INDEX_VALUE) {
91 12 : constexpr uint32_t MULTIPLIE = 2; // The unit of dstRepStride is twice the length of bytes
92 24 : ASCENDC_CHECK(CheckTensorWhlOverflowLow(maskArray, MULTIPLIE * params_.dstDtypeBytes, "dstLocal"));
93 24 : } else if (params_.order == ReduceOrder::ORDER_ONLY_VALUE) {
94 16 : ASCENDC_CHECK(CheckTensorWhlOverflowLow(maskArray, params_.dstDtypeBytes, "dstLocal"));
95 8 : } else if (params_.order == ReduceOrder::ORDER_ONLY_INDEX) {
96 16 : ASCENDC_CHECK(CheckTensorWhlOverflowLow(maskArray, sizeof(uint32_t), "dstLocal"));
97 : }
98 : }
99 :
100 16 : const std::string supportPos = "VECIN/VECOUT/VECCALC";
101 48 : ASCENDC_CHECK(CheckTensorScope(params_.dstLogicPos, static_cast<uint8_t>(HardWareIndex::UB), "dst", supportPos));
102 48 : ASCENDC_CHECK(CheckTensorScope(params_.src0LogicPos, static_cast<uint8_t>(HardWareIndex::UB), "src", supportPos));
103 :
104 16 : ASCENDC_CHECK(CheckAddrAlign());
105 :
106 48 : ASCENDC_CHECK(CheckBufferSizeOverFlow(
107 : params_.dstSize, GlobalParams::Instance().bufferSizeMap.at(params_.dstPos),
108 : "check dst tensor buffersize failed"));
109 48 : ASCENDC_CHECK(CheckBufferSizeOverFlow(
110 : params_.src0Size, GlobalParams::Instance().bufferSizeMap.at(params_.src0Pos),
111 : "check src tensor buffersize failed"));
112 :
113 : TensorOverflowParams params = {
114 16 : params_.src0Size,
115 16 : params_.src0DtypeBytes,
116 16 : static_cast<uint64_t>(params_.repeatTimes),
117 16 : static_cast<uint64_t>(params_.src0BlockStride),
118 16 : static_cast<uint64_t>(params_.src0RepeatStride),
119 16 : false};
120 48 : ASCENDC_CHECK(CheckTensorOverflowLow(maskArray, params, "srcLocal"));
121 16 : return true;
122 16 : }
123 : } // namespace check
124 : } // namespace AscendC
|