Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "aicpusd_interface_process.h"
12 : #include <securec.h>
13 : #include <unistd.h>
14 : #include "aicpusd_info.h"
15 : #include "ascend_hal.h"
16 : #include "aicpusd_event_manager.h"
17 : #include "aicpusd_event_process.h"
18 : #include "aicpusd_threads_process.h"
19 : #include "dump_task.h"
20 : #include "aicpu_context.h"
21 : #include "aicpusd_common.h"
22 : #include "aicpusd_context.h"
23 : #include "aicpusd_util.h"
24 : #include "aicpu_sched/common/aicpu_task_struct.h"
25 : #include "aicpusd_resource_manager.h"
26 : #include "aicpusd_drv_manager.h"
27 : #include "aicpusd_model_execute.h"
28 : #include "aicpu_engine.h"
29 : #include "aicpusd_profiler.h"
30 : #include "aicpusd_monitor.h"
31 : #include "aicpusd_worker.h"
32 : #include "aicpusd_cust_so_manager.h"
33 : #include "aicpusd_sub_module_interface.h"
34 :
35 : namespace {
36 : const std::map<EVENT_ID, SCHEDULE_PRIORITY> eventPriority = {
37 : {EVENT_ID::EVENT_TS_CTRL_MSG, SCHEDULE_PRIORITY::PRIORITY_LEVEL0}};
38 :
39 : // first array index
40 : constexpr size_t FIRST_INDEX = 0LU;
41 : } // namespace
42 : namespace AicpuSchedule {
43 : /**
44 : * @ingroup AicpuScheduleCore
45 : * @brief it is used to construct a object of AicpuScheduleCore.
46 : */
47 1 : AicpuScheduleInterface::AicpuScheduleInterface()
48 1 : : profilingMode_(PROFILING_CLOSE),
49 1 : noThreadFlag_(true),
50 1 : initFlag_(false),
51 1 : eventBitMap_(0U),
52 1 : runMode_(aicpu::AicpuRunMode::THREAD_MODE)
53 1 : {}
54 :
55 : /**
56 : * @ingroup AicpuScheduleCore
57 : * @brief it is used to destructor a object of AicpuScheduleCore.
58 : */
59 1 : AicpuScheduleInterface::~AicpuScheduleInterface() {}
60 :
61 22 : AicpuScheduleInterface& AicpuScheduleInterface::GetInstance()
62 : {
63 22 : static AicpuScheduleInterface instance;
64 22 : return instance;
65 : }
66 :
67 4 : int32_t AicpuScheduleInterface::BindHostPid(const std::string& pidSign, const uint32_t vfId) const
68 : {
69 4 : const AicpuPlat mode = (runMode_ == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) ? AicpuPlat::AICPU_ONLINE_PLAT :
70 : AicpuPlat::AICPU_OFFLINE_PLAT;
71 4 : int32_t ret = 0;
72 4 : ret = AicpuDrvManager::GetInstance().BindHostPid(pidSign, static_cast<int32_t>(mode), vfId, DEVDRV_PROCESS_CP1);
73 4 : if (runMode_ == aicpu::AicpuRunMode::THREAD_MODE) {
74 4 : int32_t getRet = 0;
75 : getRet =
76 4 : AicpuDrvManager::GetInstance().BindHostPid(pidSign, static_cast<int32_t>(mode), vfId, DEVDRV_PROCESS_CP2);
77 4 : aicpusd_warn("BindHostPid DEVDRV_PROCESS_CP2 ret[%d]", getRet);
78 : }
79 4 : return ret;
80 : }
81 :
82 : /**
83 : * @ingroup AicpuScheduleInterface
84 : * @brief it use to initialize aicpu schedule.
85 : * @param [in] deviceId
86 : * @param [in] hostPid : the process id of host
87 : * @param [in] pidSign : the signature of pid ,it is used in drv.
88 : * @param [in] profilingMode
89 : * @param [in] vfId : vf id
90 : * @param [in] isOnline: true-process mode; false-thread mode
91 : * @return AICPU_SCHEDULE_OK: success, other: error code
92 : */
93 11 : int32_t AicpuScheduleInterface::InitAICPUScheduler(
94 : const std::vector<uint32_t>& deviceVec, const pid_t hostPid, const std::string& pidSign,
95 : const uint32_t profilingMode, const uint32_t vfId, const bool isOnline, const std::string& hostProcName)
96 : {
97 11 : const std::unique_lock<std::mutex> lockForInit(mutexForInit_);
98 11 : if (initFlag_) {
99 2 : aicpusd_warn("Aicpu schedule is already init.");
100 2 : return AICPU_SCHEDULE_OK;
101 : }
102 9 : noThreadFlag_ = false;
103 9 : if (deviceVec.empty()) {
104 1 : aicpusd_err("device vector is empty");
105 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
106 : }
107 : // get aicpu run mode
108 8 : const int32_t getRet = GetCurrentRunMode(isOnline);
109 8 : if (getRet != AICPU_SCHEDULE_OK) {
110 1 : aicpusd_err("getRet is not ok:%u", getRet);
111 1 : return getRet;
112 : }
113 7 : if (AicpuDrvManager::GetInstance().InitDrvMgr(deviceVec, hostPid, vfId, true, runMode_, hostProcName) !=
114 : AICPU_SCHEDULE_OK) {
115 1 : aicpusd_err("Failed to init aicpu drv manager");
116 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
117 : }
118 :
119 6 : DeployContext deployCtx = DeployContext::DEVICE;
120 6 : const StatusCode status = GetAicpuDeployContext(deployCtx);
121 6 : if (status != AICPU_SCHEDULE_OK) {
122 1 : aicpusd_err("Get current deploy ctx failed.");
123 1 : return status;
124 : }
125 5 : const bool cpuMode = GetCpuMode();
126 5 : if ((deployCtx == DeployContext::DEVICE) && (!cpuMode)) {
127 5 : const int32_t bindPidRet = BindHostPid(pidSign, vfId);
128 5 : if (bindPidRet != AICPU_SCHEDULE_OK) {
129 1 : aicpusd_err("check bind pid sign failed, ret[%d].", bindPidRet);
130 1 : return bindPidRet;
131 : }
132 4 : aicpusd_info("Bind pid sign success");
133 : }
134 4 : const uint32_t groupId = CP_DEFAULT_GROUP_ID;
135 :
136 4 : int32_t ret = AicpuDrvManager::GetInstance().InitDrvSchedModule(groupId, eventPriority);
137 4 : if (ret != DRV_ERROR_NONE) {
138 1 : aicpusd_err("Failed to init the drv schedule module, ret[%d].", ret);
139 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
140 : }
141 3 : const auto retCp = ComputeProcess::GetInstance().Start(deviceVec, hostPid, pidSign, profilingMode, vfId, runMode_);
142 3 : if (retCp != AICPU_SCHEDULE_OK) {
143 1 : aicpusd_err("Compute process start failed, ret[%d].", retCp);
144 1 : ComputeProcess::GetInstance().Stop();
145 1 : return AICPU_SCHEDULE_ERROR_INIT_CP_FAILED;
146 : }
147 :
148 2 : aicpusd_info(
149 : "Successfully started compute process, deviceId[%u], hostPid[%d], runMode[%u]", deviceVec[FIRST_INDEX], hostPid,
150 : runMode_);
151 2 : initFlag_ = true;
152 2 : return AICPU_SCHEDULE_OK;
153 11 : }
154 :
155 9 : int32_t AicpuScheduleInterface::GetCurrentRunMode(const bool isOnline)
156 : {
157 9 : if (!isOnline) {
158 7 : runMode_ = aicpu::AicpuRunMode::THREAD_MODE;
159 7 : aicpusd_run_info("Current aicpu mode is offline (call by api).");
160 7 : return AICPU_SCHEDULE_OK;
161 : }
162 2 : aicpusd_err("Datadump only support thread mode.");
163 2 : return AICPU_SCHEDULE_ERROR_INIT_CP_FAILED;
164 : }
165 :
166 2 : int32_t AicpuScheduleInterface::DettachDeviceInDestroy(const std::vector<uint32_t>& deviceVec) const
167 : {
168 3 : for (size_t i = 0LU; i < deviceVec.size(); i++) {
169 2 : const drvError_t ret = halEschedDettachDevice(deviceVec[i]);
170 2 : if (ret != DRV_ERROR_NONE) {
171 1 : aicpusd_err("Failed to detach device[%u], result[%d].", deviceVec[i], ret);
172 1 : return ret;
173 : }
174 1 : aicpusd_info("Successfully detached AICPU scheduler, device[%d].", deviceVec[i]);
175 : }
176 1 : return AICPU_SCHEDULE_OK;
177 : }
178 : } // namespace AicpuSchedule
|