* 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.
*/
* \file platform_parser.cpp
* \brief
*/
#include "platform_parser.h"
#include "tilefwk/error_code.h"
namespace npu {
namespace tile_fwk {
const std::string platformConfigEnv = "PLATFORM_CONFIG_PATH";
const std::string version = "version";
const std::string aic = "AIC";
const std::string aiv = "AIV";
const std::string ccecAicVersion = "CCEC_AIC_version";
const std::string ccecAivVersion = "CCEC_AIV_version";
const std::string ccecCubeVersion = "CCEC_CUBE_version";
const std::string ccecVectorVersion = "CCEC_VECTOR_version";
bool PlatformParser::FilterCCECVersion(const std::string& key, std::string& coreType) const
{
const std::string prefix = "CCEC_";
const std::string suffix = "_version";
const size_t prefixLen = prefix.length();
const size_t suffixLen = suffix.length();
if (key.length() >= (prefixLen + suffixLen) && key.substr(0, prefixLen) == prefix &&
key.substr(key.length() - suffixLen) == suffix) {
coreType = key.substr(prefixLen, key.length() - prefixLen - suffixLen);
return true;
} else {
return false;
}
}
bool PlatformParser::GetSizeVal(const std::string& column, const std::string& key, size_t& val) const
{
std::string valStr;
const size_t max_size_t = std::numeric_limits<size_t>::max();
if (!GetStringVal(column, key, valStr)) {
return false;
}
val = 0UL;
constexpr int kRadix10 = 10;
constexpr int kMaxDigit10 = kRadix10 - 1;
for (const char& c : valStr) {
int digit = c - '0';
if (digit < 0 || digit > kMaxDigit10) {
return false;
}
if (val > (max_size_t - digit) / kRadix10) {
return false;
}
val = val * kRadix10 + digit;
}
return true;
}
bool PlatformParser::GetCCECVersion(std::unordered_map<std::string, std::string>& ccecVersion) const
{
const std::vector<std::string> ccecVersions = {ccecAicVersion, ccecAivVersion, ccecCubeVersion, ccecVectorVersion};
ccecVersion.clear();
std::string coreType;
std::string versionVal;
for (const auto& curVersion : ccecVersions) {
if (FilterCCECVersion(curVersion, coreType) && GetStringVal(version, curVersion, versionVal)) {
ccecVersion[coreType] = versionVal;
}
}
return !ccecVersion.empty();
}
INIParser::INIParser() { INIParserInit(""); }
INIParser::INIParser(const std::string& socVersion) { INIParserInit(socVersion); }
void INIParser::INIParserInit(const std::string& socVersion)
{
std::string srcPath;
SimulationPlatform simulationPlatform;
simulationPlatform.GetCostModelPlatformRealPath(socVersion, srcPath);
PLATFORM_LOGD("Try to initiate the ini parser.");
if (!Initialize(srcPath)) {
throw std::runtime_error("can not open simulation file: " + srcPath);
}
}
bool INIParser::Initialize(const std::string& iniFilePath)
{
PLATFORM_LOGI("Start to parse ini_file %s.", iniFilePath.c_str());
if (!ReadINIFile(iniFilePath)) {
PLATFORM_LOGE(FeError::NOT_EXIST, "ReadINIFile failed.");
return false;
}
PLATFORM_LOGD("Parse ini_file %s successfully.", iniFilePath.c_str());
return true;
}
bool INIParser::ReadINIFile(const std::string& filepath)
{
data_.clear();
std::ifstream file(filepath);
PLATFORM_LOGD("Try to open ini file: %s.", filepath.c_str());
if (!file.is_open()) {
PLATFORM_LOGE(FeError::BAD_FD, "Failed to open ini file: %s.", filepath.c_str());
return false;
}
std::string line;
std::string section;
while (std::getline(file, line)) {
TrimLine(line);
if (line.empty()) {
continue;
}
if (line.front() == '[' && line.back() == ']') {
constexpr size_t kLeftBracketLen = std::char_traits<char>::length("[");
constexpr size_t kRightBracketLen = std::char_traits<char>::length("]");
if (line.size() <= kLeftBracketLen + kRightBracketLen) {
continue;
}
section = line.substr(kLeftBracketLen, line.size() - kLeftBracketLen - kRightBracketLen);
continue;
}
size_t equalPos = line.find('=');
if (equalPos == std::string::npos) {
PLATFORM_LOGW("Illegal ini format[%s].", line.c_str());
continue;
}
std::string key = line.substr(0, equalPos);
std::string value = line.substr(equalPos + 1);
if (key.empty()) {
PLATFORM_LOGW("Empty attribute[%s].", line.c_str());
continue;
}
data_[section][key] = value;
}
file.close();
return true;
}
bool INIParser::GetStringVal(const std::string& column, const std::string& key, std::string& val) const
{
PLATFORM_LOGD("Try to obtain value from column[%s] and key[%s] throughs ini file.", column.c_str(), key.c_str());
val.clear();
auto iter = data_.find(column);
if (iter == data_.end()) {
PLATFORM_LOGE(FeError::INVALID_TYPE, "Cannot find attr '%s' from the ini file.", column.c_str());
return false;
}
auto value = iter->second;
auto iter2 = value.find(key);
if (iter2 == value.end()) {
PLATFORM_LOGE(FeError::INVALID_VAL, "Cannot find attr '%s' from the [%s] tab.", key.c_str(), column.c_str());
return false;
}
val = iter2->second;
PLATFORM_LOGD("Value[%s][%s] = %s.", column.c_str(), key.c_str(), val.c_str());
return true;
}
bool CmdParser::GetStringVal(const std::string& column, const std::string& key, std::string& val) const
{
val.clear();
if (!CannHostRuntime::Instance().GetSocSpec(column, key, val)) {
PLATFORM_LOGE(FeError::UNKNOWN, "Cannot find soc spec '%s' from the [%s] column.", key.c_str(), column.c_str());
return false;
}
return true;
}
}
}