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 "aiv_urma_channel.h"
12 : #include "endpoint.h"
13 : #include "orion_adpt_utils.h"
14 : #include "acl_device_slab_guard.h"
15 :
16 : #include "hcomm_c_adpt.h"
17 :
18 : // Orion
19 : #include "topo_common_types.h"
20 : #include "virtual_topo.h"
21 : #include "makebufs_helper.h"
22 : #include "orion_adapter_hccp.h"
23 : #include "adapter_rts.h"
24 : #include "acl/acl_rt.h"
25 :
26 : #include <algorithm>
27 : #include <cstdint>
28 : #include <cstdlib>
29 : #include <cstring>
30 :
31 : namespace hcomm {
32 : constexpr uint16_t DEFAULT_LISTENING_PORT = 60001;
33 :
34 : namespace {
35 : constexpr size_t AIV_URMA_ENTITY_ALIGN_SIZE = 64;
36 : constexpr size_t QUEUE_INDEX_MEM_UNIT_SIZE = sizeof(void *);
37 :
38 : struct DeviceEntitySection {
39 : size_t offset{0};
40 : size_t size{0};
41 : };
42 :
43 : struct DeviceChannelEntityLayout {
44 : DeviceEntitySection entitySection{0, sizeof(ChannelEntity)};
45 : DeviceEntitySection localNotifySection;
46 : DeviceEntitySection remoteNotifySection;
47 : DeviceEntitySection localBufferSection;
48 : DeviceEntitySection remoteBufferSection;
49 : DeviceEntitySection sqContextSection;
50 : DeviceEntitySection cqContextSection;
51 : DeviceEntitySection sqPiSection;
52 : DeviceEntitySection sqCiSection;
53 : DeviceEntitySection cqPiSection;
54 : DeviceEntitySection cqCiSection;
55 : size_t slabSize{0};
56 : };
57 :
58 6 : HcclResult SecureMemset(void *dest, size_t destMax, int value, size_t count, const char *fieldName)
59 : {
60 6 : if (dest == nullptr) {
61 0 : HCCL_ERROR("[SecureMemset] dest is nullptr, field[%s]", fieldName);
62 0 : return HCCL_E_PTR;
63 : }
64 6 : if (count > destMax) {
65 0 : HCCL_ERROR("[SecureMemset] invalid size, field[%s], count[%zu], destMax[%zu]",
66 : fieldName, count, destMax);
67 0 : return HCCL_E_PARA;
68 : }
69 :
70 6 : errno_t ret = memset_s(dest, destMax, value, count);
71 6 : if (ret != EOK) {
72 0 : HCCL_ERROR("[SecureMemset] memset_s failed, field[%s], ret[%d], count[%zu], destMax[%zu]",
73 : fieldName, ret, count, destMax);
74 0 : return HCCL_E_MEMORY;
75 : }
76 6 : return HCCL_SUCCESS;
77 : }
78 :
79 3 : HcclResult GetAllMemHandles(EndpointHandle endpointHandle, void **memHandles, uint32_t *memHandleNum)
80 : {
81 3 : return static_cast<HcclResult>(HcommMemGetAllMemHandles(endpointHandle, memHandles, memHandleNum));
82 : }
83 :
84 84 : size_t AlignUp(size_t value, size_t alignment)
85 : {
86 84 : return (value + alignment - 1) / alignment * alignment;
87 : }
88 :
89 70 : HcclResult AddDeviceEntitySection(size_t elemSize, uint32_t elemNum, size_t &offset, DeviceEntitySection §ion,
90 : const char *sectionName)
91 : {
92 70 : section.offset = AlignUp(offset, AIV_URMA_ENTITY_ALIGN_SIZE);
93 70 : if (elemNum == 0) {
94 28 : section.size = 0;
95 28 : offset = section.offset;
96 28 : return HCCL_SUCCESS;
97 : }
98 42 : CHK_PRT_RET(elemSize != 0 && elemNum > (SIZE_MAX / elemSize),
99 : HCCL_ERROR("[AivUrmaChannel::AddDeviceEntitySection] %s size overflow, elemSize[%zu], elemNum[%u]",
100 : sectionName, elemSize, elemNum), HCCL_E_PARA);
101 42 : section.size = elemSize * static_cast<size_t>(elemNum);
102 42 : CHK_PRT_RET(section.offset > (SIZE_MAX - section.size),
103 : HCCL_ERROR("[AivUrmaChannel::AddDeviceEntitySection] %s offset overflow, offset[%zu], size[%zu]",
104 : sectionName, section.offset, section.size), HCCL_E_PARA);
105 42 : offset = section.offset + section.size;
106 42 : return HCCL_SUCCESS;
107 : }
108 :
109 52 : void *GetSlabPtr(void *base, const DeviceEntitySection §ion)
110 : {
111 52 : if (section.size == 0) {
112 0 : return nullptr;
113 : }
114 52 : return reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(base) + section.offset);
115 : }
116 :
117 : template <typename T>
118 18 : HcclResult CopyArrayToSlab(void *slabBase, const T *hostArray, uint32_t arrayNum, const DeviceEntitySection §ion,
119 : T **deviceArrayPtr, const char *arrayName)
120 : {
121 18 : CHK_PTR_NULL(deviceArrayPtr);
122 18 : if (arrayNum == 0 || hostArray == nullptr) {
123 12 : CHK_PRT_RET(arrayNum != 0,
124 : HCCL_ERROR("[AivUrmaChannel::CopyArrayToSlab] %s hostArray is nullptr, num[%u]",
125 : arrayName, arrayNum), HCCL_E_PTR);
126 12 : *deviceArrayPtr = nullptr;
127 12 : return HCCL_SUCCESS;
128 : }
129 6 : CHK_PRT_RET(section.size != static_cast<size_t>(arrayNum) * sizeof(T),
130 : HCCL_ERROR("[AivUrmaChannel::CopyArrayToSlab] %s size mismatch, sectionSize[%zu], expect[%zu]",
131 : arrayName, section.size, static_cast<size_t>(arrayNum) * sizeof(T)), HCCL_E_PARA);
132 6 : void *sectionPtr = GetSlabPtr(slabBase, section);
133 6 : CHK_PTR_NULL(sectionPtr);
134 6 : Hccl::HrtMemcpy(sectionPtr, section.size, hostArray, section.size,
135 : Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
136 6 : *deviceArrayPtr = reinterpret_cast<T *>(sectionPtr);
137 6 : HCCL_INFO("[AivUrmaChannel::CopyArrayToSlab] %s: host[%p] -> dev[%p], num[%u], size[%zu]",
138 : arrayName, hostArray, sectionPtr, arrayNum, section.size);
139 6 : return HCCL_SUCCESS;
140 : }
141 :
142 7 : HcclResult BuildDeviceChannelEntityLayout(const ChannelEntity &hostChannel, DeviceChannelEntityLayout &layout)
143 : {
144 7 : layout.slabSize = AlignUp(sizeof(ChannelEntity), AIV_URMA_ENTITY_ALIGN_SIZE);
145 7 : CHK_RET(AddDeviceEntitySection(sizeof(RegedNotifyEntity), hostChannel.localNotifyNum, layout.slabSize,
146 : layout.localNotifySection, "localNotifyAddr"));
147 7 : CHK_RET(AddDeviceEntitySection(sizeof(RegedNotifyEntity), hostChannel.remoteNotifyNum, layout.slabSize,
148 : layout.remoteNotifySection, "remoteNotifyAddr"));
149 7 : CHK_RET(AddDeviceEntitySection(sizeof(RegedBufferEntity), hostChannel.localBufferNum, layout.slabSize,
150 : layout.localBufferSection, "localBufferAddr"));
151 7 : CHK_RET(AddDeviceEntitySection(sizeof(RegedBufferEntity), hostChannel.remoteBufferNum, layout.slabSize,
152 : layout.remoteBufferSection, "remoteBufferAddr"));
153 7 : CHK_RET(AddDeviceEntitySection(sizeof(SqContext), hostChannel.sqNum, layout.slabSize,
154 : layout.sqContextSection, "sqContextAddr"));
155 7 : CHK_RET(AddDeviceEntitySection(sizeof(CqContext), hostChannel.cqNum, layout.slabSize,
156 : layout.cqContextSection, "cqContextAddr"));
157 7 : CHK_RET(AddDeviceEntitySection(QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.sqNum, layout.slabSize,
158 : layout.sqPiSection, "sqPiAddr"));
159 7 : CHK_RET(AddDeviceEntitySection(QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.sqNum, layout.slabSize,
160 : layout.sqCiSection, "sqCiAddr"));
161 7 : CHK_RET(AddDeviceEntitySection(QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.cqNum, layout.slabSize,
162 : layout.cqPiSection, "cqPiAddr"));
163 7 : CHK_RET(AddDeviceEntitySection(QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.cqNum, layout.slabSize,
164 : layout.cqCiSection, "cqCiAddr"));
165 7 : layout.slabSize = AlignUp(layout.slabSize, AIV_URMA_ENTITY_ALIGN_SIZE);
166 7 : return HCCL_SUCCESS;
167 : }
168 :
169 6 : HcclResult AllocDeviceEntitySlab(size_t slabSize, AclDeviceSlabGuard &slabGuard, void *&slabPtr)
170 : {
171 6 : HcclResult ret = hrtMalloc(&slabPtr, slabSize);
172 6 : CHK_PRT_RET(ret != HCCL_SUCCESS || slabPtr == nullptr,
173 : HCCL_ERROR("[AivUrmaChannel::%s] hrtMalloc slab failed, ret[%d], size[%zu]",
174 : __func__, ret, slabSize), HCCL_E_MEMORY);
175 5 : slabGuard.Reset(slabPtr, slabSize);
176 5 : return HCCL_SUCCESS;
177 : }
178 :
179 20 : HcclResult ZeroQueueIndexSection(void *slabPtr, const std::vector<uint8_t> &zeroQueueIndexMem,
180 : const DeviceEntitySection §ion)
181 : {
182 20 : if (section.size == 0) {
183 0 : return HCCL_SUCCESS;
184 : }
185 20 : void *sectionPtr = GetSlabPtr(slabPtr, section);
186 20 : CHK_PTR_NULL(sectionPtr);
187 20 : Hccl::HrtMemcpy(sectionPtr, section.size, zeroQueueIndexMem.data(), section.size,
188 : Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
189 20 : return HCCL_SUCCESS;
190 : }
191 :
192 5 : HcclResult InitQueueIndexSections(void *slabPtr, const DeviceChannelEntityLayout &layout, uint32_t queueNum)
193 : {
194 5 : std::vector<uint8_t> zeroQueueIndexMem(QUEUE_INDEX_MEM_UNIT_SIZE * queueNum, 0);
195 5 : CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.sqPiSection));
196 5 : CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.sqCiSection));
197 5 : CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.cqPiSection));
198 5 : CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.cqCiSection));
199 5 : return HCCL_SUCCESS;
200 5 : }
201 :
202 5 : void SetQueueIndexDeviceMem(Hccl::AivUrmaTransport &transport, void *slabPtr,
203 : const DeviceChannelEntityLayout &layout, uint32_t queueNum)
204 : {
205 5 : transport.SetQueueIndexDeviceMem(GetSlabPtr(slabPtr, layout.sqPiSection),
206 5 : GetSlabPtr(slabPtr, layout.sqCiSection), GetSlabPtr(slabPtr, layout.cqPiSection),
207 5 : GetSlabPtr(slabPtr, layout.cqCiSection), queueNum * QUEUE_INDEX_MEM_UNIT_SIZE);
208 5 : }
209 :
210 3 : HcclResult CopyChannelEntityToSlab(void *slabPtr, const ChannelEntity &hostChannel,
211 : const DeviceChannelEntityLayout &layout, ChannelEntity &devChannel)
212 : {
213 3 : devChannel = hostChannel;
214 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.localNotifyAddr, hostChannel.localNotifyNum,
215 : layout.localNotifySection, &devChannel.localNotifyAddr, "localNotifyAddr"));
216 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.remoteNotifyAddr, hostChannel.remoteNotifyNum,
217 : layout.remoteNotifySection, &devChannel.remoteNotifyAddr, "remoteNotifyAddr"));
218 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.localBufferAddr, hostChannel.localBufferNum,
219 : layout.localBufferSection, &devChannel.localBufferAddr, "localBufferAddr"));
220 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.remoteBufferAddr, hostChannel.remoteBufferNum,
221 : layout.remoteBufferSection, &devChannel.remoteBufferAddr, "remoteBufferAddr"));
222 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.sqContextAddr, hostChannel.sqNum,
223 : layout.sqContextSection, &devChannel.sqContextAddr, "sqContextAddr"));
224 3 : CHK_RET(CopyArrayToSlab(slabPtr, hostChannel.cqContextAddr, hostChannel.cqNum,
225 : layout.cqContextSection, &devChannel.cqContextAddr, "cqContextAddr"));
226 3 : return HCCL_SUCCESS;
227 : }
228 :
229 3 : HcclResult CopyChannelEntityHeaderToSlab(void *slabPtr, const DeviceChannelEntityLayout &layout,
230 : const ChannelEntity &devChannel, void *&entityDevPtr)
231 : {
232 3 : entityDevPtr = GetSlabPtr(slabPtr, layout.entitySection);
233 3 : CHK_PTR_NULL(entityDevPtr);
234 3 : Hccl::HrtMemcpy(entityDevPtr, sizeof(ChannelEntity), &devChannel, sizeof(ChannelEntity),
235 : Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
236 3 : return HCCL_SUCCESS;
237 : }
238 : } // namespace
239 :
240 25 : AivUrmaChannel::AivUrmaChannel(EndpointHandle endpointHandle, const HcommChannelDesc &channelDesc)
241 25 : : endpointHandle_(endpointHandle),
242 25 : channelDesc_(channelDesc)
243 : {
244 25 : channelKind_ = HcommChannelKind::AIV_URMA;
245 25 : }
246 :
247 25 : AivUrmaChannel::~AivUrmaChannel()
248 : {
249 25 : PutSocketIfNeeded();
250 25 : ReleaseDeviceChannelEntity();
251 25 : }
252 :
253 27 : void AivUrmaChannel::PutSocketIfNeeded()
254 : {
255 27 : if (socket_ == nullptr) {
256 26 : return;
257 : }
258 1 : if (socketConfig_ == nullptr) {
259 0 : socket_ = nullptr;
260 0 : return;
261 : }
262 1 : if (channelDesc_.socket == nullptr && socket_ != nullptr) {
263 1 : (void)SocketMgr::GetInstance(devicePhyId_).PutSocket(socketConfig_, socket_);
264 : }
265 1 : socket_ = nullptr;
266 : }
267 :
268 30 : void AivUrmaChannel::ReleaseDeviceChannelEntity()
269 : {
270 30 : if (devChannelEntitySlab_ != nullptr) {
271 5 : HcclResult ret = hrtFree(devChannelEntitySlab_);
272 5 : if (ret != HCCL_SUCCESS) {
273 0 : HCCL_WARNING("[AivUrmaChannel::%s] hrtFree devChannelEntitySlab failed, ptr[%p], size[%zu], ret[%d]",
274 : __func__, devChannelEntitySlab_, devChannelEntitySlabSize_, ret);
275 : }
276 5 : devChannelEntitySlab_ = nullptr;
277 5 : devChannelEntitySlabSize_ = 0;
278 : }
279 30 : deviceMemories_.clear();
280 30 : devChannelEntity_ = nullptr;
281 30 : }
282 :
283 5 : HcclResult AivUrmaChannel::ParseInputParam()
284 : {
285 : // 1. 从 endpointHandle_,获得 localEp_ 和 rdmaHandle_
286 5 : Endpoint *localEpPtr = reinterpret_cast<Endpoint *>(endpointHandle_);
287 5 : CHK_PTR_NULL(localEpPtr);
288 4 : localEp_ = localEpPtr->GetEndpointDesc();
289 4 : rdmaHandle_ = localEpPtr->GetRdmaHandle();
290 4 : devicePhyId_ = localEp_.loc.device.devPhyId;
291 :
292 4 : socket_ = reinterpret_cast<Hccl::Socket *>(channelDesc_.socket);
293 4 : remoteEp_ = channelDesc_.remoteEndpoint;
294 4 : notifyNum_ = channelDesc_.notifyNum;
295 4 : commonRes_.bufferVec.clear();
296 4 : if (channelDesc_.exchangeAllMems) {
297 3 : HCCL_INFO("[AivUrmaChannel][%s] exchangeAllMems == true. Get memHandles from endpoint.", __func__);
298 3 : std::shared_ptr<Hccl::LocalUbRmaBuffer> *memHandles = nullptr;
299 3 : uint32_t memHandleNum = 0;
300 3 : CHK_RET(GetAllMemHandles(endpointHandle_, reinterpret_cast<void **>(&memHandles), &memHandleNum));
301 2 : HCCL_INFO("[AivUrmaChannel][%s] Got memHandleNum[%u].", __func__, memHandleNum);
302 3 : for (uint32_t i = 0; i < memHandleNum; ++i) {
303 1 : std::shared_ptr<Hccl::LocalUbRmaBuffer> &localUbRmaBuffer = memHandles[i];
304 1 : HCCL_INFO("[AivUrmaChannel][%s] Got memHandle No.%u: addr[0x%llx], size[0x%llx], memInfo[%s].",
305 : __func__, i, localUbRmaBuffer->GetAddr(), localUbRmaBuffer->GetSize(),
306 : localUbRmaBuffer->GetBuf()->GetMemInfo().c_str());
307 1 : commonRes_.bufferVec.push_back(localUbRmaBuffer.get());
308 : }
309 : } else {
310 1 : HCCL_INFO("[AivUrmaChannel][%s] exchangeAllMems == false. Get memHandles from channelDesc.", __func__);
311 1 : CHK_RET(MakeRmaBufferVecFromMemHandles(
312 : channelDesc_.memHandles, channelDesc_.memHandleNum, commonRes_.bufferVec, "AivUrmaChannel"));
313 : }
314 :
315 3 : return HCCL_SUCCESS;
316 : }
317 :
318 2 : HcclResult AivUrmaChannel::BuildSocket()
319 : {
320 2 : if (socket_ != nullptr) {
321 1 : return HCCL_SUCCESS;
322 : }
323 1 : HCCL_INFO("[AivUrmaChannel][%s] socket ptr is NULL, rebuildSocket", __func__);
324 :
325 1 : Hccl::IpAddress ipAddr{};
326 1 : CHK_RET(CommAddrToIpAddress(localEp_.commAddr, ipAddr));
327 1 : Hccl::DevNetPortType type = Hccl::DevNetPortType(Hccl::ConnectProtoType::UB);
328 1 : Hccl::PortData localPort = Hccl::PortData(static_cast<Hccl::RankId>(localEp_.loc.device.devPhyId), type, 0, ipAddr);
329 : Hccl::SocketHandle socketHandle
330 1 : = Hccl::SocketHandleManager::GetInstance().Create(localEp_.loc.device.devPhyId, localPort);
331 1 : EXCEPTION_CATCH(serverSocket_ = std::make_unique<Hccl::Socket>(socketHandle, ipAddr, DEFAULT_LISTENING_PORT, ipAddr,
332 : "server", Hccl::SocketRole::SERVER, Hccl::NicType::DEVICE_NIC_TYPE),
333 : return HCCL_E_PARA);
334 1 : HCCL_INFO("[AivUrmaChannel][%s] listen_socket_info[%s]", __func__, serverSocket_->Describe().c_str());
335 1 : EXCEPTION_CATCH(serverSocket_->Listen(), return HCCL_E_INTERNAL);
336 :
337 1 : Hccl::LinkData linkData = BuildDefaultLinkData();
338 1 : CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
339 1 : HCCL_INFO("[AivUrmaChannel][%s] built linkData: %s", __func__, linkData.Describe().c_str());
340 1 : std::string socketTag = (channelDesc_.channelName != nullptr)
341 3 : ? std::string(channelDesc_.channelName) : "AUTOMATIC_SOCKET_TAG";
342 1 : bool noRankId = true;
343 1 : EXCEPTION_CATCH(socketConfigHolder_ = std::make_unique<Hccl::SocketConfig>(linkData, socketTag, noRankId),
344 : return HCCL_E_PTR);
345 1 : socketConfig_ = socketConfigHolder_.get();
346 1 : CHK_RET(SocketMgr::GetInstance(devicePhyId_).GetSocket(*socketConfigHolder_, socket_));
347 :
348 1 : return HCCL_SUCCESS;
349 1 : }
350 :
351 1 : HcclResult AivUrmaChannel::BuildAttr()
352 : {
353 1 : attr_.devicePhyId = localEp_.loc.device.devPhyId;
354 1 : attr_.opMode = Hccl::OpMode::OPBASE;
355 1 : attr_.opAcceState = Hccl::AcceleratorState::AIV;
356 1 : return HCCL_SUCCESS;
357 : }
358 :
359 0 : HcclResult AivUrmaChannel::BuildConnection()
360 : {
361 0 : UbConnBuildContext ctx;
362 0 : CHK_RET(PrepareUbConnBuildContext(localEp_, remoteEp_, channelDesc_.qos, ctx));
363 :
364 0 : Hccl::OpMode opMode = Hccl::OpMode::OPBASE;
365 0 : bool devUsed = true;
366 0 : Hccl::HrtUbJfcMode jfcMode = Hccl::HrtUbJfcMode::USER_CTL;
367 0 : std::unique_ptr<Hccl::DevUbConnection> ubConn = nullptr;
368 0 : switch (ctx.protocol) {
369 0 : case Hccl::LinkProtocol::UB_TP:
370 0 : EXCEPTION_CATCH(ubConn = std::make_unique<Hccl::DevUbTpConnection>(
371 : rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode,
372 : Hccl::IpAddress(), Hccl::IpAddress(), ctx.qosPre),
373 : return HCCL_E_PTR);
374 0 : break;
375 0 : case Hccl::LinkProtocol::UB_CTP:
376 0 : EXCEPTION_CATCH(ubConn = std::make_unique<Hccl::DevUbCtpConnection>(
377 : rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode,
378 : Hccl::IpAddress(), Hccl::IpAddress(), ctx.qosPre),
379 : return HCCL_E_PTR);
380 0 : break;
381 0 : default:
382 0 : HCCL_ERROR("%s No LinkProtocol to match", __func__);
383 0 : break;
384 : }
385 0 : CHK_SMART_PTR_NULL(ubConn);
386 :
387 0 : commonRes_.connVec.clear();
388 0 : connections_.clear();
389 0 : commonRes_.connVec.emplace_back(ubConn.get());
390 0 : connections_.push_back(std::move(ubConn));
391 :
392 0 : return HCCL_SUCCESS;
393 0 : }
394 :
395 0 : HcclResult AivUrmaChannel::BuildAivUrmaTransport()
396 : {
397 :
398 0 : const Hccl::Socket &socket = *socket_;
399 :
400 0 : Hccl::LinkData linkData = BuildDefaultLinkData();
401 0 : CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
402 :
403 : // make_unique / make_shared / release 包一层抛异常的宏
404 0 : EXCEPTION_CATCH(transport_ = std::make_unique<Hccl::AivUrmaTransport>(
405 : commonRes_, attr_, linkData, socket, rdmaHandle_), // 这里区分是否是优先recv
406 : return HCCL_E_PTR);
407 0 : return HCCL_SUCCESS;
408 : }
409 :
410 5 : HcclResult AivUrmaChannel::BuildChannelEntityToDevice(void **devChannelPtr)
411 : {
412 5 : if (devChannelPtr == nullptr) {
413 1 : HCCL_ERROR("[AivUrmaChannel] BuildChannelEntityToDevice devChannelPtr is nullptr");
414 1 : return HCCL_E_PTR;
415 : }
416 :
417 4 : CHK_PTR_NULL(transport_.get());
418 :
419 : ChannelEntity hostChannel;
420 3 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
421 :
422 3 : transport_->PrepareHostChannelEntity(&hostChannel);
423 :
424 3 : DeviceChannelEntityLayout layout;
425 3 : CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
426 3 : void *slabPtr = nullptr;
427 3 : AclDeviceSlabGuard slabGuard;
428 3 : CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
429 2 : uint32_t queueNum = std::max(hostChannel.sqNum, hostChannel.cqNum);
430 2 : CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
431 2 : SetQueueIndexDeviceMem(*transport_, slabPtr, layout, queueNum);
432 :
433 2 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
434 2 : transport_->GetHostChannelEntity(&hostChannel);
435 2 : hostChannel.abiHeader = channelDesc_.header;
436 2 : hostChannel.engine = COMM_ENGINE_AIV;
437 2 : hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
438 :
439 : ChannelEntity devChannel;
440 2 : CHK_RET(CopyChannelEntityToSlab(slabPtr, hostChannel, layout, devChannel));
441 2 : void *entityDevPtr = nullptr;
442 2 : CHK_RET(CopyChannelEntityHeaderToSlab(slabPtr, layout, devChannel, entityDevPtr));
443 2 : ReleaseDeviceChannelEntity();
444 2 : devChannelEntitySlab_ = slabGuard.Release();
445 2 : devChannelEntitySlabSize_ = layout.slabSize;
446 2 : devChannelEntity_ = entityDevPtr;
447 2 : *devChannelPtr = devChannelEntity_;
448 2 : HCCL_INFO("[AivUrmaChannel] Build channel entity to device success, devPtr[%p], slabPtr[%p], slabSize[%zu]",
449 : devChannelEntity_, devChannelEntitySlab_, devChannelEntitySlabSize_);
450 2 : return HCCL_SUCCESS;
451 3 : }
452 :
453 6 : HcclResult AivUrmaChannel::PreAllocChannelEntityToDevice(void **devChannelPtr)
454 : {
455 6 : if (devChannelPtr == nullptr) {
456 1 : HCCL_ERROR("[AivUrmaChannel::%s] devChannelPtr is nullptr", __func__);
457 1 : return HCCL_E_PTR;
458 : }
459 5 : CHK_PTR_NULL(transport_.get());
460 :
461 4 : if (devChannelEntitySlab_ != nullptr) {
462 1 : *devChannelPtr = devChannelEntity_;
463 1 : HCCL_INFO("[AivUrmaChannel::%s] already built, return cached devPtr[%p]", __func__, devChannelEntity_);
464 1 : return HCCL_SUCCESS;
465 : }
466 :
467 3 : uint32_t bufNum = 0;
468 3 : uint32_t connNum = 0;
469 3 : transport_->GetEntityCountsForLayout(bufNum, connNum);
470 :
471 3 : ChannelEntity tmp{};
472 3 : tmp.localBufferNum = bufNum;
473 3 : tmp.remoteBufferNum = bufNum;
474 3 : tmp.sqNum = connNum;
475 3 : tmp.cqNum = connNum;
476 :
477 3 : DeviceChannelEntityLayout layout;
478 3 : CHK_RET(BuildDeviceChannelEntityLayout(tmp, layout));
479 :
480 3 : void *slabPtr = nullptr;
481 3 : AclDeviceSlabGuard slabGuard;
482 3 : CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
483 :
484 3 : uint32_t queueNum = std::max(tmp.sqNum, tmp.cqNum);
485 3 : CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
486 :
487 3 : devChannelEntitySlab_ = slabGuard.Release();
488 3 : devChannelEntitySlabSize_ = layout.slabSize;
489 3 : devChannelEntity_ = GetSlabPtr(devChannelEntitySlab_, layout.entitySection);
490 3 : SetQueueIndexDeviceMem(*transport_, devChannelEntitySlab_, layout, queueNum);
491 3 : *devChannelPtr = devChannelEntity_;
492 :
493 3 : HCCL_INFO("[AivUrmaChannel::%s] pre-alloc success, devPtr[%p], slabPtr[%p], slabSize[%zu]",
494 : __func__, devChannelEntity_, devChannelEntitySlab_, devChannelEntitySlabSize_);
495 3 : return HCCL_SUCCESS;
496 3 : }
497 :
498 2 : HcclResult AivUrmaChannel::FillChannelEntityToDevice()
499 : {
500 2 : if (devChannelEntitySlab_ == nullptr) {
501 1 : HCCL_ERROR("[AivUrmaChannel::%s] devChannelEntitySlab_ is nullptr, not pre-allocated.", __func__);
502 1 : return HCCL_E_INTERNAL;
503 : }
504 1 : CHK_PTR_NULL(transport_.get());
505 :
506 : ChannelEntity hostChannel;
507 1 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
508 1 : transport_->GetHostChannelEntity(&hostChannel);
509 1 : hostChannel.abiHeader = channelDesc_.header;
510 1 : hostChannel.engine = COMM_ENGINE_AIV;
511 1 : hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
512 :
513 1 : DeviceChannelEntityLayout layout;
514 1 : CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
515 1 : if (layout.slabSize > devChannelEntitySlabSize_) {
516 0 : HCCL_ERROR("[AivUrmaChannel::%s] slabSize[%zu] > preAllocSize[%zu]",
517 : __func__, layout.slabSize, devChannelEntitySlabSize_);
518 0 : return HCCL_E_INTERNAL;
519 : }
520 :
521 : ChannelEntity devChannel;
522 1 : CHK_RET(CopyChannelEntityToSlab(devChannelEntitySlab_, hostChannel, layout, devChannel));
523 1 : void *entityDevPtr = nullptr;
524 1 : CHK_RET(CopyChannelEntityHeaderToSlab(devChannelEntitySlab_, layout, devChannel, entityDevPtr));
525 :
526 1 : devChannelEntity_ = entityDevPtr;
527 1 : HCCL_INFO("[AivUrmaChannel::%s] fill success, devPtr[%p]", __func__, devChannelEntity_);
528 1 : return HCCL_SUCCESS;
529 : }
530 :
531 1 : HcclResult AivUrmaChannel::GetNotifyNum(uint32_t *notifyNum) const
532 : {
533 1 : HCCL_INFO("AivUrmaChannel GetNotifyNum is not supported.");
534 1 : return HCCL_SUCCESS;
535 : }
536 :
537 0 : HcclResult AivUrmaChannel::GetRemoteMems(uint32_t *memNum, CommMem **remoteMem, char ***memInfos)
538 : {
539 0 : return transport_->GetRemoteMems(memNum, remoteMem, memInfos);
540 : }
541 :
542 3 : HcclResult AivUrmaChannel::Clean()
543 : {
544 3 : ReleaseDeviceChannelEntity();
545 3 : ReleasePtrArrayDevMems();
546 3 : transport_.reset();
547 3 : return HCCL_SUCCESS;
548 : }
549 :
550 1 : HcclResult AivUrmaChannel::Resume()
551 : {
552 1 : BuildConnection();
553 1 : BuildAivUrmaTransport();
554 1 : return HCCL_SUCCESS;
555 : }
556 :
557 1 : HcclResult AivUrmaChannel::NotifyRecord(const uint32_t remoteNotifyIdx)
558 : {
559 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
560 1 : return HCCL_E_NOT_SUPPORT;
561 : }
562 :
563 1 : HcclResult AivUrmaChannel::NotifyWait(const uint32_t localNotifyIdx, const uint32_t timeout)
564 : {
565 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
566 1 : return HCCL_E_NOT_SUPPORT;
567 : }
568 :
569 1 : HcclResult AivUrmaChannel::WriteWithNotify(void *dst, const void *src, const uint64_t len,
570 : uint32_t remoteNotifyIdx)
571 : {
572 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
573 1 : return HCCL_E_NOT_SUPPORT;
574 : }
575 :
576 1 : HcclResult AivUrmaChannel::Write(void *dst, const void *src, uint64_t len)
577 : {
578 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
579 1 : return HCCL_E_NOT_SUPPORT;
580 : }
581 :
582 1 : HcclResult AivUrmaChannel::Read(void *dst, const void *src, uint64_t len)
583 : {
584 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
585 1 : return HCCL_E_NOT_SUPPORT;
586 : }
587 :
588 1 : HcclResult AivUrmaChannel::ChannelFence()
589 : {
590 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
591 1 : return HCCL_E_NOT_SUPPORT;
592 : }
593 :
594 2 : HcclResult AivUrmaChannel::Init()
595 : {
596 : /*
597 : Argue result: make_unique 配合一场捕获的宏 EXCEPTION CATCH
598 : Attention: const 和引用
599 : */
600 2 : CHK_RET(ParseInputParam());
601 1 : CHK_RET(BuildSocket());
602 1 : CHK_RET(BuildAttr());
603 1 : CHK_RET(BuildConnection());
604 1 : CHK_RET(BuildAivUrmaTransport());
605 1 : return HCCL_SUCCESS;
606 : }
607 :
608 1 : ChannelStatus AivUrmaChannel::GetStatus()
609 : {
610 1 : Hccl::TransportStatus transportStatus = transport_->GetStatus();
611 1 : ChannelStatus out = ChannelStatus::INIT;
612 1 : switch (transportStatus) {
613 0 : case Hccl::TransportStatus::INIT:
614 0 : out = ChannelStatus::INIT;
615 0 : break;
616 0 : case Hccl::TransportStatus::SOCKET_OK:
617 0 : out = ChannelStatus::SOCKET_OK;
618 0 : break;
619 1 : case Hccl::TransportStatus::SOCKET_TIMEOUT:
620 1 : out = ChannelStatus::SOCKET_TIMEOUT;
621 1 : break;
622 0 : case Hccl::TransportStatus::READY:
623 0 : out = ChannelStatus::READY;
624 0 : break;
625 0 : default:
626 0 : HCCL_ERROR("[AivUrmaChannel][%s] Invalid TransportStatus[%d]", __func__, transportStatus);
627 0 : out = ChannelStatus::INVALID;
628 0 : break;
629 : }
630 1 : return out;
631 : }
632 :
633 : } // namespace hcomm
|