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