Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "transport_mem.h"
12 : #include "log.h"
13 : #include "transport_ipc_mem.h"
14 : #include "transport_roce_mem.h"
15 : #ifdef CCL_KERNEL
16 : #include "transport_device_roce_mem.h"
17 : #endif
18 :
19 : namespace hccl {
20 : constexpr u32 INVALID_REMOTE_RANK_ID = 0xFFFFFFFF;
21 0 : TransportMem::TransportMem(
22 : const std::unique_ptr<NotifyPool>& notifyPool, const HcclNetDevCtx& netDevCtx, const HcclDispatcher& dispatcher,
23 0 : AttrInfo& attrInfo)
24 0 : : TransportMem(notifyPool, netDevCtx, dispatcher, attrInfo, false)
25 0 : {}
26 :
27 0 : TransportMem::TransportMem(
28 : const std::unique_ptr<NotifyPool>& notifyPool, const HcclNetDevCtx& netDevCtx, const HcclDispatcher& dispatcher,
29 0 : AttrInfo& attrInfo, bool aicpuUnfoldMode)
30 0 : : notifyPool_(notifyPool),
31 0 : netDevCtx_(netDevCtx),
32 0 : dispatcher_(dispatcher),
33 0 : localRankId_(attrInfo.localRankId),
34 0 : remoteRankId_(attrInfo.remoteRankId),
35 0 : aicpuUnfoldMode_(aicpuUnfoldMode)
36 0 : {}
37 :
38 0 : TransportMem::~TransportMem() {}
39 :
40 : // static
41 0 : std::shared_ptr<TransportMem> TransportMem::Create(
42 : TpType tpType, const std::unique_ptr<NotifyPool>& notifyPool, const HcclNetDevCtx& netDevCtx,
43 : const HcclDispatcher& dispatcher, AttrInfo& attrInfo)
44 : {
45 0 : return Create(tpType, notifyPool, netDevCtx, dispatcher, attrInfo, false);
46 : }
47 :
48 0 : std::shared_ptr<TransportMem> TransportMem::Create(
49 : TpType tpType, const std::unique_ptr<NotifyPool>& notifyPool, const HcclNetDevCtx& netDevCtx,
50 : const HcclDispatcher& dispatcher, AttrInfo& attrInfo, bool aicpuUnfoldMode)
51 : {
52 0 : std::shared_ptr<TransportMem> transportMemPtr;
53 : #if !defined(CCL_KERNEL) || defined(CCL_LLT)
54 0 : CHK_PRT_RET((netDevCtx == nullptr), HCCL_ERROR("[TransportMem][Create]netDevCtx is null"), nullptr);
55 0 : HCCL_DEBUG(
56 : "transportMem create tpType:%u netDevCtx:%p dispatcher:%p localRankId:%u remoteRankId:%u sdid:%u "
57 : "serverId:%u trafficClass:%u serviceLevel:%u",
58 : tpType, netDevCtx, dispatcher, attrInfo.localRankId, attrInfo.remoteRankId, attrInfo.sdid, attrInfo.serverId,
59 : attrInfo.trafficClass, attrInfo.serviceLevel);
60 0 : switch (tpType) {
61 0 : case TpType::ROCE:
62 : transportMemPtr
63 0 : = std::make_unique<TransportRoceMem>(notifyPool, netDevCtx, dispatcher, attrInfo, aicpuUnfoldMode);
64 0 : break;
65 0 : case TpType::IPC:
66 : transportMemPtr
67 0 : = std::make_unique<TransportIpcMem>(notifyPool, netDevCtx, dispatcher, attrInfo, aicpuUnfoldMode);
68 0 : break;
69 0 : default:
70 0 : break;
71 : }
72 : #else
73 : HCCL_ERROR("[TransportMem] The Create interface with qpInfo should be used on the AICPU, tpType[%u]", tpType);
74 : #endif
75 0 : return transportMemPtr;
76 0 : }
77 :
78 : std::shared_ptr<TransportMem>
79 0 : TransportMem::Create(TpType tpType, const HcclQpInfoV2& qpInfo, const HcclDispatcher& dispatcher, AttrInfo& attrInfo)
80 : {
81 0 : const std::unique_ptr<NotifyPool> notifyPool = nullptr; // dummy for device ibv transport
82 0 : const HcclNetDevCtx netDevCtx = nullptr; // dummy
83 0 : HCCL_DEBUG(
84 : "[TransportMem] create tpType:%u netDevCtx:%p dispatcher:%p localRankId:%u remoteRankId:%u", tpType, netDevCtx,
85 : dispatcher, attrInfo.localRankId, attrInfo.remoteRankId);
86 0 : std::shared_ptr<TransportMem> transportMemPtr;
87 0 : switch (tpType) {
88 0 : case TpType::ROCE_DEVICE:
89 : #ifdef CCL_KERNEL
90 0 : transportMemPtr = std::make_unique<TransportDeviceRoceMem>(
91 0 : notifyPool, netDevCtx, dispatcher, attrInfo, false, qpInfo); // aicpuUnfoldMode is set by host
92 : #else
93 : HCCL_ERROR("[TransportMem] ROCE_DEVICE Only running on the AICPU");
94 : #endif
95 0 : break;
96 0 : default:
97 0 : HCCL_ERROR("[TransportMem] unsupported TpType[%u] on the AICPU", tpType);
98 0 : break;
99 : }
100 0 : return transportMemPtr;
101 0 : }
102 :
103 0 : HcclResult TransportMem::SetDataSocket(const std::shared_ptr<HcclSocket>& socket)
104 : {
105 0 : dataSocket_ = socket;
106 0 : return HCCL_SUCCESS;
107 : }
108 :
109 : HcclResult
110 0 : TransportMem::DoExchangeMemDesc(const RmaMemDescs& localMemDescs, RmaMemDescs& remoteMemDescs, u32& actualNumOfRemote)
111 : {
112 0 : HCCL_INFO(
113 : "[HcclOneSidedConn][ExchangeMemDesc]localRank[%u] exchange memDesc begin, role[%u]", localRankId_,
114 : dataSocket_->GetLocalRole());
115 :
116 0 : if (dataSocket_->GetLocalRole() == HcclSocketRole::SOCKET_ROLE_CLIENT) {
117 : // 先收后发
118 0 : CHK_RET(ReceiveRemoteMemDesc(remoteMemDescs, actualNumOfRemote));
119 0 : CHK_RET(SendLocalMemDesc(localMemDescs));
120 : } else {
121 : // 先发后收
122 0 : CHK_RET(SendLocalMemDesc(localMemDescs));
123 0 : CHK_RET(ReceiveRemoteMemDesc(remoteMemDescs, actualNumOfRemote));
124 : }
125 0 : HCCL_INFO("[HcclOneSidedConn][ExchangeMemDesc]get actualNumOfRemotee[%u]", actualNumOfRemote);
126 : // 校验remoteDescs中的remoteRankId和conn对象中保存的localRankId是否一样
127 0 : for (u32 i = 0; i < actualNumOfRemote; i++) {
128 0 : CHK_PTR_NULL((remoteMemDescs.array) + i);
129 0 : u32 tempRankId = remoteMemDescs.array[i].remoteRankId;
130 0 : HCCL_DEBUG("[TransportMem][ExchangeMemDesc]tempRankId:%u, userRank:%u", tempRankId, localRankId_);
131 0 : if (tempRankId == INVALID_REMOTE_RANK_ID) {
132 0 : HCCL_INFO("[DoExchangeMemDesc] It's unnecessary to check remoteID.");
133 0 : continue;
134 : }
135 0 : if (tempRankId != localRankId_) {
136 0 : HCCL_ERROR(
137 : "[TransportMem][ExchangeMemDesc]localRank[%u] receive remoteMemDesc from wrong localRank[%u], "
138 : "connection is for localRank[%u]",
139 : localRankId_, tempRankId, localRankId_);
140 0 : return HCCL_E_INTERNAL;
141 : }
142 : }
143 0 : return HCCL_SUCCESS;
144 : }
145 :
146 0 : HcclResult TransportMem::SendLocalMemDesc(const RmaMemDescs& localMemDescs)
147 : {
148 0 : HcclResult ret = dataSocket_->Send(&localMemDescs.arrayLength, sizeof(u32));
149 0 : CHK_PRT_RET(
150 : ret != HCCL_SUCCESS,
151 : HCCL_ERROR(
152 : "errNo[0x%016llx] localRank[%u] send localMemDesc.arrayLength to remote "
153 : "failed, ret[%u]",
154 : HCCL_ERROR_CODE(ret), localRankId_, ret),
155 : ret);
156 0 : HCCL_DEBUG("send localMemDescs.arrayLength:%u", localMemDescs.arrayLength);
157 :
158 0 : if (localMemDescs.arrayLength == 0) {
159 0 : HCCL_INFO("localMemDescs.arrayLength[%u], no need to send data", localMemDescs.arrayLength);
160 : } else {
161 0 : HCCL_DEBUG("send descSize:%u", localMemDescs.arrayLength * sizeof(RmaMemDesc));
162 0 : ret = dataSocket_->Send(localMemDescs.array, localMemDescs.arrayLength * sizeof(RmaMemDesc));
163 0 : CHK_PRT_RET(
164 : ret != HCCL_SUCCESS,
165 : HCCL_ERROR(
166 : "errNo[0x%016llx] localRank[%u] send localMemDesc to remote "
167 : "failed, ret[%u]",
168 : HCCL_ERROR_CODE(ret), localRankId_, ret),
169 : ret);
170 : }
171 0 : return HCCL_SUCCESS;
172 : }
173 :
174 0 : HcclResult TransportMem::ReceiveRemoteMemDesc(RmaMemDescs& remoteMemDescs, u32& actualNumOfRemote)
175 : {
176 0 : HcclResult ret = dataSocket_->Recv(&actualNumOfRemote, sizeof(u32));
177 0 : remoteMemDescs.arrayLength = actualNumOfRemote;
178 0 : CHK_PRT_RET(
179 : ret != HCCL_SUCCESS,
180 : HCCL_ERROR(
181 : "errNo[0x%016llx] localRank[%u] receive actualNumOfRemote to remote "
182 : "failed, ret[%u]",
183 : HCCL_ERROR_CODE(ret), localRankId_, ret),
184 : ret);
185 0 : HCCL_DEBUG("receive actualNumOfRemote:%u", actualNumOfRemote);
186 0 : if (actualNumOfRemote == 0) {
187 0 : HCCL_INFO("actualNumOfRemote[%u], no need to receive data", actualNumOfRemote);
188 : } else {
189 0 : HCCL_DEBUG("receive descSize:%u", actualNumOfRemote * sizeof(RmaMemDesc));
190 0 : ret = dataSocket_->Recv(remoteMemDescs.array, actualNumOfRemote * sizeof(RmaMemDesc));
191 0 : CHK_PRT_RET(
192 : ret != HCCL_SUCCESS,
193 : HCCL_ERROR(
194 : "errNo[0x%016llx] localRank[%u] receive remoteMemDesc from remote "
195 : "failed, ret[%u]",
196 : HCCL_ERROR_CODE(ret), localRankId_, ret),
197 : ret);
198 : }
199 0 : return HCCL_SUCCESS;
200 : }
201 : } // namespace hccl
|