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_profiler.h"
11 : #include "hiperf_marker.h"
12 : #include "hiperf_exception.h"
13 : #include "aicpusd_common.h"
14 :
15 : namespace AicpuSchedule {
16 : namespace {
17 : constexpr float64_t SECOND_TO_NANO = 1000000000.0;
18 : constexpr float64_t ONE_MS = 1000000.0;
19 : constexpr uint32_t HIGH_POISTION_OFFSET_64_BIT = 32U;
20 : constexpr uint32_t HIGH_POISTION_OFFSET_32_BIT = 16U;
21 : constexpr uint32_t LOW_POISTION_MASK_32_BIT = 0x0000ffffU;
22 : const std::string HIPERF_LIB_PATH = "/usr/lib64/libhiperf_executor.so";
23 : } // namespace
24 :
25 : /**
26 : * @ingroup AicpuProfiler
27 : * @brief it is used to construct a object of AicpuScheduleCore.
28 : */
29 3 : AicpuProfiler::AicpuProfiler() noexcept
30 3 : : pid_(0),
31 3 : tid_(0),
32 3 : kernelTrack_({0UL}),
33 3 : frequence_(0.0),
34 3 : hiperfExisted_(false),
35 3 : accessHiperfSo_(false),
36 3 : oneMsForTick_(0UL),
37 3 : tenMsForTick_(0UL)
38 3 : {}
39 :
40 : /**
41 : * @ingroup AicpuProfiler
42 : * @brief it is used to destructor a object of AicpuProfiler.
43 : */
44 3 : void AicpuProfiler::Uninit() { ::FiniMarker(); }
45 :
46 3 : void AicpuProfiler::InitProfiler(const pid_t processId, const pid_t threadId)
47 : {
48 3 : if (!accessHiperfSo_) {
49 3 : if (access(HIPERF_LIB_PATH.c_str(), F_OK) == 0) {
50 2 : hiperfExisted_ = true;
51 : }
52 3 : accessHiperfSo_ = true;
53 : } else {
54 0 : if (!hiperfExisted_) {
55 0 : return;
56 : }
57 : }
58 3 : kernelTrack_ = {0UL};
59 3 : pid_ = processId;
60 3 : tid_ = threadId;
61 :
62 3 : if (tenMsForTick_ == 0UL) {
63 3 : frequence_ = static_cast<float64_t>(GetAicpuSysFreq());
64 3 : const float64_t oneMsForTickTemp = ONE_MS / (SECOND_TO_NANO / frequence_);
65 3 : oneMsForTick_ = static_cast<uint64_t>(oneMsForTickTemp);
66 3 : tenMsForTick_ = oneMsForTick_ * 10UL;
67 : }
68 : }
69 :
70 1 : void AicpuProfiler::ProfilerAgentInit() { ::InitMarker(); }
71 :
72 3 : void AicpuProfiler::Profiler()
73 : {
74 3 : if (!hiperfExisted_) {
75 1 : return;
76 : }
77 2 : kernelTrack_.pid = pid_;
78 2 : kernelTrack_.tid = static_cast<int32_t>(GetTid());
79 2 : (void)Hiva::MarkerAicpuScheduler(kernelTrack_);
80 2 : const uint64_t prefKey = BuildKey();
81 2 : if (kernelTrack_.activeStream != 0UL) {
82 1 : (void)Hiva::PerfDurationBegin(prefKey, kernelTrack_.activeStream);
83 1 : } else if (kernelTrack_.endGraph != 0UL) {
84 1 : (void)Hiva::PerfDurationEnd(prefKey, kernelTrack_.endGraph, tenMsForTick_, kernelTrack_);
85 : } else {
86 0 : return;
87 : }
88 : }
89 :
90 2 : uint64_t AicpuProfiler::BuildKey()
91 : {
92 2 : const uint64_t key = (static_cast<uint64_t>(kernelTrack_.modelId) << HIGH_POISTION_OFFSET_64_BIT) |
93 2 : ((static_cast<uint64_t>(kernelTrack_.rawStamp.tv_sec) & LOW_POISTION_MASK_32_BIT)
94 2 : << HIGH_POISTION_OFFSET_32_BIT) |
95 2 : (static_cast<uint64_t>(kernelTrack_.rawStamp.tv_nsec) & LOW_POISTION_MASK_32_BIT);
96 2 : return key;
97 : }
98 :
99 1 : uint64_t AicpuProfiler::SchedGetCurCpuTick(void) const
100 : {
101 1 : uint64_t cnt = 0UL;
102 : #ifndef RUN_TEST
103 : asm volatile("mrs %0, CNTVCT_EL0" : "=r"(cnt) :);
104 : #endif
105 1 : return cnt;
106 : }
107 :
108 4 : uint64_t AicpuProfiler::GetAicpuSysFreq() const
109 : {
110 4 : uint64_t freq = 1UL;
111 : #ifndef RUN_TEST
112 : asm volatile("mrs %0, CNTFRQ_EL0" : "=r"(freq) :);
113 : #endif
114 4 : return freq;
115 : }
116 :
117 : thread_local AicpuProfiler g_aicpuProfiler;
118 : } // namespace AicpuSchedule
|