Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 "plf_debug_config.h"
12 : #include "log.h"
13 : #include <sstream>
14 : #include <atomic>
15 : #include <mutex>
16 :
17 : namespace Hccl {
18 :
19 : static std::atomic<u64> g_plfDebugConfig{0};
20 : static std::once_flag g_parseOnce;
21 :
22 14 : static u64 ParseDebugConfig(const char* envName, u64 domainMask)
23 : {
24 14 : char* env = getenv(envName);
25 14 : if (env == nullptr) {
26 7 : return 0;
27 : }
28 7 : std::string configDup(env);
29 :
30 7 : bool invert = (!configDup.empty() && configDup.front() == '^');
31 : // 第一个字符是'^', 使用取反模式,用户配置的项关闭,未配置的项打开
32 7 : u64 result = invert ? domainMask : 0ULL;
33 7 : if (invert) {
34 1 : configDup.erase(configDup.begin()); // 去掉'^'符号
35 : }
36 :
37 7 : std::istringstream stream(configDup);
38 7 : std::string subConfig;
39 13 : while (std::getline(stream, subConfig, ',')) {
40 7 : if (subConfig.empty()) {
41 0 : continue;
42 : }
43 7 : u64 mask = 0;
44 7 : if (((domainMask & PLF_TASK) != 0) && strcasecmp(subConfig.c_str(), "TASK") == 0) {
45 4 : mask = PLF_TASK;
46 3 : } else if (((domainMask & PLF_ALG) != 0) && strcasecmp(subConfig.c_str(), "ALG") == 0) {
47 0 : mask = PLF_ALG;
48 3 : } else if (((domainMask & PLF_RES) != 0) && strcasecmp(subConfig.c_str(), "RESOURCE") == 0) {
49 0 : mask = PLF_RES;
50 3 : } else if (((domainMask & PLF_DATA_OP) != 0) && strcasecmp(subConfig.c_str(), "DATA_OP") == 0) {
51 2 : mask = PLF_DATA_OP;
52 : } else {
53 3 : HCCL_ERROR("%s:%s subConfig:%s is not supported", envName, env, subConfig.c_str());
54 1 : return 0;
55 : }
56 6 : result = invert ? (result & ~mask) : (result | mask);
57 : }
58 18 : HCCL_RUN_INFO("[HCCL_ENV] %s set by [%s] to [0x%llx]", envName, env, result);
59 6 : return result;
60 7 : }
61 :
62 7 : void EnvPlfDebugConfig::Parse()
63 : {
64 7 : plfDebugConfig_ = ParseDebugConfig("HCCL_DEBUG_CONFIG", PLF_TASK | PLF_ALG | PLF_RES);
65 7 : plfDebugConfig_ |= ParseDebugConfig("HCOMM_DEBUG_CONFIG", PLF_TASK | PLF_DATA_OP);
66 21 : HCCL_RUN_INFO("[HCCL_ENV] plfDebugConfig set to [0x%llx]", plfDebugConfig_);
67 7 : }
68 :
69 7 : u64 EnvPlfDebugConfig::GetConfigValue() const { return plfDebugConfig_; }
70 :
71 5381 : u64 GetPlfDebugConfigValue()
72 : {
73 5381 : std::call_once(g_parseOnce, []() {
74 10 : EnvPlfDebugConfig cfg;
75 10 : cfg.Parse();
76 10 : g_plfDebugConfig.store(cfg.GetConfigValue(), std::memory_order_relaxed);
77 10 : });
78 5381 : return g_plfDebugConfig.load(std::memory_order_relaxed);
79 : }
80 :
81 72 : void SetPlfDebugConfigValue(u64 value) { g_plfDebugConfig.store(value, std::memory_order_relaxed); }
82 :
83 : } // namespace Hccl
|