/**
* 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.
*/
#ifndef AIR_INC_COMMON_UTIL_H_
#define AIR_INC_COMMON_UTIL_H_
#include <cmath>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "graph/types.h"
#include "register/register.h"
#include "common/ge_common/debug/ge_log.h"
#include "common/ge_common/scope_guard.h"
#include "common/ge_common/string_util.h"
#include "common/ge_common/ge_inner_error_codes.h"
#include "acl/acl_rt.h"
using AddrGetter = std::function<const void*(size_t)>;
#define GE_CHECK_POSITIVE_SIZE_RANGE(size) \
do { \
if ((size) <= 0) { \
GELOGE(ge::FAILED, "param[%s] is not a positive number", #size); \
return PARAM_INVALID; \
} \
} while (false)
#define CHECK_FALSE_EXEC(expr, exec_expr, ...) \
{ \
const bool b = (expr); \
if (!b) { \
exec_expr; \
} \
}
// new ge marco
// Encapsulate common resource releases
#define GE_MAKE_GUARD_RTMEM(var) \
GE_MAKE_GUARD(var, [&var]() { \
if ((var) != nullptr) { \
GE_CHK_RT(aclrtFreeHost(var)); \
} \
})
#define GE_MAKE_GUARD_RTSTREAM(var) \
GE_MAKE_GUARD(var, [&var]() { \
if ((var) != nullptr) { \
GE_CHK_RT(rtStreamDestroy(var)); \
} \
})
#define GE_MAKE_GUARD_ACLRTSTREAM(var) \
GE_MAKE_GUARD(var, [&var]() { \
if ((var) != nullptr) { \
GE_CHK_RT(aclrtDestroyStream(var)); \
} \
})
// For propagating errors when calling a function.
#define GE_RETURN_IF_ERROR(expr) \
do { \
const ge::Status _chk_status = (expr); \
if (_chk_status != ge::SUCCESS) { \
return _chk_status; \
} \
} while (false)
#define GE_RETURN_WITH_LOG_IF_ERROR(expr, ...) \
do { \
const ge::Status _chk_status = (expr); \
if (_chk_status != ge::SUCCESS) { \
GELOGE(ge::FAILED, __VA_ARGS__); \
return _chk_status; \
} \
} while (false)
// check whether the parameter is true. If it is, return FAILED and record the error log
#define GE_RETURN_WITH_LOG_IF_TRUE(condition, ...) \
do { \
if (condition) { \
GELOGE(ge::FAILED, __VA_ARGS__); \
return ge::FAILED; \
} \
} while (false)
// Check if the parameter is false. If yes, return FAILED and record the error log
#define GE_RETURN_WITH_LOG_IF_FALSE(condition, ...) \
do { \
const bool _condition = (condition); \
if (!_condition) { \
GELOGE(ge::FAILED, __VA_ARGS__); \
return ge::FAILED; \
} \
} while (false)
// Checks whether the parameter is true. If so, returns PARAM_INVALID and records the error log
#define GE_RT_PARAM_INVALID_WITH_LOG_IF_TRUE(condition, ...) \
do { \
if (condition) { \
GELOGE(ge::FAILED, __VA_ARGS__); \
return ge::PARAM_INVALID; \
} \
} while (false)
// Check if the parameter is false. If yes, return PARAM_INVALID and record the error log
#define GE_RT_PARAM_INVALID_WITH_LOG_IF_FALSE(condition, ...) \
do { \
const bool _condition = (condition); \
if (!_condition) { \
GELOGE(ge::FAILED, __VA_ARGS__); \
return ge::PARAM_INVALID; \
} \
} while (false)
// Check if the parameter is null. If yes, return PARAM_INVALID and record the error
#define GE_CHECK_NOTNULL(val, ...) \
do { \
if ((val) == nullptr) { \
REPORT_INNER_ERR_MSG("E19999", "Param:" #val " is nullptr, check invalid" __VA_ARGS__); \
GELOGE(ge::FAILED, "[Check][Param:" #val "]null is invalid" __VA_ARGS__); \
return ge::PARAM_INVALID; \
} \
} while (false)
// Check if the parameter is null. If yes, just return and record the error
#define GE_CHECK_NOTNULL_JUST_RETURN(val) \
do { \
if ((val) == nullptr) { \
GELOGE(ge::FAILED, "param[%s] must not be null.", #val); \
return; \
} \
} while (false)
// Check whether the parameter is null. If so, execute the exec_expr expression and record the error log
#define GE_CHECK_NOTNULL_EXEC(val, exec_expr) \
do { \
if ((val) == nullptr) { \
GELOGE(ge::FAILED, "param[%s] must not be null.", #val); \
exec_expr; \
} \
} while (false)
// Check whether the parameter is null. If yes, return directly and record the error log
#define GE_RT_VOID_CHECK_NOTNULL(val) \
do { \
if ((val) == nullptr) { \
GELOGE(ge::FAILED, "param[%s] must not be null.", #val); \
return; \
} \
} while (false)
// Check if the parameter is null. If yes, return false and record the error log
#define GE_RT_FALSE_CHECK_NOTNULL(val) \
do { \
if ((val) == nullptr) { \
GELOGE(ge::FAILED, "param[%s] must not be null.", #val); \
return false; \
} \
} while (false)
// Check if the parameter is out of bounds
#define GE_CHECK_SIZE(size) \
do { \
if ((size) == 0U) { \
GELOGE(ge::FAILED, "param[%s] is out of range", #size); \
return ge::PARAM_INVALID; \
} \
} while (false)
// Check if the value on the left is greater than or equal to the value on the right
#define GE_CHECK_GE(lhs, rhs) \
do { \
if ((lhs) < (rhs)) { \
GELOGE(ge::FAILED, "param[%s][%ld] is less than[%s][%ld]", \
#lhs, static_cast<int64_t>(lhs), #rhs, static_cast<int64_t>(rhs)); \
return ge::PARAM_INVALID; \
} \
} while (false)
// Check if the value on the left is less than or equal to the value on the right
#define GE_CHECK_LE(lhs, rhs) \
do { \
if ((lhs) > (rhs)) { \
GELOGE(ge::FAILED, "param[%s][%ld] is greater than[%s][%ld]", \
#lhs, static_cast<int64_t>(lhs), #rhs, static_cast<int64_t>(rhs)); \
return ge::PARAM_INVALID; \
} \
} while (false)
#define GE_DELETE_NEW_SINGLE(var) \
do { \
if ((var) != nullptr) { \
delete (var); \
(var) = nullptr; \
} \
} while (false)
#define GE_DELETE_NEW_ARRAY(var) \
do { \
if ((var) != nullptr) { \
delete[] (var); \
(var) = nullptr; \
} \
} while (false)
#define GE_FREE_RT_LOG(addr) \
do { \
if ((addr) != nullptr) { \
const aclError error = aclrtFree(addr); \
if (error != ACL_SUCCESS) { \
GELOGE(ge::RT_FAILED, "Call aclrtFree failed, error: %#x", error); \
} \
(addr) = nullptr; \
} \
} while (false)
namespace ge {
/**
* @ingroup domi_common
* @brief version of om.proto file
*/
constexpr int32_t OM_PROTO_VERSION = 2;
/// @ingroup domi_common
/// @brief onverts Vector of a number to a string.
/// @param [in] v Vector of a number
/// @return string
template <typename T>
GE_FUNC_VISIBILITY std::string ToString(const std::vector<T> &v) {
bool first = true;
std::stringstream ss;
ss << "[";
for (const T &x : v) {
if (first) {
first = false;
ss << x;
} else {
ss << ", " << x;
}
}
ss << "]";
return ss.str();
}
/// @ingroup: domi_common
/// @brief: get length of file
/// @param [in] input_file: path of file
/// @return int64_t: File length. If the file length fails to be obtained, the value -1 is returned.
GE_FUNC_VISIBILITY extern int64_t GetFileLength(const std::string &input_file);
/// @ingroup domi_common
/// @brief Reads all data from a binary file.
/// @param [in] file_name path of file
/// @param [out] buffer Output memory address, which needs to be released by the caller.
/// @param [out] length Output memory size
/// @return false fail
/// @return true success
GE_FUNC_VISIBILITY bool ReadBytesFromBinaryFile(const char_t *const file_name, char_t **const buffer, int32_t &length);
///@ingroup domi_common
/// @brief Get binary file from file
/// @param [in] path file path.
/// @param [out] buffer char[] used to store file data
/// @param [out] data_len store read size
/// @return graphStatus GRAPH_SUCCESS: success, OTHERS: fail
GE_FUNC_VISIBILITY graphStatus GetBinFromFile(const std::string &path, char_t *buffer, size_t &data_len);
/// @ingroup domi_common
/// @brief Recursively Creating a Directory
/// @param [in] directory_path Path, which can be a multi-level directory.
/// @return 0 success
/// @return -1 fail
GE_FUNC_VISIBILITY extern int32_t CreateDirectory(const std::string &directory_path);
/// @ingroup domi_common
/// @brief Obtains the current time string.
/// @return Time character string in the format : %Y%m%d%H%M%S, eg: 20171011083555
GE_FUNC_VISIBILITY std::string CurrentTimeInStr();
/// @ingroup domi_common
/// @brief Obtains the absolute time (timestamp) of the current system.
/// @return Timestamp, in microseconds (US)
GE_FUNC_VISIBILITY uint64_t GetCurrentTimestamp();
/// @ingroup domi_common
/// @brief Obtains the absolute time (timestamp) of the current system.
/// @return Timestamp, in seconds (US)
GE_FUNC_VISIBILITY uint32_t GetCurrentSecondTimestap();
/// @ingroup domi_common
/// @brief Absolute path for obtaining files.
/// @param [in] path of input file
/// @param [out] Absolute path of a file. If the absolute path cannot be obtained, an empty string is returned
GE_FUNC_VISIBILITY std::string RealPath(const char_t *path);
/// @ingroup domi_common
/// @brief Check whether the specified input file path is valid.
/// 1. The specified path cannot be empty.
/// 2. The path can be converted to an absolute path.
/// 3. The file path exists and is readable.
/// @param [in] file_path path of input file
/// @param [out] result
GE_FUNC_VISIBILITY bool CheckInputPathValid(const std::string &file_path, const std::string &atc_param = "");
/// @ingroup domi_common
/// @brief Checks whether the specified output file path is valid.
/// @param [in] file_path path of output file
/// @param [out] result
GE_FUNC_VISIBILITY bool CheckOutputPathValid(const std::string &file_path, const std::string &atc_param = "");
/// @ingroup domi_common
/// @brief Check whether the file path meets the whitelist verification requirements.
/// @param [in] str file path
/// @param [out] result
GE_FUNC_VISIBILITY bool ValidateStr(const std::string &file_path, const std::string &mode);
GE_FUNC_VISIBILITY Status ConvertToInt32(const std::string &str, int32_t &val);
inline std::string FormatErrnoReason(const int32_t error_num, const char_t *err_msg) {
std::string reason = "[Errno " + std::to_string(error_num) + "]";
if ((err_msg != nullptr) && (err_msg[0] != '\0')) {
reason += " ";
reason += err_msg;
}
return reason;
}
GE_FUNC_VISIBILITY std::string GetErrorNumStr(const int32_t errorNum);
GE_FUNC_VISIBILITY void SplitStringByComma(const std::string &str, std::vector<std::string> &sub_str_vec);
/// @ingroup domi_common
/// @brief Parse output reuse input memory indexes from config string
/// @param [in] reuse_indexes_str Config string, format: "input_idx,output_idx|input_idx,output_idx|..." e.g., "1,1|2,3"
/// @param [out] io_same_addr_pairs Parsed pairs list (input_idx, output_idx)
GE_FUNC_VISIBILITY void ParseOutputReuseInputMemIndexes(const std::string &reuse_indexes_str,
std::vector<std::pair<size_t, size_t>> &io_same_addr_pairs);
/// @ingroup domi_common
/// @brief Check IO reuse address pairs
/// @param [in] io_same_addr_pairs Pairs list (input_idx, output_idx)
/// @param [in] get_input_addr Callback function to retrieve input address by index
/// @param [in] input_num Number of inputs
/// @param [in] get_output_addr Callback function to retrieve output address by index
/// @param [in] output_num Number of outputs
/// @return SUCCESS if all addresses match, FAILED otherwise
GE_FUNC_VISIBILITY Status CheckIoReuseAddrPairs(const std::vector<std::pair<size_t, size_t>> &io_same_addr_pairs,
const AddrGetter& get_input_addr, size_t input_num,
const AddrGetter& get_output_addr, size_t output_num);
/**
* @ingroup domi_common
* @brief brief Print options map with line length limitation
* @param [in] options The options map to print
* @param [in] prefix Log prefix (e.g., "GE option")
* @param [in] max_line_length max_line_length Maximum line length, values longer than this will be split
*/
void PrintOptionsWithLengthLimit(const std::map<std::string, std::string> &options,
const std::string &prefix,
const size_t max_line_length = 800U);
/**
* @ingroup domi_common
* @brief brief Print options map with line length limitation
* @param [in] options The options map to print
* @param [in] prefix Log prefix (e.g., "GE option")
* @param [in] max_line_length max_line_length Maximum line length, values longer than this will be split
*/
void PrintOptionsWithLengthLimit(const std::map<AscendString, AscendString> &options,
const std::string &prefix,
const size_t max_line_length = 800U);
} // namespace ge
#endif // AIR_INC_COMMON_UTIL_H_