* 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 sk_common.h
* \brief
*/
#ifndef SK_COMMON_H
#define SK_COMMON_H
#include <string>
#include <cstddef>
#include <bitset>
#include <cstdint>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
typedef void* aclmdlRI;
enum class SkNodeType : uint32_t {
NODE_KERNEL = 0,
NODE_NOTIFY = 1,
NODE_WAIT = 2,
NODE_RESET = 3,
NODE_MEMORY_WRITE = 4,
NODE_MEMORY_WAIT = 5,
NODE_DEFAULT = 6,
};
inline const char* to_string(SkNodeType type)
{
switch (type) {
case SkNodeType::NODE_KERNEL:
return "KERNEL";
case SkNodeType::NODE_NOTIFY:
return "NOTIFY";
case SkNodeType::NODE_WAIT:
return "WAIT";
case SkNodeType::NODE_RESET:
return "RESET";
case SkNodeType::NODE_MEMORY_WRITE:
return "MEMORY_WRITE";
case SkNodeType::NODE_MEMORY_WAIT:
return "MEMORY_WAIT";
case SkNodeType::NODE_DEFAULT:
return "DEFAULT";
default:
return "UNKNOWN";
}
}
enum class SkKernelType : uint8_t {
AIC_ONLY = 1,
AIV_ONLY = 2,
MIX_AIV_1_0 = 3,
MIX_AIC_1_0 = 4,
MIX_AIC_1_1 = 5,
MIX_AIC_1_2 = 6,
DEFAULT = 0xFF,
};
constexpr size_t SK_KERNEL_TYPE_COUNT = 6;
inline const char* to_string(SkKernelType type)
{
switch (type) {
case SkKernelType::AIC_ONLY:
return "AIC_ONLY";
case SkKernelType::AIV_ONLY:
return "AIV_ONLY";
case SkKernelType::MIX_AIV_1_0:
return "MIX_AIV_1_0";
case SkKernelType::MIX_AIC_1_0:
return "MIX_AIC_1_0";
case SkKernelType::MIX_AIC_1_1:
return "MIX_1_1";
case SkKernelType::MIX_AIC_1_2:
return "MIX_1_2";
case SkKernelType::DEFAULT:
return "DEFAULT";
default:
return "UNKNOWN";
}
}
enum class SkTaskType : uint8_t {
TYPE_FUNC,
TYPE_SYNC,
TYPE_PRELOAD,
TYPE_EVENT_NOTIFY,
TYPE_EVENT_WAIT,
TYPE_EVENT_RESET,
TYPE_MAX,
};
enum class SkOpTraceType : uint8_t {
ORIGIN = 0,
SK_ENTRY_LAUNCHED,
OP_LAUNCHED,
OP_FINISHED,
SK_ENTRY_FINISHED,
};
inline const char* to_string(SkTaskType type)
{
switch (type) {
case SkTaskType::TYPE_FUNC:
return "FUNC";
case SkTaskType::TYPE_SYNC:
return "SYNC";
case SkTaskType::TYPE_PRELOAD:
return "PRELOAD";
case SkTaskType::TYPE_EVENT_NOTIFY:
return "EVENT_NOTIFY";
case SkTaskType::TYPE_EVENT_WAIT:
return "EVENT_WAIT";
case SkTaskType::TYPE_EVENT_RESET:
return "EVENT_RESET";
default:
return "UNKNOWN";
}
}
enum class SkCoreSyncType : uint8_t {
ALL_SYNC = 0,
CROSS_SYNC_AIC_TO_AIC,
CROSS_SYNC_AIV_TO_AIV,
INTER_SYNC_SET_AIC_TO_AIV,
INTER_SYNC_SET_AIV_TO_AIC,
INTER_SYNC_WAIT_AIC_TO_AIV,
INTER_SYNC_WAIT_AIV_TO_AIC,
SYNC_NONE,
};
inline const char* to_string(SkCoreSyncType type)
{
switch (type) {
case SkCoreSyncType::ALL_SYNC:
return "ALL_SYNC";
case SkCoreSyncType::CROSS_SYNC_AIC_TO_AIC:
return "AIC_TO_AIC";
case SkCoreSyncType::CROSS_SYNC_AIV_TO_AIV:
return "AIV_TO_AIV";
case SkCoreSyncType::INTER_SYNC_SET_AIC_TO_AIV:
return "SET_AIC_TO_AIV";
case SkCoreSyncType::INTER_SYNC_SET_AIV_TO_AIC:
return "SET_AIV_TO_AIC";
case SkCoreSyncType::INTER_SYNC_WAIT_AIC_TO_AIV:
return "WAIT_AIC_TO_AIV";
case SkCoreSyncType::INTER_SYNC_WAIT_AIV_TO_AIC:
return "WAIT_AIV_TO_AIC";
case SkCoreSyncType::SYNC_NONE:
return "SYNC_NONE";
default:
return "UNKNOWN";
}
}
enum class SkMemoryWaitFlag : uint32_t {
GEQ = 0x0,
EQ = 0x1,
AND = 0x2,
NOR = 0x3,
};
inline const char* to_string(SkMemoryWaitFlag flag)
{
switch (flag) {
case SkMemoryWaitFlag::GEQ:
return "GEQ";
case SkMemoryWaitFlag::EQ:
return "EQ";
case SkMemoryWaitFlag::AND:
return "AND";
case SkMemoryWaitFlag::NOR:
return "NOR";
default:
return "UNKNOWN";
}
}
constexpr uint64_t SK_DEFAULT_NOTIFY_VALUE = 1;
constexpr uint64_t SK_DEFAULT_WAIT_VALUE = 1;
constexpr uint64_t SK_DEFAULT_RESET_VALUE = 0;
constexpr uint32_t SK_DEFAULT_WRITE_FLAG = 0;
struct TaskInfo {
uint32_t index;
SkTaskType type;
SkKernelType originType = SkKernelType::DEFAULT;
uint8_t numBlocks;
uint8_t entryCnt;
uint64_t args;
uint64_t entry[4];
uint64_t debugOptions;
uint64_t reserved;
};
inline void SetEventTaskArgs(TaskInfo& taskInfo, uint64_t addr, uint64_t value, uint32_t flag)
{
taskInfo.args = addr;
taskInfo.entry[0] = value;
taskInfo.reserved = static_cast<uint64_t>(flag);
}
inline uint64_t GetEventTaskAddr(const TaskInfo& taskInfo)
{
return taskInfo.args;
}
inline uint64_t GetEventTaskValue(const TaskInfo& taskInfo)
{
return taskInfo.entry[0];
}
inline uint32_t GetEventTaskFlag(const TaskInfo& taskInfo)
{
return static_cast<uint32_t>(taskInfo.reserved);
}
struct TaskQue {
uint32_t taskCnt;
uint32_t cap;
TaskInfo taskInfos[0];
};
struct SkHeaderInfo {
uint32_t aicQueSize;
uint32_t aivQueSize;
uint32_t aicQueOffset;
uint32_t aivQueOffset;
uint32_t counterOffset;
uint32_t dfxOffset;
uint32_t eventConfigOffset;
uint32_t nodeCnt;
uint64_t modelRIIdAndSkScopeId;
uint64_t totalSize;
};
struct SkCounterInfo {
uint32_t index;
uint8_t launch;
uint8_t exit;
uint8_t reserve[58];
};
struct SkDfxInfo {
uint64_t binHdl;
uint64_t funcHdlOri;
uint32_t aicSize;
uint32_t aivSize;
uint64_t entryAic[4];
uint64_t entryAiv[4];
uint32_t numBlocks;
uint32_t cubeNum;
uint32_t vecNum;
uint32_t reserved;
};
struct SkDeviceEntryArgs {
SkHeaderInfo skHeader;
uint8_t data[0];
};
struct SkKernelEventRecord {
uint64_t modelRI;
uint32_t skId;
uint32_t nodeId;
uint8_t blockIdx;
uint8_t blockNum;
uint64_t startTime;
uint64_t endTime;
};
struct SkKernelEventCoreBuf {
uint32_t offset;
uint32_t reserved;
};
struct SkEventConfig {
uint64_t eventGmAddr;
uint64_t modelRI;
uint32_t skId;
uint8_t enabled;
uint32_t coreSize;
};
bool GetFuncSymbolInfo(const char* binAddr, size_t binSize, uint64_t funcAddr, std::string& symbolName,
uint64_t& funcSize, std::string& symbolBind);
enum class ScheModeState : uint8_t {
SCHE_MODE_OFF = 0,
SCHE_MODE_ON = 1,
NONE = 0xff,
};
* @brief Convert aclmdlRI (void*) to string for logging
* @param model Model RI pointer
* @return String representation: "model_{address}"
*
* @example
* aclmdlRI model = (aclmdlRI)0x12345678;
* std::string modelStr = ModelRIToString(model);
* // Returns: "model_305419896"
*/
inline std::string ModelRIToString(aclmdlRI model) {
if (model == nullptr) {
return "model_nullptr";
}
return "model_" + std::to_string(reinterpret_cast<uintptr_t>(model));
}
* @brief Sanitize path component by replacing invalid characters
* @param component Path component to sanitize
* @return Sanitized string safe for use as directory name
*/
inline std::string SanitizePathComponent(const std::string& component) {
std::string result = component;
for (char& c : result) {
if (c == '/' || c == '\\' || c == ':' || c == '*' ||
c == '?' || c == '"' || c == '<' || c == '>' || c == '|') {
c = '_';
}
}
return result;
}
* @brief Get sk_meta base directory path (sk_meta/{pid})
* @return sk_meta/{pid} path string
*
* This is the unified path generation function for sk_meta directory structure.
* If the path structure needs to change in the future, only modify this function.
*/
inline std::string GetSkMetaBasePath() {
pid_t pid = getpid();
return "sk_meta/" + std::to_string(pid);
}
* @brief Get full sk_meta directory path (sk_meta/{pid}/{modelRI})
* @param model Model RI pointer (will be converted to string internally)
* @return Full path string
*
* This is the unified path generation function for sk_meta directory structure.
* If the path structure needs to change in the future, only modify this function.
*
* @example
* aclmdlRI model = (aclmdlRI)0x12345678;
* std::string path = GetSkMetaPath(model);
* // Returns: "sk_meta/{pid}/model_305419896"
*
* std::string path = GetSkMetaPath(nullptr);
* // Returns: "sk_meta/{pid}/model_nullptr"
*/
inline std::string GetSkMetaPath(aclmdlRI model) {
std::string basePath = GetSkMetaBasePath();
std::string modelStr = ModelRIToString(model);
return basePath + "/" + SanitizePathComponent(modelStr);
}
* @brief Create directory with full path (recursively create parent directories)
* @param path Full directory path to create
* @return true if directory exists or created successfully, false otherwise
*/
inline bool CreateDirectoryRecursive(const std::string& path) {
if (path.empty()) {
return false;
}
size_t pos = 0;
do {
pos = path.find('/', pos + 1);
std::string subPath = path.substr(0, pos);
if (subPath.empty()) {
continue;
}
struct stat st;
if (stat(subPath.c_str(), &st) != 0) {
if (mkdir(subPath.c_str(), 0755) != 0 && errno != EEXIST) {
return false;
}
}
} while (pos != std::string::npos && pos < path.size());
return true;
}
* @brief Create sk_meta directory structure: sk_meta/{pid}/{modelRI}
* @param model Model RI pointer (will be converted to string internally)
* @return Full path of created directory, empty string on failure
*
* This function creates the directory structure using the unified path generator:
* - sk_meta/{pid} (always created)
* - sk_meta/{pid}/{modelRI} (created based on model pointer)
*
* @example
* aclmdlRI model = (aclmdlRI)0x12345678;
* std::string path = CreateSkMetaDirectory(model);
* // Creates: sk_meta/{pid}/model_305419896
* // Returns: "sk_meta/{pid}/model_305419896"
*
* std::string path = CreateSkMetaDirectory(nullptr);
* // Creates: sk_meta/{pid}/model_nullptr
* // Returns: "sk_meta/{pid}/model_nullptr"
*/
inline std::string CreateSkMetaDirectory(aclmdlRI model) {
std::string dirPath = GetSkMetaPath(model);
if (!CreateDirectoryRecursive(dirPath)) {
return "";
}
return dirPath;
}
namespace sk {
ASCENDC_SUPER_KERNEL_EARLY_START_AIC_TO_AIC : 0b00;
ASCENDC_SUPER_KERNEL_EARLY_START_AIC_TO_AIV : 0b01;
ASCENDC_SUPER_KERNEL_EARLY_START_AIC_TO_MIX : 0b10;
ASCENDC_SUPER_KERNEL_EARLY_START_AIV_TO_AIC : 0b0100;
ASCENDC_SUPER_KERNEL_EARLY_START_AIV_TO_AIV : 0b0101;
ASCENDC_SUPER_KERNEL_EARLY_START_AIV_TO_MIX : 0b0110;
ASCENDC_SUPER_KERNEL_EARLY_START_MIX_TO_AIC : 0b1000;
ASCENDC_SUPER_KERNEL_EARLY_START_MIX_TO_AIV : 0b1001;
ASCENDC_SUPER_KERNEL_EARLY_START_MIX_TO_MIX : 0b1010;
*/
constexpr uint16_t SYNC_COMBINATION_TABLE[SK_KERNEL_TYPE_COUNT][SK_KERNEL_TYPE_COUNT] = {
{ 0b00, 0b01, 0b10, 0b10, 0b10, 0b10 },
{ 0b0100, 0b0101, 0b0110, 0b0110, 0b0110, 0b0110 },
{ 0b1000, 0b1001, 0b1010, 0b1010, 0b1010, 0b1010 },
{ 0b1000, 0b1001, 0b1010, 0b1010, 0b1010, 0b1010 },
{ 0b1000, 0b1001, 0b1010, 0b1010, 0b1010, 0b1010 },
{ 0b1000, 0b1001, 0b1010, 0b1010, 0b1010, 0b1010 },
};
constexpr uint16_t INVALID_SYNC_COMBINATION = 0xFFFF;
}
#endif