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 : #include "aicpusd_threads_process.h"
11 : #include <cstring>
12 : #include <unistd.h>
13 : #include <sys/types.h>
14 : #include <sys/syscall.h>
15 : #include "ascend_hal.h"
16 : #include "tdt_server.h"
17 : #include "task_queue.h"
18 : #include "profiling_adp.h"
19 : #include "aicpusd_util.h"
20 : #include "aicpusd_status.h"
21 : #include "aicpusd_common.h"
22 : #include "aicpusd_event_manager.h"
23 : #include "aicpusd_drv_manager.h"
24 : #include "aicpusd_interface_process.h"
25 : #include "aicpusd_drv_manager.h"
26 : #include "aicpusd_worker.h"
27 : #include "aicpu_context.h"
28 : #include "aicpusd_monitor.h"
29 : #include "aicpusd_msg_send.h"
30 : #include "aicpu_async_event.h"
31 : #include "aicpusd_hal_interface_ref.h"
32 : #include "aicpu_prof.h"
33 : #include "aicpu_engine.h"
34 : #include "aicpusd_message_queue.h"
35 : namespace {
36 : constexpr size_t FIRST_INDEX = 0UL;
37 : }
38 :
39 : namespace AicpuSchedule {
40 20 : ComputeProcess::ComputeProcess()
41 40 : : deviceVec_({}),
42 20 : hostDeviceId_(0U),
43 20 : hostPid_(-1),
44 40 : pidSign_(""),
45 20 : aicpuNum_(0U),
46 20 : profilingMode_(PROFILING_CLOSE),
47 20 : vfId_(0U),
48 20 : isStartTdtFlag_(false),
49 20 : runMode_(aicpu::AicpuRunMode::THREAD_MODE)
50 20 : {}
51 :
52 65 : ComputeProcess& ComputeProcess::GetInstance()
53 : {
54 65 : static ComputeProcess instance;
55 65 : return instance;
56 : }
57 :
58 10 : void ComputeProcess::LoadKernelSo()
59 : {
60 10 : if (runMode_ == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
61 : try {
62 4 : aicpusd_run_info("Start to preload aicpu so.");
63 4 : const uint32_t loadSoCnt = 3U;
64 4 : const char_t* soNames[loadSoCnt] = {"libtf_kernels.so", "libaicpu_kernels.so", "libcpu_kernels.so"};
65 4 : (void)aeBatchLoadKernelSo(static_cast<uint32_t>(aicpu::KERNEL_TYPE_AICPU), loadSoCnt, &(soNames[0]));
66 4 : aicpusd_run_info("End to preload aicpu so.");
67 0 : } catch (...) {
68 : // do nothing
69 0 : }
70 : }
71 10 : }
72 :
73 12 : void ComputeProcess::LoadExtendKernelSo()
74 : {
75 12 : if (!FeatureCtrl::ShouldLoadExtendKernelSo()) {
76 1 : aicpusd_info("no need load extend kernels so");
77 1 : return;
78 : }
79 :
80 : // extend kernel so 走mc2流程,如果有就必须加载
81 : try {
82 11 : aicpusd_run_info("Start to preload extend kernel so.");
83 11 : const uint32_t loadSoCnt = 1U;
84 11 : const char_t* soNames[loadSoCnt] = {"libaicpu_extend_kernels.so"};
85 11 : (void)aeBatchLoadKernelSo(static_cast<uint32_t>(aicpu::KERNEL_TYPE_AICPU), loadSoCnt, &(soNames[0]));
86 11 : aicpusd_run_info("End to preload extend kernel so.");
87 0 : } catch (...) {
88 : // do nothing
89 0 : }
90 : }
91 :
92 14 : int32_t ComputeProcess::Start(
93 : const std::vector<uint32_t>& deviceVec, const pid_t hostPid, const std::string& pidSign, const uint32_t profilMode,
94 : const uint32_t vfId, const aicpu::AicpuRunMode runMode)
95 : {
96 14 : const AicpuSchedMode schedMode = FeatureCtrl::GetAicpuSchedMode();
97 14 : aicpusd_info(
98 : "Aicpu scheduler start, hostpid[%d], profilingMode[%u], runMode[%u], vfId[%u], schedMode[%u]", hostPid,
99 : profilMode, runMode, vfId, schedMode);
100 14 : if (deviceVec.empty()) {
101 0 : aicpusd_err("device vector is empty.");
102 0 : return AICPU_SCHEDULE_ERROR_PARAMETER_NOT_VALID;
103 : }
104 14 : const AicpuSchedule::AicpuDrvManager& drvMgr = AicpuSchedule::AicpuDrvManager::GetInstance();
105 14 : deviceVec_ = deviceVec;
106 14 : aicpuNum_ = drvMgr.GetAicpuNum();
107 14 : hostPid_ = hostPid;
108 14 : pidSign_ = pidSign;
109 14 : runMode_ = runMode;
110 14 : vfId_ = vfId;
111 14 : aicpu::InitProfilingDataInfo(deviceVec_[FIRST_INDEX], hostPid, static_cast<uint32_t>(CHANNEL_AICPU));
112 14 : aicpu::LoadProfilingLib();
113 14 : if (profilMode != 0U) {
114 8 : aicpu::SetProfilingFlagForKFC(profilMode);
115 8 : aicpu::UpdateMode((profilMode & 1U) == PROFILING_OPEN);
116 : }
117 :
118 14 : int32_t ret = AICPU_SCHEDULE_OK;
119 14 : if (runMode_ == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
120 8 : ret = MemorySvmDevice();
121 8 : if (ret != AICPU_SCHEDULE_OK) {
122 0 : aicpusd_err("Memory svm device failed.");
123 0 : return ret;
124 : }
125 : }
126 : // set aicpu runmode
127 14 : (void)aicpu::SetAicpuRunMode(runMode_);
128 : // set cust aicpu sd flag
129 14 : aicpu::SetCustAicpuSdFlag(false);
130 :
131 14 : if (schedMode == SCHED_MODE_MSGQ) {
132 11 : const uint32_t deviceId = deviceVec[0];
133 22 : ret = MessageQueue::GetInstance().InitMessageQueue(
134 22 : deviceId, AicpuDrvManager::GetInstance().GetAicpuPhysIndexs(deviceId));
135 11 : if (ret != AICPU_SCHEDULE_OK) {
136 1 : aicpusd_err("Init aicpu message queue failed, ret=%d", ret);
137 1 : return ret;
138 : }
139 : }
140 :
141 13 : ret = RegisterScheduleTask();
142 13 : if (ret != AICPU_SCHEDULE_OK) {
143 1 : aicpusd_err("Register aicpu nonblock task and async event manager task failed.");
144 1 : return ret;
145 : }
146 :
147 12 : ret = AicpuSchedule::ThreadPool::Instance().CreateWorker(schedMode);
148 12 : if (ret != AICPU_SCHEDULE_OK) {
149 0 : aicpusd_err("Drv create aicpu work tasks failed, ret[%d].", ret);
150 0 : return ret;
151 : }
152 12 : if (runMode_ == aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
153 6 : AicpuSchedule::ThreadPool::Instance().SetThreadSchedModeByTsd();
154 : }
155 :
156 12 : if (vfId > 0) {
157 : // start TDT Server thread
158 3 : ret = StartTdtServer();
159 3 : if (ret != AICPU_SCHEDULE_OK) {
160 1 : aicpusd_err("Start tdt server failed ret[%d].", ret);
161 1 : return ret;
162 : }
163 : }
164 :
165 11 : if (AicpuScheduleInterface::GetInstance().NeedLoadKernelSo()) {
166 9 : LoadKernelSo();
167 : }
168 :
169 11 : LoadExtendKernelSo();
170 11 : aicpusd_info(
171 : "Aicpu scheduler start successfully, deviceId[%u], hostpid[%d], profilingMode[%u], runMode[%u]",
172 : deviceVec_[FIRST_INDEX], hostPid, profilMode, runMode_);
173 11 : return AICPU_SCHEDULE_OK;
174 : }
175 :
176 3 : void ComputeProcess::UpdateProfilingMode(const ProfilingMode mode) const { aicpu::UpdateMode(mode == PROFILING_OPEN); }
177 :
178 3 : void ComputeProcess::UpdateProfilingModelMode(const bool mode) const { aicpu::UpdateModelMode(mode); }
179 :
180 8 : void ComputeProcess::Stop()
181 : {
182 8 : splitKernelTask_.Clear();
183 8 : randomKernelTask_.Clear();
184 8 : StopTdtServer();
185 8 : aicpu::ReleaseProfiling();
186 8 : }
187 : #ifndef _AOSCORE_
188 7 : int32_t ComputeProcess::StartTdtServer()
189 : {
190 7 : if (runMode_ != aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
191 3 : return AICPU_SCHEDULE_OK;
192 : }
193 4 : aicpusd_info("Start tdt server, deviceId=%u.", deviceVec_[0]);
194 4 : uint32_t dcpuBase = 0U;
195 4 : uint32_t dcpuNumber = 0U;
196 4 : AicpuSchedule::AicpuDrvManager::GetInstance().GetDcpuRange(dcpuBase, dcpuNumber);
197 :
198 4 : const uint32_t aicpuNumber = AicpuSchedule::AicpuDrvManager::GetInstance().GetAicpuNumPerDevice();
199 :
200 : // Set TDT thread binding list
201 4 : std::list<uint32_t> tdtBindCoreList;
202 4 : if (dcpuNumber != 0U) {
203 2 : isStartTdtFlag_ = true;
204 4 : for (uint32_t i = 0U; i < dcpuNumber; ++i) {
205 2 : tdtBindCoreList.push_back(dcpuBase + i);
206 : }
207 : } else {
208 2 : const bool isFPGA = AicpuUtil::IsEnvValEqual(ENV_NAME_DATAMASTER_RUN_MODE, "1");
209 2 : aicpusd_info("Start tdt in mode %d", isFPGA);
210 :
211 2 : if ((isFPGA) && (aicpuNumber != 0U)) {
212 1 : isStartTdtFlag_ = true;
213 2 : for (uint32_t i = 0U; i < aicpuNumber; ++i) {
214 1 : tdtBindCoreList.push_back(AicpuSchedule::AicpuDrvManager::GetInstance().GetAicpuPhysIndex(i, 0U));
215 : }
216 1 : } else {
217 1 : isStartTdtFlag_ = false;
218 1 : aicpusd_info("Not need to start tdt server.");
219 1 : return AICPU_SCHEDULE_OK;
220 : }
221 : }
222 :
223 : // Start the TDT thread that binds the core
224 3 : const int32_t tdtInitRet = tdt::TDTServerInit(deviceVec_[FIRST_INDEX], tdtBindCoreList);
225 3 : if (tdtInitRet != 0) {
226 0 : aicpusd_err(
227 : "TDT server init failed, deviceId[%u], dcpuBase[%u], dcpuNum[%u], ret[%d].", deviceVec_[FIRST_INDEX],
228 : dcpuBase, dcpuNumber, tdtInitRet);
229 0 : return tdtInitRet;
230 : }
231 3 : aicpusd_info("TDT Server init success.");
232 3 : return AICPU_SCHEDULE_OK;
233 4 : }
234 :
235 15 : void ComputeProcess::StopTdtServer() const
236 : {
237 15 : if (runMode_ != aicpu::AicpuRunMode::PROCESS_PCIE_MODE) {
238 7 : return;
239 : }
240 8 : if (!isStartTdtFlag_) {
241 3 : aicpusd_info("It don`t need to stop tdt server.");
242 3 : return;
243 : }
244 5 : aicpusd_info("Stop tdt server, deviceId=%u.", deviceVec_[0]);
245 :
246 5 : const int32_t tdtStopRet = tdt::TDTServerStop();
247 5 : if (tdtStopRet != 0) {
248 1 : aicpusd_err("TDT server stop failed, ret[%d].", tdtStopRet);
249 1 : return;
250 : }
251 4 : aicpusd_info("TDT Server stop success.");
252 : }
253 : #else
254 : int32_t ComputeProcess::StartTdtServer() { return AICPU_SCHEDULE_OK; }
255 :
256 : void ComputeProcess::StopTdtServer() const { return; }
257 : #endif
258 :
259 30 : int32_t ComputeProcess::RegisterScheduleTask()
260 : {
261 3 : const auto randomKernelScheduler = [this](const aicpu::Closure& task) { return SubmitRandomKernelTask(task); };
262 : const auto splitKernelScheduler =
263 41 : [this](const uint32_t parallelId, const int64_t shardNum, const std::queue<aicpu::Closure>& taskQueue) {
264 41 : const AICPUSharderTaskInfo taskInfo = {.parallelId = parallelId, .shardNum = shardNum};
265 82 : return SubmitSplitKernelTask(taskInfo, taskQueue);
266 30 : };
267 130 : const auto splitKernelGetProcesser = [this]() { return GetAndDoSplitKernelTask(); };
268 :
269 30 : aicpu::SharderNonBlock::GetInstance().Register(
270 : aicpuNum_, randomKernelScheduler, splitKernelScheduler, splitKernelGetProcesser);
271 30 : if ((aicpuNum_ > 0U) && (aicpu::InitTaskMonitorContext(aicpuNum_) != aicpu::AICPU_ERROR_NONE)) {
272 1 : aicpusd_err("Init task monitor context failed");
273 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
274 : }
275 :
276 0 : const auto notifyWaitFunc = [](const void* const notifyParam, const uint32_t paramLen) {
277 0 : return AicpuSchedule::AicpuMsgSend::SendAicpuRecordMsg(notifyParam, paramLen);
278 : };
279 29 : aicpu::AsyncEventManager::GetInstance().Register(notifyWaitFunc);
280 29 : return AICPU_SCHEDULE_OK;
281 : }
282 :
283 3 : uint32_t ComputeProcess::SubmitRandomKernelTask(const aicpu::Closure& task)
284 : {
285 3 : if (!randomKernelTask_.Enqueue(task)) {
286 1 : aicpusd_err("Add random kernel task failed.");
287 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
288 : }
289 :
290 2 : AICPUSubEventInfo aicpuEventInfo = {};
291 2 : event_summary eventInfoSummary = {};
292 2 : eventInfoSummary.pid = getpid();
293 2 : eventInfoSummary.event_id = EVENT_RANDOM_KERNEL;
294 2 : eventInfoSummary.msg = PtrToPtr<AICPUSubEventInfo, char_t>(&aicpuEventInfo);
295 2 : eventInfoSummary.msg_len = static_cast<uint32_t>(sizeof(AICPUSubEventInfo));
296 :
297 2 : const int32_t drvRet = halEschedSubmitEvent(deviceVec_[FIRST_INDEX], &eventInfoSummary);
298 2 : if (drvRet != DRV_ERROR_NONE) {
299 1 : aicpusd_err("Submit random kernel event failed. ret=%d", drvRet);
300 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
301 : }
302 :
303 1 : return AICPU_SCHEDULE_OK;
304 : }
305 :
306 41 : uint32_t ComputeProcess::SubmitSplitKernelTask(
307 : const AICPUSharderTaskInfo& taskInfo, const std::queue<aicpu::Closure>& taskQueue)
308 : {
309 41 : if (!splitKernelTask_.BatchAddTask(taskInfo, taskQueue)) {
310 1 : aicpusd_err("Add split kernel task to map failed, parallelId=%u", taskInfo.parallelId);
311 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
312 : }
313 :
314 40 : uint32_t ret = AICPU_SCHEDULE_OK;
315 40 : if (FeatureCtrl::ShouldSubmitTaskOneByOne()) {
316 2 : ret = SubmitBatchSplitKernelEventOneByOne(taskInfo);
317 : } else {
318 38 : ret = SubmitBatchSplitKernelEventDc(taskInfo);
319 : }
320 40 : if (ret != AICPU_SCHEDULE_OK) {
321 2 : aicpusd_err(
322 : "Submit batch split kernel event failed. parallelId=%u, submitNum=%ld", taskInfo.parallelId,
323 : taskInfo.shardNum);
324 2 : return ret;
325 : }
326 :
327 38 : aicpusd_info(
328 : "Submit split kernel event success. parallelId=%u, submitNum=%ld", taskInfo.parallelId, taskInfo.shardNum);
329 :
330 38 : return AICPU_SCHEDULE_OK;
331 : }
332 :
333 2 : uint32_t ComputeProcess::SubmitBatchSplitKernelEventOneByOne(const AICPUSharderTaskInfo& taskInfo) const
334 : {
335 2 : const uint32_t submitNum = static_cast<uint32_t>(taskInfo.shardNum);
336 3 : for (uint32_t i = 0U; i < submitNum; ++i) {
337 2 : const uint32_t ret = SubmitOneSplitKernelEvent(taskInfo);
338 2 : if (ret != AICPU_SCHEDULE_OK) {
339 1 : aicpusd_err("Submit single split kernel event failed. parallelId=%u, i=%u", taskInfo.parallelId, i);
340 1 : return ret;
341 : }
342 : }
343 :
344 1 : return AICPU_SCHEDULE_OK;
345 : }
346 :
347 38 : uint32_t ComputeProcess::SubmitBatchSplitKernelEventDc(const AICPUSharderTaskInfo& taskInfo)
348 : {
349 38 : AICPUSubEventInfo aicpuEventInfo = {};
350 38 : aicpuEventInfo.para.sharderTaskInfo = taskInfo;
351 38 : event_summary eventInfoSummary = {};
352 38 : eventInfoSummary.pid = getpid();
353 38 : eventInfoSummary.event_id = EVENT_SPLIT_KERNEL;
354 38 : eventInfoSummary.msg = PtrToPtr<AICPUSubEventInfo, char_t>(&aicpuEventInfo);
355 38 : eventInfoSummary.msg_len = static_cast<uint32_t>(sizeof(AICPUSubEventInfo));
356 38 : uint32_t submitSuccessNum = 0U;
357 38 : const uint32_t submitNum = static_cast<uint32_t>(taskInfo.shardNum);
358 38 : const int32_t drvRet = halEschedSubmitEventBatch(
359 38 : deviceVec_[FIRST_INDEX], SHARED_EVENT_ENTRY, &eventInfoSummary, submitNum, &submitSuccessNum);
360 38 : if ((drvRet == DRV_ERROR_NONE) && (submitSuccessNum == submitNum)) {
361 35 : aicpusd_info(
362 : "Batch submit split kernel event success, parallelId=%u, submitNum=%u", taskInfo.parallelId, submitNum);
363 35 : return AICPU_SCHEDULE_OK;
364 : }
365 :
366 : /*
367 : * The queue depth of event schedule is only dozens. If too many split kernel event are submited,
368 : * the queue will be full. Therefore, the main thread needs to process the task sending failure.
369 : */
370 3 : aicpusd_warn(
371 : "Batch submit some of split kernel event success, ret=%d, parallelId=%u, submitNum=%u, "
372 : "submitSuccessNum=%u",
373 : drvRet, taskInfo.parallelId, submitNum, submitSuccessNum);
374 :
375 3 : const uint32_t remainNum = (drvRet == DRV_ERROR_NONE) ? submitNum - submitSuccessNum : submitNum;
376 5 : for (uint32_t i = 0U; i < remainNum; ++i) {
377 3 : if (!DoSplitKernelTask(taskInfo)) {
378 1 : aicpusd_err(
379 : "Run single task failed after batch submit fail, parallelId=%u, submitNum=%u, "
380 : "remainNum=%u, i=%u",
381 : taskInfo.parallelId, submitNum, remainNum, i);
382 1 : return AICPU_SCHEDULE_ERROR_INNER_ERROR;
383 : }
384 : }
385 :
386 2 : return AICPU_SCHEDULE_OK;
387 : }
388 :
389 2 : uint32_t ComputeProcess::SubmitOneSplitKernelEvent(const AICPUSharderTaskInfo& taskInfo) const
390 : {
391 2 : AICPUSubEventInfo aicpuEventInfo = {};
392 2 : aicpuEventInfo.para.sharderTaskInfo = taskInfo;
393 2 : event_summary eventInfoSummary = {};
394 2 : eventInfoSummary.pid = getpid();
395 2 : eventInfoSummary.event_id = EVENT_SPLIT_KERNEL;
396 2 : eventInfoSummary.msg = PtrToPtr<AICPUSubEventInfo, char_t>(&aicpuEventInfo);
397 2 : eventInfoSummary.msg_len = static_cast<uint32_t>(sizeof(AICPUSubEventInfo));
398 :
399 2 : const int32_t drvRet = halEschedSubmitEvent(deviceVec_[FIRST_INDEX], &eventInfoSummary);
400 2 : if (drvRet != DRV_ERROR_NONE) {
401 1 : aicpusd_err("Submit split kernel event failed. ret=%d, parallelId=%u", drvRet, taskInfo.parallelId);
402 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
403 : }
404 :
405 1 : return AICPU_SCHEDULE_OK;
406 : }
407 :
408 130 : bool ComputeProcess::GetAndDoSplitKernelTask()
409 : {
410 130 : event_info eventInfo = {};
411 130 : const uint32_t threadIndex = aicpu::GetAicpuThreadIndex();
412 : const int32_t retVal =
413 130 : halEschedGetEvent(deviceVec_[FIRST_INDEX], CP_DEFAULT_GROUP_ID, threadIndex, EVENT_SPLIT_KERNEL, &eventInfo);
414 130 : if (retVal == DRV_ERROR_NO_EVENT) {
415 7 : return true;
416 : }
417 123 : if (retVal != DRV_ERROR_NONE) {
418 1 : aicpusd_err("Cannot get event, threadIndex=%u, ret=%d", threadIndex, retVal);
419 1 : return false;
420 : }
421 :
422 122 : const AICPUSubEventInfo* const subEventInfo = PtrToPtr<const char_t, const AICPUSubEventInfo>(eventInfo.priv.msg);
423 122 : aicpusd_info(
424 : "Begin to process split kernel event. parallelId=%u, threadIdx=%u, type=get",
425 : subEventInfo->para.sharderTaskInfo.parallelId, threadIndex);
426 :
427 122 : return DoSplitKernelTask(subEventInfo->para.sharderTaskInfo);
428 : }
429 :
430 129 : bool ComputeProcess::DoSplitKernelTask(const AICPUSharderTaskInfo& taskInfo)
431 : {
432 129 : aicpu::Closure task;
433 129 : if (!splitKernelTask_.PopTask(taskInfo, task)) {
434 1 : aicpusd_run_warn(
435 : "Get split kernel task from map failed, parallelId=%u, %s", taskInfo.parallelId,
436 : splitKernelTask_.DebugString().c_str());
437 1 : return true;
438 : }
439 :
440 : try {
441 128 : task();
442 1 : } catch (std::exception& e) {
443 1 : aicpusd_err("Run split kernel task failed. parallelId=%u, exception=%s", taskInfo.parallelId, e.what());
444 1 : return false;
445 1 : }
446 :
447 127 : return true;
448 129 : }
449 :
450 6 : bool ComputeProcess::DoRandomKernelTask()
451 : {
452 6 : aicpu::Closure task;
453 6 : if (!randomKernelTask_.Dequeue(task)) {
454 4 : aicpusd_err("Get random kernel task from map failed, %s", randomKernelTask_.DebugString().c_str());
455 4 : return false;
456 : }
457 :
458 : try {
459 2 : task();
460 1 : } catch (std::exception& e) {
461 1 : aicpusd_err("Run random kernel task failed. exception=%s", e.what());
462 1 : return false;
463 1 : }
464 :
465 1 : return true;
466 6 : }
467 :
468 9 : int32_t ComputeProcess::MemorySvmDevice()
469 : {
470 17 : for (size_t i = 0UL; i < deviceVec_.size(); i++) {
471 9 : if (&halMemInitSvmDevice == nullptr) {
472 0 : aicpusd_err("Interface halMemInitSvmDevice is not supported in current device");
473 0 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
474 : }
475 9 : const drvError_t drvRet = halMemInitSvmDevice(hostPid_, vfId_, deviceVec_[i]);
476 9 : if (drvRet != DRV_ERROR_NONE) {
477 1 : aicpusd_err("Drv mem init svm device[%u] failed ret[%d].", deviceVec_[i], drvRet);
478 1 : return AICPU_SCHEDULE_ERROR_DRV_ERR;
479 : }
480 : }
481 8 : aicpusd_info("Drv mem init svm device success.");
482 8 : return AICPU_SCHEDULE_OK;
483 : }
484 :
485 2 : std::string ComputeProcess::DebugString() { return splitKernelTask_.DebugString(); }
486 : } // namespace AicpuSchedule
|