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 "typical_qp_manager.h"
12 : #include <map>
13 : #include <memory>
14 : #include "externalinput.h"
15 : #include "adapter_rts_common.h"
16 : #include "rdma_resource_manager.h"
17 :
18 : namespace hccl {
19 66 : TypicalQpManager::TypicalQpManager() {}
20 :
21 66 : TypicalQpManager::~TypicalQpManager()
22 : {
23 66 : std::unique_lock<std::mutex> cqLock(cqMutex_);
24 66 : for (auto& item : cqMap_) {
25 0 : if (item.second.second == nullptr) {
26 0 : continue;
27 : }
28 0 : DestroyTypicalCq(rdmaHandle_, item.first, item.second.second);
29 : }
30 66 : cqMap_.clear();
31 66 : cqLock.unlock();
32 :
33 66 : std::unique_lock<std::mutex> lock(qpMutex_);
34 72 : for (auto& item : qpMap_) {
35 6 : if (item.second.second == nullptr) {
36 0 : continue;
37 : }
38 6 : HrtRaQpDestroy(item.second.second);
39 : }
40 66 : qpMap_.clear();
41 66 : for (auto& item : verbsQpMap_) {
42 0 : if (item.second.second == nullptr) {
43 0 : continue;
44 : }
45 0 : HrtRaQpDestroyWithoutCQ(item.second.second);
46 : }
47 66 : verbsQpMap_.clear();
48 66 : lock.unlock();
49 66 : }
50 :
51 209 : TypicalQpManager& TypicalQpManager::GetInstance()
52 : {
53 275 : static TypicalQpManager qpInstance[MAX_MODULE_DEVICE_NUM + 1];
54 209 : s32 deviceLogicId = INVALID_INT;
55 209 : HcclResult ret = hrtGetDevice(&deviceLogicId);
56 209 : if (ret == HCCL_SUCCESS && (static_cast<u32>(deviceLogicId) < MAX_MODULE_DEVICE_NUM)) {
57 209 : HCCL_INFO("[TypicalQpManager::GetInstance]deviceLogicID[%d]", deviceLogicId);
58 209 : return qpInstance[deviceLogicId];
59 : }
60 0 : HCCL_WARNING("[TypicalQpManager::GetInstance]deviceLogicID[%d] is invalid, ret[%d]", deviceLogicId, ret);
61 0 : return qpInstance[MAX_MODULE_DEVICE_NUM];
62 : }
63 :
64 30 : HcclResult TypicalQpManager::CreateQp(struct TypicalQp& qpInfo)
65 : {
66 30 : HcclResult ret = HCCL_SUCCESS;
67 30 : QpHandle qpHandle = nullptr;
68 30 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
69 30 : CHK_PTR_NULL(rdmaHandle_);
70 30 : std::unique_lock<std::mutex> lock(qpMutex_);
71 30 : ret = hrtRaTypicalQpCreate(rdmaHandle_, QP_FLAG_RC, OPBASE_QP_MODE, &qpInfo, qpHandle);
72 30 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][CreateQp] Create qp failed."), HCCL_E_INTERNAL);
73 30 : qpMap_.insert(std::make_pair(qpInfo.qpn, std::make_pair(qpInfo, qpHandle)));
74 30 : return HCCL_SUCCESS;
75 30 : }
76 :
77 10 : HcclResult TypicalQpManager::CreateQp(struct TypicalQp& qpInfo, const QpConfigInfo& qpConfig)
78 : {
79 10 : HcclResult ret = HCCL_SUCCESS;
80 10 : QpHandle qpHandle = nullptr;
81 10 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
82 10 : CHK_PTR_NULL(rdmaHandle_);
83 10 : std::unique_lock<std::mutex> lock(qpMutex_);
84 10 : ret = CreateQpWithDepthConfig(rdmaHandle_, OPBASE_QP_MODE, qpConfig, qpHandle, qpInfo);
85 10 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][CreateQp] Create qp failed."), HCCL_E_INTERNAL);
86 9 : qpMap_.insert(std::make_pair(qpInfo.qpn, std::make_pair(qpInfo, qpHandle)));
87 9 : return HCCL_SUCCESS;
88 10 : }
89 :
90 1 : HcclResult TypicalQpManager::CreateCq(AscendCQInfo& cqInfo)
91 : {
92 1 : HcclResult ret = HCCL_SUCCESS;
93 1 : void* cqHandle = nullptr;
94 1 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
95 1 : CHK_PTR_NULL(rdmaHandle_);
96 1 : std::unique_lock<std::mutex> lock(cqMutex_);
97 1 : ret = CreateTypicalCq(rdmaHandle_, cqInfo.cqDepth, cqInfo.cqn, &cqHandle);
98 1 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][CreateCq] Create cq failed."), HCCL_E_INTERNAL);
99 1 : cqMap_.insert(std::make_pair(cqInfo.cqn, std::make_pair(cqInfo, cqHandle)));
100 1 : return HCCL_SUCCESS;
101 1 : }
102 :
103 0 : HcclResult TypicalQpManager::DestroyCq(uint32_t cqn)
104 : {
105 0 : HcclResult ret = HCCL_SUCCESS;
106 0 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
107 0 : CHK_PTR_NULL(rdmaHandle_);
108 0 : std::unique_lock<std::mutex> lock(cqMutex_);
109 0 : auto it = cqMap_.find(cqn);
110 0 : CHK_PRT_RET((it == cqMap_.end()), HCCL_ERROR("[TypicalQpManager][DestroyCq] cqn[%u] not found.", cqn), HCCL_E_PARA);
111 0 : ret = DestroyTypicalCq(rdmaHandle_, cqn, it->second.second);
112 0 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][DestroyCq] Destroy cq failed."), HCCL_E_INTERNAL);
113 0 : cqMap_.erase(it);
114 0 : return HCCL_SUCCESS;
115 0 : }
116 :
117 0 : HcclResult TypicalQpManager::ValidateCq(uint32_t cqn)
118 : {
119 0 : std::unique_lock<std::mutex> lock(cqMutex_);
120 0 : auto it = cqMap_.find(cqn);
121 0 : CHK_PRT_RET(
122 : (it == cqMap_.end()), HCCL_ERROR("[TypicalQpManager][ValidateCq] cqn[%u] not found.", cqn), HCCL_E_PARA);
123 0 : return HCCL_SUCCESS;
124 0 : }
125 :
126 0 : HcclResult TypicalQpManager::GetCqDepth(uint32_t cqn, uint32_t& cqDepth)
127 : {
128 0 : std::unique_lock<std::mutex> lock(cqMutex_);
129 0 : auto it = cqMap_.find(cqn);
130 0 : CHK_PRT_RET(
131 : (it == cqMap_.end()), HCCL_ERROR("[TypicalQpManager][GetCqDepth] cqn[%u] not found.", cqn), HCCL_E_PARA);
132 0 : cqDepth = it->second.first.cqDepth;
133 0 : return HCCL_SUCCESS;
134 0 : }
135 :
136 0 : HcclResult TypicalQpManager::GetCqHandle(uint32_t cqn, void*& cqHandle)
137 : {
138 0 : std::unique_lock<std::mutex> lock(cqMutex_);
139 0 : auto it = cqMap_.find(cqn);
140 0 : CHK_PRT_RET(
141 : (it == cqMap_.end()), HCCL_ERROR("[TypicalQpManager][GetCqHandle] cqn[%u] not found.", cqn), HCCL_E_PARA);
142 0 : cqHandle = it->second.second;
143 0 : return HCCL_SUCCESS;
144 0 : }
145 :
146 2 : HcclResult TypicalQpManager::CreateQpWithCQ(struct TypicalQp& qpInfo, const QpConfigWithCQInfo& qpConfig)
147 : {
148 2 : HcclResult ret = HCCL_SUCCESS;
149 2 : QpHandle qpHandle = nullptr;
150 2 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
151 2 : CHK_PTR_NULL(rdmaHandle_);
152 2 : std::unique_lock<std::mutex> lock(qpMutex_);
153 2 : ret = CreateQpWithCQConfig(rdmaHandle_, OPBASE_QP_MODE, qpConfig, qpHandle, qpInfo);
154 2 : CHK_PRT_RET(
155 : ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][CreateQpWithCQ] Create qp with cq failed."),
156 : HCCL_E_INTERNAL);
157 1 : verbsQpMap_.insert(std::make_pair(qpInfo.qpn, std::make_pair(qpInfo, qpHandle)));
158 1 : return HCCL_SUCCESS;
159 2 : }
160 :
161 30 : HcclResult TypicalQpManager::ModifyQp(struct TypicalQp& localQpInfo, struct TypicalQp& remoteQpInfo)
162 : {
163 30 : CHK_PRT_RET(
164 : (localQpInfo.qpn == 0 || remoteQpInfo.qpn == 0),
165 : HCCL_ERROR("[TypicalQpManager][ModifyQp] the qpinfo is wrong, qpn is 0."), HCCL_E_PARA);
166 30 : QpHandle qpHandle = nullptr;
167 30 : CHK_RET(GetQpHandleByQpn(localQpInfo.qpn, qpHandle));
168 30 : CHK_PTR_NULL(qpHandle);
169 30 : CHK_RET(SetQpRdmaRetryCfg(localQpInfo));
170 30 : std::unique_lock<std::mutex> lock(qpMutex_);
171 30 : HcclResult ret = hrtRaTypicalQpModify(qpHandle, &localQpInfo, &remoteQpInfo);
172 30 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][ModifyQp] Modify qp failed."), HCCL_E_INTERNAL);
173 :
174 30 : return HCCL_SUCCESS;
175 30 : }
176 :
177 5 : HcclResult TypicalQpManager::ModifyVerbsQp(struct TypicalQp& localQpInfo, struct TypicalQp& remoteQpInfo)
178 : {
179 5 : CHK_PRT_RET(
180 : (localQpInfo.qpn == 0 || remoteQpInfo.qpn == 0),
181 : HCCL_ERROR("[TypicalQpManager][ModifyVerbsQp] the qpinfo is wrong, qpn is 0."), HCCL_E_PARA);
182 3 : QpHandle qpHandle = nullptr;
183 3 : CHK_RET(GetVerbsQpHandleByQpn(localQpInfo.qpn, qpHandle));
184 2 : CHK_PTR_NULL(qpHandle);
185 2 : CHK_RET(SetQpRdmaRetryCfg(localQpInfo));
186 2 : std::unique_lock<std::mutex> lock(qpMutex_);
187 2 : HcclResult ret = hrtRaTypicalQpModify(qpHandle, &localQpInfo, &remoteQpInfo);
188 2 : CHK_PRT_RET(
189 : ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][ModifyVerbsQp] Modify qp failed."), HCCL_E_INTERNAL);
190 :
191 1 : return HCCL_SUCCESS;
192 2 : }
193 :
194 30 : HcclResult TypicalQpManager::DestroyQp(struct TypicalQp& qpInfo)
195 : {
196 30 : CHK_PRT_RET(
197 : (qpInfo.qpn == 0), HCCL_ERROR("[TypicalQpManager][DestroyQp] The qpinfo is wrong, qpn is 0."), HCCL_E_PARA);
198 : QpHandle qpHandle;
199 30 : CHK_RET(GetQpHandleByQpn(qpInfo.qpn, qpHandle));
200 30 : CHK_PTR_NULL(qpHandle);
201 30 : std::unique_lock<std::mutex> lock(qpMutex_);
202 30 : HcclResult ret = HrtRaQpDestroy(qpHandle);
203 30 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][DestroyQp] Destroy qp failed."), HCCL_E_INTERNAL);
204 30 : qpMap_.erase(qpInfo.qpn);
205 30 : return HCCL_SUCCESS;
206 30 : }
207 :
208 4 : HcclResult TypicalQpManager::DestroyQpWithoutCQ(struct TypicalQp& qpInfo)
209 : {
210 4 : CHK_PRT_RET(
211 : (qpInfo.qpn == 0), HCCL_ERROR("[TypicalQpManager][DestroyQpWithoutCQ] The qpinfo is wrong, qpn is 0."),
212 : HCCL_E_PARA);
213 : QpHandle qpHandle;
214 3 : CHK_RET(GetVerbsQpHandleByQpn(qpInfo.qpn, qpHandle));
215 2 : CHK_PTR_NULL(qpHandle);
216 2 : std::unique_lock<std::mutex> lock(qpMutex_);
217 2 : HcclResult ret = HrtRaQpDestroyWithoutCQ(qpHandle);
218 2 : CHK_PRT_RET(
219 : ret != HCCL_SUCCESS, HCCL_ERROR("[TypicalQpManager][DestroyQpWithoutCQ] Destroy qp without cq failed."),
220 : HCCL_E_INTERNAL);
221 1 : verbsQpMap_.erase(qpInfo.qpn);
222 1 : return HCCL_SUCCESS;
223 2 : }
224 :
225 32 : HcclResult TypicalQpManager::SetQpRdmaRetryCfg(struct TypicalQp& qpInfo)
226 : {
227 32 : qpInfo.retryCnt = GetExternalInputRdmaRetryCnt();
228 32 : qpInfo.retryTime = GetExternalInputRdmaTimeOut();
229 32 : HCCL_INFO(
230 : "[TypicalQpManager][SetQpCreateBaseInfo] Qpinfo is set, tc is %u, sl is %u, retry cnt is %u, "
231 : "retry time is %u",
232 : qpInfo.tc, qpInfo.sl, qpInfo.retryCnt, qpInfo.retryTime);
233 32 : return HCCL_SUCCESS;
234 : }
235 :
236 108 : HcclResult TypicalQpManager::GetQpHandleByQpn(u32 qpn, QpHandle& qpHandle)
237 : {
238 108 : HCCL_DEBUG("[TypicalQpManager][GetQpHandleByQpn] Get qpHandle by qpn[%u]", qpn);
239 108 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
240 108 : CHK_PTR_NULL(rdmaHandle_);
241 108 : std::unique_lock<std::mutex> lock(qpMutex_);
242 108 : auto it = qpMap_.find(qpn);
243 108 : CHK_PRT_RET(
244 : (it == qpMap_.end()), HCCL_ERROR("[TypicalQpManager][GetQpHandleByQpn] Qpn is not found"), HCCL_E_NOT_FOUND);
245 108 : qpHandle = it->second.second;
246 108 : CHK_PRT_RET(
247 : (qpHandle == nullptr),
248 : HCCL_ERROR("[TypicalQpManager][GetQpHandleByQpn] Get Qphandle failed, qphandle is nullptr. qpn is %u", qpn),
249 : HCCL_E_NOT_FOUND);
250 108 : return HCCL_SUCCESS;
251 108 : }
252 :
253 10 : HcclResult TypicalQpManager::GetVerbsQpHandleByQpn(u32 qpn, QpHandle& qpHandle)
254 : {
255 10 : HCCL_DEBUG("[TypicalQpManager][GetVerbsQpHandleByQpn] Get qpHandle by qpn[%u]", qpn);
256 10 : CHK_RET(RdmaResourceManager::GetInstance().GetRdmaHandle(rdmaHandle_));
257 9 : CHK_PTR_NULL(rdmaHandle_);
258 9 : std::unique_lock<std::mutex> lock(qpMutex_);
259 9 : auto it = verbsQpMap_.find(qpn);
260 9 : CHK_PRT_RET(
261 : (it == verbsQpMap_.end()), HCCL_ERROR("[TypicalQpManager][GetVerbsQpHandleByQpn] Qpn is not found"),
262 : HCCL_E_NOT_FOUND);
263 6 : qpHandle = it->second.second;
264 6 : CHK_PRT_RET(
265 : (qpHandle == nullptr),
266 : HCCL_ERROR(
267 : "[TypicalQpManager][GetVerbsQpHandleByQpn] Get Qphandle failed, qphandle is nullptr. qpn is %u", qpn),
268 : HCCL_E_NOT_FOUND);
269 5 : return HCCL_SUCCESS;
270 9 : }
271 : } // namespace hccl
|