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 : #include "dev_ub_connection.h"
11 :
12 : #include <cstdlib>
13 :
14 : #include "hccp_ctx.h"
15 : #include "exception_util.h"
16 : #include "rma_conn_exception.h"
17 : #include "rdma_handle_manager.h"
18 : #include "exchange_ub_conn_dto.h"
19 : #include "env_config/env_config.h"
20 :
21 : namespace Hccl {
22 :
23 : constexpr u32 OPBASED_UB_SQ_DEPTH_MAX = 8192;
24 : constexpr u32 UB_SQ_OFFLOAD_DEPTH = 128;
25 : constexpr u32 UB_SQ_WQEBB_SIZE = 64;
26 : constexpr u32 WQE_NUM_PER_SQE = 4; // URMA约束每个SQE包含4个WQEBB
27 : constexpr u32 UB_MAX_TRANS_SIZE = 256 * 1024 * 1024; // UB单次最大传输量256*1024*1024 Byte
28 :
29 104 : DevUbConnection::DevUbConnection(const RdmaHandle rdmaHandle, const IpAddress &locAddr, const IpAddress &rmtAddr,
30 : const OpMode opMode, const bool devUsed, const HrtUbJfcMode jfcMode,
31 104 : const IpAddress &locIpv4Addr, const IpAddress &rmtIpv4Addr, u8 qos, CommEngine engine)
32 104 : : RmaConnection(nullptr, RmaConnType::UB), rdmaHandle(rdmaHandle), locAddr(locAddr), rmtAddr(rmtAddr),
33 104 : opMode(opMode), jfcMode(jfcMode), engine_(engine), locIpv4Addr(locIpv4Addr), rmtIpv4Addr(rmtIpv4Addr),
34 104 : rmtEid(rmtAddr.GetReverseEid()), locEid(locAddr.GetReverseEid()), qos_(qos), devUsed_(devUsed)
35 : {
36 312 : HCCL_INFO("[DevUbConnection::DevUbConnection] rmtEid=%s, engine=%d", rmtEid.Describe().c_str(),
37 : static_cast<s32>(engine_));
38 104 : devLogicId = HrtGetDevice();
39 :
40 104 : auto dieIdAndFuncId = RdmaHandleManager::GetInstance().GetDieAndFuncId(rdmaHandle); // 获取dieId和FuncId
41 104 : dieId = dieIdAndFuncId.first;
42 104 : funcId = dieIdAndFuncId.second;
43 :
44 104 : if (engine_ == COMM_ENGINE_AIV) {
45 1 : CreateAivUrmaJfc();
46 103 : } else if (jfcMode == HrtUbJfcMode::USER_CTL) {
47 0 : jfcHandle = RdmaHandleManager::GetInstance().GetJfcHandleAndCqInfo(rdmaHandle, cqInfo_, jfcMode);
48 : } else {
49 103 : jfcHandle = RdmaHandleManager::GetInstance().GetJfcHandle(rdmaHandle, cqInfo_, jfcMode);
50 : }
51 104 : isdevUsed = devUsed;
52 :
53 104 : sqDepth = OPBASED_UB_SQ_DEPTH_MAX;
54 104 : if (opMode == OpMode::OFFLOAD && devUsed == false) {
55 5 : sqDepth = UB_SQ_OFFLOAD_DEPTH;
56 : }
57 312 : HCCL_INFO("[DevUbConnection][Constructor] set sqDepth[%u]", sqDepth);
58 :
59 104 : if (sqDepth > (UINT32_MAX / UB_SQ_WQEBB_SIZE / WQE_NUM_PER_SQE)) {
60 0 : THROW<InternalException>("integer overflow occurs");
61 : }
62 :
63 104 : if (!devUsed_) {
64 102 : CreateJetty(devUsed_);
65 : } else {
66 6 : HCCL_INFO("[DevUbConnection][Constructor] devUsed: defer CreateJetty until GetTpInfo maps qos.");
67 : }
68 104 : }
69 :
70 2 : DevUbTpConnection::DevUbTpConnection(const RdmaHandle rdmaHandle, const IpAddress &locAddr, const IpAddress &rmtAddr,
71 : const OpMode opMode, const bool devUsed, const HrtUbJfcMode jfcMode,
72 2 : const IpAddress &locIpv4Addr, const IpAddress &rmtIpv4Addr, u8 qos, CommEngine engine)
73 2 : : DevUbConnection(rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, engine)
74 : {
75 2 : tpProtocol = TpProtocol::TP;
76 2 : }
77 :
78 4 : DevUbCtpConnection::DevUbCtpConnection(const RdmaHandle rdmaHandle, const IpAddress &locAddr, const IpAddress &rmtAddr,
79 : const OpMode opMode, const bool devUsed, const HrtUbJfcMode jfcMode,
80 4 : const IpAddress &locIpv4Addr, const IpAddress &rmtIpv4Addr, u8 qos, CommEngine engine)
81 4 : : DevUbConnection(rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, engine)
82 : {
83 4 : tpProtocol = TpProtocol::CTP;
84 4 : }
85 :
86 0 : DevUbUboeConnection::DevUbUboeConnection(const RdmaHandle rdmaHandle, const IpAddress &locAddr, const IpAddress &rmtAddr,
87 : const OpMode opMode, const bool devUsed, const HrtUbJfcMode jfcMode,
88 0 : const IpAddress &locIpv4Addr, const IpAddress &rmtIpv4Addr, u8 qos, CommEngine engine)
89 0 : : DevUbConnection(rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locIpv4Addr, rmtIpv4Addr, qos, engine)
90 : {
91 0 : tpProtocol = TpProtocol::UBOE;
92 0 : jettyTimeOut = 16; // UBOE Jetty异步创建超时16秒
93 0 : }
94 :
95 1 : DevUbUbgConnection::DevUbUbgConnection(const RdmaHandle rdmaHandle, const IpAddress &locAddr, const IpAddress &rmtAddr,
96 : const OpMode opMode, const bool devUsed, const HrtUbJfcMode jfcMode,
97 1 : const IpAddress &locAddrEid, const IpAddress &rmtAddrEid, CommEngine engine)
98 : : DevUbConnection(rdmaHandle, locAddr, rmtAddr, opMode, devUsed, jfcMode, locAddrEid, rmtAddrEid,
99 1 : static_cast<u8>(UB_QOS_DEFAULT), engine)
100 : {
101 1 : tpProtocol = TpProtocol::UBG;
102 : // UBG与UBOE同属UB传输,Jetty异步创建超时一致,均为16秒
103 1 : jettyTimeOut = 16;
104 1 : }
105 :
106 43 : std::vector<char> DevUbConnection::GetUniqueId() const
107 : {
108 43 : BinaryStream binaryStream;
109 43 : binaryStream << dieId;
110 43 : binaryStream << funcId;
111 43 : binaryStream << jettyId;
112 :
113 43 : u32 jfcPollMode = 0; // 待修改,0代表STARS POLL,1代表software Poll
114 43 : bool dwqeCacheLocked = false; // 待修改,该jetty是否支持dwqeCachedLocked,默认不支持
115 43 : u64 sqCiAddr = 0; // 待修改,软件poll CQ情况下,需要AICPU从该地址中读取CI,依赖UB驱动支持
116 43 : binaryStream << jfcPollMode;
117 43 : binaryStream << dwqeCacheLocked;
118 43 : binaryStream << dbAddr;
119 43 : binaryStream << sqCiAddr;
120 43 : binaryStream << sqBuffVa;
121 43 : binaryStream << sqDepth;
122 43 : binaryStream << tpn;
123 43 : binaryStream << rmtEid.raw;
124 43 : binaryStream << locEid.raw;
125 43 : binaryStream << maxReadSize;
126 43 : binaryStream << maxWriteSize;
127 43 : binaryStream << static_cast<uint64_t>(jettyHandle);
128 :
129 43 : std::vector<char> result;
130 43 : binaryStream.Dump(result);
131 129 : HCCL_INFO("DevUbConnection::GetUniqueId:%s", Describe().c_str());
132 129 : HCCL_INFO("type=%s, jfcPollMode=%u, dwqeCacheLocked=%d, sqCiAddr=0x%llx", rmaConnType.Describe().c_str(),
133 : jfcPollMode, dwqeCacheLocked, sqCiAddr);
134 43 : return result;
135 43 : }
136 :
137 0 : void DevUbConnection::SetCqInfo(HcclAiRMACQ &cq) const
138 : {
139 0 : cq.jfcId = cqInfo_.id;
140 0 : cq.cqVA = cqInfo_.va;
141 0 : cq.cqeSize = cqInfo_.cqeSize;
142 0 : cq.cqDepth = cqInfo_.cqDepth;
143 0 : cq.dbAddr = cqInfo_.swdbAddr;
144 0 : }
145 :
146 0 : void DevUbConnection::SetWqInfo(HcclAiRMAWQ &wq) const
147 : {
148 0 : wq.jettyId = jettyId;
149 0 : wq.dbAddr = dbAddr;
150 0 : wq.sqVA = sqBuffVa;
151 0 : wq.sqDepth = sqDepth * WQE_NUM_PER_SQE;
152 0 : wq.tp_id = tpn;
153 0 : memcpy_s(wq.rmtEid, sizeof(wq.rmtEid), rmtEid.raw, sizeof(wq.rmtEid));
154 0 : }
155 :
156 0 : void DevUbConnection::SetSqContextInfo(SqContext &sq) const
157 : {
158 0 : sq.contextInfo.ubJfs.jfsID = jettyId;
159 0 : sq.contextInfo.ubJfs.dbVa = dbAddr;
160 0 : sq.contextInfo.ubJfs.sqVa = sqBuffVa;
161 0 : sq.contextInfo.ubJfs.sqDepth = sqDepth * WQE_NUM_PER_SQE;
162 0 : sq.contextInfo.ubJfs.tpID = tpn;
163 0 : memcpy_s(sq.contextInfo.ubJfs.remoteEID, sizeof(sq.contextInfo.ubJfs.remoteEID), rmtEid.raw,
164 : sizeof(sq.contextInfo.ubJfs.remoteEID));
165 0 : }
166 :
167 0 : void DevUbConnection::SetCqContextInfo(CqContext &cq) const
168 : {
169 0 : cq.contextInfo.ubJfc.jfcID = cqInfo_.id;
170 0 : cq.contextInfo.ubJfc.scqVa = cqInfo_.va;
171 0 : cq.contextInfo.ubJfc.cqeSize = cqInfo_.cqeSize;
172 0 : cq.contextInfo.ubJfc.cqDepth = cqInfo_.cqDepth;
173 0 : cq.contextInfo.ubJfc.dbVa = cqInfo_.swdbAddr;
174 0 : }
175 :
176 0 : void DevUbConnection::Connect()
177 : {
178 0 : GetStatus();
179 0 : }
180 :
181 0 : inline uint32_t GetRandomNum()
182 : {
183 0 : uint32_t randNum = std::rand();
184 0 : return randNum;
185 : }
186 :
187 1 : HcclResult DevUbConnection::CalcTotalTimeout(uint32_t &outTotalTimeoutMs)
188 : {
189 1 : TpHandle tpHandle = tpInfo.tpHandle;
190 1 : uint32_t attrBitmap = 0;
191 1 : struct TpAttr tpAttr = {0};
192 1 : u32 devicePhyId = HrtGetDevicePhyIdByIndex(devLogicId);
193 4 : CHK_RET(HrtRaGetTpAttrAsync(devicePhyId, rdmaHandle, tpHandle, attrBitmap, tpAttr, reqHandle));
194 0 : TpAttrInfo tpAttrInfo = TpAttrInfo(tpAttr);
195 0 : CHK_RET(TpManager::GetTpTotalTimeout(tpAttrInfo, outTotalTimeoutMs));
196 0 : return HCCL_SUCCESS;
197 : }
198 :
199 6 : void DevUbConnection::GetTimeOut() // 直接基于环境变量控制
200 : {
201 6 : if (tpProtocol == TpProtocol::INVALID) { // 不感知tp建链,当前默认不支持
202 0 : HCCL_ERROR(
203 : "[DevUbConnection][%s] failed, tpProtocol[%s] is not expected.", __func__, tpProtocol.Describe().c_str());
204 0 : ThrowAbnormalStatus(std::string(__func__));
205 : }
206 :
207 6 : uint8_t envValue = static_cast<uint8_t>(EnvConfig::GetInstance().GetRdmaConfig().GetUbTimeOut());
208 6 : uint32_t envTimeOut = TpManager::TaHwValueToMs(envValue);
209 :
210 6 : if (tpProtocol == TpProtocol::CTP) {
211 5 : jettyTimeOut = envValue;
212 15 : HCCL_INFO("%s [UbCtp] Env Value [%u] (%ums).", __func__, envValue, envTimeOut);
213 5 : return;
214 : }
215 :
216 1 : if (tpProtocol == TpProtocol::UBOE || tpProtocol == TpProtocol::UBG) {
217 0 : envValue = static_cast<uint8_t>(EnvConfig::GetInstance().GetRdmaConfig().GetUboeTimeOut());
218 0 : envTimeOut = TpManager::TaHwValueToMs(envValue);
219 0 : const char *tag = (tpProtocol == TpProtocol::UBG) ? "[UBG]" : "[UBoE]";
220 0 : HCCL_INFO("%s %s Env Value [%u] (%ums).", __func__, tag, envValue, envTimeOut);
221 : }
222 :
223 1 : uint32_t tpTimeOut = 0;
224 1 : CalcTotalTimeout(tpTimeOut);
225 1 : if (envTimeOut < tpTimeOut) {
226 : // 规则: 如果环境变量时间 < TP总超时,选择大于TP总超时的最小TA挡位
227 0 : jettyTimeOut = TpManager::FindMinTaHwValue(tpTimeOut);
228 0 : HCCL_WARNING("%s Env timeout [%ums] < TP timeout [%ums]. Auto upgrade TA to hw_val[%u] (%ums).", __func__,
229 : envTimeOut, tpTimeOut, envValue, tpTimeOut);
230 : } else {
231 : // 规则: 否则,直接使用环境变量对应的挡位 (对齐到 0/8/16/24)
232 : // 注意:这里我们取环境变量所在挡位的基准值 (例如 env=10 -> 取 8)
233 1 : jettyTimeOut = envValue;
234 3 : HCCL_INFO("%s Env timeout [%ums] >= TP timeout [%ums]. Use env gear base hw_val[%u] (%ums).", __func__,
235 : envTimeOut, tpTimeOut, envValue, envTimeOut);
236 : }
237 :
238 3 : HCCL_INFO("%s final TA Timeout [%u] (%ums).", __func__, jettyTimeOut, envTimeOut);
239 : }
240 :
241 6 : void DevUbConnection::AdvanceUbConnAfterTpInfoReady()
242 : {
243 6 : if (devUsed_) {
244 1 : GetTimeOut();
245 1 : CreateJetty(devUsed_);
246 1 : ubConnStatus = UbConnStatus::JETTY_CREATING;
247 1 : return;
248 : }
249 5 : GetTimeOut();
250 5 : CreateJetty(isdevUsed);
251 5 : if (!CheckRequestResult()) {
252 0 : ubConnStatus = UbConnStatus::JETTY_CREATING;
253 0 : return;
254 : }
255 5 : SetJettyInfo();
256 5 : status = RmaConnStatus::EXCHANGEABLE;
257 5 : ubConnStatus = UbConnStatus::JETTY_CREATED;
258 : }
259 :
260 6 : void DevUbConnection::AdvanceUbConnFromInit()
261 : {
262 18 : HCCL_INFO("[DevUbConnection][%s] start, status[%s], ubConnStatus[%s].", __func__, status.Describe().c_str(),
263 : ubConnStatus.Describe().c_str());
264 :
265 6 : if (!GetTpInfo()) {
266 6 : ubConnStatus = UbConnStatus::TP_INFO_GETTING;
267 6 : return;
268 : }
269 0 : AdvanceUbConnAfterTpInfoReady();
270 : }
271 :
272 6 : void DevUbConnection::AdvanceUbConnFromTpInfoGetting()
273 : {
274 6 : if (!GetTpInfo()) {
275 0 : return;
276 : }
277 6 : AdvanceUbConnAfterTpInfoReady();
278 : }
279 :
280 1 : void DevUbConnection::AdvanceUbConnFromJettyCreating()
281 : {
282 1 : if (CheckRequestResult()) {
283 1 : SetJettyInfo();
284 1 : status = RmaConnStatus::EXCHANGEABLE;
285 1 : ubConnStatus = UbConnStatus::JETTY_CREATED;
286 : }
287 1 : }
288 :
289 0 : void DevUbConnection::AdvanceUbConnFromJettyCreated()
290 : {
291 0 : HCCL_INFO("[DevUbConnection][%s] status[%s] will not change, "
292 : "should call ImportRmtDto to change status.",
293 : __func__, status.Describe().c_str());
294 0 : }
295 :
296 4 : void DevUbConnection::AdvanceUbConnFromJettyImporting()
297 : {
298 4 : SetImportInfo();
299 :
300 4 : status = RmaConnStatus::READY;
301 4 : ubConnStatus = UbConnStatus::READY;
302 4 : }
303 :
304 20 : RmaConnStatus DevUbConnection::GetStatus()
305 : {
306 20 : if (!CheckRequestResult()) {
307 0 : return status;
308 : }
309 :
310 20 : switch (ubConnStatus) {
311 6 : case UbConnStatus::INIT:
312 6 : AdvanceUbConnFromInit();
313 6 : break;
314 6 : case UbConnStatus::TP_INFO_GETTING:
315 6 : AdvanceUbConnFromTpInfoGetting();
316 6 : break;
317 1 : case UbConnStatus::JETTY_CREATING:
318 1 : AdvanceUbConnFromJettyCreating();
319 1 : break;
320 0 : case UbConnStatus::JETTY_CREATED:
321 0 : AdvanceUbConnFromJettyCreated();
322 0 : break;
323 4 : case UbConnStatus::JETTY_IMPORTING:
324 4 : AdvanceUbConnFromJettyImporting();
325 4 : break;
326 2 : case UbConnStatus::READY:
327 2 : break;
328 1 : default:
329 2 : ThrowAbnormalStatus(std::string(__func__));
330 : }
331 :
332 19 : return status;
333 : }
334 :
335 6 : std::unique_ptr<Serializable> DevUbConnection::GetExchangeDto()
336 : {
337 6 : if (status != RmaConnStatus::READY && status != RmaConnStatus::EXCHANGEABLE) {
338 0 : HCCL_ERROR("[DevUbConnection][%s] status[%s] is not expected.", __func__,
339 : status.Describe().c_str());
340 0 : ThrowAbnormalStatus(std::string(__func__));
341 : }
342 :
343 6 : if (tpProtocol != TpProtocol::INVALID) {
344 4 : jettyImportCfg.localTpHandle = tpInfo.tpHandle;
345 :
346 12 : HCCL_INFO("[DevUbConnection][%s] tpEnable, localTpHandle[0x%llx] localPsn[%u].", __func__,
347 : jettyImportCfg.localTpHandle, jettyImportCfg.localPsn);
348 : }
349 :
350 : std::unique_ptr<ExchangeUbConnDto> dto
351 6 : = make_unique<ExchangeUbConnDto>(tokenValue, keySize, jettyImportCfg.localTpHandle, jettyImportCfg.localPsn);
352 6 : (void)memcpy_s(dto->qpKey, HRT_UB_QP_KEY_MAX_LEN, localQpKey, HRT_UB_QP_KEY_MAX_LEN);
353 12 : return std::unique_ptr<Serializable>(dto.release());
354 6 : }
355 :
356 4 : void DevUbConnection::ParseRmtExchangeDto(const Serializable &rmtDto)
357 : {
358 4 : auto dto = dynamic_cast<const ExchangeUbConnDto &>(rmtDto);
359 12 : HCCL_INFO("[DevUbConnection][%s] remoteConnDto[%s]", __func__, dto.Describe().c_str());
360 4 : remoteTokenValue = dto.tokenValue;
361 4 : (void)memcpy_s(remoteQpKey, HRT_UB_QP_KEY_MAX_LEN, dto.qpKey, HRT_UB_QP_KEY_MAX_LEN);
362 :
363 4 : if (tpProtocol != TpProtocol::INVALID) {
364 4 : jettyImportCfg.remoteTpHandle = dto.tpHandle;
365 4 : jettyImportCfg.remotePsn = dto.psn;
366 12 : HCCL_INFO("[DevUbConnection][%s] tpEnable, remoteTpHandle[0x%llx], remotePsn[%u].", __func__,
367 : jettyImportCfg.remoteTpHandle, jettyImportCfg.remotePsn);
368 : }
369 4 : }
370 :
371 6 : void DevUbConnection::ImportRmtDto()
372 : {
373 6 : if (ubConnStatus == UbConnStatus::READY) {
374 3 : HCCL_WARNING("[DevUbConnection][%s] import jetty already, %s.",
375 : __func__, Describe().c_str());
376 1 : return;
377 : }
378 :
379 5 : if (ubConnStatus != UbConnStatus::JETTY_CREATED) {
380 0 : HCCL_ERROR("[DevUbConnection][%s] failed, ubConnStatus[%s] is not expected.",
381 : __func__, ubConnStatus.Describe().c_str());
382 0 : ThrowAbnormalStatus(std::string(__func__));
383 : }
384 :
385 5 : ImportJetty();
386 5 : ubConnStatus = UbConnStatus::JETTY_IMPORTING;
387 : }
388 :
389 2 : void DevUbConnection::ThrowAbnormalStatus(std::string funcName)
390 : {
391 : auto errMsg = StringFormat("[DevUbConnection][%s] failed, [%s].",
392 2 : funcName.c_str(), Describe().c_str());
393 2 : status = RmaConnStatus::CONN_INVALID;
394 2 : ubConnStatus = UbConnStatus::CONN_INVALID;
395 2 : THROW<RmaConnException>(errMsg);
396 2 : }
397 :
398 26 : bool DevUbConnection::CheckRequestResult()
399 : {
400 26 : if (reqHandle == 0) {
401 10 : return true;
402 : }
403 :
404 16 : ReqHandleResult result = HrtRaGetAsyncReqResult(reqHandle);
405 16 : if (result == ReqHandleResult::NOT_COMPLETED) {
406 0 : return false;
407 : }
408 :
409 16 : if (result != ReqHandleResult::COMPLETED) {
410 0 : THROW<InternalException>("[DevUbConnection][%s] failed, result[%s] is unexpected.",
411 0 : __func__, result.Describe().c_str());
412 : }
413 :
414 16 : return true;
415 : }
416 :
417 110 : void DevUbConnection::CreateJetty(const bool devUsed)
418 : {
419 110 : if (sqDepth > UINT32_MAX / UB_SQ_WQEBB_SIZE / WQE_NUM_PER_SQE) {
420 0 : THROW<InternalException>("[DevUbConnection][%s] failed, sqDepth[%u] times "
421 : "UB_SQ_WQEBB_SIZE[%u] overflow uint32 max.", __func__, sqDepth, UB_SQ_WQEBB_SIZE);
422 : }
423 110 : u32 size = static_cast<u32>(sqDepth) * static_cast<u32>(UB_SQ_WQEBB_SIZE) * static_cast<u32>(WQE_NUM_PER_SQE);
424 : HrtRaUbCreateJettyParam req {
425 : jfcHandle, jfcHandle,
426 : GetUbToken(), 0,
427 : HrtJettyMode::HOST_OPBASE, // 默认HOST单算子模式
428 : 0, // HOST展开与AICPU展开传入jetty id为0,申请一个新的jetty
429 : 0, // va由底层分配,此处填0即可。
430 110 : size, 0, sqDepth, jettyTimeOut}; // 非CCUv2不需要填写sqeBufIndex
431 :
432 110 : if (opMode == OpMode::OFFLOAD) { // HOST展开图模式切换模式
433 5 : req.jettyMode = HrtJettyMode::HOST_OFFLOAD;
434 : }
435 :
436 110 : if (devUsed) { // AICPU场景切换模式
437 1 : req.jettyMode = HrtJettyMode::DEV_USED;
438 3 : HCCL_INFO("[DevUbConnection][%s] HrtJettyMode is DEV_USED.", __func__);
439 : }
440 :
441 110 : if (tpInfo.hasMappedJettyPriority) {
442 2 : req.qos = static_cast<u8>(tpInfo.mappedJettyPriority & 0xFU);
443 : }
444 330 : HCCL_INFO("[DevUbConnection][%s] jetty create qos[%u] (maps to attr.ub.priority lower 4 bits).", __func__,
445 : static_cast<unsigned int>(req.qos));
446 :
447 110 : reqHandle = RaUbCreateJettyAsync(rdmaHandle, req, reqDataBuffer, jettyHandlePtr);
448 110 : }
449 :
450 7 : void DevUbConnection::SetJettyInfo()
451 : {
452 7 : struct QpCreateInfo *info = reinterpret_cast<QpCreateInfo *>(reqDataBuffer.data());
453 7 : jettyId = info->ub.id;
454 7 : jettyHandle = reinterpret_cast<JettyHandle>(jettyHandlePtr);
455 7 : keySize = info->key.size;
456 7 : sqBuffVa = info->ub.sqBuffVa; // hccp提供
457 21 : HCCL_INFO("[DevUbConnection][%s] Get sqBuffVa is %llx.", __func__, sqBuffVa);
458 :
459 7 : s32 ret = memcpy_s(localQpKey, HRT_UB_QP_KEY_MAX_LEN, info->key.value, info->key.size);
460 7 : if (ret != 0) {
461 0 : THROW<InternalException>(StringFormat("[DevUbConnection][%s] memcpy_s failed, ret=%d", __func__, ret));
462 : }
463 :
464 7 : dbAddr = info->ub.dbAddr;
465 7 : }
466 :
467 12 : bool DevUbConnection::GetTpInfo()
468 : {
469 12 : if (tpProtocol == TpProtocol::INVALID) { // 不感知tp建链,当前默认不支持
470 0 : HCCL_ERROR("[DevUbConnection][%s] failed, tpProtocol[%s] is not expected.",
471 : __func__, tpProtocol.Describe().c_str());
472 0 : ThrowAbnormalStatus(std::string(__func__));
473 : }
474 :
475 12 : RaUbGetTpInfoParam p{};
476 12 : p.locAddr = locAddr;
477 12 : p.rmtAddr = rmtAddr;
478 12 : p.tpProtocol = tpProtocol;
479 12 : p.qos = static_cast<uint32_t>(qos_);
480 12 : p.slLevelCount = 0;
481 12 : p.loopFirstTpLowestSl = false;
482 12 : p.locIpv4Addr = locIpv4Addr;
483 12 : p.rmtIpv4Addr = rmtIpv4Addr;
484 :
485 12 : auto ret = TpManager::GetInstance(devLogicId).GetTpInfo(p, tpInfo);
486 :
487 12 : switch (ret) {
488 6 : case HcclResult::HCCL_SUCCESS:
489 6 : GenerateLocalPsn();
490 6 : return true;
491 6 : case HcclResult::HCCL_E_AGAIN:
492 6 : return false;
493 0 : case HcclResult::HCCL_E_NOT_FOUND:
494 : default:
495 0 : HCCL_ERROR("[DevUbConnection][%s] failed, hccl result[%d]", __func__, ret);
496 0 : ThrowAbnormalStatus(std::string(__func__));
497 0 : break;
498 : }
499 0 : return true;
500 : }
501 :
502 6 : void DevUbConnection::GenerateLocalPsn()
503 : {
504 6 : jettyImportCfg.localPsn = GetRandomNum();
505 6 : }
506 :
507 5 : void DevUbConnection::ImportJetty()
508 : {
509 5 : HrtRaUbJettyImportedInParam in{};
510 5 : in.key = remoteQpKey;
511 5 : in.keyLen = keySize;
512 5 : in.tokenValue = remoteTokenValue;
513 5 : in.jettyImportCfg = jettyImportCfg;
514 5 : in.jettyImportCfg.protocol = tpProtocol;
515 :
516 5 : if (tpProtocol != TpProtocol::CTP && tpProtocol != TpProtocol::TP && tpProtocol != TpProtocol::UBOE &&
517 0 : tpProtocol != TpProtocol::UBG) {
518 0 : HCCL_ERROR("[DevUbConnection][%s] failed, tp protocol[%s] is not expected, %s.",
519 : __func__, tpProtocol.Describe().c_str(), Describe().c_str());
520 0 : ThrowAbnormalStatus(std::string(__func__));
521 : }
522 :
523 10 : reqHandle = RaUbTpImportJettyAsync(rdmaHandle, in,
524 5 : reqDataBuffer, remoteJettyHandlePtr);
525 5 : }
526 :
527 4 : void DevUbConnection::SetImportInfo()
528 : {
529 4 : struct QpImportInfoT *info = reinterpret_cast<QpImportInfoT *>(reqDataBuffer.data());
530 4 : remoteJettyHandle = reinterpret_cast<TargetJettyHandle>(remoteJettyHandlePtr);
531 4 : tpn = info->out.ub.tpn;
532 4 : }
533 :
534 108 : void DevUbConnection::ReleaseTp()
535 : {
536 108 : ReleaseUbConnectionTp(devLogicId, locAddr, rmtAddr, tpProtocol, tpInfo, static_cast<uint32_t>(qos_));
537 108 : }
538 :
539 106 : void DevUbConnection::ReleaseResource()
540 : {
541 106 : if (rdmaHandle && remoteJettyHandle != 0) {
542 0 : HrtRaUbUnimportJetty(rdmaHandle, remoteJettyHandle);
543 0 : remoteJettyHandle = 0;
544 : }
545 :
546 106 : ReleaseTp();
547 :
548 106 : if (jettyHandle != 0) {
549 4 : HrtRaUbDestroyJetty(jettyHandle);
550 4 : jettyHandle = 0;
551 : }
552 :
553 106 : if (engine_ == COMM_ENGINE_AIV && jfcHandle != 0) {
554 0 : HrtRaUbDestroyJfc(rdmaHandle, jfcHandle);
555 0 : jfcHandle = 0;
556 : }
557 106 : }
558 :
559 1 : void DevUbConnection::CreateAivUrmaJfc()
560 : {
561 1 : jfcHandle = HrtRaUbCreateJfcUserCtl(rdmaHandle, cqInfo_);
562 3 : HCCL_INFO("[DevUbConnection][CreateAivUrmaJfc] create jfcHandle[%p] for rdmaHandle[%p].", jfcHandle, rdmaHandle);
563 1 : }
564 :
565 106 : DevUbConnection::~DevUbConnection()
566 : {
567 104 : DECTOR_TRY_CATCH("DevUbConnection", ReleaseResource());
568 106 : }
569 :
570 : // Suspend接口当前已不使用,由框架调用触发析构流程
571 3 : bool DevUbConnection::Suspend()
572 : {
573 9 : HCCL_WARNING("[DevUbConnection][%s] should not be called.", __func__);
574 3 : if (status == RmaConnStatus::SUSPENDED) {
575 3 : HCCL_INFO("[DevUbConnection][%s] RmaConnStatus is SUSPENDED, status[%s].", __func__, status.Describe().c_str());
576 1 : return true;
577 : }
578 :
579 2 : if (status != RmaConnStatus::READY) {
580 2 : ThrowAbnormalStatus(std::string(__func__));
581 : }
582 :
583 1 : ReleaseResource();
584 1 : status = RmaConnStatus::SUSPENDED;
585 1 : return true;
586 : }
587 :
588 15 : static void PrepareUbSendWrReqParamForWriteOrRead(HrtRaUbSendWrReqParam &sendWrReq, const HrtUbSendWrOpCode sendWrOpCode,
589 : const MemoryBuffer &remoteMemBuf, const MemoryBuffer &localMemBuf,
590 : JettyHandle remoteJettyHandle, const SqeConfig &config, u32 cqeEnable = 1)
591 : {
592 15 : sendWrReq.cqeEn = cqeEnable;
593 15 : sendWrReq.opcode = sendWrOpCode;
594 15 : sendWrReq.size = localMemBuf.size;
595 15 : sendWrReq.localAddr = localMemBuf.addr;
596 15 : sendWrReq.remoteAddr = remoteMemBuf.addr;
597 :
598 15 : sendWrReq.lmemHandle = localMemBuf.memHandle;
599 15 : sendWrReq.rmemHandle = remoteMemBuf.memHandle;
600 15 : sendWrReq.handle = remoteJettyHandle;
601 :
602 : // 打印入参
603 45 : HCCL_INFO("PrepareOneUbSendForRead params opCode=[%u], size=[%u], localAddr=[0x%llx], "
604 : "remoteAddr=[0x%llx], lmemHandle=[0x%llx], rmemHandle=[0x%llx], "
605 : "jettyHandle=[0x%llx], cqeEn=[%u], config=[%d]",
606 : static_cast<u32>(sendWrReq.opcode), sendWrReq.size, localMemBuf.addr, remoteMemBuf.addr,
607 : localMemBuf.memHandle, remoteMemBuf.memHandle, remoteJettyHandle, sendWrReq.cqeEn, config);
608 15 : }
609 :
610 9 : static void PrepareUbSendWrReqParamReduceInfo(HrtRaUbSendWrReqParam &sendWrReq, DataType dataType, ReduceOp reduceOp)
611 : {
612 9 : sendWrReq.inlineReduceFlag = true;
613 9 : sendWrReq.dataType = dataType;
614 9 : sendWrReq.reduceOp = reduceOp;
615 27 : HCCL_INFO("PrepareUbSendWrReqParamReduceInfo params inlineReduceFlag[%u], dataType[%s], reduceOp[%s]",
616 : sendWrReq.inlineReduceFlag, dataType.Describe().c_str(), reduceOp.Describe().c_str());
617 9 : }
618 :
619 4 : static void PrepareUbSendWrReqParamNotifyInfo(HrtRaUbSendWrReqParam &sendWrReq, u64 data,
620 : const MemoryBuffer &remoteNotifyMemBuf)
621 : {
622 4 : sendWrReq.opcode = HrtUbSendWrOpCode::WRITE_WITH_NOTIFY;
623 4 : sendWrReq.notifyData = data;
624 4 : sendWrReq.notifyAddr = remoteNotifyMemBuf.addr;
625 4 : sendWrReq.notifyHandle = remoteNotifyMemBuf.memHandle;
626 12 : HCCL_INFO("PrepareUbSendWrReqParamNotifyInfo params opCode[%u], "
627 : "notifyData[0x%llx], notifyAddr[0x%llx], notifyHandle[0x%llx]",
628 : static_cast<u32>(sendWrReq.opcode), sendWrReq.notifyData, sendWrReq.notifyAddr, sendWrReq.notifyHandle);
629 4 : }
630 :
631 18 : std::unique_ptr<BaseTask> DevUbConnection::ConstructTaskUbSend(const HrtRaUbSendWrRespParam &sendWrResp,
632 : const SqeConfig &config)
633 : {
634 18 : unique_ptr<BaseTask> result;
635 18 : if (opMode == OpMode::OPBASE) {
636 15 : if (config.wqeMode == WqeMode::DWQE) {
637 7 : result = make_unique<TaskUbDirectSend>(sendWrResp.funcId, sendWrResp.dieId, sendWrResp.jettyId,
638 7 : sendWrResp.dwqeSize, sendWrResp.dwqe);
639 8 : } else if (config.wqeMode == WqeMode::DB_SEND) {
640 : result
641 7 : = make_unique<TaskUbDbSend>(sendWrResp.jettyId, sendWrResp.funcId, sendWrResp.piVal, sendWrResp.dieId);
642 1 : } else if (config.wqeMode == WqeMode::WRITE_VALUE) {
643 3 : HCCL_INFO("[DevUbConnection::%s] dbAddr=[%llx], piVal=[%u]", __func__, dbAddr, sendWrResp.piVal);
644 1 : result = make_unique<TaskWriteValue>(dbAddr, sendWrResp.piVal);
645 : } else {
646 0 : auto msg = StringFormat("Invalid WqeMode[%s]", config.wqeMode.Describe().c_str());
647 0 : THROW<InvalidParamsException>(msg);
648 0 : }
649 3 : } else if (opMode == OpMode::OFFLOAD) {
650 8 : CHK_PRT_THROW(sendWrResp.piVal < piVal,
651 : HCCL_ERROR("[DevUbConnection::%s] sendWrResp.piVal[%u] is less than piVal[%u]", __func__, sendWrResp.piVal, piVal),
652 : InvalidParamsException, "sendWrResp.piVal or piVal is invalid");
653 2 : u32 sendPiVal = sendWrResp.piVal - piVal;
654 2 : result = make_unique<TaskUbDbSend>(sendWrResp.jettyId, sendWrResp.funcId, sendPiVal, sendWrResp.dieId);
655 6 : HCCL_INFO("[DevUbConnection::%s] sendPiVal[%u] piVal[%u] sendWrResp.piVal[%u]", __func__, sendPiVal, piVal, sendWrResp.piVal);
656 : } else {
657 0 : auto msg = StringFormat("Invalid OpMode[%s]", opMode.Describe().c_str());
658 0 : THROW<InvalidParamsException>(msg);
659 0 : }
660 :
661 17 : piVal = sendWrResp.piVal;
662 17 : return result;
663 1 : }
664 :
665 11 : void DevUbConnection::ProcessSlices(const MemoryBuffer &loc, const MemoryBuffer &rmt,
666 : std::function<void(const MemoryBuffer &, const MemoryBuffer &, u32)> processOneSlice,
667 : DataType dataType) const
668 : {
669 33 : HCCL_INFO("[DevUbConnection::%s] start", __func__);
670 :
671 : // reduce操作需要保证切片大小是数据类型大小的整数倍
672 11 : u32 sliceSize = UB_MAX_TRANS_SIZE;
673 11 : if (dataType != DataType::INVALID) {
674 7 : u32 dataTypeSize = DATA_TYPE_SIZE_MAP.at(dataType);
675 7 : sliceSize = UB_MAX_TRANS_SIZE / dataTypeSize * dataTypeSize;
676 : }
677 :
678 11 : u32 locBufSize = loc.size;
679 11 : u32 sliceNum = locBufSize / sliceSize;
680 11 : u32 lastSliceSize = locBufSize % sliceSize;
681 11 : u64 totalSize = static_cast<u64>(sliceNum) * static_cast<u64>(sliceSize);
682 11 : if (loc.addr > UINT64_MAX - totalSize || rmt.addr > UINT64_MAX - totalSize) {
683 0 : THROW<InternalException>("integer overflow occurs");
684 : }
685 11 : for (u32 sliceIdx = 0; sliceIdx < sliceNum; sliceIdx++) {
686 0 : MemoryBuffer locSlice(loc.addr + sliceIdx * sliceSize, sliceSize, loc.memHandle);
687 0 : MemoryBuffer rmtSlice(rmt.addr + sliceIdx * sliceSize, sliceSize, rmt.memHandle);
688 : // 当前是最后一片,且没有lastSlice时,启用cqe
689 0 : u32 cqeEnable = (sliceIdx == sliceNum - 1 && lastSliceSize == 0) ? 1 : 0;
690 0 : processOneSlice(locSlice, rmtSlice, cqeEnable);
691 : }
692 :
693 11 : if (lastSliceSize > 0) {
694 11 : MemoryBuffer lastLocSlice(loc.addr + sliceNum * sliceSize, lastSliceSize, loc.memHandle);
695 11 : MemoryBuffer lastRmtSlice(rmt.addr + sliceNum * sliceSize, lastSliceSize, rmt.memHandle);
696 11 : processOneSlice(lastLocSlice, lastRmtSlice, 1);
697 11 : sliceNum++;
698 : }
699 :
700 33 : HCCL_INFO("[DevUbConnection::%s] end, locBufSize[%u], sliceNUm[%u], sliceSize[%u], lastSliceSize[%u]", __func__,
701 : locBufSize, sliceNum, sliceSize, lastSliceSize);
702 11 : }
703 :
704 4 : void DevUbConnection::ProcessSlicesWithNotify(
705 : const MemoryBuffer &loc, const MemoryBuffer &rmt,
706 : std::function<void(const MemoryBuffer &, const MemoryBuffer &, u32)> processOneSlice,
707 : std::function<void(const MemoryBuffer &, const MemoryBuffer &)> processOneSliceWithNotify, DataType dataType) const
708 : {
709 12 : HCCL_INFO("[DevUbConnection::%s] start", __func__);
710 :
711 : // reduce操作需要保证切片大小是数据类型大小的整数倍
712 4 : u32 sliceSize = UB_MAX_TRANS_SIZE;
713 4 : if (dataType != DataType::INVALID) {
714 2 : u32 dataTypeSize = DATA_TYPE_SIZE_MAP.at(dataType);
715 2 : sliceSize = UB_MAX_TRANS_SIZE / dataTypeSize * dataTypeSize;
716 : }
717 :
718 4 : u32 locBufSize = loc.size;
719 4 : u32 sliceNum = locBufSize / sliceSize;
720 4 : u32 lastSliceSize = locBufSize % sliceSize;
721 4 : if (sliceNum > 0 && lastSliceSize == 0) {
722 0 : sliceNum--;
723 0 : lastSliceSize = sliceSize;
724 : }
725 :
726 4 : for (u32 sliceIdx = 0; sliceIdx < sliceNum; sliceIdx++) {
727 0 : MemoryBuffer locSlice(loc.addr + sliceIdx * sliceSize, sliceSize, loc.memHandle);
728 0 : MemoryBuffer rmtSlice(rmt.addr + sliceIdx * sliceSize, sliceSize, rmt.memHandle);
729 : // 固定会有lastSlice,则前面的cqe都不启用
730 0 : processOneSlice(locSlice, rmtSlice, 0);
731 : }
732 :
733 4 : if (lastSliceSize > 0) {
734 4 : MemoryBuffer lastLocSlice(loc.addr + sliceNum * sliceSize, lastSliceSize, loc.memHandle);
735 4 : MemoryBuffer lastRmtSlice(rmt.addr + sliceNum * sliceSize, lastSliceSize, rmt.memHandle);
736 4 : processOneSliceWithNotify(lastLocSlice, lastRmtSlice);
737 4 : sliceNum++;
738 : }
739 :
740 12 : HCCL_INFO("[DevUbConnection::%s] end, locBufSize[%u], sliceNum[%u], sliceSize[%u], lastSliceSize[%u]", __func__,
741 : locBufSize, sliceNum, sliceSize, lastSliceSize);
742 4 : }
743 :
744 2 : unique_ptr<BaseTask> DevUbConnection::PrepareRead(const MemoryBuffer &remoteMemBuf, const MemoryBuffer &localMemBuf,
745 : const SqeConfig &config)
746 : {
747 2 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareRead");
748 :
749 2 : if (localMemBuf.size == 0) {
750 0 : return nullptr;
751 : }
752 :
753 2 : HrtRaUbSendWrRespParam sendWrResp{};
754 2 : ProcessSlices(localMemBuf, remoteMemBuf, [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
755 2 : HrtRaUbSendWrReqParam sendWrReq = {};
756 2 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::READ, rmtSlice, locSlice, remoteJettyHandle,
757 : config, cqeEnable);
758 :
759 2 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
760 2 : });
761 :
762 2 : return ConstructTaskUbSend(sendWrResp, config);
763 : }
764 :
765 2 : unique_ptr<BaseTask> DevUbConnection::PrepareReadReduce(const MemoryBuffer &remoteMemBuf,
766 : const MemoryBuffer &localMemBuf, DataType dataType,
767 : ReduceOp reduceOp, const SqeConfig &config)
768 : {
769 2 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareReadReduce");
770 :
771 2 : if (localMemBuf.size == 0) {
772 0 : return nullptr;
773 : }
774 :
775 2 : HrtRaUbSendWrRespParam sendWrResp{};
776 2 : ProcessSlices(
777 : localMemBuf, remoteMemBuf,
778 2 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
779 2 : HrtRaUbSendWrReqParam sendWrReq = {};
780 2 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::READ, rmtSlice, locSlice,
781 : remoteJettyHandle, config, cqeEnable);
782 2 : PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
783 :
784 2 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
785 2 : },
786 : dataType);
787 :
788 2 : return ConstructTaskUbSend(sendWrResp, config);
789 : }
790 :
791 6 : unique_ptr<BaseTask> DevUbConnection::PrepareWrite(const MemoryBuffer &remoteMemBuf, const MemoryBuffer &localMemBuf,
792 : const SqeConfig &config)
793 : {
794 8 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWrite");
795 :
796 4 : if (localMemBuf.size == 0) {
797 2 : return nullptr;
798 : }
799 :
800 2 : HrtRaUbSendWrRespParam sendWrResp{};
801 2 : ProcessSlices(localMemBuf, remoteMemBuf, [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
802 2 : HrtRaUbSendWrReqParam sendWrReq = {};
803 2 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
804 : remoteJettyHandle, config, cqeEnable);
805 2 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
806 2 : });
807 :
808 2 : return ConstructTaskUbSend(sendWrResp, config);
809 : }
810 :
811 7 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteReduce(const MemoryBuffer &remoteMemBuf,
812 : const MemoryBuffer &localMemBuf, DataType dataType,
813 : ReduceOp reduceOp, const SqeConfig &config)
814 : {
815 8 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteReduce");
816 :
817 6 : if (localMemBuf.size == 0) {
818 1 : return nullptr;
819 : }
820 :
821 5 : HrtRaUbSendWrRespParam sendWrResp{};
822 5 : ProcessSlices(
823 : localMemBuf, remoteMemBuf,
824 5 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
825 5 : HrtRaUbSendWrReqParam sendWrReq = {};
826 5 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
827 : remoteJettyHandle, config, cqeEnable);
828 5 : PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
829 5 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
830 5 : },
831 : dataType);
832 :
833 5 : return ConstructTaskUbSend(sendWrResp, config);
834 : }
835 :
836 3 : unique_ptr<BaseTask> DevUbConnection::PrepareInlineWrite(const MemoryBuffer &remoteMemBuf, u64 data,
837 : const SqeConfig &config)
838 : {
839 3 : HrtRaUbSendWrReqParam sendWrReq = {};
840 3 : sendWrReq.opcode = HrtUbSendWrOpCode::WRITE;
841 3 : sendWrReq.remoteAddr = remoteMemBuf.addr;
842 3 : sendWrReq.rmemHandle = remoteMemBuf.memHandle;
843 3 : sendWrReq.handle = remoteJettyHandle;
844 3 : sendWrReq.inlineFlag = true;
845 3 : sendWrReq.inlineData = reinterpret_cast<u8 *>(&data);
846 3 : sendWrReq.size = sizeof(data);
847 : /*
848 : * 当前只有前后同步使用writeValue任务
849 : * 由于writeValue任务不使能cqe,
850 : * writeValue和dwqe混用会有潜在问题,所以后面需要区分开这两种任务模式
851 : * 不在同一个connection里面既使用writeValue又使用dwqe
852 : */
853 3 : if (config.wqeMode == WqeMode::WRITE_VALUE && opMode == OpMode::OPBASE) {
854 : // 当前只有inlineWrite使用write value
855 : // 图模式不能使用writeValue
856 : // writeValue 不需要使能cqe
857 1 : sendWrReq.cqeEn = false;
858 : }
859 :
860 9 : HCCL_INFO(
861 : "DevUbConnection::PrepareInlineWrite params opCode=[%u], "
862 : "remoteAddr=[0x%llx], rmemHandle=[0x%llx], remoteJettyHandle=[0x%llx], inlineFlag[%u], size=[%u], data=[%u]",
863 : sendWrReq.opcode, sendWrReq.remoteAddr, sendWrReq.rmemHandle, sendWrReq.handle, sendWrReq.inlineFlag,
864 : sendWrReq.size, static_cast<u32>(*sendWrReq.inlineData));
865 3 : auto res = HrtRaUbPostSend(jettyHandle, sendWrReq);
866 :
867 6 : return ConstructTaskUbSend(res, config);
868 : }
869 :
870 : inline HrtRaUbSendWrReqParam ConstructUbSendWrReqParamForWriteWithNotify(const MemoryBuffer &remoteMemBuf,
871 : const MemoryBuffer &localMemBuf, u64 data,
872 : const MemoryBuffer &remoteNotifyMemBuf)
873 : {
874 : HrtRaUbSendWrReqParam sendWrReq = {};
875 : sendWrReq.opcode = HrtUbSendWrOpCode::WRITE_WITH_NOTIFY;
876 : sendWrReq.size = remoteMemBuf.size;
877 : sendWrReq.localAddr = localMemBuf.addr;
878 : sendWrReq.remoteAddr = remoteMemBuf.addr;
879 : sendWrReq.lmemHandle = localMemBuf.memHandle;
880 : sendWrReq.rmemHandle = remoteMemBuf.memHandle;
881 : sendWrReq.notifyData = data;
882 : sendWrReq.notifyAddr = remoteNotifyMemBuf.addr;
883 : sendWrReq.notifyHandle = remoteNotifyMemBuf.memHandle;
884 :
885 : return sendWrReq;
886 : }
887 :
888 2 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteWithNotify(const MemoryBuffer &remoteMemBuf,
889 : const MemoryBuffer &localMemBuf, u64 data,
890 : const MemoryBuffer &remoteNotifyMemBuf,
891 : const SqeConfig &config)
892 : {
893 2 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteWithNotify");
894 :
895 2 : if (localMemBuf.size == 0) {
896 0 : return nullptr;
897 : }
898 :
899 2 : HrtRaUbSendWrRespParam sendWrResp{};
900 2 : ProcessSlicesWithNotify(
901 : localMemBuf, remoteMemBuf,
902 4 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
903 0 : HrtRaUbSendWrReqParam sendWrReq = {};
904 0 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
905 : remoteJettyHandle, config, cqeEnable);
906 0 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
907 0 : },
908 2 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice) {
909 2 : HrtRaUbSendWrReqParam sendWrReq = {};
910 2 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
911 : remoteJettyHandle, config);
912 2 : PrepareUbSendWrReqParamNotifyInfo(sendWrReq, data, remoteNotifyMemBuf);
913 :
914 2 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
915 2 : });
916 :
917 2 : return ConstructTaskUbSend(sendWrResp, config);
918 : }
919 :
920 2 : unique_ptr<BaseTask> DevUbConnection::PrepareWriteReduceWithNotify(const MemoryBuffer &remoteMemBuf,
921 : const MemoryBuffer &localMemBuf, DataType dataType,
922 : ReduceOp reduceOp, u64 data,
923 : const MemoryBuffer &remoteNotifyMemBuf,
924 : const SqeConfig &config)
925 : {
926 2 : VerifySizeIsEqual(remoteMemBuf, localMemBuf, "DevUbConnection::PrepareWriteReduceWithNotify");
927 :
928 2 : if (localMemBuf.size == 0) {
929 0 : return nullptr;
930 : }
931 :
932 2 : HrtRaUbSendWrRespParam sendWrResp{};
933 2 : ProcessSlicesWithNotify(
934 : localMemBuf, remoteMemBuf,
935 4 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice, u32 cqeEnable) {
936 0 : HrtRaUbSendWrReqParam sendWrReq = {};
937 0 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
938 : remoteJettyHandle, config, cqeEnable);
939 0 : PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
940 0 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
941 0 : },
942 2 : [&](const MemoryBuffer &locSlice, const MemoryBuffer &rmtSlice) {
943 2 : HrtRaUbSendWrReqParam sendWrReq = {};
944 2 : PrepareUbSendWrReqParamForWriteOrRead(sendWrReq, HrtUbSendWrOpCode::WRITE, rmtSlice, locSlice,
945 : remoteJettyHandle, config);
946 2 : PrepareUbSendWrReqParamReduceInfo(sendWrReq, dataType, reduceOp);
947 2 : PrepareUbSendWrReqParamNotifyInfo(sendWrReq, data, remoteNotifyMemBuf);
948 2 : sendWrResp = HrtRaUbPostSend(jettyHandle, sendWrReq);
949 2 : },
950 : dataType);
951 :
952 2 : return ConstructTaskUbSend(sendWrResp, config);
953 : }
954 :
955 138 : string DevUbConnection::Describe() const
956 : {
957 : return StringFormat(
958 : "DevUbConnection[locAddr=%s, rmtAddr=%s, status=%s, dieId=%u, funcId=%u, jettyId=%u, sqBuffVa=%llx, "
959 : "sqDepth=%u, maxReadSize=%u, maxWriteSize=%u, tpn=%u, dbAddr=0x%llx]",
960 414 : locAddr.Describe().c_str(), rmtAddr.Describe().c_str(), status.Describe().c_str(), dieId, funcId, jettyId,
961 552 : sqBuffVa, sqDepth, maxReadSize, maxWriteSize, tpn, dbAddr);
962 : }
963 :
964 1 : HcclResult DevUbConnection::Describe(std::string &dfxMsg)
965 : {
966 1 : uint16_t udpSport = 0xFFFF; // 无法获取实际的udpSport,使用0xFFFF表示未知
967 1 : if (tpProtocol == TpProtocol::TP) {
968 1 : struct TpAttr tpAttr {0};
969 1 : uint32_t attrBitmap = 1 << 13; // 13对应dataUdpSrcport
970 1 : TRY_CATCH_PRINT_ERROR(
971 : u32 devicePhyId = HrtGetDevicePhyIdByIndex(devLogicId);
972 : HcclResult ret = HrtRaGetTpAttrAsync(devicePhyId, rdmaHandle, tpInfo.tpHandle, attrBitmap, tpAttr, reqHandle);
973 : if (ret == HCCL_E_NOT_SUPPORT) {
974 : HCCL_ERROR("[DevUbConnection::%s] this package does not support RaGetTpAttrAsync for device,"
975 : " please change new package, devPhyId[%u]", __func__, devicePhyId);
976 : return ret;
977 : } else if (ret != HCCL_SUCCESS) {
978 : HCCL_ERROR("[DevUbConnection::%s] failed, hccl result[%d]", __func__, ret);
979 : return ret;
980 : }
981 : );
982 1 : udpSport = tpAttr.dataUdpSrcport;
983 : }
984 1 : udpSport = udpSport & 0xFF;
985 :
986 : std::string dfxStr = StringFormat("chip id[%u] die id[%u] func id[%u] jetty id[%u] "
987 : "local %s remote %s udp sport[%u]",
988 1 : devLogicId, dieId, funcId, jettyId, locEid.Describe().c_str(), rmtEid.Describe().c_str(), udpSport);
989 1 : dfxMsg += dfxStr;
990 3 : HCCL_INFO("[DevUbConnection::%s] %s", __func__, dfxStr.c_str());
991 1 : return HCCL_SUCCESS;
992 1 : }
993 :
994 4 : void DevUbConnection::AddNop(const Stream &stream)
995 : {
996 4 : if (opMode != OpMode::OFFLOAD) {
997 3 : HCCL_WARNING("[DevUbConnection][AddNop]Invalid OpMode[%s]", opMode.Describe().c_str());
998 1 : return;
999 : }
1000 3 : if (sqDepth < piVal) {
1001 1 : auto msg = StringFormat("Invalid piVal[%u], piVal should be less than or equal to sqDepth[%u]", piVal, sqDepth);
1002 1 : THROW<InvalidParamsException>(msg);
1003 1 : }
1004 2 : if (sqDepth == piVal) {
1005 0 : return;
1006 : }
1007 2 : u32 numNop = sqDepth - piVal;
1008 2 : HrtRaUbPostNops(jettyHandle, remoteJettyHandle, numNop);
1009 :
1010 : HrtUbDbInfo info;
1011 2 : info.dbNum = 1;
1012 2 : info.wrCqe = 0; // 默认值是0 不会cqe 如果传1,驱动分发,会给hccl cqe,用于维护ci指针。
1013 2 : info.info[0].functionId = funcId;
1014 2 : info.info[0].dieId = dieId;
1015 2 : info.info[0].jettyId = jettyId;
1016 2 : info.info[0].piValue = numNop;
1017 2 : HrtUbDbSend(info, stream.GetPtr());
1018 :
1019 2 : piVal = sqDepth;
1020 : }
1021 :
1022 4 : HrtUbJfcMode DevUbConnection::GetUbJfcMode() const
1023 : {
1024 4 : return jfcMode;
1025 : }
1026 :
1027 5 : JettyHandle& DevUbConnection::GetJettyHandle()
1028 : {
1029 5 : return jettyHandle;
1030 : }
1031 :
1032 2 : JettyHandle& DevUbConnection::GetRemoteJettyHandle()
1033 : {
1034 2 : return remoteJettyHandle;
1035 : }
1036 :
1037 2 : RdmaHandle& DevUbConnection::GetRdmaHandle()
1038 : {
1039 2 : return rdmaHandle;
1040 : }
1041 :
1042 6 : u32 DevUbConnection::GetPiVal() const
1043 : {
1044 6 : return piVal;
1045 : }
1046 :
1047 5 : u32 DevUbConnection::GetCiVal() const
1048 : {
1049 5 : return ciVal;
1050 : }
1051 :
1052 3 : u32 DevUbConnection::GetSqDepth() const
1053 : {
1054 3 : return sqDepth;
1055 : }
1056 :
1057 2 : void DevUbConnection::UpdateCiVal(u32 ci)
1058 : {
1059 2 : ciVal = ci;
1060 2 : }
1061 :
1062 7 : std::vector<DevUbConnection *> GetStarsPollUbConns(const std::vector<RmaConnection *> &rmaConns)
1063 : {
1064 7 : std::vector<DevUbConnection *> ubConns;
1065 8 : for (auto &rmaConn : rmaConns) {
1066 1 : if (rmaConn->GetRmaConnType() == RmaConnType::UB) {
1067 1 : if (dynamic_cast<DevUbConnection *>(rmaConn)->GetUbJfcMode() == HrtUbJfcMode::STARS_POLL) {
1068 1 : ubConns.emplace_back(dynamic_cast<DevUbConnection *>(rmaConn));
1069 : }
1070 : }
1071 : }
1072 7 : return ubConns;
1073 0 : }
1074 :
1075 7 : bool IfNeedUpdatingUbCi(const std::vector<DevUbConnection *> &ubConns)
1076 : {
1077 9 : for (auto &ubConn : ubConns) {
1078 2 : u32 pi = ubConn->GetPiVal();
1079 2 : u32 ci = ubConn->GetCiVal();
1080 2 : u32 sqDepth = ubConn->GetSqDepth();
1081 : // 考虑pi翻转场景
1082 2 : u32 extra = pi >= ci ? 0 : sqDepth;
1083 2 : constexpr u32 thresholdDivisor = 2;
1084 :
1085 2 : if (static_cast<double>(pi + extra - ci)
1086 2 : >= static_cast<double>(sqDepth) / thresholdDivisor) { // 当pi和ci差距大于sqDepth/2时,更新ci
1087 0 : return true;
1088 : }
1089 : }
1090 7 : return false;
1091 : }
1092 :
1093 0 : void DevUbConnection::SetMaxReadSize(u32 value)
1094 : {
1095 0 : maxReadSize = value;
1096 0 : }
1097 :
1098 0 : void DevUbConnection::SetMaxWriteSize(u32 value)
1099 : {
1100 0 : maxWriteSize = value;
1101 0 : }
1102 :
1103 : } // namespace Hccl
|