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 : #include "sqe_build_a5.h"
12 : #include "communicator_impl_lite_manager.h"
13 :
14 : namespace Hccl {
15 :
16 2 : u32 GetKernelExecTimeoutFromEnvConfig()
17 : {
18 2 : const u32 envTimeout = CommunicatorImplLiteMgr::GetInstance().GetEnvConfig().hcclExecTimeout;
19 2 : return envTimeout;
20 : }
21 :
22 : namespace {
23 1 : void ConstructLHWI(const Rt91095StarsCondIsaRegister_t dstReg, const u64 immd, Rt91095StarsCondOpLHWI_t& opLHWI)
24 : {
25 1 : opLHWI.opCode = static_cast<uint32_t>(Hccl::Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_LWI);
26 1 : opLHWI.func3 = static_cast<uint32_t>(Rt91095StarsCondIsaLwiFunc3_t::RT_91095_STARS_COND_ISA_LWI_FUNC3_LHWI);
27 1 : opLHWI.rd = static_cast<uint32_t>(dstReg);
28 1 : opLHWI.immd = static_cast<uint32_t>((immd >> 49U) & 0x7FFFU); // High15-immd[63:49]
29 1 : }
30 :
31 1 : void ConstructLLWI(const Rt91095StarsCondIsaRegister_t dstReg, const u64 immd, Rt91095StarsCondOpLLWI_t& opLLWI)
32 : {
33 1 : opLLWI.opCode = static_cast<uint32_t>(Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_LWI);
34 1 : opLLWI.func3 = static_cast<uint32_t>(Rt91095StarsCondIsaLwiFunc3_t::RT_91095_STARS_COND_ISA_LWI_FUNC3_LLWI);
35 1 : opLLWI.rd = static_cast<uint32_t>(dstReg);
36 1 : opLLWI.immdHigh = static_cast<uint32_t>((immd >> 32U) & 0x1FFFFU); // Low49-immd[48:32]
37 1 : opLLWI.immdLow = static_cast<uint32_t>(immd & 0xFFFFFFFFU); // Low49-immd[31:0]
38 1 : }
39 :
40 3 : void ConstructLoadImm(
41 : const Rt91095StarsCondIsaRegister_t dstReg, const u64 addr, const Rt91095StarsCondIsaLoadImmFunc3_t func3,
42 : Rt91095StarsCondOpLoadImm_t& loadImm)
43 : {
44 3 : loadImm.opCode = static_cast<uint32_t>(Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_LOAD_IMM);
45 3 : loadImm.rd = static_cast<uint32_t>(dstReg);
46 3 : loadImm.func3 = static_cast<uint32_t>(func3);
47 3 : loadImm.immdAddrHigh = static_cast<uint32_t>((addr >> 32U) & 0X1FFFFU); // bit[48:32]
48 3 : loadImm.immdAddrLow = static_cast<uint32_t>(addr & 0xFFFFFFFFU); // bit[31:0]
49 3 : }
50 :
51 1 : void ConstructBranch(
52 : const Rt91095StarsCondIsaRegister_t rs1Reg, const Rt91095StarsCondIsaRegister_t rs2Reg,
53 : const Rt91095StarsCondIsaBranchFunc3_t func3, const uint8_t instrOffset, Rt91095StarsCondOpBranch_t& opBranch)
54 : {
55 1 : opBranch.opCode = static_cast<uint32_t>(Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_BRANCH);
56 1 : opBranch.func3 = static_cast<uint32_t>(func3);
57 1 : opBranch.rs1 = static_cast<uint32_t>(rs1Reg);
58 1 : opBranch.rs2 = static_cast<uint32_t>(rs2Reg);
59 1 : opBranch.jumpInstrOffset = instrOffset & 0xFU; // Jump-immd[3:0]
60 1 : }
61 :
62 1 : void ConstructStore(
63 : const Rt91095StarsCondIsaRegister_t addrReg, const Rt91095StarsCondIsaRegister_t valReg,
64 : const uint16_t immdOffset, const Rt91095StarsCondIsaStoreFunc3_t func3, Rt91095StarsCondOpStore_t& opStore)
65 : {
66 1 : opStore.opCode = static_cast<uint32_t>(Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_STORE);
67 1 : opStore.immdLow = static_cast<uint8_t>(immdOffset & 0x1FU); // S-immd[4:0]
68 1 : opStore.func3 = static_cast<uint32_t>(func3);
69 1 : opStore.rs1 = static_cast<uint32_t>(addrReg);
70 1 : opStore.rs2 = static_cast<uint32_t>(valReg);
71 1 : opStore.immdHigh = static_cast<uint8_t>((immdOffset & 0xFE0U) >> 5U); // S-immd[11:5]
72 1 : }
73 :
74 13 : void ConstructNop(Rt91095StarsCondOpNop_t& nop)
75 : {
76 13 : nop.opCode = static_cast<uint32_t>(Rt91095StarsCondIsaOpCode_t::RT_91095_STARS_COND_ISA_OP_CODE_NOP);
77 13 : nop.rd = static_cast<uint32_t>(Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R0);
78 13 : nop.func3 = static_cast<uint32_t>(Rt91095StarsCondIsaOpImmFunc3_t::RT_91095_STARS_COND_ISA_OP_IMM_FUNC3_NOP);
79 13 : nop.rs1 = static_cast<uint32_t>(Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R0);
80 13 : nop.immd = 0U;
81 13 : }
82 : } // namespace
83 :
84 1 : void BuildA5SqeCCoreNotifyWait(u32 streamId, u32 taskId, u64 waitAddr, u64 actAddr, bool last, uint8_t* const sqeIn)
85 : {
86 1 : Rt91095StarsCCoreSqeNotifyWait* sqe = (Rt91095StarsCCoreSqeNotifyWait*)sqeIn;
87 1 : sqe->header.type = static_cast<uint8_t>(Rt91095StarsSqeType::RT_91095_SQE_TYPE_COND);
88 1 : sqe->header.rtStreamId = static_cast<uint16_t>(taskId);
89 1 : sqe->header.taskId = static_cast<uint16_t>(taskId >> LOW_BITS);
90 :
91 1 : sqe->kernelCredit = RT_STARS_DEFAULT_KERNEL_CREDIT;
92 1 : sqe->csc = 1U;
93 :
94 1 : constexpr Rt91095StarsCondIsaRegister_t r0 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R0;
95 1 : constexpr Rt91095StarsCondIsaRegister_t r1 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R1;
96 1 : constexpr Rt91095StarsCondIsaRegister_t r2 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R2;
97 1 : constexpr Rt91095StarsCondIsaRegister_t r3 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R3;
98 :
99 : // load current Turn to r3
100 1 : ConstructLoadImm(
101 1 : r3, actAddr, Rt91095StarsCondIsaLoadImmFunc3_t::RT_91095_STARS_COND_ISA_LOAD_IMM_FUNC3_LHU, sqe->ldrImm1);
102 :
103 : // load sendcnt to r2
104 1 : ConstructLoadImm(
105 1 : r2, waitAddr, Rt91095StarsCondIsaLoadImmFunc3_t::RT_91095_STARS_COND_ISA_LOAD_IMM_FUNC3_LHU, sqe->ldrImm2);
106 1 : uint8_t loadInstrOff
107 : = (offsetof(Rt91095StarsCCoreSqeNotifyWait, ldrImm2) - offsetof(Rt91095StarsCCoreSqeNotifyWait, ldrImm1));
108 1 : loadInstrOff = loadInstrOff / sizeof(uint32_t);
109 :
110 : // r2(sendCnt) < r3(curTurn),goto reload r2
111 1 : ConstructBranch(
112 1 : r2, r3, Rt91095StarsCondIsaBranchFunc3_t::RT_91095_STARS_COND_ISA_BRANCH_FUNC3_BLTU, loadInstrOff, sqe->beq);
113 :
114 1 : if (last) {
115 : // load sendcount addr to r1
116 0 : ConstructLLWI(r1, waitAddr, sqe->clear.llwi1);
117 0 : ConstructLHWI(r1, waitAddr, sqe->clear.lhwi1);
118 : // the last turn clear sendCnt, r0(0) value store to r1(sendCnt),
119 0 : ConstructStore(
120 0 : r1, r0, 0U, Rt91095StarsCondIsaStoreFunc3_t::RT_91095_STARS_COND_ISA_STORE_FUNC3_SH, sqe->clear.sw);
121 0 : for (Rt91095StarsCondOpNop_t& nop : sqe->clear.nop) {
122 0 : ConstructNop(nop);
123 : }
124 : } else {
125 8 : for (Rt91095StarsCondOpNop_t& nop : sqe->nop) {
126 7 : ConstructNop(nop);
127 : }
128 : }
129 :
130 3 : HCCL_INFO(
131 : "[SQE]CCoreWait: waitAddr=%llu, actAddr=%llu, last=%u, streamId=%u, taskId=%u, "
132 : "ISA=%08x %08x %08x %08x %08x %08x %08x",
133 : waitAddr, actAddr, last, streamId, taskId, sqe->ldrImm1, sqe->ldrImm2, sqe->beq, sqe->clear.llwi1,
134 : sqe->clear.lhwi1, sqe->clear.sw, sqe->clear.nop[0]);
135 1 : }
136 :
137 1 : void BuildA5SqeCCoreNotifyRecord(u32 streamId, u32 taskId, u64 writeAddr, u64 valueAddr, uint8_t* const sqeIn)
138 : {
139 1 : Rt91095StarsCCoreSqeNotifyRecord* sqe = (Rt91095StarsCCoreSqeNotifyRecord*)sqeIn;
140 1 : sqe->header.type = static_cast<uint8_t>(Rt91095StarsSqeType::RT_91095_SQE_TYPE_COND);
141 1 : sqe->header.rtStreamId = static_cast<uint16_t>(taskId);
142 1 : sqe->header.taskId = static_cast<uint16_t>(taskId >> LOW_BITS);
143 :
144 1 : sqe->kernelCredit = RT_STARS_DEFAULT_KERNEL_CREDIT;
145 1 : sqe->csc = 1U;
146 :
147 1 : constexpr Rt91095StarsCondIsaRegister_t r1 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R1;
148 1 : constexpr Rt91095StarsCondIsaRegister_t r2 = Rt91095StarsCondIsaRegister_t::RT_91095_STARS_COND_ISA_REGISTER_R2;
149 :
150 1 : ConstructLoadImm(
151 1 : r1, valueAddr, Rt91095StarsCondIsaLoadImmFunc3_t::RT_91095_STARS_COND_ISA_LOAD_IMM_FUNC3_LHU, sqe->ldrImm);
152 1 : ConstructLLWI(r2, writeAddr, sqe->llwi1);
153 1 : ConstructLHWI(r2, writeAddr, sqe->lhwi1);
154 :
155 1 : ConstructStore(r2, r1, 0U, Rt91095StarsCondIsaStoreFunc3_t::RT_91095_STARS_COND_ISA_STORE_FUNC3_SH, sqe->sw);
156 7 : for (Rt91095StarsCondOpNop_t& nop : sqe->nop) {
157 6 : ConstructNop(nop);
158 : }
159 :
160 3 : HCCL_INFO(
161 : "[SQE]CCoreWrite: writeAddr=%p, valueAddr=%p, streamId=%u, taskId=%u, "
162 : "ISA=%08x %08x %08x %08x %08x",
163 : writeAddr, valueAddr, streamId, taskId, sqe->ldrImm, sqe->llwi1, sqe->lhwi1, sqe->sw, sqe->nop[0]);
164 1 : }
165 :
166 : // 写64bit值的形式来完成敲DB
167 6 : void BuildA5SqeRdmaDbSend(u32 streamId, u32 taskId, u64 dbAddr, u64 dbValue, uint8_t* const sqeIn)
168 : {
169 : (void)streamId;
170 6 : Rt91095StarsWriteValueSqe* sqe = reinterpret_cast<Rt91095StarsWriteValueSqe*>(sqeIn);
171 6 : SetSqeHeaderTaskFields(sqe, taskId);
172 6 : sqe->header.type = static_cast<uint8_t>(Rt91095StarsSqeType::RT_91095_SQE_TYPE_WRITE_VALUE);
173 :
174 6 : sqe->kernelCredit = RT_STARS_DEFAULT_KERNEL_CREDIT;
175 6 : sqe->header.rtStreamId = streamId;
176 6 : sqe->header.taskId = taskId;
177 :
178 6 : sqe->writeAddrLow = dbAddr & MASK_32_BIT;
179 6 : sqe->writeAddrHigh = (dbAddr >> UINT32_BIT_NUM) & MASK_17_BIT;
180 :
181 6 : sqe->awsize = RtStarsWriteValueSizeType::RT_STARS_WRITE_VALUE_SIZE_TYPE_64BIT; // writeValue 为 8 byte
182 6 : sqe->writeValuePart[0] = static_cast<uint32_t>(dbValue & MASK_32_BIT); // low 32 bit
183 6 : sqe->writeValuePart[1] = static_cast<uint32_t>((dbValue >> UINT32_BIT_NUM) & MASK_32_BIT); // high 32 bit
184 :
185 6 : sqe->va = 1U;
186 6 : }
187 :
188 : } // namespace Hccl
|