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