Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 : #include "ccu_rep_v1.h"
12 : #include <climits>
13 :
14 : #include "exception_util.h"
15 : #include "ccu_api_exception.h"
16 : #include "ccu_ins_generator_base.h"
17 : #include "ccu_ins_generator_v1.h"
18 : #include "ccu_ins_generator_v2.h"
19 :
20 : namespace hcomm {
21 : namespace CcuRep {
22 :
23 : using namespace Hccl;
24 :
25 10 : CcuRepLoop::CcuRepLoop(CcuInsGeneratorBase* insGeneratorPtr, const std::string& label, const Variable& loopParam)
26 10 : : insGeneratorPtr_(insGeneratorPtr),
27 10 : label(label),
28 10 : loopParam(loopParam)
29 : {
30 10 : type = CcuRepType::LOOP;
31 10 : instrCount = insGeneratorPtr_->GetInstrCount(type);
32 10 : supportCcuV1 = true;
33 10 : supportCcuV2 = false; // 缺少A6格式下必需的loop参数
34 10 : }
35 :
36 0 : CcuRepLoop::CcuRepLoop(
37 : CcuInsGeneratorBase* insGeneratorPtr, const std::string& label, const Variable& loopParam,
38 0 : const Variable& loopIterNum, const Variable& loopGsaOffset)
39 0 : : insGeneratorPtr_(insGeneratorPtr),
40 0 : label(label),
41 0 : loopParam(loopParam),
42 0 : loopIterNum(loopIterNum),
43 0 : loopGsaOffset(loopGsaOffset)
44 : {
45 0 : type = CcuRepType::LOOP;
46 0 : instrCount = insGeneratorPtr_->GetInstrCount(type);
47 0 : supportCcuV1 = false; // loopParam按照A6格式填写,不适用A5
48 0 : supportCcuV2 = true;
49 0 : }
50 :
51 5 : void CcuRepLoop::ValidateInsGeneratorForLoop()
52 : {
53 5 : CcuInsGeneratorV1* tmpPtrV1 = dynamic_cast<CcuInsGeneratorV1*>(insGeneratorPtr_);
54 5 : CcuInsGeneratorV2* tmpPtrV2 = dynamic_cast<CcuInsGeneratorV2*>(insGeneratorPtr_);
55 5 : if (tmpPtrV1 && !supportCcuV1) {
56 : // 在A5场景下没有使用A5的loop调用方式
57 0 : Hccl::THROW<Hccl::CcuApiException>("Cannot translate CcuRepLoop when supportCcuV1 is false!");
58 : }
59 5 : if (tmpPtrV2 && !supportCcuV2) {
60 : // 在A5场景下没有使用A6的loop调用方式
61 0 : Hccl::THROW<Hccl::CcuApiException>("Cannot translate CcuRepLoop when supportCcuV2 is false!");
62 : }
63 5 : }
64 :
65 1 : const std::string& CcuRepLoop::GetLabel() const { return label; }
66 :
67 5 : void CcuRepLoop::Reference(std::shared_ptr<CcuRepLoopBlock> refRep) { loopBlock = refRep; }
68 :
69 1 : std::shared_ptr<CcuRepBase> CcuRepLoop::SetLoopParam(Executor executor, Variable var)
70 : {
71 1 : return std::make_shared<CcuRepSetLoop>(insGeneratorPtr_, loopParam, executor, var);
72 : }
73 :
74 5 : bool CcuRepLoop::Translate(
75 : [[maybe_unused]] CcuKernel* ccuKernel, CcuInstr*& instr, uint16_t& instrId, const TransDep& dep)
76 : {
77 : (void)dep;
78 5 : ValidateInsGeneratorForLoop();
79 :
80 5 : this->instrId = instrId;
81 5 : translated = true;
82 :
83 6 : Hccl::CHECK_NULLPTR(loopBlock, "[CcuRepLoop::Translate] LoopBlock is nullptr!");
84 :
85 4 : if (!loopBlock->Translated()) {
86 1 : Hccl::THROW<Hccl::CcuApiException>("Reference To Invalid LoopBlock");
87 : }
88 :
89 3 : uint16_t startInstrId = loopBlock->StartInstrId();
90 3 : uint16_t loopBlockInstrCount = loopBlock->InstrCount();
91 3 : if (loopBlockInstrCount == 0) {
92 1 : HCCL_ERROR(
93 : "[CcuRepLoop][Translate] loopBlockInstrCount[%u] is 0, which causes underflow in endInstrId "
94 : "calculation.",
95 : loopBlockInstrCount);
96 1 : return false;
97 : }
98 2 : if (startInstrId > USHRT_MAX - loopBlockInstrCount) {
99 0 : HCCL_ERROR(
100 : "[CcuRepLoop][Translate] startInstrId[%u] + loopBlockInstrCount[%u] exceeds the maximum value of "
101 : "unsigned short int.",
102 : startInstrId, loopBlockInstrCount);
103 0 : return false;
104 : }
105 :
106 2 : if (instrId > USHRT_MAX - instrCount) {
107 1 : HCCL_ERROR("[CcuRepLoop][Translate] instrId[%u] exceeds the maximum value of unsigned short int.", instrId);
108 1 : return false;
109 : }
110 :
111 1 : uint16_t endInstrId = startInstrId + loopBlockInstrCount - 1;
112 :
113 1 : LoopInstr(instr++, startInstrId, endInstrId, loopParam.Id());
114 :
115 1 : instrId += instrCount;
116 :
117 1 : return translated;
118 : }
119 :
120 1 : std::string CcuRepLoop::Describe() { return Hccl::StringFormat("Loop reference to [%s]", label.c_str()); }
121 :
122 : }; // namespace CcuRep
123 : }; // namespace hcomm
|