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 32 : AivUrmaChannel::AivUrmaChannel(EndpointHandle endpointHandle, const HcommChannelDesc &channelDesc)
241 32 : : endpointHandle_(endpointHandle),
242 32 : channelDesc_(channelDesc)
243 : {
244 32 : channelKind_ = HcommChannelKind::AIV_URMA;
245 32 : }
246 :
247 33 : AivUrmaChannel::~AivUrmaChannel()
248 : {
249 32 : PutSocketIfNeeded();
250 32 : ReleaseDeviceChannelEntity();
251 33 : }
252 :
253 34 : void AivUrmaChannel::PutSocketIfNeeded()
254 : {
255 34 : if (socket_ == nullptr) {
256 32 : return;
257 : }
258 2 : if (socketConfig_ == nullptr) {
259 1 : socket_ = nullptr;
260 1 : 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 37 : void AivUrmaChannel::ReleaseDeviceChannelEntity()
269 : {
270 37 : 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 37 : deviceMemories_.clear();
280 37 : devChannelEntity_ = nullptr;
281 37 : }
282 :
283 6 : HcclResult AivUrmaChannel::ParseInputParam()
284 : {
285 : // 1. 从 endpointHandle_,获得 localEp_ 和 rdmaHandle_
286 6 : Endpoint *localEpPtr = reinterpret_cast<Endpoint *>(endpointHandle_);
287 6 : CHK_PTR_NULL(localEpPtr);
288 5 : localEp_ = localEpPtr->GetEndpointDesc();
289 5 : rdmaHandle_ = localEpPtr->GetRdmaHandle();
290 5 : devicePhyId_ = localEp_.loc.device.devPhyId;
291 :
292 5 : socket_ = reinterpret_cast<Hccl::Socket *>(channelDesc_.socket);
293 5 : remoteEp_ = channelDesc_.remoteEndpoint;
294 5 : notifyNum_ = channelDesc_.notifyNum;
295 5 : commonRes_.bufferVec.clear();
296 5 : 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 2 : HCCL_INFO("[AivUrmaChannel][%s] exchangeAllMems == false. Get memHandles from channelDesc.", __func__);
311 2 : CHK_RET(MakeRmaBufferVecFromMemHandles(
312 : channelDesc_.memHandles, channelDesc_.memHandleNum, commonRes_.bufferVec, "AivUrmaChannel"));
313 : }
314 :
315 4 : return HCCL_SUCCESS;
316 : }
317 :
318 4 : HcclResult AivUrmaChannel::BuildSocket()
319 : {
320 4 : if (socket_ != nullptr) {
321 2 : return HCCL_SUCCESS;
322 : }
323 2 : HCCL_INFO("[AivUrmaChannel][%s] socket ptr is NULL, rebuildSocket", __func__);
324 :
325 2 : Hccl::LinkData linkData = BuildDefaultLinkData();
326 2 : CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
327 2 : HCCL_INFO("[AivUrmaChannel][%s] built linkData: %s", __func__, linkData.Describe().c_str());
328 2 : uint16_t port = channelDesc_.port;
329 2 : if (port == 0) {
330 0 : port = DEFAULT_LISTENING_PORT;
331 0 : HCCL_INFO("[AivUrmaChannel::%s] channelDesc port is 0, use default port [%u]", __func__, port);
332 : }
333 2 : std::string socketTag = (channelDesc_.channelName != nullptr)
334 6 : ? std::string(channelDesc_.channelName) : "AUTOMATIC_SOCKET_TAG";
335 2 : if (channelDesc_.role == HCOMM_SOCKET_ROLE_RESERVED) {
336 1 : EXCEPTION_CATCH(socketConfigHolder_ = std::make_unique<Hccl::SocketConfig>(
337 : linkData, port, socketTag),
338 : return HCCL_E_PTR);
339 1 : socketConfigHolder_->noRankId = true;
340 : } else {
341 1 : bool isServer = (channelDesc_.role == HCOMM_SOCKET_ROLE_SERVER);
342 1 : EXCEPTION_CATCH(socketConfigHolder_ = std::make_unique<Hccl::SocketConfig>(
343 : linkData, port, socketTag, isServer),
344 : return HCCL_E_PTR);
345 : }
346 2 : socketConfig_ = socketConfigHolder_.get();
347 2 : CHK_RET(SocketMgr::GetInstance(devicePhyId_).GetSocket(*socketConfigHolder_, socket_));
348 2 : HCCL_INFO("[AivUrmaChannel::%s] SUCCESS. port[%u].", __func__, port);
349 2 : return HCCL_SUCCESS;
350 2 : }
351 :
352 5 : HcclResult AivUrmaChannel::StartListen()
353 : {
354 5 : if (channelDesc_.role != HCOMM_SOCKET_ROLE_SERVER) {
355 3 : return HCCL_SUCCESS;
356 : }
357 :
358 2 : uint16_t port = channelDesc_.port;
359 2 : HCCL_INFO("[AivUrmaChannel::%s] Start. EndpointHandle[%p], port[%u]", __func__, endpointHandle_, port);
360 2 : if (port == 0) {
361 1 : port = DEFAULT_LISTENING_PORT;
362 1 : HCCL_INFO("[AivUrmaChannel::%s] channelDesc port is 0, use default port [%u]", __func__, port);
363 : }
364 2 : CHK_RET(static_cast<HcclResult>(HcommEndpointStartListen(endpointHandle_, port, nullptr)));
365 2 : HCCL_INFO("[AivUrmaChannel::%s] SUCCESS. port[%u].", __func__, port);
366 2 : return HCCL_SUCCESS;
367 : }
368 :
369 2 : HcclResult AivUrmaChannel::BuildAttr()
370 : {
371 2 : attr_.devicePhyId = localEp_.loc.device.devPhyId;
372 2 : attr_.opMode = Hccl::OpMode::OPBASE;
373 2 : attr_.opAcceState = Hccl::AcceleratorState::AIV;
374 2 : return HCCL_SUCCESS;
375 : }
376 :
377 1 : HcclResult AivUrmaChannel::BuildConnection()
378 : {
379 1 : UbConnBuildContext ctx;
380 1 : CHK_RET(PrepareUbConnBuildContext(localEp_, remoteEp_, channelDesc_.qos, ctx));
381 :
382 1 : Hccl::OpMode opMode = Hccl::OpMode::OPBASE;
383 1 : bool devUsed = true;
384 1 : Hccl::HrtUbJfcMode jfcMode = Hccl::HrtUbJfcMode::USER_CTL;
385 1 : std::unique_ptr<Hccl::DevUbConnection> ubConn = nullptr;
386 1 : switch (ctx.protocol) {
387 0 : case Hccl::LinkProtocol::UB_TP:
388 0 : EXCEPTION_CATCH(ubConn = std::make_unique<Hccl::DevUbTpConnection>(
389 : rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode,
390 : Hccl::IpAddress(), Hccl::IpAddress(), ctx.qosPre, COMM_ENGINE_AIV),
391 : return HCCL_E_PTR);
392 0 : break;
393 0 : case Hccl::LinkProtocol::UB_CTP:
394 0 : EXCEPTION_CATCH(ubConn = std::make_unique<Hccl::DevUbCtpConnection>(
395 : rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode,
396 : Hccl::IpAddress(), Hccl::IpAddress(), ctx.qosPre, COMM_ENGINE_AIV),
397 : return HCCL_E_PTR);
398 0 : break;
399 1 : case Hccl::LinkProtocol::UBG:
400 1 : EXCEPTION_CATCH(ubConn = std::make_unique<Hccl::DevUbUbgConnection>(
401 : rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode,
402 : ctx.locAddr, ctx.rmtAddr),
403 : return HCCL_E_PTR);
404 1 : break;
405 0 : default:
406 0 : HCCL_ERROR("%s No LinkProtocol to match", __func__);
407 0 : break;
408 : }
409 1 : CHK_SMART_PTR_NULL(ubConn);
410 :
411 1 : commonRes_.connVec.clear();
412 1 : connections_.clear();
413 1 : commonRes_.connVec.emplace_back(ubConn.get());
414 1 : connections_.push_back(std::move(ubConn));
415 :
416 1 : return HCCL_SUCCESS;
417 1 : }
418 :
419 1 : HcclResult AivUrmaChannel::BuildAivUrmaTransport()
420 : {
421 :
422 1 : const Hccl::Socket &socket = *socket_;
423 :
424 1 : Hccl::LinkData linkData = BuildDefaultLinkData();
425 1 : CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
426 :
427 : // make_unique / make_shared / release 包一层抛异常的宏
428 1 : EXCEPTION_CATCH(transport_ = std::make_unique<Hccl::AivUrmaTransport>(
429 : commonRes_, attr_, linkData, socket, rdmaHandle_), // 这里区分是否是优先recv
430 : return HCCL_E_PTR);
431 1 : return HCCL_SUCCESS;
432 : }
433 :
434 5 : HcclResult AivUrmaChannel::BuildChannelEntityToDevice(void **devChannelPtr)
435 : {
436 5 : if (devChannelPtr == nullptr) {
437 1 : HCCL_ERROR("[AivUrmaChannel] BuildChannelEntityToDevice devChannelPtr is nullptr");
438 1 : return HCCL_E_PTR;
439 : }
440 :
441 4 : CHK_PTR_NULL(transport_.get());
442 :
443 : ChannelEntity hostChannel;
444 3 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
445 :
446 3 : transport_->PrepareHostChannelEntity(&hostChannel);
447 :
448 3 : DeviceChannelEntityLayout layout;
449 3 : CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
450 3 : void *slabPtr = nullptr;
451 3 : AclDeviceSlabGuard slabGuard;
452 3 : CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
453 2 : uint32_t queueNum = std::max(hostChannel.sqNum, hostChannel.cqNum);
454 2 : CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
455 2 : SetQueueIndexDeviceMem(*transport_, slabPtr, layout, queueNum);
456 :
457 2 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
458 2 : transport_->GetHostChannelEntity(&hostChannel);
459 2 : hostChannel.abiHeader = channelDesc_.header;
460 2 : hostChannel.engine = COMM_ENGINE_AIV;
461 2 : hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
462 :
463 : ChannelEntity devChannel;
464 2 : CHK_RET(CopyChannelEntityToSlab(slabPtr, hostChannel, layout, devChannel));
465 2 : void *entityDevPtr = nullptr;
466 2 : CHK_RET(CopyChannelEntityHeaderToSlab(slabPtr, layout, devChannel, entityDevPtr));
467 2 : ReleaseDeviceChannelEntity();
468 2 : devChannelEntitySlab_ = slabGuard.Release();
469 2 : devChannelEntitySlabSize_ = layout.slabSize;
470 2 : devChannelEntity_ = entityDevPtr;
471 2 : *devChannelPtr = devChannelEntity_;
472 2 : HCCL_INFO("[AivUrmaChannel] Build channel entity to device success, devPtr[%p], slabPtr[%p], slabSize[%zu]",
473 : devChannelEntity_, devChannelEntitySlab_, devChannelEntitySlabSize_);
474 2 : return HCCL_SUCCESS;
475 3 : }
476 :
477 6 : HcclResult AivUrmaChannel::PreAllocChannelEntityToDevice(void **devChannelPtr)
478 : {
479 6 : if (devChannelPtr == nullptr) {
480 1 : HCCL_ERROR("[AivUrmaChannel::%s] devChannelPtr is nullptr", __func__);
481 1 : return HCCL_E_PTR;
482 : }
483 5 : CHK_PTR_NULL(transport_.get());
484 :
485 4 : if (devChannelEntitySlab_ != nullptr) {
486 1 : *devChannelPtr = devChannelEntity_;
487 1 : HCCL_INFO("[AivUrmaChannel::%s] already built, return cached devPtr[%p]", __func__, devChannelEntity_);
488 1 : return HCCL_SUCCESS;
489 : }
490 :
491 3 : uint32_t bufNum = 0;
492 3 : uint32_t connNum = 0;
493 3 : transport_->GetEntityCountsForLayout(bufNum, connNum);
494 :
495 3 : ChannelEntity tmp{};
496 3 : tmp.localBufferNum = bufNum;
497 3 : tmp.remoteBufferNum = bufNum;
498 3 : tmp.sqNum = connNum;
499 3 : tmp.cqNum = connNum;
500 :
501 3 : DeviceChannelEntityLayout layout;
502 3 : CHK_RET(BuildDeviceChannelEntityLayout(tmp, layout));
503 :
504 3 : void *slabPtr = nullptr;
505 3 : AclDeviceSlabGuard slabGuard;
506 3 : CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
507 :
508 3 : uint32_t queueNum = std::max(tmp.sqNum, tmp.cqNum);
509 3 : CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
510 :
511 3 : devChannelEntitySlab_ = slabGuard.Release();
512 3 : devChannelEntitySlabSize_ = layout.slabSize;
513 3 : devChannelEntity_ = GetSlabPtr(devChannelEntitySlab_, layout.entitySection);
514 3 : SetQueueIndexDeviceMem(*transport_, devChannelEntitySlab_, layout, queueNum);
515 3 : *devChannelPtr = devChannelEntity_;
516 :
517 3 : HCCL_INFO("[AivUrmaChannel::%s] pre-alloc success, devPtr[%p], slabPtr[%p], slabSize[%zu]",
518 : __func__, devChannelEntity_, devChannelEntitySlab_, devChannelEntitySlabSize_);
519 3 : return HCCL_SUCCESS;
520 3 : }
521 :
522 2 : HcclResult AivUrmaChannel::FillChannelEntityToDevice()
523 : {
524 2 : if (devChannelEntitySlab_ == nullptr) {
525 1 : HCCL_ERROR("[AivUrmaChannel::%s] devChannelEntitySlab_ is nullptr, not pre-allocated.", __func__);
526 1 : return HCCL_E_INTERNAL;
527 : }
528 1 : CHK_PTR_NULL(transport_.get());
529 :
530 : ChannelEntity hostChannel;
531 1 : CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
532 1 : transport_->GetHostChannelEntity(&hostChannel);
533 1 : hostChannel.abiHeader = channelDesc_.header;
534 1 : hostChannel.engine = COMM_ENGINE_AIV;
535 1 : hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
536 :
537 1 : DeviceChannelEntityLayout layout;
538 1 : CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
539 1 : if (layout.slabSize > devChannelEntitySlabSize_) {
540 0 : HCCL_ERROR("[AivUrmaChannel::%s] slabSize[%zu] > preAllocSize[%zu]",
541 : __func__, layout.slabSize, devChannelEntitySlabSize_);
542 0 : return HCCL_E_INTERNAL;
543 : }
544 :
545 : ChannelEntity devChannel;
546 1 : CHK_RET(CopyChannelEntityToSlab(devChannelEntitySlab_, hostChannel, layout, devChannel));
547 1 : void *entityDevPtr = nullptr;
548 1 : CHK_RET(CopyChannelEntityHeaderToSlab(devChannelEntitySlab_, layout, devChannel, entityDevPtr));
549 :
550 1 : devChannelEntity_ = entityDevPtr;
551 1 : HCCL_INFO("[AivUrmaChannel::%s] fill success, devPtr[%p]", __func__, devChannelEntity_);
552 1 : return HCCL_SUCCESS;
553 : }
554 :
555 1 : HcclResult AivUrmaChannel::GetNotifyNum(uint32_t *notifyNum) const
556 : {
557 1 : HCCL_INFO("AivUrmaChannel GetNotifyNum is not supported.");
558 1 : return HCCL_SUCCESS;
559 : }
560 :
561 0 : HcclResult AivUrmaChannel::GetRemoteMems(uint32_t *memNum, CommMem **remoteMem, char ***memInfos)
562 : {
563 0 : return transport_->GetRemoteMems(memNum, remoteMem, memInfos);
564 : }
565 :
566 3 : HcclResult AivUrmaChannel::Clean()
567 : {
568 3 : ReleaseDeviceChannelEntity();
569 3 : ReleasePtrArrayDevMems();
570 3 : transport_.reset();
571 3 : return HCCL_SUCCESS;
572 : }
573 :
574 1 : HcclResult AivUrmaChannel::Resume()
575 : {
576 1 : BuildConnection();
577 1 : BuildAivUrmaTransport();
578 1 : return HCCL_SUCCESS;
579 : }
580 :
581 1 : HcclResult AivUrmaChannel::NotifyRecord(const uint32_t remoteNotifyIdx)
582 : {
583 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
584 1 : return HCCL_E_NOT_SUPPORT;
585 : }
586 :
587 1 : HcclResult AivUrmaChannel::NotifyWait(const uint32_t localNotifyIdx, const uint32_t timeout)
588 : {
589 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
590 1 : return HCCL_E_NOT_SUPPORT;
591 : }
592 :
593 1 : HcclResult AivUrmaChannel::WriteWithNotify(void *dst, const void *src, const uint64_t len,
594 : uint32_t remoteNotifyIdx)
595 : {
596 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
597 1 : return HCCL_E_NOT_SUPPORT;
598 : }
599 :
600 1 : HcclResult AivUrmaChannel::Write(void *dst, const void *src, uint64_t len)
601 : {
602 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
603 1 : return HCCL_E_NOT_SUPPORT;
604 : }
605 :
606 1 : HcclResult AivUrmaChannel::Read(void *dst, const void *src, uint64_t len)
607 : {
608 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
609 1 : return HCCL_E_NOT_SUPPORT;
610 : }
611 :
612 1 : HcclResult AivUrmaChannel::ChannelFence()
613 : {
614 1 : HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
615 1 : return HCCL_E_NOT_SUPPORT;
616 : }
617 :
618 3 : HcclResult AivUrmaChannel::Init()
619 : {
620 : /*
621 : Argue result: make_unique 配合一场捕获的宏 EXCEPTION CATCH
622 : Attention: const 和引用
623 : */
624 3 : CHK_RET(ParseInputParam());
625 2 : CHK_RET(StartListen());
626 2 : CHK_RET(BuildSocket());
627 2 : CHK_RET(BuildAttr());
628 2 : CHK_RET(BuildConnection());
629 2 : CHK_RET(BuildAivUrmaTransport());
630 2 : return HCCL_SUCCESS;
631 : }
632 :
633 1 : ChannelStatus AivUrmaChannel::GetStatus()
634 : {
635 1 : Hccl::TransportStatus transportStatus = transport_->GetStatus();
636 1 : ChannelStatus out = ChannelStatus::INIT;
637 1 : switch (transportStatus) {
638 0 : case Hccl::TransportStatus::INIT:
639 0 : out = ChannelStatus::INIT;
640 0 : break;
641 0 : case Hccl::TransportStatus::SOCKET_OK:
642 0 : out = ChannelStatus::SOCKET_OK;
643 0 : break;
644 1 : case Hccl::TransportStatus::SOCKET_TIMEOUT:
645 1 : out = ChannelStatus::SOCKET_TIMEOUT;
646 1 : break;
647 0 : case Hccl::TransportStatus::READY:
648 0 : out = ChannelStatus::READY;
649 0 : break;
650 0 : default:
651 0 : HCCL_ERROR("[AivUrmaChannel][%s] Invalid TransportStatus[%d]", __func__, transportStatus);
652 0 : out = ChannelStatus::INVALID;
653 0 : break;
654 : }
655 1 : return out;
656 : }
657 :
658 : } // namespace hcomm
|