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 "aicpu_channel_process.h"
12 : #include "dev_aicpu_ts_channel_mgr.h"
13 : #include "aicpu_res_package_helper.h"
14 : #include "../channel.h"
15 : #include "aicpu_ts_channel_helper.h"
16 :
17 : #include "adapter_rts_common.h"
18 : #include "log.h"
19 :
20 : #include <securec.h>
21 :
22 : #include <cstdint>
23 : #include <vector>
24 :
25 : std::mutex AicpuChannelProcess::mutex_;
26 : std::unordered_map<ChannelHandle, std::unique_ptr<Hccl::UbTransportLiteImpl>> AicpuChannelProcess::ubTransportMap_;
27 :
28 0 : HcclResult AicpuChannelProcess::ParsePackData(std::vector<char>& data, ChannelHandle& handle)
29 : {
30 0 : HCCL_DEBUG("[HcclCommAicpu][%s] data: ptr[%p], size[%u]", __func__, data.data(), data.size());
31 0 : Hccl::BinaryStream binaryStream(data);
32 :
33 0 : std::vector<char> transpUniqueId;
34 0 : binaryStream >> transpUniqueId;
35 :
36 0 : Hccl::BinaryStream binaryStreamForType(transpUniqueId);
37 : u32 transType;
38 0 : binaryStreamForType >> transType;
39 0 : HCCL_INFO("[CollCommAicpu][ParsePackData] transType[%u]", transType);
40 0 : if (transType == Hccl::TransportType::UB) {
41 0 : std::unique_ptr<Hccl::UbTransportLiteImpl> ubTransportLiteImpl;
42 0 : EXCEPTION_CATCH(
43 : (ubTransportLiteImpl = std::make_unique<Hccl::UbTransportLiteImpl>(transpUniqueId)), return HCCL_E_PTR);
44 0 : CHK_SMART_PTR_NULL(ubTransportLiteImpl);
45 :
46 0 : handle = reinterpret_cast<uint64_t>(ubTransportLiteImpl.get());
47 0 : ubTransportMap_.insert({handle, std::move(ubTransportLiteImpl)});
48 0 : } else {
49 0 : HCCL_ERROR("[AicpuChannelProcess][%s] transType[%u] is invalid", __func__, transType);
50 0 : return HCCL_E_PARA;
51 : }
52 :
53 0 : return HCCL_SUCCESS;
54 0 : }
55 :
56 0 : HcclResult AicpuChannelProcess::InitUrmaChannel(HcclChannelUrmaRes* commParam)
57 : {
58 0 : HCCL_INFO(
59 : "[HcclCommAicpu][%s] commParam->uniqueIdAddr[%p], commParam->uniqueIdSize[%u]", __func__,
60 : commParam->uniqueIdAddr, commParam->uniqueIdSize);
61 :
62 0 : u8* currentSrcAddr = reinterpret_cast<u8*>(commParam->uniqueIdAddr);
63 0 : u32* addSize = reinterpret_cast<u32*>(commParam->channelSizeAddr);
64 0 : for (u32 index = 0; index < commParam->listNum; index++) {
65 0 : std::vector<char> data(*addSize);
66 :
67 0 : CHK_SAFETY_FUNC_RET(memcpy_s(data.data(), data.size(), currentSrcAddr, *addSize));
68 0 : currentSrcAddr += *addSize;
69 0 : addSize++;
70 : Hccl::AicpuResPackageHelper helper;
71 0 : auto dataVec = helper.ParsePackedData(data);
72 :
73 0 : Hccl::AicpuResMgrType resType = Hccl::AicpuResMgrType::STREAM;
74 0 : if (static_cast<u32>(resType) >= dataVec.size()) {
75 0 : HCCL_ERROR("[HcclCommAicpu][%s] fail, resType[%d], dataVec size[%u]", __func__, resType, dataVec.size());
76 0 : return HCCL_E_PARA;
77 : }
78 : ChannelHandle channelHandle;
79 0 : CHK_RET(ParsePackData(dataVec[resType].data, channelHandle));
80 :
81 0 : if (commParam->ctxList != nullptr) {
82 : // ctx模式:device侧填充abiHeader + deviceChannel
83 0 : auto** ctxList = reinterpret_cast<HcommAicpuChannelCtx**>(commParam->ctxList);
84 0 : ctxList[index]->abiHeader.version = HCOMM_AICPU_CHANNEL_CTX_VERSION;
85 0 : ctxList[index]->abiHeader.magicWord = HCOMM_AICPU_CHANNEL_CTX_MAGIC_WORD;
86 0 : ctxList[index]->abiHeader.size = sizeof(HcommAicpuChannelCtx);
87 0 : ctxList[index]->deviceChannel = reinterpret_cast<void*>(channelHandle);
88 : } else {
89 0 : ChannelHandle* channelList = reinterpret_cast<ChannelHandle*>(commParam->channelList);
90 0 : channelList[index] = channelHandle;
91 : }
92 0 : HCCL_INFO(
93 : "[HcclCommAicpu][%s] index[%u], currentSrcAddr[%p], channelSizeAddr[%p], channelHandle[0x%llx]", __func__,
94 : index, currentSrcAddr, commParam->channelSizeAddr, channelHandle);
95 0 : }
96 :
97 0 : return HCCL_SUCCESS;
98 : }
99 :
100 0 : HcclResult AicpuChannelProcess::AicpuChannelInit(HcclChannelUrmaRes* commParam)
101 : {
102 0 : HCCL_INFO(
103 : "[AicpuChannelProcess][%s] commParam->channelList[%p], commParam->listNum[%u], commParam->uniqueIdAddr[%p], "
104 : "commParam->uniqueIdSize[%u]",
105 : __func__, commParam->channelList, commParam->listNum, commParam->uniqueIdAddr, commParam->uniqueIdSize);
106 :
107 0 : CHK_RET(hrtSetWorkModeAicpu(true));
108 0 : CHK_RET(hrtSetlocalDevice(commParam->deviceLogicId));
109 0 : CHK_RET(hrtSetlocalDeviceType(static_cast<DevType>(commParam->deviceType)));
110 :
111 0 : std::lock_guard<std::mutex> addLock(mutex_);
112 :
113 0 : HcclResult ret = InitUrmaChannel(commParam);
114 0 : CHK_PRT_RET(
115 : ret != HCCL_SUCCESS,
116 : HCCL_ERROR(
117 : "[AicpuChannelProcess][AicpuChannelInit]errNo[0x%016llx] Failed to init channels", HCCL_ERROR_CODE(ret)),
118 : ret);
119 :
120 0 : HCCL_INFO("[AicpuChannelProcess][%s] aicpuTask End.", __func__);
121 0 : return HCCL_SUCCESS;
122 0 : }
123 :
124 : namespace {
125 :
126 1 : void RollbackDestroy(DevAicpuTsChannelMgr& mgr, const std::vector<ChannelHandle>& rollback)
127 : {
128 1 : for (const auto& h : rollback) {
129 0 : if (mgr.DestroyChannel(h)) {
130 0 : HCCL_DEBUG("[AicpuChannelProcess][%s] rollback destroyed handle[0x%llx]", __func__, h);
131 : } else {
132 0 : HCCL_WARNING("[AicpuChannelProcess][%s] rollback failed to destroy handle[0x%llx]", __func__, h);
133 : }
134 : }
135 1 : }
136 :
137 2 : HcclResult CreateSingleHcommChannel(
138 : DevAicpuTsChannelMgr& mgr, void* dp, u64 sz, const HcommDeviceInfo& deviceInfo, hcomm::HcommChannelKind kind,
139 : HcommChannelRes* commParam, u32 index, ChannelHandle* channelList, std::vector<ChannelHandle>& rollback)
140 : {
141 2 : DevAicpuTsChannel* channel = mgr.GetOrCreateAicpuTsChannel(kind);
142 2 : if (channel == nullptr) {
143 1 : HCCL_ERROR(
144 : "[AicpuChannelProcess][%s] index[%u] unsupported kind[%u]", __func__, index, static_cast<uint32_t>(kind));
145 1 : RollbackDestroy(mgr, rollback);
146 1 : return HCCL_E_NOT_SUPPORT;
147 : }
148 1 : CHK_PTR_NULL(dp);
149 1 : ChannelHandle h{};
150 1 : HcclResult pret = channel->Create(dp, sz, deviceInfo, h);
151 1 : if (pret != HCCL_SUCCESS) {
152 0 : HCCL_ERROR("[AicpuChannelProcess][%s] parse fail at index[%u]", __func__, index);
153 0 : RollbackDestroy(mgr, rollback);
154 0 : return pret;
155 : }
156 1 : if (commParam->ctxList != nullptr) {
157 0 : auto** ctxList = reinterpret_cast<HcommAicpuChannelCtx**>(commParam->ctxList);
158 0 : ctxList[index]->abiHeader.version = HCOMM_AICPU_CHANNEL_CTX_VERSION;
159 0 : ctxList[index]->abiHeader.magicWord = HCOMM_AICPU_CHANNEL_CTX_MAGIC_WORD;
160 0 : ctxList[index]->abiHeader.size = sizeof(HcommAicpuChannelCtx);
161 0 : ctxList[index]->deviceChannel = reinterpret_cast<void*>(h);
162 : } else {
163 1 : channelList[index] = h;
164 : }
165 1 : rollback.push_back(h);
166 1 : return HCCL_SUCCESS;
167 : }
168 :
169 : } // namespace
170 :
171 4 : HcclResult AicpuChannelProcess::InitHcommChannelRes(HcommChannelRes* commParam)
172 : {
173 4 : CHK_PTR_NULL(commParam);
174 3 : HCCL_INFO(
175 : "[AicpuChannelProcess][%s] channelList[%p], listNum[%u]", __func__, commParam->channelList, commParam->listNum);
176 :
177 3 : CHK_PTR_NULL(commParam->channelList);
178 2 : CHK_PTR_NULL(commParam->channelDataListAddr);
179 2 : CHK_PTR_NULL(commParam->channelDataSizeListAddr);
180 2 : CHK_PTR_NULL(commParam->channelTypeListAddr);
181 :
182 2 : CHK_RET(hrtSetWorkModeAicpu(true));
183 2 : CHK_RET(hrtSetlocalDevice(commParam->deviceInfo.deviceLogicId));
184 2 : CHK_RET(hrtSetlocalDeviceType(static_cast<DevType>(commParam->deviceInfo.deviceType)));
185 :
186 2 : void** dataList = reinterpret_cast<void**>(commParam->channelDataListAddr);
187 2 : auto* sizeList = reinterpret_cast<u64*>(commParam->channelDataSizeListAddr);
188 2 : auto* typeList = reinterpret_cast<u32*>(commParam->channelTypeListAddr);
189 2 : auto* channelList = reinterpret_cast<ChannelHandle*>(commParam->channelList);
190 :
191 2 : auto& mgr = DevAicpuTsChannelMgr::Instance();
192 2 : std::vector<ChannelHandle> rollback;
193 2 : rollback.reserve(commParam->listNum);
194 :
195 2 : std::lock_guard<std::mutex> addLock(mutex_);
196 3 : for (u32 index = 0; index < commParam->listNum; ++index) {
197 2 : hcomm::HcommChannelKind kind = static_cast<hcomm::HcommChannelKind>(typeList[index]);
198 2 : CHK_RET(CreateSingleHcommChannel(
199 : mgr, dataList[index], sizeList[index], commParam->deviceInfo, kind, commParam, index, channelList,
200 : rollback));
201 1 : HCCL_INFO(
202 : "[AicpuChannelProcess][%s] index[%u] channelHandle[0x%llx]", __func__, index,
203 : commParam->ctxList != nullptr ? 0 : channelList[index]);
204 : }
205 :
206 1 : HCCL_INFO("[AicpuChannelProcess][%s] aicpu_task End.", __func__);
207 1 : return HCCL_SUCCESS;
208 2 : }
209 :
210 0 : HcclResult AicpuChannelProcess::AicpuChannelDestroy(HcclChannelUrmaRes* commParam)
211 : {
212 0 : HCCL_INFO(
213 : "[AicpuChannelProcess][%s] commParam->channelList[%p], commParam->listNum[%u]", __func__,
214 : commParam->channelList, commParam->listNum);
215 :
216 0 : auto& mgr = DevAicpuTsChannelMgr::Instance();
217 0 : std::lock_guard<std::mutex> addLock(mutex_);
218 :
219 0 : ChannelHandle* channelList = reinterpret_cast<ChannelHandle*>(commParam->channelList);
220 0 : for (u32 index = 0; index < commParam->listNum; ++index) {
221 0 : ChannelHandle handle = channelList[index];
222 :
223 0 : auto it = ubTransportMap_.find(handle);
224 0 : if (it != ubTransportMap_.end()) {
225 0 : ubTransportMap_.erase(it);
226 0 : HCCL_DEBUG("[AicpuChannelProcess][%s] destroyed ub handle[0x%llx]", __func__, handle);
227 0 : continue;
228 : }
229 :
230 0 : if (mgr.DestroyChannel(handle)) {
231 0 : HCCL_DEBUG("[AicpuChannelProcess][%s] destroyed hcomm res handle[0x%llx]", __func__, handle);
232 0 : continue;
233 : }
234 :
235 0 : HCCL_WARNING(
236 : "[AicpuChannelProcess][%s] handle[0x%llx] not found in ub/hcomm maps, maybe already destroyed?", __func__,
237 : handle);
238 : }
239 :
240 0 : HCCL_INFO("[AicpuChannelProcess][%s] aicpu_task End.", __func__);
241 0 : return HCCL_SUCCESS;
242 0 : }
|