/**
* Copyright (c) 2026 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 TSD_BASIC_COMPONENT_MESSAGE_BUILDER_HDC_MESSAGE_BUILDER_H
#define TSD_BASIC_COMPONENT_MESSAGE_BUILDER_HDC_MESSAGE_BUILDER_H
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "driver/ascend_hal_base.h" // process_sign
#include "proto/tsd_message.pb.h"
#include "tsd/status.h"
#include "tsd/tsd_client.h" // SchedMode
namespace tsd {
// Pure value-type snapshot of the inputs required to assemble an HDC message.
// Constructed at the call site (e.g. inside ProcessModeManager::Construct*Msg)
// and consumed in the same call frame; no references, no lifetime coupling.
// This struct is the single migration anchor for moving HDC message assembly
// out of ProcessModeManager. Every field a message type may need is pre-embedded
// here so that:
// 1. ProcessModeManager fills the common, manager-derived fields exactly once
// (see ProcessModeManager::BuildBaseMessageContext), avoiding the duplicated
// "copy member -> message" code that exists per message type today.
// 2. A new BuildXxx in HdcMessageBuilder only reads the fields it cares about;
// unused fields stay value-initialized and are ignored.
// Enum-typed values are stored as the raw integer already cast from the caller's
// enum so this header does not pull in tsdclient-internal enum definitions.
struct MessageContext {
// ---- Device / process identity (common, manager-derived) ----
uint32_t logicDeviceId = 0U;
uint32_t rankSize = 0U;
process_sign procSign = {};
// ---- Profiling ----
uint32_t profilingMode = 0U;
// ---- Log levels ----
std::string logLevel;
std::string ccecpuLogLevel;
std::string aicpuLogLevel;
// ---- Package host check codes ----
uint32_t aicpuKernelCheckCode = 0U;
uint32_t aicpuExtendKernelCheckCode = 0U;
uint32_t ascendcppCheckCode = 0U;
// ---- AICPU / scheduler ----
uint32_t aicpuDeviceMode = 0U;
SchedMode aicpuSchedMode = {};
// ---- Queue schedule (QS) ----
std::string qsInitGroupName;
uint64_t schedPolicy = 0UL;
// ---- Start flags ----
bool startHccp = false;
bool startCp = false;
bool startQs = false;
// ---- Paths / misc flags ----
std::string ascendInstallPath;
bool waitFlag = false;
bool asan = false;
// ---- Generic package operation (per-call) ----
uint32_t msgType = 0U; // raw HDCMessage::MsgType for generic builders
uint32_t checkCode = 0U;
uint32_t packageType = 0U;
uint32_t packageWorkerType = 0U;
uint32_t packageMaxProcessTime = 0U;
bool beforeSendPkg = false;
std::string packageName;
std::string hashCode;
// ---- Check-package query (per-call, TSD_CHECK_PACKAGE) ----
uint32_t extendpkgCheckCode = 0U;
// ---- Normal check-code with plugin version (per-call, TSD_GET_DEVICE_PACKAGE_CHECKCODE_NORMAL) ----
// Optional: when version is non-empty, a host_plugin_versions entry is appended.
struct HostPluginVersion {
std::string version;
std::string timestamp;
} hostPluginVersion;
// ---- Capability query (per-call) ----
// Raw TsdCapabilityType (cast from the caller's enum) used to derive the
// HDCMessage::MsgType for capability-query messages.
int32_t capabilityType = 0;
// ---- File operations (per-call) ----
std::string omfileName;
std::string removeFilePath;
// ---- Sub-process control (per-call) ----
uint32_t closeSubProcPid = 0U;
// ---- Sub-process status / close lists (per-call) ----
// Parallel arrays describing the sub-process entries carried by
// TSD_GET_SUB_PROC_STATUS / TSD_CLOSE_SUB_PROC_LIST. subProcTypeList may be
// empty (e.g. GetSubProcStatus carries only pids).
std::vector<uint32_t> subProcPidList;
std::vector<uint32_t> subProcTypeList;
// ---- Common open sub-process (per-call, TSD_OPEN_SUB_PROC) ----
uint32_t subProcOpenType = 0U; // helper_sub_proc.process_type
bool hasSubProcFilePath = false;
std::string subProcFilePath;
bool withSubProcLogLevel = false; // include log_level (HCCP case)
std::vector<std::pair<std::string, std::string>> subProcEnvList; // (env_name, env_value)
std::vector<std::string> subProcExtParamList;
};
inline bool HostPluginVersionEmpty(const MessageContext::HostPluginVersion& v)
{
return v.version.empty() && v.timestamp.empty();
}
// Pure HDC message assembler.
// Responsibility scope: given an immutable MessageContext + per-call inputs,
// populate the HDCMessage proto. Methods are static, side-effect free w.r.t.
// any owning object (only logging and env-lookup happen internally).
// Sending the message (devCommClient_->Send, WaitRsp, ...) is NOT part of
// this class and remains in ProcessModeManager.
class HdcMessageBuilder {
public:
HdcMessageBuilder() = delete;
~HdcMessageBuilder() = delete;
HdcMessageBuilder(const HdcMessageBuilder&) = delete;
HdcMessageBuilder(HdcMessageBuilder&&) = delete;
HdcMessageBuilder& operator=(const HdcMessageBuilder&) = delete;
HdcMessageBuilder& operator=(HdcMessageBuilder&&) = delete;
// Build TSD_START_PROC_MSG.
// Byte-equivalent to the legacy ProcessModeManager::ConstructOpenMsg.
static TSD_StatusT BuildOpen(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_CLOSE_PROC_MSG.
// Byte-equivalent to the legacy ProcessModeManager::ConstructCloseMsg.
static TSD_StatusT BuildClose(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_UPDATE_PROIFILING_MSG.
// Reads ctx.profilingMode / rankSize / logicDeviceId / procSign.
static TSD_StatusT BuildUpdateProfiling(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_OM_PKG_DECOMPRESS_STATUS.
// Reads ctx.omfileName / logicDeviceId / procSign.
static TSD_StatusT BuildOmFileDecompress(HDCMessage& msg, const MessageContext& ctx);
// Build a generic package check-code message. The concrete proto type is
// carried by ctx.msgType (raw HDCMessage::MsgType), and the body uses
// ctx.checkCode / beforeSendPkg / logicDeviceId / procSign.
static TSD_StatusT BuildPackageCheckCode(HDCMessage& msg, const MessageContext& ctx);
// Build a capability-query message.
// Reads ctx.capabilityType (raw TsdCapabilityType) to derive the proto
// message type, plus ctx.logicDeviceId / ctx.procSign.
static TSD_StatusT BuildCapability(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_CLOSE_SUB_PROC.
// Reads ctx.closeSubProcPid / logicDeviceId / procSign.
static TSD_StatusT BuildCloseSubProc(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_REMOVE_FILE.
// Reads ctx.removeFilePath / logicDeviceId / procSign.
static TSD_StatusT BuildRemoveFile(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_GET_DEVICE_CANN_HS_CHECKCODE.
// Reads ctx.packageMaxProcessTime / packageWorkerType / packageType /
// packageName / hashCode / logicDeviceId.
static TSD_StatusT BuildCannHsCheckCode(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_GET_SUB_PROC_STATUS.
// Reads ctx.subProcPidList (+ optional ctx.subProcTypeList) / logicDeviceId /
// procSign. Handles both GetSubProcStatus (pids only) and GetSubProcListStatus
// (pids + types).
static TSD_StatusT BuildGetSubProcStatus(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_CLOSE_SUB_PROC_LIST.
// Reads ctx.subProcPidList / subProcTypeList / logicDeviceId / procSign.
static TSD_StatusT BuildCloseSubProcList(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_OPEN_SUB_PROC (common open).
// Reads ctx.subProcOpenType / subProcFilePath / subProcEnvList /
// subProcExtParamList / ascendInstallPath / withSubProcLogLevel / logLevel /
// logicDeviceId / procSign.
static TSD_StatusT BuildCommonOpen(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_CHECK_PACKAGE_RETRY.
// Reads ctx.checkCode / packageType / logicDeviceId / procSign / waitFlag.
static TSD_StatusT BuildCheckPackageRetry(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_CHECK_PACKAGE.
// Reads ctx.checkCode / extendpkgCheckCode / ascendcppCheckCode / asan /
// logicDeviceId / procSign.
static TSD_StatusT BuildCheckPackage(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_UPDATE_PACKAGE_PROCESS_CONFIG.
// Reads ctx.logicDeviceId / procSign. The caller is responsible for
// filling package config fields via PackageProcessConfig::ConstructPkgConfigMsg
// after this builder sets the header.
static TSD_StatusT BuildUpdatePackageConfig(HDCMessage& msg, const MessageContext& ctx);
// Build TSD_GET_DEVICE_PACKAGE_CHECKCODE_NORMAL.
// Reads ctx.packageName / hashCode / packageWorkerType / packageMaxProcessTime /
// packageType / logicDeviceId. Optionally appends a host_plugin_versions entry
// when ctx.hostPluginVersion is non-empty.
static TSD_StatusT BuildNormalCheckCode(HDCMessage& msg, const MessageContext& ctx);
};
} // namespace tsd
#endif // TSD_BASIC_COMPONENT_MESSAGE_BUILDER_HDC_MESSAGE_BUILDER_H