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 "adapter_rts_common.h"
12 : #include "share_ccl_buffer_manager.h"
13 :
14 : namespace hccl {
15 :
16 638 : ShareCCLbufferMgr& ShareCCLbufferMgr::GetInstance()
17 : {
18 1028 : static ShareCCLbufferMgr shareCCLbufferMgr[MAX_MODULE_DEVICE_NUM];
19 : s32 deviceLogicId;
20 638 : hrtGetDevice(&deviceLogicId);
21 638 : if (static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM) {
22 0 : HCCL_WARNING("[ShareCCLbufferMgr][GetInstance] deviceLogicID[%d] is invalid", deviceLogicId);
23 0 : return shareCCLbufferMgr[0];
24 : }
25 638 : return shareCCLbufferMgr[deviceLogicId];
26 : }
27 :
28 0 : HcclResult ShareCCLbufferMgr::CreateDevMem(u64 size, DeviceMem &buffer)
29 : {
30 0 : CHK_PRT_RET(size == 0, HCCL_INFO("[ShareCCLbufferMgr][CreateDevMem]buffer size is zero. not need to malloc memory"),
31 : HCCL_SUCCESS);
32 :
33 : CHK_PRT_RET((size > ULONG_MAX),
34 : HCCL_ERROR("[ShareCCLbufferMgr][CreateDevMem]buffer size is greater than %llu", ULONG_MAX), HCCL_E_PARA);
35 :
36 0 : buffer = DeviceMem::alloc(size);
37 0 : CHK_PRT_RET(buffer.ptr() == nullptr,HCCL_ERROR("[ShareCCLbufferMgr][CreateDevMem]Create ccl buffer fail,buffer ptr is nullptr"),HCCL_E_PTR);
38 0 : HCCL_INFO("[ShareCCLbufferMgr][CreateDevMem] buffer ptr[%p], size[%llu]", buffer.ptr(), buffer.size());
39 0 : CHK_PRT_RET(static_cast<bool>(size) && !buffer, HCCL_ERROR("[ShareCCLbufferMgr][CreateDevMem]Create ccl buffer size[%llu] fail,"
40 : "please check env ironmental variable HCCL_BUFFSIZE.", size), HCCL_E_PTR);
41 0 : return HCCL_SUCCESS;
42 : }
43 :
44 403 : HcclResult ShareCCLbufferMgr::RecordShareCCLbuffer(const std::string &bufferName)
45 : {
46 403 : CHK_PRT_RET(bufferName.empty(), HCCL_INFO("[ShareCCLbufferMgr][RecordShareCCLbuffer]: buffername is empty, no need record share buffer"), HCCL_SUCCESS);
47 :
48 0 : std::lock_guard<std::mutex> lock(lock_);
49 0 : auto memIter = memRecord_.find(bufferName);
50 0 : if (memIter == memRecord_.end()) {
51 0 : ShareCCLMem memResource;
52 0 : memResource.refCount = static_cast<uint64_t>(1);
53 0 : memRecord_.emplace(bufferName, std::move(memResource));
54 0 : HCCL_INFO("[ShareCCLbufferMgr][RecordShareCCLbuffer]: buffername=%s, refCount=1", bufferName.c_str());
55 0 : } else {
56 0 : memIter->second.refCount++;
57 0 : HCCL_INFO("[ShareCCLbufferMgr][RecordShareCCLbuffer]: buffername=%s, refCount=%d", bufferName.c_str(), memIter->second.refCount);
58 : }
59 0 : return HCCL_SUCCESS;
60 0 : }
61 :
62 :
63 0 : HcclResult ShareCCLbufferMgr::CreateShareCCLbuffer(const std::string &bufferName, u64 bufferSize, DeviceMem &cclBuffer)
64 : {
65 0 : CHK_PRT_RET(bufferName.empty(), HCCL_INFO("[ShareCCLbufferMgr][CreateShareCCLbuffer]: buffername is empty, no need create share buffer"), HCCL_SUCCESS);
66 :
67 0 : std::lock_guard<std::mutex> lock(lock_);
68 0 : CHK_PRT_RET(bufferSize == 0, HCCL_ERROR("[ShareCCLbufferMgr][CreateShareCCLbuffer]: ccl buffer size is abnormal!"), HCCL_E_PARA);
69 0 : if (shareBufferSize_ == 0) {
70 0 : shareBufferSize_ = bufferSize;
71 : }
72 0 : if (shareBufferSize_ != bufferSize) {
73 0 : HCCL_WARNING("[ShareCCLbufferMgr][CreateShareCCLbuffer]: share ccLBuffer size [%d], expect buffsize [%d]", shareBufferSize_, bufferSize);
74 : }
75 :
76 0 : auto memIter = memRecord_.find(bufferName);
77 : // 申请inCCL,outCCL buffer
78 0 : if (memIter->second.cclBuffer.ptr() == nullptr) {
79 0 : CHK_RET(CreateDevMem(bufferSize, memIter->second.cclBuffer));
80 0 : CHK_RET(hrtMemSet(memIter->second.cclBuffer.ptr(), bufferSize, bufferSize));
81 : }
82 0 : cclBuffer = memIter->second.cclBuffer;
83 0 : HCCL_INFO("[ShareCCLbufferMgr][CreateShareCCLbuffer]: buffername=%s, cclBuffer=%p", bufferName.c_str(), cclBuffer.ptr());
84 0 : return HCCL_SUCCESS;
85 0 : }
86 :
87 :
88 235 : HcclResult ShareCCLbufferMgr::FreeShareCCLbuffer(const std::string &bufferName)
89 : {
90 235 : CHK_PRT_RET(bufferName.empty(), HCCL_INFO("[ShareCCLbufferMgr][FreeShareCCLbuffer]: buffername is empty, no need free share cclbuffer"),
91 : HCCL_SUCCESS);
92 :
93 0 : std::lock_guard<std::mutex> lock(lock_);
94 0 : auto it = memRecord_.find(bufferName);
95 0 : if (it == memRecord_.end()) {
96 0 : HCCL_ERROR("[ShareCCLbufferMgr][FreeShareCCLbuffer] Cannot found the corresponding record of memory[%s].", bufferName.c_str());
97 0 : return HCCL_E_PARA;
98 : }
99 0 : int refCnt = --(it->second.refCount);
100 0 : if (refCnt == 0) {
101 0 : HCCL_INFO("[ShareCCLbufferMgr][FreeShareCCLbuffer]: free share cclbuffername=%s", bufferName.c_str());
102 0 : memRecord_.erase(it);
103 0 : streamIdMap_.erase(bufferName);
104 : }
105 0 : HCCL_INFO("[ShareCCLbufferMgr][FreeShareCCLbuffer]: buffername=%s, refCount=%d", bufferName.c_str(), refCnt);
106 0 : return HCCL_SUCCESS;
107 0 : }
108 :
109 : // 约束共享buffer的算子下发到同一条流
110 0 : HcclResult ShareCCLbufferMgr::CheckCCLbuffConflict(const std::string &bufferName, s32 streamId)
111 : {
112 0 : CHK_PRT_RET(bufferName.empty(), HCCL_INFO("[ShareCCLbufferMgr][CheckCCLbuffConflict]: buffername is empty, no need check CCLbuff conflict"),
113 : HCCL_SUCCESS);
114 :
115 0 : std::lock_guard<std::mutex> lock(lock_);
116 0 : auto streamIter = streamIdMap_.find(bufferName);
117 0 : if (streamIter == streamIdMap_.end()) {
118 : // 首次记录该缓冲区的stream ID
119 0 : streamIdMap_[bufferName] = streamId;
120 0 : HCCL_INFO("CheckCCLbuffConflict: sharebuffer[%s] bound to stream[%d]", bufferName.c_str(), streamId);
121 0 : return HCCL_SUCCESS;
122 : }
123 0 : const s32 recordedStreamId = streamIter->second;
124 0 : if (streamId != recordedStreamId) {
125 0 : HCCL_ERROR("[CheckCCLbuffConflict] sharebuffer[%s] stream conflict: "
126 : "current %d vs recorded %d", bufferName.c_str(), streamId, recordedStreamId);
127 0 : return HCCL_E_PARA;
128 : }
129 0 : return HCCL_SUCCESS;
130 0 : }
131 :
132 : }
|