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