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 "acl/acl_platform.h"
12 :
13 : #include <cstring>
14 : #include <map>
15 : #include <string>
16 : #include <utility>
17 : #include <vector>
18 : #include <securec.h>
19 :
20 : #include "platform/platform_info.h"
21 : #include "platform/platform_infos_def.h"
22 : #include "platform_log.h"
23 :
24 : namespace {
25 25 : aclError CopyToBuffer(const std::string& src, char* dst, uint32_t max_len)
26 : {
27 25 : if (src.size() + 1U > static_cast<size_t>(max_len)) {
28 2 : PF_LOGE("Buffer too small: need %zu bytes, got %u.", src.size() + 1U, max_len);
29 2 : return ACL_ERROR_INVALID_PARAM;
30 : }
31 23 : if (memcpy_s(dst, static_cast<size_t>(max_len), src.c_str(), src.size() + 1U) != 0) {
32 0 : PF_LOGE("memcpy_s failed.");
33 0 : return ACL_ERROR_INVALID_PARAM;
34 : }
35 23 : return ACL_SUCCESS;
36 : }
37 :
38 : // Try to obtain a valid PlatFormInfos from the given manager.
39 : // Strategy 1: runtime device binding (device 0).
40 : // Strategy 2: fallback via OptionalInfos soc_version.
41 : // Returns true and fills |platform_infos| on success.
42 34 : bool TryGetPlatFormInfos(fe::PlatformInfoManager& mgr, fe::PlatFormInfos& platform_infos, std::string& source)
43 : {
44 34 : auto IsValid = [&]() -> bool {
45 34 : std::string probe;
46 170 : return platform_infos.GetPlatformResWithLock("SoCInfo", "ai_core_cnt", probe) && !probe.empty();
47 34 : };
48 :
49 34 : fe::OptionalInfos optional_infos;
50 34 : if (mgr.GetPlatformInfoWithOutSocVersion(platform_infos, optional_infos) == 0U && IsValid()) {
51 26 : source = "optional_infos";
52 26 : return true;
53 : }
54 :
55 8 : if (mgr.GetRuntimePlatformInfosByDevice(0U, platform_infos) == 0U && IsValid()) {
56 2 : source = "device_binding";
57 2 : return true;
58 : }
59 :
60 6 : return false;
61 34 : }
62 :
63 : // Query order:
64 : // 1. Instance – GetPlatformInfoWithOutSocVersion
65 : // 2. Instance – GetRuntimePlatformInfosByDevice
66 : // 3. GeInstance – GetPlatformInfoWithOutSocVersion
67 : // 4. GeInstance – GetRuntimePlatformInfosByDevice
68 30 : bool GetPlatFormInfos(fe::PlatFormInfos& platform_infos)
69 : {
70 30 : std::string source;
71 30 : const char* instance_name = nullptr;
72 :
73 30 : if (TryGetPlatFormInfos(fe::PlatformInfoManager::Instance(), platform_infos, source)) {
74 26 : instance_name = "Instance";
75 4 : } else if (TryGetPlatFormInfos(fe::PlatformInfoManager::GeInstance(), platform_infos, source)) {
76 2 : instance_name = "GeInstance";
77 : }
78 :
79 30 : if (instance_name != nullptr) {
80 28 : PF_LOGD("GetPlatFormInfos succeeded: source=%s, path=%s.", instance_name, source.c_str());
81 28 : return true;
82 : }
83 :
84 2 : PF_LOGE("Failed to obtain PlatFormInfos via Instance/GeInstance device[0] or OptionalInfos.");
85 2 : return false;
86 30 : }
87 :
88 : const std::vector<std::pair<std::string, std::string>> kDevInfoTable = {
89 : /* 0: ACL_PLATFORM_AICORE_CNT */ {"SoCInfo", "ai_core_cnt"},
90 : /* 1: ACL_PLATFORM_AICORE_UB_SIZE */ {"AICoreSpec", "ub_size"},
91 : /* 2: ACL_PLATFORM_CUBE_CORE_CNT */ {"SoCInfo", "cube_core_cnt"},
92 : /* 3: ACL_PLATFORM_VECTOR_CORE_CNT */ {"SoCInfo", "vector_core_cnt"},
93 : /* 4: ACL_PLATFORM_L2_SIZE */ {"SoCInfo", "l2_size"},
94 : /* 5: ACL_PLATFORM_MEMORY_SIZE */ {"SoCInfo", "memory_size"},
95 : /* 6: ACL_PLATFORM_CUBE_FREQ */ {"AICoreSpec", "cube_freq"},
96 : /* 7: ACL_PLATFORM_VEC_FREQ */ {"VectorCoreSpec", "vec_freq"},
97 : /* 8: ACL_PLATFORM_BT_SIZE */ {"AICoreSpec", "bt_size"},
98 : /* 9: ACL_PLATFORM_L0_A_SIZE */ {"AICoreSpec", "l0_a_size"},
99 : /* 10: ACL_PLATFORM_L0_B_SIZE */ {"AICoreSpec", "l0_b_size"},
100 : /* 11: ACL_PLATFORM_L0_C_SIZE */ {"AICoreSpec", "l0_c_size"},
101 : /* 12: ACL_PLATFORM_L1_SIZE */ {"AICoreSpec", "l1_size"},
102 : /* 13: ACL_PLATFORM_SOC_VERSION */ {"version", "SoC_version"},
103 : /* 14: ACL_PLATFORM_AIC_VERSION */ {"version", "AIC_version"},
104 : /* 15: ACL_PLATFORM_NPU_ARCH */ {"version", "NpuArch"},
105 : /* 16: ACL_PLATFORM_MEMORY_TYPE */ {"SoCInfo", "memory_type"},
106 : };
107 : } // namespace
108 :
109 26 : aclError aclplatformGetDeviceInfo(aclplatformDevInfo infoType, char* value, uint32_t maxLen)
110 : {
111 : // --- parameter validation ---
112 26 : const uint32_t info_idx = static_cast<uint32_t>(infoType);
113 26 : if (info_idx >= static_cast<uint32_t>(kDevInfoTable.size())) {
114 1 : PF_LOGE("Invalid info type %u.", info_idx);
115 1 : return ACL_ERROR_INVALID_PARAM;
116 : }
117 25 : if (value == nullptr) {
118 1 : PF_LOGE("Device info: output buffer pointer is NULL.");
119 1 : return ACL_ERROR_INVALID_PARAM;
120 : }
121 24 : if (maxLen == 0U) {
122 1 : PF_LOGE("Device info: output buffer length is 0.");
123 1 : return ACL_ERROR_INVALID_PARAM;
124 : }
125 :
126 : // --- obtain platform info ---
127 23 : fe::PlatFormInfos platform_infos;
128 23 : if (!GetPlatFormInfos(platform_infos)) {
129 2 : return ACL_ERROR_INTERNAL_ERROR;
130 : }
131 :
132 : // --- query the value ---
133 21 : const std::string& section = kDevInfoTable[info_idx].first;
134 21 : const std::string& key = kDevInfoTable[info_idx].second;
135 21 : std::string result;
136 :
137 21 : if (!platform_infos.GetPlatformResWithLock(section, key, result)) {
138 2 : PF_LOGE("Key [%s/%s] not found in platform info.", section.c_str(), key.c_str());
139 2 : return ACL_ERROR_INVALID_PARAM;
140 : }
141 19 : if (result.empty()) {
142 0 : PF_LOGE("Empty result for key [%s/%s].", section.c_str(), key.c_str());
143 0 : return ACL_ERROR_INVALID_PARAM;
144 : }
145 :
146 19 : PF_LOGI("Device info queried: [%s, %s] = %s.", section.c_str(), key.c_str(), result.c_str());
147 19 : return CopyToBuffer(result, value, maxLen);
148 23 : }
149 :
150 11 : aclError aclplatformGetInstructionInfo(aclplatformCoreType type, const char* instruction, char* value, uint32_t maxLen)
151 : {
152 : // --- parameter validation ---
153 11 : if (type != ACL_PLATFORM_CORE_TYPE_AI_CORE && type != ACL_PLATFORM_CORE_TYPE_VECTOR_CORE) {
154 1 : PF_LOGE("Invalid core type %d.", static_cast<int>(type));
155 1 : return ACL_ERROR_INVALID_PARAM;
156 : }
157 10 : if (instruction == nullptr) {
158 1 : PF_LOGE("Instruction info: instruction pointer is NULL.");
159 1 : return ACL_ERROR_INVALID_PARAM;
160 : }
161 9 : if (value == nullptr) {
162 1 : PF_LOGE("Instruction info: output buffer pointer is NULL.");
163 1 : return ACL_ERROR_INVALID_PARAM;
164 : }
165 8 : if (maxLen == 0U) {
166 1 : PF_LOGE("Instruction info: output buffer length is 0.");
167 1 : return ACL_ERROR_INVALID_PARAM;
168 : }
169 :
170 : // --- obtain platform info ---
171 7 : fe::PlatFormInfos platform_infos;
172 7 : if (!GetPlatFormInfos(platform_infos)) {
173 0 : return ACL_ERROR_INTERNAL_ERROR;
174 : }
175 :
176 : // --- query intrinsic dtype map ---
177 7 : const std::string instr_name(instruction);
178 7 : std::map<std::string, std::vector<std::string>> intrinsic_map;
179 :
180 7 : if (type == ACL_PLATFORM_CORE_TYPE_AI_CORE) {
181 5 : intrinsic_map = platform_infos.GetAICoreIntrinsicDtype();
182 : } else {
183 2 : intrinsic_map = platform_infos.GetVectorCoreIntrinsicDtype();
184 : }
185 :
186 7 : const auto it = intrinsic_map.find(instr_name);
187 7 : if (it == intrinsic_map.end() || it->second.empty()) {
188 1 : PF_LOGE("Instruction [%s] not found for core type %d.", instruction, static_cast<int>(type));
189 1 : return ACL_ERROR_INVALID_PARAM;
190 : }
191 :
192 : // --- join dtypes with "," ---
193 6 : std::string result;
194 6 : const std::vector<std::string>& dtypes = it->second;
195 28 : for (size_t i = 0U; i < dtypes.size(); ++i) {
196 22 : if (i > 0U) {
197 16 : result += ',';
198 : }
199 22 : result += dtypes[i];
200 : }
201 :
202 6 : PF_LOGI(
203 : "Instruction info queried: [%s], core[%d], result = %s.", instruction, static_cast<int>(type), result.c_str());
204 6 : return CopyToBuffer(result, value, maxLen);
205 7 : }
|