* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "common/platform_context.h"
#include "runtime/base.h"
#include "common/checker.h"
#include "runtime/dev.h"
namespace {
const uint32_t kSocStrMaxLen = 32U;
const uint32_t kMaxValueLen = 16U;
const char *kSocInfo = "SoCInfo";
const char *kAICoreSpec = "AICoreSpec";
const char *kVectorCoreCnt = "vector_core_cnt";
const char *kUbSize = "ub_size";
bool ParseInt64(const char *value, const char *key_name, int64_t &result) {
try {
std::string str_value(value);
result = static_cast<int64_t>(std::stoll(str_value));
} catch (...) {
GE_LOGE("ParseInt64 failed: invalid value '%s' for %s", value, key_name);
return false;
}
return true;
}
}
namespace ge {
PlatformContext &PlatformContext::GetInstance() {
static PlatformContext instance;
return instance;
}
std::mutex PlatformContext::mutex_;
void PlatformContext::SetPlatform(const std::string &platform_name) {
std::lock_guard<std::mutex> lg(mutex_);
if (!platform_name.empty()) {
platform_info_.soc_ver = platform_name;
initialized_ = true;
GELOGI("Set platform: soc_ver=%s", platform_info_.soc_ver.c_str());
}
}
void PlatformContext::SetPlatformInfo(const PlatformInfo &platform_info) {
std::lock_guard<std::mutex> lg(mutex_);
if (!platform_info.soc_ver.empty()) {
platform_info_ = platform_info;
initialized_ = true;
GELOGI("Set platform info: soc_ver=%s, aiv_num=%lld, ub_size=%lld",
platform_info_.soc_ver.c_str(), platform_info_.aiv_num, platform_info_.ub_size);
}
}
ge::Status PlatformContext::GetCurrentPlatformString(std::string &platform_name) {
if (!initialized_) {
GE_ASSERT_SUCCESS(Initialize(), "Failed to init platform info with name %s.", platform_name.c_str());
}
std::lock_guard<std::mutex> lg(mutex_);
platform_name = platform_info_.soc_ver;
return ge::SUCCESS;
}
ge::Status PlatformContext::Initialize() {
std::lock_guard<std::mutex> lg(mutex_);
if (initialized_) {
return ge::SUCCESS;
}
char soc_version[kSocStrMaxLen] = {};
auto res = rtGetSocSpec("version", "NpuArch", soc_version, kSocStrMaxLen);
GE_ASSERT_TRUE(res == RT_ERROR_NONE, "Failed to get npu arch str.");
platform_info_.soc_ver = std::string(soc_version);
GE_ASSERT_SUCCESS(InitPlatformInfo(), "Failed to init platform info.");
return ge::SUCCESS;
}
ge::Status PlatformContext::InitPlatformInfo() {
char aiv_num_str[kMaxValueLen] = {};
auto res = rtGetSocSpec(kSocInfo, kVectorCoreCnt, aiv_num_str, kMaxValueLen);
GE_ASSERT_TRUE(res == RT_ERROR_NONE, "Failed to get vector_core_cnt.");
GE_ASSERT_TRUE(ParseInt64(aiv_num_str, "vector_core_cnt", platform_info_.aiv_num),
"Failed to parse vector_core_cnt.");
char ub_size_str[kMaxValueLen] = {};
res = rtGetSocSpec(kAICoreSpec, kUbSize, ub_size_str, kMaxValueLen);
GE_ASSERT_TRUE(res == RT_ERROR_NONE, "Failed to get ub_size.");
GE_ASSERT_TRUE(ParseInt64(ub_size_str, "ub_size", platform_info_.ub_size),
"Failed to parse ub_size.");
initialized_ = true;
GELOGI("Platform info: soc_ver=%s, aiv_num=%lld, ub_size=%lld",
platform_info_.soc_ver.c_str(), platform_info_.aiv_num, platform_info_.ub_size);
return ge::SUCCESS;
}
ge::Status PlatformContext::GetPlatformInfo(PlatformInfo &platform_info) {
if (!initialized_) {
GE_ASSERT_SUCCESS(Initialize(), "Failed to init platform info.");
}
std::lock_guard<std::mutex> lg(mutex_);
platform_info = platform_info_;
GELOGD("GetPlatformInfo: soc_ver=%s, aiv_num=%lld, ub_size=%lld", platform_info_.soc_ver.c_str(),
platform_info_.aiv_num, platform_info_.ub_size);
return ge::SUCCESS;
}
}