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 "base_config.h"
12 : #include <fstream>
13 : #include <algorithm>
14 : #include <array>
15 : #include "log.h"
16 :
17 : namespace Hccl {
18 :
19 : // EnvHostNicConfig
20 :
21 16 : void EnvHostNicConfig::Parse()
22 : {
23 16 : hcclIfIp.Parse();
24 28 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_IF_IP set by %s to [%s]", hcclIfIp.GetSource(), GetControlIfIp().Describe().c_str());
25 :
26 16 : hcclIfBasePort.Parse();
27 28 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_IF_BASE_PORT set by %s to [%u]", hcclIfBasePort.GetSource(), GetIfBasePort());
28 :
29 16 : hcclSocketIfName.Parse();
30 28 : HCCL_RUN_INFO(
31 : "[HCCL_ENV] HCCL_SOCKET_IFNAME set by %s to [%s]", hcclSocketIfName.GetSource(),
32 : GetSocketIfName().configIfNameStr.c_str());
33 :
34 16 : whitelistDisable.Parse();
35 28 : HCCL_RUN_INFO(
36 : "[HCCL_ENV] HCCL_WHITELIST_DISABLE set by %s to [%d]", whitelistDisable.GetSource(), whitelistDisable.Get());
37 :
38 16 : if (!whitelistDisable.Get()) {
39 1 : hcclWhiteListFile.Parse();
40 3 : HCCL_RUN_INFO(
41 : "[HCCL_ENV] HCCL_WHITELIST_FILE set by %s to [%s]", hcclWhiteListFile.GetSource(),
42 : GetWhiteListFile().c_str());
43 : }
44 :
45 16 : hcclHostSocketPortRange.Parse();
46 16 : std::ostringstream hosrPortRangeOss;
47 17 : for (auto range : GetHostSocketPortRange()) {
48 1 : hosrPortRangeOss << "[" << range.min << ", " << range.max << "]";
49 : }
50 28 : HCCL_RUN_INFO(
51 : "[HCCL_ENV] HCCL_HOST_SOCKET_PORT_RANGE set by %s to %s", hcclHostSocketPortRange.GetSource(),
52 : hosrPortRangeOss.str().c_str());
53 :
54 16 : hcclDeviceSocketPortRange.Parse();
55 16 : std::ostringstream devicePortRangeOss;
56 16 : for (auto range : GetDeviceSocketPortRange()) {
57 0 : devicePortRangeOss << "[" << range.min << ", " << range.max << "]";
58 : }
59 28 : HCCL_RUN_INFO(
60 : "[HCCL_ENV] HCCL_NPU_SOCKET_PORT_RANGE set by %s to %s", hcclDeviceSocketPortRange.GetSource(),
61 : devicePortRangeOss.str().c_str());
62 16 : }
63 :
64 24 : const IpAddress& EnvHostNicConfig::GetControlIfIp() const { return hcclIfIp.Get(); }
65 :
66 51 : u32 EnvHostNicConfig::GetIfBasePort() const { return hcclIfBasePort.Get(); }
67 :
68 25 : const SocketIfName& EnvHostNicConfig::GetSocketIfName() const { return hcclSocketIfName.Get(); }
69 :
70 42 : bool EnvHostNicConfig::GetWhitelistDisable() const { return whitelistDisable.Get(); }
71 :
72 2 : const std::string& EnvHostNicConfig::GetWhiteListFile() const { return hcclWhiteListFile.Get(); }
73 :
74 54 : const std::vector<SocketPortRange>& EnvHostNicConfig::GetHostSocketPortRange() const
75 : {
76 54 : return hcclHostSocketPortRange.Get();
77 : }
78 :
79 34 : const std::vector<SocketPortRange>& EnvHostNicConfig::GetDeviceSocketPortRange() const
80 : {
81 34 : return hcclDeviceSocketPortRange.Get();
82 : }
83 :
84 : // EnvSocketConfig
85 :
86 16 : void EnvSocketConfig::Parse()
87 : {
88 16 : hcclSocketFamily.Parse();
89 28 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_SOCKET_FAMILY set by %s to [%d]", hcclSocketFamily.GetSource(), GetSocketFamily());
90 :
91 16 : linkTimeOut.Parse();
92 28 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_CONNECT_TIMEOUT set by %s to [%d]s", linkTimeOut.GetSource(), GetLinkTimeOut());
93 16 : }
94 :
95 23 : s32 EnvSocketConfig::GetSocketFamily() const { return hcclSocketFamily.Get(); }
96 :
97 66 : s32 EnvSocketConfig::GetLinkTimeOut() const { return linkTimeOut.Get(); }
98 :
99 : // EnvRtsConfig
100 :
101 16 : void EnvRtsConfig::Parse()
102 : {
103 16 : execTimeOut.Parse();
104 16 : aivExecTimeOut.Parse();
105 28 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_EXEC_TIMEOUT set by %s to [%u]s", execTimeOut.GetSource(), GetExecTimeOut());
106 16 : }
107 :
108 253 : u32 EnvRtsConfig::GetExecTimeOut() const { return execTimeOut.Get(); }
109 :
110 1 : double EnvRtsConfig::GetAivExecTimeOut() const { return aivExecTimeOut.Get(); }
111 :
112 : // EnvRdmaConfig
113 :
114 37 : void EnvRdmaConfig::Parse()
115 : {
116 37 : rdmaTrafficClass.Parse();
117 91 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_RDMA_TC set by %s to [%u]", rdmaTrafficClass.GetSource(), GetRdmaTrafficClass());
118 :
119 37 : rdmaServerLevel.Parse();
120 91 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_RDMA_SL set by %s to [%u]", rdmaServerLevel.GetSource(), GetRdmaServerLevel());
121 :
122 37 : rdmaTimeOut.Parse();
123 91 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_RDMA_TIMEOUT set by %s to [%u]", rdmaTimeOut.GetSource(), GetRdmaTimeOut());
124 :
125 37 : rdmaRetryCnt.Parse();
126 91 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_RDMA_RETRY_CNT set by %s to [%u]", rdmaRetryCnt.GetSource(), GetRdmaRetryCnt());
127 :
128 37 : uboeTimeOut.Parse();
129 88 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_UBOE_TIMEOUT set by %s to [%u]", uboeTimeOut.GetSource(), GetUboeTimeOut());
130 :
131 36 : ubTimeOut.Parse();
132 85 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_UB_TIMEOUT set by %s to [%u]", ubTimeOut.GetSource(), GetUbTimeOut());
133 :
134 35 : queueNum.Parse();
135 82 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_RDMA_QPS_PER_CONNECTION set by %s to [%u]", queueNum.GetSource(), GetRdmaQueueNum());
136 :
137 34 : multiQpThreshold.Parse();
138 79 : HCCL_RUN_INFO(
139 : "[HCCL_ENV] HCCL_MULTI_QP_THRESHOLD set by %s to [%u]B", multiQpThreshold.GetSource(),
140 : GetRdmaMultiQpThreshold());
141 :
142 33 : qpPortConfigPath.Parse();
143 73 : HCCL_RUN_INFO(
144 : "[HCCL_ENV] HCCL_RDMA_QP_PORT_CONFIG_PATH set by %s to [%s]", qpPortConfigPath.GetSource(),
145 : qpPortConfigPath.Get().c_str());
146 31 : ParseMultiQpSrcPortConfig();
147 31 : }
148 :
149 6 : HcclResult EnvRdmaConfig::OpenMultiQpConfigFile(std::ifstream& inFile)
150 : {
151 6 : std::string fileStr = qpPortConfigPath.Get() + "/MultiQpSrcPort.cfg";
152 6 : std::array<char, PATH_MAX> realFile{};
153 6 : if (realpath(fileStr.c_str(), realFile.data()) == nullptr) {
154 0 : HCCL_ERROR("[EnvRdmaConfig][OpenMultiQpConfigFile] config file path[%s] is invalid.", fileStr.c_str());
155 0 : return HCCL_E_PARA;
156 : }
157 :
158 6 : inFile.open(fileStr.c_str(), std::ifstream::in);
159 6 : if (!inFile) {
160 0 : HCCL_ERROR("[EnvRdmaConfig][OpenMultiQpConfigFile] open config file[%s] failed.", fileStr.c_str());
161 0 : return HCCL_E_PARA;
162 : }
163 18 : HCCL_INFO("[EnvRdmaConfig][OpenMultiQpConfigFile] open config file[%s] success.", fileStr.c_str());
164 6 : return HCCL_SUCCESS;
165 6 : }
166 :
167 6 : HcclResult EnvRdmaConfig::ParseConfigContent(std::ifstream& inFile, MultiQpSrcPortConfig& config)
168 : {
169 6 : config.configDirPath = qpPortConfigPath.Get();
170 6 : u32 lineCnt = 1;
171 6 : std::string line;
172 131079 : while (std::getline(inFile, line)) {
173 131076 : std::string lineAvator = line;
174 131076 : line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
175 131076 : line.erase(std::remove(line.begin(), line.end(), '\t'), line.end());
176 131076 : auto hashPos = line.find('#');
177 131076 : std::string lineInfo = (hashPos != std::string::npos) ? line.substr(0, hashPos) : line;
178 131076 : if (lineInfo.empty()) {
179 131070 : lineCnt++;
180 131070 : continue;
181 : }
182 :
183 6 : std::string ipPairKey, portPart;
184 6 : HcclResult ret = ParseLineToIpPairAndPortPart(lineInfo, lineCnt, lineAvator, ipPairKey, portPart);
185 6 : if (ret != HCCL_SUCCESS) {
186 1 : return ret;
187 : }
188 5 : std::vector<std::uint16_t> ports;
189 5 : ret = ParseSrcPortsFromPortPart(portPart, lineCnt, lineAvator, ports);
190 5 : if (ret != HCCL_SUCCESS) {
191 1 : return ret;
192 : }
193 4 : CHK_PRT_RET(
194 : config.ipPairToPorts.find(ipPairKey) != config.ipPairToPorts.end(),
195 : HCCL_ERROR(
196 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] ip pair[%s] already exists.[%s]", lineCnt,
197 : ipPairKey.c_str(), lineAvator.c_str()),
198 : HCCL_E_PARA);
199 4 : config.ipPairToPorts[ipPairKey] = ports;
200 4 : if (lineCnt >= MultiQpSrcPortConfig::CONFIG_FILE_LINE_MAX) {
201 3 : HCCL_RUN_INFO("config file is too large, stop parsing at line %u.", lineCnt);
202 1 : break;
203 : }
204 3 : lineCnt++;
205 262157 : }
206 4 : return HCCL_SUCCESS;
207 6 : }
208 :
209 31 : void EnvRdmaConfig::ParseMultiQpSrcPortConfig()
210 : {
211 31 : if (!qpPortConfigPath.IsSetByEnvironment() || qpPortConfigPath.Get().empty()) {
212 25 : return;
213 : }
214 : try {
215 6 : std::ifstream inFile;
216 6 : CHK_PRT_THROW(
217 : OpenMultiQpConfigFile(inFile) != HCCL_SUCCESS,
218 : HCCL_ERROR("[EnvRdmaConfig][Parse] open multi qp src port config file failed."), InvalidParamsException,
219 : "open config file fail.");
220 :
221 6 : MultiQpSrcPortConfig config;
222 16 : CHK_PRT_THROW(
223 : ParseConfigContent(inFile, config) != HCCL_SUCCESS,
224 : HCCL_ERROR("[EnvRdmaConfig][Parse] parse multi qp src port config content failed."), InvalidParamsException,
225 : "parse config content fail.");
226 :
227 4 : inFile.close();
228 4 : multiQpSrcPortConfig_ = config;
229 4 : LogMultiQpSrcPortConfig();
230 10 : } catch (const HcclException& e) {
231 6 : HCCL_ERROR("[EnvRdmaConfig][Parse] LoadMultiQpSrcPortConfig failed: %s", e.what());
232 2 : } catch (const std::exception& e) {
233 0 : HCCL_ERROR("[EnvRdmaConfig][Parse] LoadMultiQpSrcPortConfig failed: %s", e.what());
234 0 : }
235 : }
236 :
237 6 : HcclResult EnvRdmaConfig::ParseLineToIpPairAndPortPart(
238 : const std::string& lineInfo, u32 lineCnt, const std::string& lineAvator, std::string& ipPairKey,
239 : std::string& portPart)
240 : {
241 6 : auto eqPos = lineInfo.find('=');
242 9 : CHK_PRT_RET(
243 : eqPos == std::string::npos || eqPos == 0 || eqPos == lineInfo.size() - 1,
244 : HCCL_ERROR(
245 : "[MulQpInfo][ParseSrcPortsFromString][line: %u]Expected format: "
246 : "'srcIP,dstIP=srcPort0,srcPort1,...'.[%s]",
247 : lineCnt, lineAvator.c_str()),
248 : HCCL_E_PARA);
249 5 : CHK_PRT_RET(
250 : lineInfo.find('=', eqPos + 1) != std::string::npos,
251 : HCCL_ERROR(
252 : "[MulQpInfo][ParseSrcPortsFromString][line: %u]Expected format: "
253 : "'srcIP,dstIP=srcPort0,srcPort1,...'.[%s]",
254 : lineCnt, lineAvator.c_str()),
255 : HCCL_E_PARA);
256 5 : std::string ipPart = lineInfo.substr(0, eqPos);
257 5 : portPart = lineInfo.substr(eqPos + 1);
258 :
259 5 : auto commaPos = ipPart.find(',');
260 5 : CHK_PRT_RET(
261 : commaPos == std::string::npos,
262 : HCCL_ERROR(
263 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] IP pair format error, "
264 : "expected 'srcIP,dstIP'.[%s]",
265 : lineCnt, lineAvator.c_str()),
266 : HCCL_E_PARA);
267 5 : CHK_PRT_RET(
268 : ipPart.find(',', commaPos + 1) != std::string::npos,
269 : HCCL_ERROR(
270 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] IP pair format error, "
271 : "expected 'srcIP,dstIP'.[%s]",
272 : lineCnt, lineAvator.c_str()),
273 : HCCL_E_PARA);
274 :
275 5 : IpAddress srcIpAddr, dstIpAddr;
276 : try {
277 5 : srcIpAddr = IpAddress(ipPart.substr(0, commaPos));
278 5 : dstIpAddr = IpAddress(ipPart.substr(commaPos + 1));
279 0 : } catch (const InvalidParamsException& e) {
280 0 : HCCL_ERROR(
281 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] IP format error: %s.[%s]", lineCnt, e.what(),
282 : lineAvator.c_str());
283 0 : return HCCL_E_PARA;
284 0 : }
285 :
286 5 : ipPairKey = srcIpAddr.GetIpStr() + "," + dstIpAddr.GetIpStr();
287 5 : return HCCL_SUCCESS;
288 5 : }
289 :
290 5 : HcclResult EnvRdmaConfig::ParseSrcPortsFromPortPart(
291 : const std::string& portPart, u32 lineCnt, const std::string& lineAvator, std::vector<std::uint16_t>& ports)
292 : {
293 5 : std::size_t start = 0;
294 : while (true) {
295 69 : auto p = portPart.find(',', start);
296 69 : std::string token = (p != std::string::npos) ? portPart.substr(start, p - start) : portPart.substr(start);
297 :
298 69 : CHK_PRT_RET(
299 : token.empty(),
300 : HCCL_ERROR(
301 : "[MulQpInfo][ParseSrcPortsFromString][line: %u]src port[%s] is empty.[%s]", lineCnt, token.c_str(),
302 : lineAvator.c_str()),
303 : HCCL_E_PARA);
304 :
305 69 : unsigned long val = 0;
306 : try {
307 69 : std::size_t parsePos = 0;
308 69 : val = std::stoul(token, &parsePos, 0);
309 69 : if (parsePos != token.size()) {
310 0 : HCCL_ERROR(
311 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] port[%s] is not a valid integer.[%s]", lineCnt,
312 : token.c_str(), lineAvator.c_str());
313 0 : return HCCL_E_PARA;
314 : }
315 0 : } catch (...) {
316 0 : HCCL_ERROR(
317 : "[MulQpInfo][ParseSrcPortsFromString][line: %u] port[%s] is not a valid integer.[%s]", lineCnt,
318 : token.c_str(), lineAvator.c_str());
319 0 : return HCCL_E_PARA;
320 0 : }
321 :
322 69 : CHK_PRT_RET(
323 : val == 0 || val > MultiQpSrcPortConfig::CONFIG_SRC_PORT_ID_MAX,
324 : HCCL_ERROR(
325 : "[MulQpInfo][ParseSrcPortsFromString][line: %u]src port[%s] "
326 : "should be within the range of[1, %u].[%s]",
327 : lineCnt, token.c_str(), MultiQpSrcPortConfig::CONFIG_SRC_PORT_ID_MAX, lineAvator.c_str()),
328 : HCCL_E_PARA);
329 :
330 69 : ports.emplace_back(static_cast<std::uint16_t>(val));
331 69 : if (p == std::string::npos)
332 5 : break;
333 64 : start = p + 1;
334 133 : }
335 :
336 8 : CHK_PRT_RET(
337 : ports.size() > MultiQpSrcPortConfig::CONFIG_SRC_PORT_NUM_MAX || ports.empty(),
338 : HCCL_ERROR(
339 : "[MulQpInfo][ParseSrcPortsFromString][line: %u]config ports num[%zu] more than the "
340 : "threshold[%u].[%s]",
341 : lineCnt, ports.size(), MultiQpSrcPortConfig::CONFIG_SRC_PORT_NUM_MAX, lineAvator.c_str()),
342 : HCCL_E_PARA);
343 :
344 4 : return HCCL_SUCCESS;
345 : }
346 :
347 4 : void EnvRdmaConfig::LogMultiQpSrcPortConfig() const
348 : {
349 8 : for (const auto& entry : multiQpSrcPortConfig_.ipPairToPorts) {
350 4 : std::string portsStr;
351 40 : for (size_t j = 0; j < entry.second.size(); j++) {
352 36 : if (j > 0)
353 32 : portsStr += ",";
354 36 : portsStr += std::to_string(entry.second[j]);
355 : }
356 12 : HCCL_RUN_INFO("[HCCL_ENV] MultiQpSrcPort: ipPair[%s] -> ports[%s]", entry.first.c_str(), portsStr.c_str());
357 4 : }
358 4 : }
359 :
360 43 : u32 EnvRdmaConfig::GetRdmaTrafficClass() const { return rdmaTrafficClass.Get(); }
361 :
362 43 : u32 EnvRdmaConfig::GetRdmaServerLevel() const { return rdmaServerLevel.Get(); }
363 :
364 38 : u32 EnvRdmaConfig::GetRdmaTimeOut() const { return rdmaTimeOut.Get(); }
365 :
366 38 : u32 EnvRdmaConfig::GetRdmaRetryCnt() const { return rdmaRetryCnt.Get(); }
367 :
368 39 : u32 EnvRdmaConfig::GetUboeTimeOut() const { return uboeTimeOut.Get(); }
369 :
370 276 : u32 EnvRdmaConfig::GetUbTimeOut() const { return ubTimeOut.Get(); }
371 35 : u32 EnvRdmaConfig::GetRdmaQueueNum() const { return queueNum.Get(); }
372 :
373 36 : u32 EnvRdmaConfig::GetRdmaMultiQpThreshold() const { return multiQpThreshold.Get(); }
374 :
375 83 : const MultiQpSrcPortConfig& EnvRdmaConfig::GetMultiQpSrcPortConfig() const { return multiQpSrcPortConfig_; }
376 :
377 : // EnvAlgoConfig
378 :
379 17 : void EnvAlgoConfig::Parse()
380 : {
381 : // Hcomm中不再解析HCCL_ALGO配置,因为没有实际使用
382 17 : primQueueGenName.Parse();
383 29 : HCCL_RUN_INFO(
384 : "[HCCL_ENV] PRIM_QUEUE_GEN_NAME set by %s to [%s]", primQueueGenName.GetSource(),
385 : GetPrimQueueGenName().c_str());
386 :
387 17 : bufferSize.Parse();
388 29 : HCCL_RUN_INFO("[HCCL_ENV] HCCL_BUFFSIZE set by %s to [%llu]B", bufferSize.GetSource(), GetBuffSize());
389 :
390 17 : hcclAccelerator_.Parse();
391 29 : HCCL_RUN_INFO(
392 : "[HCCL_ENV] HCCL_OP_EXPANSION_MODE set by %s to [%s]", hcclAccelerator_.GetSource(),
393 : GetHcclAccelerator().Describe().c_str());
394 17 : }
395 :
396 18 : const std::string& EnvAlgoConfig::GetPrimQueueGenName() const { return primQueueGenName.Get(); }
397 :
398 2 : const std::map<OpType, std::vector<HcclAlgoType>> EnvAlgoConfig::GetAlgoConfig() const
399 : {
400 : // hcomm不支持HCCL_ALGO解析, 返回空
401 2 : return {};
402 : }
403 :
404 27 : u64 EnvAlgoConfig::GetBuffSize() const { return bufferSize.Get(); }
405 :
406 33 : HcclAccelerator EnvAlgoConfig::GetHcclAccelerator() const { return hcclAccelerator_.Get(); }
407 :
408 : // EnvLogConfig
409 16 : void EnvLogConfig::Parse()
410 : {
411 16 : entryLogEnable.Parse();
412 28 : HCCL_RUN_INFO(
413 : "[HCCL_ENV] HCCL_ENTRY_LOG_ENABLE set by %s to [%d]", entryLogEnable.GetSource(), GetEntryLogEnable());
414 :
415 16 : cannVersion.Parse();
416 28 : HCCL_RUN_INFO("[HCCL_ENV] LD_LIBRARY_PATH set by %s to [%s]", cannVersion.GetSource(), GetCannVersion().c_str());
417 :
418 16 : dfsConfig.Parse();
419 28 : HCCL_RUN_INFO(
420 : "[HCCL_ENV] HCCL_DFS_CONFIG task_exception set by %s to [%d], cluster_heartbeat set by %s to [%d], "
421 : "rankConsistentState set by %s to [%d]",
422 : dfsConfig.GetSource(), GetDfsConfig().taskExceptionEnable, dfsConfig.GetSource(),
423 : GetDfsConfig().clusterHeartBeatEnable, dfsConfig.GetSource(), GetDfsConfig().rankConsistentState);
424 16 : }
425 :
426 156 : bool EnvLogConfig::GetEntryLogEnable() const { return entryLogEnable.Get(); }
427 :
428 17 : const std::string& EnvLogConfig::GetCannVersion() const { return cannVersion.Get(); }
429 :
430 257 : const DfsConfig& EnvLogConfig::GetDfsConfig() const { return dfsConfig.Get(); }
431 :
432 : // EnvDetourConfig
433 :
434 16 : void EnvDetourConfig::Parse()
435 : {
436 16 : detourType.Parse();
437 28 : HCCL_RUN_INFO(
438 : "[HCCL_ENV] HCCL_DETOUR set by %s to [%s]", detourType.GetSource(), GetDetourType().Describe().c_str());
439 16 : }
440 :
441 261 : HcclDetourType EnvDetourConfig::GetDetourType() const { return detourType.Get(); }
442 :
443 : } // namespace Hccl
|