* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* 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 FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ------------------------------------------------------------------------- */
#ifndef MSOPT_VISUALIZE_H
#define MSOPT_VISUALIZE_H
#include "json.hpp"
#include "log.h"
namespace Utility {
constexpr char const *VISUALIZE_DATA_BIN = "visualize_data.bin";
constexpr uint8_t RESERVED_VALUE = 0x5a;
enum class VisualizeBinDType : int {
DO_NOT_DISPLAY = 0,
INT = 1,
FLOAT = 2,
STRING = 3,
PERCENTAGE = 4,
JSON_STR = 5,
CUSTOM_PERCENTAGE = 100,
};
enum class VisualizeType : uint8_t {
INVALID = 0x0,
CODE = 0x1,
TRACE = 0x2,
FILE_API = 0x3,
INSTR_API = 0x4,
OP_BASIC_INFO = 0x5,
COMPUTE_LOAD_FIGURE = 0x6,
COMPUTE_LOAD_TABLE = 0x7,
STORAGE_ACCESS_HEAT_MAP = 0x8,
STORAGE_ACCESS_TABLE = 0x9,
OCCUPANCY_MAP = 0xc,
ROOF_LINE = 0xd,
CACHELINE_HEAT_MAP = 0xe,
TOP_STALL_REASON = 0xf,
END,
};
const std::map<VisualizeType, std::string> VISUALIZE_TYPE_STR = {
{VisualizeType::INVALID, "Invalid type"},
{VisualizeType::CODE, "Code"},
{VisualizeType::TRACE, "Trace"},
{VisualizeType::FILE_API, "FileApi"},
{VisualizeType::INSTR_API, "InstrApi"},
{VisualizeType::OP_BASIC_INFO, "OpBasicInfo"},
{VisualizeType::COMPUTE_LOAD_FIGURE, "ComputeLoadFigure"},
{VisualizeType::COMPUTE_LOAD_TABLE, "ComputeLoadTable"},
{VisualizeType::STORAGE_ACCESS_HEAT_MAP, "StorageAccessHeatMap"},
{VisualizeType::STORAGE_ACCESS_TABLE, "StorageAccessTable"},
{VisualizeType::OCCUPANCY_MAP, "OccupancyMap"},
{VisualizeType::ROOF_LINE, "RoofLine"},
{VisualizeType::CACHELINE_HEAT_MAP, "CacheLineHeatMap"},
{VisualizeType::TOP_STALL_REASON, "TopStallReason"},
};
struct VISUALIZE_COLOR_NAME {
static constexpr char const *GRASS_GREEN = "thread_state_runnable";
static constexpr char const *GREEN = "good";
static constexpr char const *PINK = "thread_state_iowait";
static constexpr char const *YELLOW = "thread_state_unknown";
static constexpr char const *PURPLE = "heap_dump_child_node_arrow";
static constexpr char const *BLUE = "thread_state_running";
static constexpr char const *ORANGE = "startup";
static constexpr char const *CYAN = "background_memory_dump";
static constexpr char const *RED = "rail_response";
static constexpr char const *VIVID_BLUE = "thread_state_uninterruptible";
static constexpr char const *AMETHYST_PURPLE = "head_dump_object_type";
static constexpr char const *SKY_BLUE = "cq_build_attempt_passed";
};
* Visualize class writes string to `${outputPath}/visualize_data.bin` in append mode.
* A user-defined data header is added to form a visualize_data.bin.
* use like:
* 1. Utility::VisualizeFactory::Visualize<Utility::VisualizeType::FILE_API>(outputPath, apiFileJson);
* 2. Utility::VisualizeFactory::Visualize<Utility::VisualizeType::CODE>(outputPath, fileContent, fileName);
* Data header's version control is in XXXWriter::Write(...), please explicit comment what newer version do.
* For some historical reasons, default version(reserved bytes also) were filled with 0x5A.
* */
class Visualize {
public:
template<VisualizeType type, typename... Args>
static void WriteBin(std::string outputPath, Args&&... args)
{
typename VisualizeType2Writer<type>::Writer writer(type, std::move(outputPath));
writer.WriteBin(std::forward<Args>(args)...);
}
private:
template<typename Derived>
class VisualizeWriter {
public:
VisualizeWriter(VisualizeType visualizeType, std::string outputPath)
: visualizeType_(visualizeType), outputPath_(std::move(outputPath)) {}
template<typename... Args>
inline void WriteBin(const std::string &content, Args&&... args) const
{
if (!Check(content)) {
return;
}
static_cast<const Derived*>(this)->Write(content, std::forward<Args>(args)...);
}
template<typename... Args>
inline void WriteBin(const nlohmann::json &content, Args&&... args) const
{
WriteBin(content.dump(), std::forward<Args>(args)...);
}
protected:
bool Check(const std::string &content) const
{
if (VISUALIZE_TYPE_STR.find(visualizeType_) == VISUALIZE_TYPE_STR.end()) {
LogWarn("Visualize data type is invalid %u", static_cast<uint32_t>(visualizeType_));
return false;
}
const std::string &typeStr = VISUALIZE_TYPE_STR.at(visualizeType_);
if (content.empty()) {
LogWarn("%s content for %s is empty, skip.", typeStr.c_str(), VISUALIZE_DATA_BIN);
return false;
}
if (outputPath_.empty()) {
LogWarn("%s output path for %s is empty, skip.", typeStr.c_str(), VISUALIZE_DATA_BIN);
return false;
}
return true;
}
void WriteVisualizeBin(const std::string &header, const std::string &&data) const;
VisualizeType visualizeType_;
std::string outputPath_;
};
class DefaultWriter : public VisualizeWriter<DefaultWriter> {
friend class VisualizeWriter<DefaultWriter>;
public:
DefaultWriter(VisualizeType visualizeType, std::string outputPath)
: VisualizeWriter<DefaultWriter>(visualizeType, std::move(outputPath)) {}
private:
void Write(const std::string &content) const;
};
class CodeWriter : public VisualizeWriter<CodeWriter> {
friend class VisualizeWriter<CodeWriter>;
public:
CodeWriter(VisualizeType visualizeType, std::string outputPath)
: VisualizeWriter<CodeWriter>(visualizeType, std::move(outputPath)) {}
private:
void Write(const std::string &content, const std::string &codeFile) const;
};
class InstrApiWriter : public VisualizeWriter<InstrApiWriter> {
friend class VisualizeWriter<InstrApiWriter>;
public:
InstrApiWriter(VisualizeType visualizeType, std::string outputPath)
: VisualizeWriter<InstrApiWriter>(visualizeType, std::move(outputPath)) {}
private:
void Write(const std::string &content) const;
};
template<VisualizeType type>
struct VisualizeType2Writer { using Writer = DefaultWriter; };
};
template<>
struct Visualize::VisualizeType2Writer<VisualizeType::CODE> { using Writer = CodeWriter; };
template<>
struct Visualize::VisualizeType2Writer<VisualizeType::INSTR_API> { using Writer = InstrApiWriter; };
}
#endif