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 <dlfcn.h>
12 : #include <climits>
13 : #include <memory>
14 : #include "securec.h"
15 : #include "aicpusd_common.h"
16 : #include "aicpusd_status.h"
17 : #include "aicpusd_so_manager.h"
18 :
19 : namespace AicpuSchedule {
20 1 : AicpuSoManager::~AicpuSoManager()
21 : {
22 : // close so
23 1 : CloseSo();
24 1 : }
25 :
26 15 : AicpuSoManager &AicpuSoManager::GetInstance()
27 : {
28 15 : static AicpuSoManager instance;
29 15 : return instance;
30 : }
31 :
32 5 : bool AicpuSoManager::OpenSo(const std::string &soFile)
33 : {
34 : // Use API in glibc to open the so lib, load this so to process.
35 5 : std::unique_ptr<char_t []> path(new (std::nothrow) char_t[PATH_MAX]);
36 5 : if (path == nullptr) {
37 0 : aicpusd_err("Alloc memory for path failed.");
38 0 : return false;
39 : }
40 :
41 5 : const auto eRet = memset_s(path.get(), PATH_MAX, 0, PATH_MAX);
42 5 : if (eRet != EOK) {
43 1 : aicpusd_err("Mem set error, ret=%d", eRet);
44 1 : return false;
45 : }
46 :
47 4 : if (realpath(soFile.data(), path.get()) == nullptr) {
48 1 : aicpusd_err("Format to realpath failed:%s", soFile.c_str());
49 1 : return false;
50 : }
51 3 : aicpusd_info("Open so %s begin.", path.get());
52 3 : soHandle_ = dlopen(path.get(),
53 : static_cast<int32_t>((static_cast<uint32_t>(RTLD_LAZY)) | (static_cast<uint32_t>(RTLD_NODELETE)) |
54 : (static_cast<uint32_t>(RTLD_GLOBAL))));
55 3 : if (soHandle_ == nullptr) {
56 1 : aicpusd_err("Open so %s failed", path.get());
57 1 : return false;
58 : }
59 2 : aicpusd_info("Open so %s success.", soFile.c_str());
60 2 : return true;
61 5 : }
62 :
63 3 : void AicpuSoManager::CloseSo()
64 : {
65 3 : std::lock_guard<std::mutex> lock(soMutex_);
66 3 : if (soHandle_ != nullptr) {
67 1 : (void)dlclose(soHandle_);
68 1 : soHandle_ = nullptr;
69 : }
70 3 : aicpusd_info("dlclose soHandle_ success");
71 3 : }
72 :
73 4 : void AicpuSoManager::SetDeviceIdToDvpp(uint32_t deviceId)
74 : {
75 4 : std::lock_guard<std::mutex> lock(soMutex_);
76 4 : if (soHandle_ != nullptr) {
77 2 : aicpusd_info("Already loaded libmpi_dvpp_adapter.so");
78 : } else {
79 2 : bool retOpenSo = OpenSo("/lib64/libmpi_dvpp_adapter.so");
80 2 : if ((retOpenSo == false) || (soHandle_ == nullptr)) {
81 1 : aicpusd_warn("cannot open libmpi_dvpp_adapter.so");
82 1 : return;
83 : }
84 : }
85 :
86 : using SetDeviceIdFunc = int32_t (*)(uint32_t);
87 : SetDeviceIdFunc funcSetDeviceId =
88 3 : reinterpret_cast<SetDeviceIdFunc>(dlsym(soHandle_, "HiMpiSysSetDeviceId"));
89 3 : if (funcSetDeviceId == nullptr) {
90 1 : aicpusd_err("cannot find HiMpiSysSetDeviceId");
91 1 : return;
92 : }
93 :
94 2 : const int32_t ret = funcSetDeviceId(deviceId);
95 2 : if (ret != 0) {
96 1 : aicpusd_err("HiMpiSysSetDeviceId fail");
97 : }
98 4 : }
99 : } // namespace AicpuSchedule
|