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 <dlfcn.h>
11 : #include <vector>
12 : #include "aicpu_prof/profiling_adp.h"
13 : #include "prof_so_manager.h"
14 : #include "aicpu_prof.h"
15 :
16 : namespace aicpu {
17 :
18 33 : ProfSoManager* ProfSoManager::GetInstance()
19 : {
20 33 : static ProfSoManager msprofSoInstance;
21 33 : return &msprofSoInstance;
22 : }
23 :
24 7 : void ProfSoManager::LoadSo()
25 : {
26 7 : const std::lock_guard<std::mutex> loadSoLock(profMtx_);
27 7 : if (soHandle_ != nullptr) {
28 2 : AICPU_LOG_INFO("Already loaded libascend_devprof.so");
29 2 : return;
30 : }
31 5 : bool isProfApiSo = false;
32 5 : soHandle_ = dlopen(
33 : "libprofapi.so",
34 : static_cast<int32_t>((static_cast<uint32_t>(RTLD_LAZY)) | (static_cast<uint32_t>(RTLD_GLOBAL))));
35 5 : if (soHandle_ != nullptr) {
36 5 : void* func = dlsym(soHandle_, "MsprofReportBatchAdditionalInfo");
37 5 : if (func != nullptr) {
38 0 : isProfApiSo = true;
39 0 : AICPU_RUN_INFO("The new profiling so had taken effect.");
40 : } else {
41 5 : dlclose(soHandle_);
42 5 : soHandle_ = nullptr;
43 5 : AICPU_RUN_INFO("The new profiling so hadn't taken effect. try another old one.");
44 : }
45 : } else {
46 0 : AICPU_RUN_INFO("dlopen libprofapi.so was not successful. reason: %s", dlerror());
47 : }
48 5 : if (isProfApiSo == false) {
49 5 : soHandle_ = dlopen(
50 : "libascend_devprof.so",
51 : static_cast<int32_t>((static_cast<uint32_t>(RTLD_LAZY)) | (static_cast<uint32_t>(RTLD_GLOBAL))));
52 5 : if (soHandle_ == nullptr) {
53 0 : AICPU_RUN_INFO("dlopen libascend_devprof.so was not successful. reason: %s", dlerror());
54 0 : return;
55 : }
56 : const std::vector<std::string> funcName = {
57 10 : "AdprofAicpuStartRegister", "AdprofReportData", "AdprofReportAdditionalInfo", "AdprofAicpuStop"};
58 5 : InitFunctionMap(funcName);
59 5 : return;
60 5 : }
61 0 : ProfilingAdp::GetInstance().SetNewSoFlag(true);
62 : const std::vector<std::string> funcName = {
63 : "MsprofInit",
64 : "MsprofReportAdditionalInfo",
65 0 : };
66 0 : InitFunctionMap(funcName);
67 0 : AICPU_LOG_INFO("Load profiling so successfully. [%u]", isProfApiSo);
68 7 : }
69 :
70 5 : void ProfSoManager::InitFunctionMap(const std::vector<std::string>& funcName)
71 : {
72 5 : if (soHandle_ == nullptr) {
73 0 : AICPU_LOG_ERROR("soHandle is nullptr");
74 0 : return;
75 : }
76 25 : for (auto iter = funcName.begin(); iter != funcName.end(); iter++) {
77 20 : void* func = dlsym(soHandle_, iter->c_str());
78 20 : if (func != nullptr) {
79 20 : (void)funcMap_.insert(make_pair(*iter, func));
80 : } else {
81 0 : AICPU_LOG_ERROR("Failed to get function [%s]", iter->c_str());
82 : }
83 : }
84 5 : return;
85 : }
86 :
87 10 : void ProfSoManager::UnloadSo()
88 : {
89 10 : funcMap_.clear();
90 10 : if (soHandle_ != nullptr) {
91 5 : (void)dlclose(soHandle_);
92 5 : soHandle_ = nullptr;
93 : }
94 10 : }
95 :
96 17 : void* ProfSoManager::GetFunc(const std::string& name) const
97 : {
98 17 : const auto it = funcMap_.find(name);
99 17 : if (it != funcMap_.end()) {
100 7 : return it->second;
101 : }
102 10 : return nullptr;
103 : }
104 :
105 1 : ProfSoManager::~ProfSoManager() { UnloadSo(); }
106 :
107 6 : int32_t AdprofAicpuStartRegisterFunc(AicpuStartFunc aicpuStartCallback, const struct AicpuStartPara* para)
108 : {
109 12 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("AdprofAicpuStartRegister");
110 6 : if (func == nullptr) {
111 2 : AICPU_LOG_ERROR("Failed to get function AdprofAicpuStartRegister");
112 2 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
113 : }
114 4 : return (reinterpret_cast<ProfAicpuStartRegisterFunc>(func))(aicpuStartCallback, para);
115 : }
116 :
117 5 : int32_t AdprofReportDataFunc(VOID_PTR data, uint32_t len)
118 : {
119 10 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("AdprofReportData");
120 5 : if (func == nullptr) {
121 4 : AICPU_LOG_ERROR("Failed to get function AdprofReportData");
122 4 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
123 : }
124 1 : return (reinterpret_cast<ProfReportDataFunc>(func))(data, len);
125 : }
126 :
127 3 : int32_t AdprofReportAdditionalInfoFunc(uint32_t agingFlag, const VOID_PTR data, uint32_t length)
128 : {
129 6 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("AdprofReportAdditionalInfo");
130 3 : if (func == nullptr) {
131 2 : AICPU_LOG_ERROR("Failed to get function AdprofReportAdditionalInfo");
132 2 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
133 : }
134 1 : return (reinterpret_cast<ProfReportAdditionalInfoFunc>(func))(agingFlag, data, length);
135 : }
136 :
137 3 : int32_t AdprofAicpuStopFunc()
138 : {
139 6 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("AdprofAicpuStop");
140 3 : if (func == nullptr) {
141 2 : AICPU_LOG_ERROR("Failed to get function AdprofAicpuStop.");
142 2 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
143 : }
144 1 : return (reinterpret_cast<ProfAdprofAicpuStopFunc>(func))();
145 : }
146 : using ProfMsprofInitFunc = int32_t (*)(uint32_t dataType, VOID_PTR data, uint32_t dataLen);
147 : using ProfMsprofReportAdditionalInfoFunc =
148 : int32_t (*)(uint32_t nonPersistantFlag, const VOID_PTR data, uint32_t length);
149 :
150 0 : int32_t MsprofInitFunc(uint32_t dataType, VOID_PTR data, uint32_t dataLen)
151 : {
152 0 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("MsprofInit");
153 0 : if (func == nullptr) {
154 0 : AICPU_LOG_ERROR("Failed to get function MsprofInit.");
155 0 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
156 : }
157 0 : return (PtrToFunctionPtr<void, ProfMsprofInitFunc>(func))(dataType, data, dataLen);
158 : }
159 :
160 0 : int32_t MsprofReportAdditionalInfoFunc(uint32_t nonPersistantFlag, const VOID_PTR data, uint32_t length)
161 : {
162 0 : void* const func = aicpu::ProfSoManager::GetInstance()->GetFunc("MsprofReportAdditionalInfo");
163 0 : if (func == nullptr) {
164 0 : AICPU_LOG_ERROR("Failed to get function MsprofReportAdditionalInfo.");
165 0 : return static_cast<int32_t>(ProfStatusCode::PROFILINE_FAILED);
166 : }
167 0 : return (PtrToFunctionPtr<void, ProfMsprofReportAdditionalInfoFunc>(func))(nonPersistantFlag, data, length);
168 : }
169 : } // namespace aicpu
|