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 "dump_tensor_plugin.h"
12 : #include "log/adx_log.h"
13 : #include "lib_path.h"
14 : #include "adump_pub.h"
15 : #include "file_utils.h"
16 : #include "sys_utils.h"
17 : namespace Adx {
18 :
19 3 : DumpTensorPlugin::~DumpTensorPlugin()
20 : {
21 : // Close all plugin library and clear all map.
22 8 : for (auto& handle : pluginLibHandles_) {
23 2 : if (handle != nullptr) {
24 2 : dlclose(handle);
25 2 : handle = nullptr;
26 : }
27 : }
28 3 : headProcessMap_.clear();
29 3 : tensorProcessMap_.clear();
30 3 : pluginLibHandles_.clear();
31 3 : }
32 :
33 : /**
34 : * @name ReceiveInitialFunc
35 : * @brief Load the initialization method and trigger it. If a new method needs to be loaded,
36 : * it can be implemented and called in the same way as this method.
37 : * @param handle [IN] The handle of the loaded target so by dlopen.
38 : * @return void
39 : */
40 2 : void DumpTensorPlugin::ReceiveInitialFunc(void* handle) const
41 : {
42 2 : AdumpPluginInitFunc initFunc = SysUtils::ReinterpretCast<AdumpPluginInit, void>(dlsym(handle, "AdumpPluginInit"));
43 2 : IDE_CTRL_VALUE_WARN(initFunc != nullptr, return, "Cannot find symbol AdumpPluginInit in library mentioned above.");
44 2 : initFunc();
45 : }
46 :
47 : /**
48 : * @name InitPluginLib
49 : * @brief Load all plugin.so files, obtain and launch the corresponding method.
50 : * @return success: ADUMP_SUCCESS, fail: ADUMP_FAILED
51 : */
52 49 : int32_t DumpTensorPlugin::InitPluginLib()
53 : {
54 49 : std::lock_guard<std::mutex> lk(dlopenMtx_);
55 49 : IDE_CTRL_VALUE_WARN(pluginLibHandles_.empty(), return ADUMP_SUCCESS, "The plugin library has been loaded.");
56 :
57 : // Get plugin.so path
58 48 : const std::string pluginPath = LibPath::Instance().GetTargetPath("/plugin/adump");
59 24 : IDE_CTRL_VALUE_FAILED(!pluginPath.empty(), return ADUMP_FAILED, "Received an empty path for file %s.");
60 24 : IDE_LOGD("The path of the target plugin.so is %s.", pluginPath.c_str());
61 :
62 : // Obtaining the absolute path of all plugin.so files
63 24 : std::vector<std::string> pluginList = LibPath::Instance().ObtainAllPluginSo(pluginPath);
64 50 : for (const auto& plugin : pluginList) {
65 : // Check whether the path is reasonable.
66 2 : std::string realFile;
67 2 : IDE_CTRL_VALUE_WARN_NODO(
68 : FileUtils::FileNameIsReal(plugin, realFile) == IDE_DAEMON_OK, continue,
69 : "Unable to get real file %s and the search file is %s.", realFile.c_str(), plugin.c_str());
70 2 : IDE_CTRL_VALUE_WARN_NODO(
71 : FileUtils::IsFileExist(realFile), continue, "Unable to find plugin file from %s.", realFile.c_str());
72 2 : IDE_LOGD("The file of the target plugin.so is %s.", realFile.c_str());
73 :
74 : // Load target plugin so by dlopen
75 2 : IDE_LOGD("Load plugin library from %s.", realFile.c_str());
76 2 : void* handle = dlopen(realFile.c_str(), RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
77 2 : IDE_CTRL_VALUE_WARN_NODO(
78 : handle != nullptr, continue, "Cannot open library %s, error: %s.", realFile.c_str(), dlerror());
79 :
80 : // Load initialization method and trigger it
81 2 : ReceiveInitialFunc(handle);
82 2 : pluginLibHandles_.push_back(handle);
83 2 : }
84 :
85 24 : return ADUMP_SUCCESS;
86 49 : }
87 :
88 2 : void DumpTensorPlugin::HeadCallbackRegister(DfxTensorType tensorType, HeadProcess headProcess)
89 : {
90 2 : std::lock_guard<std::mutex> lk(regMtx_);
91 : // Only one head process can be saved for each tensor type.
92 2 : headProcessMap_[tensorType] = headProcess;
93 2 : }
94 :
95 2 : void DumpTensorPlugin::TensorCallbackRegister(DfxTensorType tensorType, TensorProcess tensorProcess)
96 : {
97 2 : std::lock_guard<std::mutex> lk(regMtx_);
98 : // Only one tensor process can be saved for each tensor type.
99 2 : tensorProcessMap_[tensorType] = tensorProcess;
100 2 : }
101 :
102 : /**
103 : * @name IsTensorTypeRegistered
104 : * @brief Check whether the two associated map have registered the method of this tensor type.
105 : * @param tensorType [IN] tensor type
106 : * @return exist: true, not exist: false
107 : */
108 0 : bool DumpTensorPlugin::IsTensorTypeRegistered(DfxTensorType tensorType)
109 : {
110 0 : std::lock_guard<std::mutex> lk(regMtx_);
111 0 : return (headProcessMap_.find(tensorType) != headProcessMap_.end()) &&
112 0 : (tensorProcessMap_.find(tensorType) != tensorProcessMap_.end());
113 0 : }
114 :
115 : /**
116 : * @name NotifyHeadCallback
117 : * @brief Trigger the head callback of the corresponding tensor type.
118 : * @param tensorType [IN] tensor type
119 : * @param addr [IN] Pointer to the header addr
120 : * @param headerSize [IN] Header size
121 : * @param newHeaderSize [OUT] New header size after target size is added
122 : * @return exist: true, not exist: false
123 : */
124 1 : int32_t DumpTensorPlugin::NotifyHeadCallback(
125 : DfxTensorType tensorType, uint32_t devId, const void* addr, uint64_t headerSize, uint64_t& newHeaderSize)
126 : {
127 : // If neither of the two associated callbacks is registered, indicating that the default function is used.
128 1 : std::lock_guard<std::mutex> lk(regMtx_);
129 2 : return headProcessMap_[tensorType](devId, addr, headerSize, newHeaderSize);
130 1 : }
131 :
132 : /**
133 : * @name NotifyTensorCallback
134 : * @brief Trigger the tensor callback of the corresponding tensor type.
135 : * @param tensorType [IN] tensor type
136 : * @param addr [IN] Pointer to the header addr
137 : * @param size [IN] Header size
138 : * @param fd [IN] File descriptor
139 : * @return exist: true, not exist: false
140 : */
141 1 : int32_t DumpTensorPlugin::NotifyTensorCallback(
142 : DfxTensorType tensorType, uint32_t devId, const void* addr, uint64_t size, int32_t fd)
143 : {
144 1 : std::lock_guard<std::mutex> lk(regMtx_);
145 2 : return tensorProcessMap_[tensorType](devId, addr, size, fd);
146 1 : }
147 : } // namespace Adx
|