• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { BaseElement, element } from '../../../../../base-ui/BaseElement';
17import { LitTable } from '../../../../../base-ui/table/lit-table';
18import { SelectionParam } from '../../../../bean/BoxSelection';
19import { XpowerGpuFreqStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerGpuFreq';
20import { SpSystemTrace } from '../../../SpSystemTrace';
21import { SpChartList } from '../../SpChartList';
22import { TraceRow } from '../../base/TraceRow';
23import { SortDetail, resizeObserver } from '../SheetUtils';
24
25@element('tabpane-xpower-gpu-freq')
26export class TabPaneXpowerGpuFreq extends BaseElement {
27  private XpowerGpuFreqTbl: LitTable | null | undefined;
28  private XpowerGpuFreqRange: HTMLLabelElement | null | undefined;
29  private XpowerGpuFreqSource: Array<TabXpowerGpuFreqStruct> = [];
30  private sumCount: number = 0;
31  private tabTitle: HTMLDivElement | undefined | null;
32  private traceRow: TraceRow<XpowerGpuFreqStruct> | undefined | null;
33  private checked: boolean[] = [];
34  private checkedValue: string[] = [];
35  private systemTrace: SpSystemTrace | undefined | null;
36  private spChartList: SpChartList | undefined | null;
37
38  set data(XpowerGpuFreqValue: SelectionParam) {
39    this.init();
40    this.XpowerGpuFreqTbl!.shadowRoot!.querySelector<HTMLDivElement>('.table')!.style!.height = `${
41      this.parentElement!.clientHeight - 45
42    }px`;
43    this.XpowerGpuFreqRange!.textContent = `Selected range: ${parseFloat(
44      ((XpowerGpuFreqValue.rightNs - XpowerGpuFreqValue.leftNs) / 1000000.0).toFixed(5)
45    )} ms`;
46    this.traceRow = this.systemTrace!.shadowRoot?.querySelector<TraceRow<XpowerGpuFreqStruct>>(
47      "trace-row[row-id='gpu-frequency']"
48    );
49    if (!this.traceRow) {
50      this.spChartList = this.systemTrace!.shadowRoot?.querySelector('div > sp-chart-list');
51      this.traceRow = this.spChartList?.shadowRoot!.querySelector(".root > div > trace-row[row-id='gpu-frequency']");
52    }
53    this.checked = this.traceRow!.rowSettingCheckedBoxList!;
54    this.checkedValue = this.traceRow!.rowSettingCheckBoxList!;
55    this.getGpuFreqData(XpowerGpuFreqValue).then();
56  }
57
58  async getGpuFreqData(XpowerGpuFreqValue: SelectionParam): Promise<void> {
59    this.sumCount = 0;
60    let dataSource: Array<TabXpowerGpuFreqStruct> = [];
61    let collect = XpowerGpuFreqValue.xpowerGpuFreqMapData;
62    this.XpowerGpuFreqTbl!.loading = true;
63    for (let key of collect.keys()) {
64      let gpuFreqs = collect.get(key);
65      let res = (await gpuFreqs?.({
66        startNS: XpowerGpuFreqValue.leftNs,
67        endNS: XpowerGpuFreqValue.rightNs,
68        queryAll: true,
69      })) as XpowerGpuFreqStruct[];
70      res = res.filter((item) => this.checked[this.checkedValue?.indexOf(item.frequency.toString())]);
71      let sd = this.createTabXpowerGpuFreqStruct(res || []);
72      dataSource = dataSource.concat(sd);
73    }
74    this.XpowerGpuFreqTbl!.loading = false;
75    this.XpowerGpuFreqSource = dataSource;
76    this.XpowerGpuFreqTbl!.recycleDataSource = dataSource;
77  }
78
79  private init(): void {
80    const thTable = this.tabTitle!.querySelector('.th');
81    const list = thTable!.querySelectorAll('div');
82    if (this.tabTitle!.hasAttribute('sort')) {
83      this.tabTitle!.removeAttribute('sort');
84      list.forEach((item) => {
85        item.querySelectorAll('svg').forEach((svg) => {
86          svg.style.display = 'none';
87        });
88      });
89    }
90  }
91
92  initElements(): void {
93    this.systemTrace = document
94      .querySelector('body > sp-application')
95      ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace');
96    this.XpowerGpuFreqTbl = this.shadowRoot?.querySelector<LitTable>('#tb-gpu-freq');
97    this.tabTitle = this.XpowerGpuFreqTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
98    this.XpowerGpuFreqRange = this.shadowRoot?.querySelector('#time-range');
99    this.XpowerGpuFreqTbl!.addEventListener('column-click', (evt): void => {
100      // @ts-ignore
101      this.sortByColumn(evt.detail);
102    });
103  }
104
105  connectedCallback(): void {
106    super.connectedCallback();
107    resizeObserver(this.parentElement!, this.XpowerGpuFreqTbl!);
108  }
109
110  initHtml(): string {
111    return `
112        <style>
113        .xpower-gpu-freq-label{
114            margin-bottom: 5px;
115        }
116        :host{
117            padding: 10px 10px;
118            display: flex;
119            flex-direction: column;
120        }
121        </style>
122        <label id="time-range" class="xpower-gpu-freq-label" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label>
123        <lit-table id="tb-gpu-freq" style="height: auto">
124            <lit-table-column title="Frequency" data-index="frequency" key="frequency" align="flex-start" width="25%" order>
125            </lit-table-column>
126            <lit-table-column  title="Count" data-index="count" key="count" align="flex-start" width="1fr" order>
127            </lit-table-column>
128            <lit-table-column title="Avg RunTime(ms)" data-index="avgRunTime" key="avgRunTime" align="flex-start" width="1fr" order>
129            </lit-table-column>
130            <lit-table-column title="Max RunTime(ms)"  data-index="maxRunTime" key="maxRunTime" align="flex-start" width="1fr" order>
131            </lit-table-column>
132            <lit-table-column title="Min RunTime(ms)" data-index="minRunTime" key="minRunTime" align="flex-start" width="1fr" order>
133            </lit-table-column>
134            <lit-table-column title="Avg IdleTime(ms)" data-index="avgIdleTime" key="avgIdleTime" align="flex-start" width="1fr" order>
135            </lit-table-column>
136            <lit-table-column title="Max IdleTime(ms)"  data-index="maxIdleTime" key="maxIdleTime" align="flex-start" width="1fr" order>
137            </lit-table-column>
138            <lit-table-column title="Min IdleTime(ms)" data-index="minIdleTime" key="minIdleTime" align="flex-start" width="1fr" order>
139            </lit-table-column>
140        </lit-table>
141        `;
142  }
143
144  private setGpuFreqMap(list: Array<XpowerGpuFreqStruct>): Map<number, XpowerGpuFreqStruct[]> {
145    let gpuFreqMap = new Map();
146    list.forEach((item) => {
147      if (gpuFreqMap.has(item.frequency)) {
148        const data = gpuFreqMap.get(item.frequency)!;
149        data.push(item);
150      } else {
151        const data: XpowerGpuFreqStruct[] = [];
152        data.push(item);
153        gpuFreqMap.set(item.frequency, data);
154      }
155    });
156    return gpuFreqMap;
157  }
158
159  private setTabXpowerGpuFreqStruct(
160    runTimeValue: number,
161    idleTimeValue: number,
162    tabXpowerGpuFreqStruct: TabXpowerGpuFreqStruct
163  ): TabXpowerGpuFreqStruct {
164    tabXpowerGpuFreqStruct.avgRunTime = parseFloat(runTimeValue.toFixed(2));
165    tabXpowerGpuFreqStruct.maxRunTime = runTimeValue;
166    tabXpowerGpuFreqStruct.minRunTime = runTimeValue;
167    tabXpowerGpuFreqStruct.avgIdleTime = parseFloat(idleTimeValue.toFixed(2));
168    tabXpowerGpuFreqStruct.maxIdleTime = idleTimeValue;
169    tabXpowerGpuFreqStruct.minIdleTime = idleTimeValue;
170    return tabXpowerGpuFreqStruct;
171  }
172  private getRunTimeMax(itemArray: XpowerGpuFreqStruct[]): number {
173    let max = itemArray
174      .map((item: { runTime: number }) => item.runTime)
175      .reduce((a: number, b: number) => Math.max(a, b));
176    return max;
177  }
178
179  private getRunTimeMin(itemArray: XpowerGpuFreqStruct[]): number {
180    let min = itemArray
181      .map((item: { runTime: number }) => item.runTime)
182      .reduce((a: number, b: number) => Math.min(a, b));
183    return min;
184  }
185
186  private getIdleTimeMax(itemArray: XpowerGpuFreqStruct[]): number {
187    let max = itemArray
188      .map((item: { idleTime: number }) => item.idleTime)
189      .reduce((a: number, b: number) => Math.max(a, b));
190    return max;
191  }
192
193  private getIdleTimeMin(itemArray: XpowerGpuFreqStruct[]): number {
194    let min = itemArray
195      .map((item: { idleTime: number }) => item.idleTime)
196      .reduce((a: number, b: number) => Math.min(a, b));
197    return min;
198  }
199
200  createTabXpowerGpuFreqStruct(list: Array<XpowerGpuFreqStruct>): TabXpowerGpuFreqStruct[] {
201    let SelectGpuFreqArray: TabXpowerGpuFreqStruct[] = [];
202    if (list.length > 0) {
203      let gpuFreqMap = this.setGpuFreqMap(list);
204      for (let itemArray of gpuFreqMap.values()) {
205        let tabXpowerGpuFreqStruct = new TabXpowerGpuFreqStruct();
206        tabXpowerGpuFreqStruct.frequency = itemArray[0].frequency;
207        tabXpowerGpuFreqStruct.count = itemArray.length;
208        if (itemArray.length > 1) {
209          let maxRunTime = this.getRunTimeMax(itemArray);
210          let minRunTime = this.getRunTimeMin(itemArray); // @ts-ignore
211          let sumRunTime: unknown = itemArray.reduce((acc: unknown, obj: { runTime: unknown }) => acc + obj.runTime, 0); // @ts-ignore
212          tabXpowerGpuFreqStruct.avgRunTime = parseFloat((sumRunTime / itemArray.length).toFixed(2));
213          tabXpowerGpuFreqStruct.maxRunTime = maxRunTime;
214          tabXpowerGpuFreqStruct.minRunTime = minRunTime;
215          let maxIdleTime = this.getIdleTimeMax(itemArray);
216          let minIdleTime = this.getIdleTimeMin(itemArray); // @ts-ignore
217          let sumIdleTime: unknown = itemArray.reduce((acc: unknown, obj: { idleTime: unknown }) => acc + obj.idleTime, 0); // @ts-ignore
218          tabXpowerGpuFreqStruct.avgIdleTime = parseFloat((sumIdleTime / itemArray.length).toFixed(2));
219          tabXpowerGpuFreqStruct.maxIdleTime = maxIdleTime;
220          tabXpowerGpuFreqStruct.minIdleTime = minIdleTime;
221        } else if (itemArray.length === 1) {
222          tabXpowerGpuFreqStruct = this.setTabXpowerGpuFreqStruct(
223            itemArray[0].runTime,
224            itemArray[0].idleTime,
225            tabXpowerGpuFreqStruct
226          );
227        }
228        this.sumCount += itemArray.length;
229        SelectGpuFreqArray.push(tabXpowerGpuFreqStruct);
230      }
231    }
232    return SelectGpuFreqArray;
233  }
234
235  private sortByColumn(detail: SortDetail): void {
236    function compare(property: string, sort: number, type: string) {
237      return function (
238        xpowerCounterLeftData: TabXpowerGpuFreqStruct,
239        xpowerCounterRightData: TabXpowerGpuFreqStruct
240      ): number {
241        if (!xpowerCounterLeftData.frequency || !xpowerCounterRightData.frequency) {
242          return 0;
243        }
244        if (type === 'number') {
245          return sort === 2 // @ts-ignore
246            ? parseFloat(xpowerCounterRightData[property]) - parseFloat(xpowerCounterLeftData[property]) // @ts-ignore
247            : parseFloat(xpowerCounterLeftData[property]) - parseFloat(xpowerCounterRightData[property]);
248        } else {
249          // @ts-ignore
250          if (xpowerCounterRightData[property] > xpowerCounterLeftData[property]) {
251            return sort === 2 ? 1 : -1;
252          } else {
253            // @ts-ignore
254            if (xpowerCounterRightData[property] === xpowerCounterLeftData[property]) {
255              return 0;
256            } else {
257              return sort === 2 ? -1 : 1;
258            }
259          }
260        }
261      };
262    }
263    this.XpowerGpuFreqSource.sort(compare(detail.key, detail.sort, 'number'));
264    this.XpowerGpuFreqTbl!.recycleDataSource = this.XpowerGpuFreqSource;
265  }
266}
267
268export class TabXpowerGpuFreqStruct {
269  frequency: number = 0;
270  count: number = 0;
271  avgRunTime: number = 0;
272  maxRunTime: number = 0;
273  minRunTime: number = 0;
274  avgIdleTime: number = 0;
275  maxIdleTime: number = 0;
276  minIdleTime: number = 0;
277}
278