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 <hccl/hccl_one_sided_services.h>
12 : #include "exception_handler.h"
13 : #include "hccl_one_sided_service.h"
14 : #include "hccl_comm_pub.h"
15 : #include "i_hccl_one_sided_service.h"
16 : #include "adapter_prof.h"
17 : #include "param_check_pub.h"
18 : #include "externalinput_pub.h"
19 : #include "profiling_manager_pub.h"
20 : #include "adapter_rts_common.h"
21 : #include "global_mem_manager.h"
22 :
23 : #include "one_sided_service_adapt_v2.h"
24 :
25 : using namespace hccl;
26 : using namespace std;
27 :
28 : constexpr u64 ONE_SIDE_DEVICE_MEM_MAX_SIZE = 64llu * 1024 * 1024 * 1024; // device侧支持内存注册大小上限为64GB
29 : constexpr u64 ONE_SIDE_HOST_MEM_MAX_SIZE = 1024llu * 1024 * 1024 * 1024; // host侧支持内存注册大小上限为1TB
30 : constexpr u64 ONE_SIDE_HOST_MEM_ZERO = 0;
31 : constexpr u32 MAX_DESC_NUM = 256;
32 :
33 0 : HcclResult HcclOneSidedSetIfProfile()
34 : {
35 0 : bool ifOpbase = (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
36 0 : bool state = ProfilingManagerPub::GetAllState();
37 0 : SetIfProfile((!ifOpbase) || (!state));
38 0 : return HCCL_SUCCESS;
39 : }
40 :
41 0 : void HcclOneSidedResetIfProfile()
42 : {
43 0 : SetIfProfile(true);
44 0 : }
45 :
46 0 : static HcclResult AddDescTraceInfo(hccl::hcclComm* hcclComm, HcclOneSideOpDesc* desc, u32 descNum, const std::string& tag)
47 : {
48 : char stackLogBuffer[LOG_TMPBUF_SIZE];
49 : // trace日志逐个记录描述符信息
50 0 : for (u32 i = 0; i < descNum; i++) {
51 0 : CHK_PTR_NULL((desc + i)->localAddr);
52 0 : CHK_PTR_NULL((desc + i)->remoteAddr);
53 0 : CHK_RET(HcomCheckCount((desc + i)->count));
54 0 : CHK_RET(HcomCheckDataType((desc + i)->dataType));
55 0 : s32 ret = snprintf_s(stackLogBuffer, LOG_TMPBUF_SIZE, LOG_TMPBUF_SIZE - 1U,
56 : "[%s] HcclOneSideOpDesc[%d] : localAddr[%p], remoteAddr[%p], count[%llu], dataType[%d].",
57 0 : __func__, i, (desc + i)->localAddr, (desc + i)->remoteAddr, (desc + i)->count, (desc + i)->dataType);
58 0 : CHK_PRT_CONT(ret == -1, HCCL_WARNING("Failed to build log info, tag[%s].", tag.c_str()));
59 0 : std::string logInfo(stackLogBuffer);
60 0 : CHK_RET(hcclComm->SaveTraceInfo(logInfo));
61 0 : }
62 0 : return HCCL_SUCCESS;
63 : }
64 :
65 1 : HcclResult HcclRemapRegistedMemory(HcclComm *comm, CommMem *memInfoArray, u64 commSize, u64 arraySize)
66 : {
67 1 : RPT_INPUT_ERR(comm == nullptr,
68 : "EI0003",
69 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
70 : std::vector<std::string>({"HcclRemapRegistedMemory", "nullptr", "comm", "non-null pointer"}));
71 1 : CHK_PTR_NULL(comm);
72 1 : RPT_INPUT_ERR(memInfoArray == nullptr,
73 : "EI0003",
74 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
75 : std::vector<std::string>({"HcclRemapRegistedMemory", "nullptr", "memInfoArray", "non-null pointer"}));
76 1 : CHK_PTR_NULL(memInfoArray);
77 :
78 1 : RPT_INPUT_ERR(commSize <= ONE_SIDE_HOST_MEM_ZERO,
79 : "EI0003",
80 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
81 : std::vector<std::string>(
82 : {"HcclRemapRegistedMemory", "less than or equal to 0", "commSize", "greater than 0 (positive number)"}));
83 1 : CHK_PRT_RET(commSize <= ONE_SIDE_HOST_MEM_ZERO,
84 : HCCL_ERROR("[%s][%s]commSize[%llu] is invalid, "
85 : "please check commSize",
86 : LOG_KEYWORDS_TASK_EXEC.c_str(),
87 : LOG_KEYWORDS_INVALID_ARGUMENT.c_str(),
88 : commSize),
89 : HCCL_E_PARA);
90 1 : RPT_INPUT_ERR(arraySize <= ONE_SIDE_HOST_MEM_ZERO,
91 : "EI0003",
92 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
93 : std::vector<std::string>(
94 : {"HcclRemapRegistedMemory", "less than or equal to 0", "arraySize", "greater than 0 (positive number)"}));
95 1 : CHK_PRT_RET(arraySize <= ONE_SIDE_HOST_MEM_ZERO,
96 : HCCL_ERROR("[%s][%s]arraySize[%llu] is invalid, "
97 : "please check arraySize",
98 : LOG_KEYWORDS_TASK_EXEC.c_str(),
99 : LOG_KEYWORDS_INVALID_ARGUMENT.c_str(),
100 : arraySize),
101 : HCCL_E_PARA);
102 :
103 1 : IHcclOneSidedService *service = nullptr;
104 2 : for (u64 i = 0; i < commSize; i++) {
105 1 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm[i]);
106 1 : CHK_PTR_NULL(hcclComm);
107 1 : CHK_RET(hcclComm->GetOneSidedService(&service));
108 1 : CHK_PTR_NULL(service);
109 1 : CHK_RET(static_cast<HcclOneSidedService*>(service)->ReMapMem(reinterpret_cast<HcclMem*>(memInfoArray), arraySize));
110 : }
111 :
112 1 : return HCCL_SUCCESS;
113 : }
114 :
115 0 : static HcclResult CallOneSideMsprofReportHostApi(hccl::hcclComm* hcclComm, HcclCMDType cmdType, uint64_t beginTime, u64 count,
116 : HcclDataType dataType, std::string tag)
117 : {
118 0 : if (GetIfProfile()) {
119 0 : AlgType algType;
120 0 : CHK_RET(hcclComm->GetAlgType(algType, cmdType));
121 0 : uint64_t groupName = hrtMsprofGetHashId(hcclComm->GetIdentifier().c_str(), hcclComm->GetIdentifier().length());
122 0 : CHK_RET_AND_PRINT_IDE(ProfilingManagerPub::CallMsprofReportHostApi(cmdType, beginTime, count, dataType, algType,
123 : groupName), tag.c_str());
124 : }
125 0 : return HCCL_SUCCESS;
126 : }
127 :
128 : // HcclCommInitClusterInfoMem在open_hccl中
129 0 : HcclResult HcclRegisterMem(HcclComm comm, u32 remoteRank, int type,
130 : void* addr, u64 size, HcclMemDesc* desc)
131 : {
132 : EXCEPTION_HANDLE_BEGIN
133 : // 参数校验和适配
134 0 : RPT_INPUT_ERR(comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
135 : std::vector<std::string>({"HcclRegisterMem", "nullptr", "comm", "non-null pointer"}));
136 0 : CHK_PTR_NULL(comm);
137 0 : RPT_INPUT_ERR(addr == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
138 : std::vector<std::string>({"HcclRegisterMem", "nullptr", "addr", "non-null pointer"}));
139 0 : CHK_PTR_NULL(addr);
140 0 : RPT_INPUT_ERR(desc == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
141 : std::vector<std::string>({"HcclRegisterMem", "nullptr", "memory description", "non-null pointer"}));
142 0 : CHK_PTR_NULL(desc);
143 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
144 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
145 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
146 : CHK_PTR_NULL(commV2);
147 : CHK_RET(HcclRegisterMemV2(commV2, remoteRank, type, addr, size, desc));
148 : return HCCL_SUCCESS;
149 : }());
150 0 : u32 localRank = INVALID_VALUE_RANKID;
151 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
152 0 : CHK_RET(hcclComm->GetUserRank(localRank));
153 0 : std::string commIdentifier = hcclComm->GetIdentifier();
154 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], remoteRank[%u], memType[%d], memAddr[%p], memSize[%llu], memDescPtr[%p]",
155 : __func__, commIdentifier.c_str(), remoteRank, type, addr, size, desc);
156 0 : CHK_PRT_RET(remoteRank == localRank, HCCL_WARNING("remoteRank[%u] is equal to localRank[%u], no need to "\
157 : "register memory, return HcclRegisterMem success", remoteRank, localRank), HCCL_SUCCESS);
158 :
159 0 : CHK_PRT_RET(type != HCCL_MEM_TYPE_DEVICE && type != HCCL_MEM_TYPE_HOST,
160 : HCCL_ERROR("[HcclRegisterMem]memoryType[%d] must be device or host, please check type", type), HCCL_E_PARA);
161 0 : CHK_PRT_RET(size <= ONE_SIDE_HOST_MEM_ZERO, HCCL_ERROR("[HcclRegisterMem]memory size[%llu] is invalid, "\
162 : "please check memory size", size), HCCL_E_PARA);
163 0 : CHK_PRT_RET(type == HCCL_MEM_TYPE_DEVICE && size > ONE_SIDE_DEVICE_MEM_MAX_SIZE,
164 : HCCL_ERROR("[HcclRegisterMem]memory size[%llu] is too large, please check memory size", size), HCCL_E_PARA);
165 0 : CHK_PRT_RET(type == HCCL_MEM_TYPE_HOST && size > ONE_SIDE_HOST_MEM_MAX_SIZE,
166 : HCCL_ERROR("[HcclRegisterMem]memory size[%llu] is too large, please check memory size", size), HCCL_E_PARA);
167 :
168 0 : IHcclOneSidedService *service = nullptr;
169 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
170 0 : CHK_PTR_NULL(service);
171 :
172 : // 校验netDevCtx是否为空
173 : bool useRdma;
174 0 : CHK_RET(static_cast<HcclOneSidedService*>(service)->GetIsUsedRdma(remoteRank, useRdma));
175 : HcclNetDevCtx netDevCtx;
176 0 : CHK_RET(service->GetNetDevCtx(netDevCtx, useRdma));
177 0 : if (netDevCtx == nullptr) {
178 0 : HCCL_INFO("[%s]Network resources are not initialized, start to initOneSidedServiceNetDevCtx", __func__);
179 0 : CHK_RET(hcclComm->InitOneSidedServiceNetDevCtx(remoteRank));
180 : }
181 0 : CHK_RET(static_cast<HcclOneSidedService*>(service)->RegMem(addr, size, static_cast<HcclMemType>(type), remoteRank, *desc));
182 :
183 0 : HCCL_RUN_INFO("%s success:comm[%s], remoteRank[%u], memType[%d], memAddr[%p], memSize[%llu], memDescPtr[%p]",
184 : __func__, commIdentifier.c_str(), remoteRank, type, addr, size, desc);
185 0 : EXCEPTION_HANDLE_END
186 0 : return HCCL_SUCCESS;
187 : }
188 :
189 0 : HcclResult HcclDeregisterMem(HcclComm comm, HcclMemDesc* desc)
190 : {
191 : EXCEPTION_HANDLE_BEGIN
192 : // 参数校验和适配
193 0 : RPT_INPUT_ERR(comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
194 : std::vector<std::string>({"HcclDeregisterMem", "nullptr", "comm", "non-null pointer"}));
195 0 : CHK_PTR_NULL(comm);
196 0 : RPT_INPUT_ERR(desc == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
197 : std::vector<std::string>({"HcclDeregisterMem", "nullptr", "memory description", "non-null pointer"}));
198 0 : CHK_PTR_NULL(desc);
199 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
200 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
201 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
202 : CHK_PTR_NULL(commV2);
203 : CHK_RET(HcclDeregisterMemV2(commV2, desc));
204 : return HCCL_SUCCESS;
205 : }());
206 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
207 0 : std::string commIdentifier = hcclComm->GetIdentifier();
208 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], memDescPtr[%p]", __func__, commIdentifier.c_str(), desc);
209 0 : IHcclOneSidedService *service = nullptr;
210 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
211 0 : CHK_PTR_NULL(service);
212 0 : CHK_RET(static_cast<HcclOneSidedService*>(service)->DeregMem(*desc));
213 :
214 0 : HCCL_RUN_INFO("%s success:comm[%s], memDescPtr[%p]", __func__, commIdentifier.c_str(), desc);
215 0 : EXCEPTION_HANDLE_END
216 0 : return HCCL_SUCCESS;
217 : }
218 :
219 0 : HcclResult HcclExchangeMemDesc(HcclComm comm, u32 remoteRank, HcclMemDescs* local,
220 : int timeout, HcclMemDescs* remote, u32* actualNum)
221 : {
222 : EXCEPTION_HANDLE_BEGIN
223 : // 参数校验和适配
224 0 : RPT_INPUT_ERR(comm == nullptr,
225 : "EI0003",
226 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
227 : std::vector<std::string>({"HcclExchangeMemDesc", "nullptr", "comm", "non-null pointer"}));
228 0 : CHK_PTR_NULL(comm);
229 0 : RPT_INPUT_ERR(local == nullptr,
230 : "EI0003",
231 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
232 : std::vector<std::string>(
233 : {"HcclExchangeMemDesc", "nullptr", "local memory description", "non-null pointer"}));
234 0 : CHK_PTR_NULL(local);
235 0 : RPT_INPUT_ERR(remote == nullptr,
236 : "EI0003",
237 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
238 : std::vector<std::string>(
239 : {"HcclExchangeMemDesc", "nullptr", "remote memory description", "non-null pointer"}));
240 0 : CHK_PTR_NULL(remote);
241 0 : RPT_INPUT_ERR(actualNum == nullptr,
242 : "EI0003",
243 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
244 : std::vector<std::string>({"HcclExchangeMemDesc", "nullptr", "actualNum", "non-null pointer"}));
245 0 : CHK_PTR_NULL(actualNum);
246 :
247 : // timeout = 0 表示使用HCCL_CONNECT_TIMEOUT超时时间,timeout=-1 永不超时,其他为合法值
248 0 : const auto timeoutIsInvalid = timeout <= -2;
249 0 : RPT_INPUT_ERR(timeoutIsInvalid,
250 : "EI0003",
251 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
252 : std::vector<std::string>({"HcclExchangeMemDesc",
253 : std::to_string(timeout),
254 : "timeout",
255 : "-1(never timeout) or any integer greater than or equal 0."}));
256 0 : CHK_PRT_RET(timeoutIsInvalid,
257 : HCCL_ERROR("[%s][%s] The parameter timeout[%d s] is invalid. It should be -1(never timeout) or any "
258 : "integer greater than or equal 0.",
259 : LOG_KEYWORDS_TASK_EXEC.c_str(),
260 : LOG_KEYWORDS_INVALID_ARGUMENT.c_str(),
261 : timeout),
262 : HCCL_E_PARA);
263 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
264 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
265 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
266 : CHK_PTR_NULL(commV2);
267 : CHK_RET(HcclExchangeMemDescV2(commV2, remoteRank, local, timeout, remote, actualNum));
268 : return HCCL_SUCCESS;
269 : }());
270 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
271 0 : std::string commIdentifier = hcclComm->GetIdentifier();
272 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], remoteRank[%u], localMemDescPtr[%p], timeout[%d s], remoteMemDescPtr[%p], "
273 : "actualNum[%u]", __func__, commIdentifier.c_str(), remoteRank, local, timeout, remote, *actualNum);
274 0 : u32 localRank = INVALID_VALUE_RANKID;
275 0 : CHK_RET(hcclComm->GetUserRank(localRank));
276 0 : CHK_PRT_RET(remoteRank == localRank, HCCL_WARNING("remoteRank[%u] is equal to localRank[%u], no need to "\
277 : "register memory, return HcclRegisterMem success", remoteRank, localRank), HCCL_SUCCESS);
278 :
279 0 : IHcclOneSidedService *service = nullptr;
280 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
281 0 : CHK_PTR_NULL(service);
282 0 : CHK_RET(static_cast<HcclOneSidedService *>(service)->ExchangeMemDesc(
283 : remoteRank, *local, *remote, *actualNum, commIdentifier, timeout));
284 :
285 0 : HCCL_RUN_INFO("%s success:comm[%s], remoteRank[%u], localMemDescPtr[%p], timeout[%d s], remoteMemDescPtr[%p], "
286 : "actualNum[%u]", __func__, commIdentifier.c_str(), remoteRank, local, timeout, remote, *actualNum);
287 0 : EXCEPTION_HANDLE_END
288 0 : return HCCL_SUCCESS;
289 0 : }
290 :
291 1 : HcclResult HcclEnableMemAccess(HcclComm comm, HcclMemDesc* remoteMemDesc, CommMem* remoteMem)
292 : {
293 : EXCEPTION_HANDLE_BEGIN
294 : // 参数校验和适配
295 1 : RPT_INPUT_ERR(comm == nullptr,
296 : "EI0003",
297 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
298 : std::vector<std::string>({"HcclEnableMemAccess", "nullptr", "comm", "non-null pointer"}));
299 1 : CHK_PTR_NULL(comm);
300 1 : RPT_INPUT_ERR(remoteMemDesc == nullptr,
301 : "EI0003",
302 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
303 : std::vector<std::string>(
304 : {"HcclEnableMemAccess", "nullptr", "remote memory description", "non-null pointer"}));
305 1 : CHK_PTR_NULL(remoteMemDesc);
306 1 : RPT_INPUT_ERR(remoteMem == nullptr,
307 : "EI0003",
308 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
309 : std::vector<std::string>({"HcclEnableMemAccess", "nullptr", "remoteMem Param error", "non-null pointer"}));
310 1 : CHK_PTR_NULL(remoteMem);
311 1 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
312 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
313 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
314 : CHK_PTR_NULL(commV2);
315 : CHK_RET(HcclEnableMemAccessV2(commV2, remoteMemDesc, reinterpret_cast<HcclMem*>(remoteMem)));
316 : return HCCL_SUCCESS;
317 : }());
318 1 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
319 1 : std::string commIdentifier = hcclComm->GetIdentifier();
320 1 : HCCL_RUN_INFO("Entry-%s:comm[%s], remoteMemDescPtr[%p], remoteMemPtr[%p]", __func__, commIdentifier.c_str(), remoteMemDesc,
321 : remoteMem);
322 1 : IHcclOneSidedService *service = nullptr;
323 1 : CHK_RET(hcclComm->GetOneSidedService(&service));
324 1 : CHK_PTR_NULL(service);
325 1 : static_cast<HcclOneSidedService*>(service)->EnableMemAccess(*remoteMemDesc, *reinterpret_cast<HcclMem*>(remoteMem));
326 :
327 1 : HCCL_RUN_INFO("%s success:comm[%s], remoteMemDescPtr[%p], remoteMemPtr[%p]", __func__, commIdentifier.c_str(), remoteMemDesc,
328 : remoteMem);
329 1 : EXCEPTION_HANDLE_END
330 1 : return HCCL_SUCCESS;
331 : }
332 :
333 0 : HcclResult HcclDisableMemAccess(HcclComm comm, HcclMemDesc* remoteMemDesc)
334 : {
335 : EXCEPTION_HANDLE_BEGIN
336 : // 参数校验和适配
337 0 : RPT_INPUT_ERR(comm == nullptr,
338 : "EI0003",
339 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
340 : std::vector<std::string>({"HcclEnableMemAccess", "nullptr", "comm", "non-null pointer"}));
341 0 : CHK_PTR_NULL(comm);
342 0 : RPT_INPUT_ERR(remoteMemDesc == nullptr,
343 : "EI0003",
344 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
345 : std::vector<std::string>(
346 : {"HcclEnableMemAccess", "nullptr", "remote memory description", "non-null pointer"}));
347 0 : CHK_PTR_NULL(remoteMemDesc);
348 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
349 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
350 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
351 : CHK_PTR_NULL(commV2);
352 : CHK_RET(HcclDisableMemAccessV2(commV2, remoteMemDesc));
353 : return HCCL_SUCCESS;
354 : }());
355 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
356 0 : std::string commIdentifier = hcclComm->GetIdentifier();
357 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], remoteMemDescPtr[%p]", __func__, commIdentifier.c_str(), remoteMemDesc);
358 0 : IHcclOneSidedService *service = nullptr;
359 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
360 0 : CHK_PTR_NULL(service);
361 0 : static_cast<HcclOneSidedService*>(service)->DisableMemAccess(*remoteMemDesc);
362 :
363 0 : HCCL_RUN_INFO("%s success:comm[%s], remoteMemDescPtr[%p]", __func__, commIdentifier.c_str(), remoteMemDesc);
364 0 : EXCEPTION_HANDLE_END
365 0 : return HCCL_SUCCESS;
366 : }
367 :
368 0 : inline static HcclResult HcclBatchParaCheck(HcclBatchData ¶Data, std::string &getTag)
369 : {
370 : // 参数校验和适配
371 0 : CHK_PTR_NULL(paraData.comm);
372 0 : CHK_PTR_NULL(paraData.stream);
373 0 : CHK_PTR_NULL(paraData.desc);
374 0 : std::string batchString = (paraData.cmdType == HcclCMDType::HCCL_CMD_BATCH_GET) ? "BatchGet" : "BatchPut";
375 0 : CHK_PRT_RET(paraData.descNum == 0, HCCL_WARNING("[%s] the count of HcclOneSideOpDesc is zero.",
376 : batchString.c_str()), HCCL_SUCCESS);
377 0 : CHK_PRT_RET(paraData.descNum > MAX_DESC_NUM,
378 : HCCL_ERROR("[%s] the count of HcclOneSideOpDesc exceeds specification[%u].", batchString.c_str(), MAX_DESC_NUM),
379 : HCCL_E_PARA);
380 :
381 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(paraData.comm);
382 : // 同算子复用tag
383 0 : u32 localRank = INVALID_VALUE_RANKID;
384 0 : CHK_RET(hcclComm->GetGroupRank(localRank));
385 :
386 0 : const std::string tag = batchString + "_" + std::to_string(localRank) + "_" + std::to_string(paraData.remoteRank)
387 0 : + "_" + hcclComm->GetIdentifier();
388 0 : getTag = tag;
389 :
390 0 : u32 rankSize = INVALID_VALUE_RANKSIZE;
391 0 : CHK_RET_AND_PRINT_IDE(hcclComm->GetRankSize(rankSize), tag.c_str());
392 0 : CHK_RET(HcomCheckUserRank(rankSize, paraData.remoteRank));
393 0 : CHK_PRT_RET(paraData.remoteRank == localRank,
394 : HCCL_ERROR("[%s] the remoteRank can't be equal to localRank, please check.", batchString.c_str()), HCCL_E_PARA);
395 :
396 0 : if (GetExternalInputHcclEnableEntryLog()) {
397 0 : s32 deviceLogicId = 0;
398 0 : s32 streamId = 0;
399 0 : CHK_RET(hrtGetDeviceRefresh(&deviceLogicId));
400 0 : CHK_RET(hrtGetStreamId(paraData.stream, streamId));
401 : // 记录接口交互信息日志
402 0 : std::string logInfo = "Entry-";
403 0 : logInfo.append(batchString);
404 0 : logInfo.append(":tag[");
405 0 : logInfo.append(tag);
406 0 : logInfo.append("], descNum[");
407 0 : logInfo.append(std::to_string(paraData.descNum));
408 0 : logInfo.append("], streamId[");
409 0 : logInfo.append(std::to_string(streamId));
410 0 : logInfo.append("], deviceLogicId[");
411 0 : logInfo.append(std::to_string(deviceLogicId));
412 0 : logInfo.append("].");
413 0 : CHK_RET(hcclComm->SaveTraceInfo(logInfo));
414 0 : CHK_RET(AddDescTraceInfo(hcclComm, paraData.desc, paraData.descNum, tag));
415 0 : }
416 0 : return HCCL_SUCCESS;
417 0 : }
418 :
419 0 : HcclResult HcclBatchPut(HcclComm comm, u32 remoteRank, HcclOneSideOpDesc* desc, u32 descNum, rtStream_t stream)
420 : {
421 : EXCEPTION_HANDLE_BEGIN
422 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
423 : CHK_PTR_NULL(comm);
424 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
425 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
426 : CHK_PTR_NULL(commV2);
427 : CHK_RET(HcclBatchPutV2(commV2, remoteRank, desc, descNum, stream));
428 : return HCCL_SUCCESS;
429 : }());
430 0 : HcclOneSidedSetIfProfile();
431 0 : HcclUs startut = TIME_NOW();
432 0 : uint64_t beginTime = hrtMsprofSysCycleTime();
433 0 : std::string getTag;
434 0 : HcclBatchData paraData = {comm, HcclCMDType::HCCL_CMD_BATCH_PUT, remoteRank, desc, descNum, stream};
435 0 : CHK_RET(HcclBatchParaCheck(paraData, getTag));
436 :
437 0 : IHcclOneSidedService *service = nullptr;
438 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
439 :
440 0 : HCCL_PROFILER_ADD_TAG(getTag, hcclComm->GetIdentifier(), HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
441 0 : HCCL_PROFILER_ADD_STREAM(stream, getTag, 0, AlgType::Reserved());
442 :
443 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
444 0 : CHK_PTR_NULL(service);
445 0 : static_cast<HcclOneSidedService*>(service)->BatchPut(remoteRank, desc, descNum, stream);
446 :
447 0 : CHK_RET(CallOneSideMsprofReportHostApi(hcclComm, HcclCMDType::HCCL_CMD_BATCH_PUT, beginTime, desc->count,
448 : desc->dataType, getTag));
449 0 : HcclOneSidedResetIfProfile();
450 0 : if (GetExternalInputHcclEnableEntryLog()) {
451 0 : HcclUs endut = TIME_NOW();
452 0 : std::string endInfo = "HcclBatchPut:success,take time: " +
453 0 : std::to_string(DURATION_US(endut - startut).count()) + " us, tag: " + getTag;
454 0 : CHK_RET_AND_PRINT_IDE(hcclComm->SaveTraceInfo(endInfo), getTag.c_str());
455 0 : }
456 0 : HCCL_PROFILER_DEL_TAG(getTag);
457 0 : HCCL_PROFILER_DEL_STREAM(stream);
458 0 : EXCEPTION_HANDLE_END
459 0 : return HCCL_SUCCESS;
460 : }
461 :
462 0 : HcclResult HcclBatchGet(HcclComm comm, u32 remoteRank, HcclOneSideOpDesc* desc, u32 descNum, rtStream_t stream)
463 : {
464 : EXCEPTION_HANDLE_BEGIN
465 0 : HCCLV2_FUNC_RUN([&]() -> HcclResult {
466 : CHK_PTR_NULL(comm);
467 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
468 : HcclComm commV2 = hcclComm->GetCommunicatorV2();
469 : CHK_PTR_NULL(commV2);
470 : CHK_RET(HcclBatchGetV2(commV2, remoteRank, desc, descNum, stream));
471 : return HCCL_SUCCESS;
472 : }());
473 0 : HcclOneSidedSetIfProfile();
474 0 : HcclUs startut = TIME_NOW();
475 0 : uint64_t beginTime = hrtMsprofSysCycleTime();
476 0 : std::string getTag;
477 0 : HcclBatchData paraData = {comm, HcclCMDType::HCCL_CMD_BATCH_GET, remoteRank, desc, descNum, stream};
478 0 : CHK_RET(HcclBatchParaCheck(paraData, getTag));
479 :
480 0 : IHcclOneSidedService *service = nullptr;
481 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
482 :
483 0 : HCCL_PROFILER_ADD_TAG(getTag, hcclComm->GetIdentifier(), HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
484 0 : HCCL_PROFILER_ADD_STREAM(stream, getTag, 0, AlgType::Reserved());
485 :
486 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
487 0 : CHK_PTR_NULL(service);
488 0 : static_cast<HcclOneSidedService*>(service)->BatchGet(remoteRank, desc, descNum, stream);
489 :
490 0 : CHK_RET(CallOneSideMsprofReportHostApi(hcclComm, HcclCMDType::HCCL_CMD_BATCH_GET, beginTime, desc->count,
491 : desc->dataType, getTag));
492 0 : HcclOneSidedResetIfProfile();
493 0 : if (GetExternalInputHcclEnableEntryLog()) {
494 0 : HcclUs endut = TIME_NOW();
495 0 : std::string endInfo = "HcclBatchGet:success,take time: " +
496 0 : std::to_string(DURATION_US(endut - startut).count()) + " us, tag: " + getTag;
497 0 : CHK_RET_AND_PRINT_IDE(hcclComm->SaveTraceInfo(endInfo), getTag.c_str());
498 0 : }
499 0 : HCCL_PROFILER_DEL_TAG(getTag);
500 0 : HCCL_PROFILER_DEL_STREAM(stream);
501 0 : EXCEPTION_HANDLE_END
502 0 : return HCCL_SUCCESS;
503 : }
504 :
505 1 : inline static HcclResult HcclMemHandleParamCheck(void *memHandle, const std::string &funcName)
506 : {
507 1 : const bool isValid = GlobalMemRegMgr::GetInstance().CheckHandleIsValid(memHandle);
508 1 : if (isValid) {
509 1 : return HCCL_SUCCESS;
510 : }
511 0 : std::stringstream ss;
512 0 : ss << std::hex << std::uppercase << reinterpret_cast<uintptr_t>(memHandle);
513 0 : const std::string hexStr = ss.str();
514 0 : RPT_INPUT_ERR(true,
515 : "EI0003",
516 : std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
517 : std::vector<std::string>({funcName, hexStr, "memHandle", "a valid registered memory handle"}));
518 0 : HCCL_ERROR("[%s][%s] The parameter memHandle[%p] is invalid.",
519 : LOG_KEYWORDS_TASK_EXEC.c_str(),
520 : LOG_KEYWORDS_INVALID_ARGUMENT.c_str(),
521 : memHandle);
522 0 : return HCCL_E_PARA;
523 0 : }
524 :
525 : // 通信域创建OneSidedService对象的回调函数
526 0 : HcclResult HcclBuildOneSidedService(std::unique_ptr<IHcclOneSidedService> &service, std::unique_ptr<hccl::HcclSocketManager> &socketManager,
527 : std::unique_ptr<hccl::NotifyPool> ¬ifyPool, const CommConfig &commConfig)
528 : {
529 : EXCEPTION_HANDLE_BEGIN
530 0 : service = std::make_unique<HcclOneSidedService>(socketManager, notifyPool, commConfig);
531 0 : EXCEPTION_HANDLE_END
532 0 : return HCCL_SUCCESS;
533 : }
534 :
535 : // 进程粒度注册内存
536 1 : HcclResult HcclRegisterGlobalMem(const CommMem* mem, void** memHandle)
537 : {
538 : EXCEPTION_HANDLE_BEGIN
539 : // 入参校验
540 1 : RPT_INPUT_ERR(mem == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
541 : std::vector<std::string>({"HcclRegisterGlobalMem", "nullptr", "mem", "non-null pointer"}));
542 1 : CHK_PTR_NULL(mem);
543 1 : CHK_PTR_NULL(memHandle);
544 :
545 1 : HCCL_RUN_INFO("Entry-%s:mem[%p]", __func__, mem);
546 :
547 : // 注册内存
548 : // 内部检查内存是否重复
549 1 : CHK_RET(GlobalMemRegMgr::GetInstance().Reg(reinterpret_cast<const HcclMem*>(mem), memHandle));
550 :
551 1 : HCCL_RUN_INFO("%s success:mem addr[%p], size[%llu], type[%d], memHandle[%p]",
552 : __func__, mem->addr, mem->size, mem->type, *memHandle);
553 :
554 0 : EXCEPTION_HANDLE_END
555 1 : return HCCL_SUCCESS;
556 : }
557 :
558 : // 进程粒度注销内存
559 1 : HcclResult HcclDeregisterGlobalMem(void* memHandle)
560 : {
561 : EXCEPTION_HANDLE_BEGIN
562 : // 入参校验
563 2 : CHK_RET(HcclMemHandleParamCheck(memHandle, "HcclDeregisterGlobalMem"));
564 :
565 1 : HCCL_RUN_INFO("Entry-%s:memHandle[%p]", __func__, memHandle);
566 :
567 : // 注销内存
568 : // 内部判断内存是否还再使用
569 1 : CHK_RET(GlobalMemRegMgr::GetInstance().DeReg(memHandle));
570 :
571 : // 状态打印
572 1 : HCCL_RUN_INFO("%s success:memHandle[%p]", __func__, memHandle);
573 :
574 0 : EXCEPTION_HANDLE_END
575 1 : return HCCL_SUCCESS;
576 : }
577 :
578 0 : inline static HcclResult HcclCommHandleMem(HcclComm comm, void* memHandle, const char* funcName,
579 : std::function<HcclResult(IHcclOneSidedService*, const std::string&)> operation)
580 : {
581 : EXCEPTION_HANDLE_BEGIN
582 : // 入参校验
583 0 : RPT_INPUT_ERR(comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
584 : std::vector<std::string>({funcName, "nullptr", "comm", "non-null pointer"}));
585 0 : CHK_PTR_NULL(comm);
586 0 : CHK_RET(HcclMemHandleParamCheck(memHandle, funcName));
587 :
588 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
589 0 : std::string commIdentifier = hcclComm->GetIdentifier();
590 :
591 0 : IHcclOneSidedService *service = nullptr;
592 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
593 0 : CHK_PTR_NULL(service);
594 :
595 : // 在单边service中绑定/解绑内存
596 : // 注册成功还是失败在service里处理,该接口只透传handle
597 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], memHandle[%p]", funcName, commIdentifier.c_str(), memHandle);
598 0 : CHK_RET(operation(service, commIdentifier));
599 :
600 0 : EXCEPTION_HANDLE_END
601 0 : return HCCL_SUCCESS;
602 0 : }
603 :
604 0 : HcclResult HcclCommBindMem(HcclComm comm, void* memHandle)
605 : {
606 0 : return HcclCommHandleMem(comm, memHandle, __func__,
607 0 : [memHandle](IHcclOneSidedService *service, const std::string& commIdentifier) {
608 0 : return static_cast<HcclOneSidedService *>(service)->BindMem(memHandle, commIdentifier);
609 0 : });
610 : }
611 :
612 0 : HcclResult HcclCommUnbindMem(HcclComm comm, void* memHandle)
613 : {
614 0 : return HcclCommHandleMem(comm, memHandle, __func__,
615 0 : [memHandle](IHcclOneSidedService *service, const std::string& commIdentifier) {
616 0 : return static_cast<HcclOneSidedService *>(service)->UnbindMem(memHandle, commIdentifier);
617 0 : });
618 : }
619 :
620 : // 使用固定的连接方式为通信域预先分配需要协商的资源,阻塞接口
621 0 : HcclResult HcclCommPrepare(HcclComm comm, const HcclPrepareConfig* prepareConfig, const int timeout)
622 : {
623 : EXCEPTION_HANDLE_BEGIN
624 0 : HcclUs startut = TIME_NOW();
625 : // 参数校验和适配
626 0 : RPT_INPUT_ERR(comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
627 : std::vector<std::string>({"HcclCommPrepare", "nullptr", "comm", "non-null pointer"}));
628 0 : RPT_INPUT_ERR(prepareConfig == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
629 : std::vector<std::string>({"HcclCommPrepare", "nullptr", "prepareConfig", "non-null pointer"}));
630 0 : CHK_PTR_NULL(comm);
631 0 : CHK_PTR_NULL(prepareConfig);
632 :
633 : // timeout = 0 表示使用HCCL_CONNECT_TIMEOUT超时时间,timeout=-1 永不超时,其他为合法值
634 0 : const auto timeoutIsInvalid = timeout <= -2;
635 0 : RPT_INPUT_ERR(timeoutIsInvalid, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),\
636 : std::vector<std::string>({"HcclCommPrepare", std::to_string(timeout), "prepareConfig",
637 : "-1(never timeout) or any integer greater than or equal 0"}));
638 0 : CHK_PRT_RET(timeoutIsInvalid,
639 : HCCL_ERROR("[%s][%s]The parameter timeout[%d s] is invalid. It should be -1(never timeout) or any "\
640 : "integer greater than or equal 0.",
641 : LOG_KEYWORDS_TASK_EXEC.c_str(),
642 : LOG_KEYWORDS_INVALID_ARGUMENT.c_str(),
643 : timeout),
644 : HCCL_E_PARA);
645 :
646 0 : hccl::hcclComm* hcclComm = static_cast<hccl::hcclComm *>(comm);
647 0 : std::string commIdentifier = hcclComm->GetIdentifier();
648 0 : HCCL_RUN_INFO("Entry-%s:comm[%s], timeout[%d s]", __func__, commIdentifier.c_str(), timeout);
649 :
650 0 : IHcclOneSidedService *service = nullptr;
651 0 : CHK_RET(hcclComm->GetOneSidedService(&service));
652 0 : CHK_PTR_NULL(service);
653 :
654 : // 校验netDevCtx是否为空
655 : bool useNic;
656 : bool useVnic;
657 0 : CHK_RET(static_cast<HcclOneSidedService*>(service)->InitIsUsedRdmaMap(useNic, useVnic));
658 : HcclNetDevCtx nicNetDevCtx;
659 0 : CHK_RET(service->GetNetDevCtx(nicNetDevCtx, true));
660 :
661 : HcclNetDevCtx vnicNetDevCtx;
662 0 : CHK_RET(service->GetNetDevCtx(vnicNetDevCtx, false));
663 0 : bool needInitNic = useNic && nicNetDevCtx == nullptr;
664 0 : bool needInitVnic = useVnic && vnicNetDevCtx == nullptr;
665 :
666 0 : if (needInitNic) {
667 0 : CHK_RET(GlobalMemRegMgr::GetInstance().InitNic());
668 0 : HcclIpAddress ipAddr;
669 0 : u32 port{};
670 0 : CHK_RET(hcclComm->GetOneSidedServiceDevIpAndPort(NicType::DEVICE_NIC_TYPE, ipAddr, port));
671 0 : HcclNetDevCtx netDevCtx{};
672 0 : CHK_RET(GlobalMemRegMgr::GetInstance().GetNetDevCtx(NicType::DEVICE_NIC_TYPE, ipAddr, port, netDevCtx));
673 0 : CHK_PTR_NULL(netDevCtx);
674 0 : CHK_RET(hcclComm->OneSidedServiceStartListen(NicType::DEVICE_NIC_TYPE, netDevCtx));
675 0 : CHK_RET(service->SetNetDevCtx(netDevCtx, true));
676 0 : HCCL_INFO("[%s]Network resources are not initialized, start to initnic", __func__);
677 0 : }
678 0 : if (needInitVnic) {
679 0 : HcclIpAddress ipAddr;
680 0 : u32 port{};
681 0 : CHK_RET(hcclComm->GetOneSidedServiceDevIpAndPort(NicType::VNIC_TYPE, ipAddr, port));
682 0 : HcclNetDevCtx netDevCtx{};
683 0 : CHK_RET(GlobalMemRegMgr::GetInstance().GetNetDevCtx(NicType::VNIC_TYPE, ipAddr, port, netDevCtx));
684 0 : CHK_PTR_NULL(netDevCtx);
685 0 : CHK_RET(service->SetNetDevCtx(netDevCtx, false));
686 0 : HCCL_INFO("[%s]Network resources are not initialized, start to initvnic", __func__);
687 0 : }
688 :
689 0 : CHK_RET(static_cast<HcclOneSidedService*>(service)->Prepare(commIdentifier, prepareConfig, timeout));
690 :
691 0 : HCCL_RUN_INFO("%s success:comm[%s], take time [%lld us]", __func__, commIdentifier.c_str(), DURATION_US(TIME_NOW() - startut));
692 0 : EXCEPTION_HANDLE_END
693 0 : return HCCL_SUCCESS;
694 0 : }
695 :
|