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 { type LitTable } from '../../../../../base-ui/table/lit-table'; 18import { type SelectionParam } from '../../../../bean/BoxSelection'; 19import { resizeObserver } from '../SheetUtils'; 20import { GpuMemory } from '../../../../bean/AbilityMonitor'; 21import { MemoryConfig } from '../../../../bean/MemoryConfig'; 22import { Utils } from '../../base/Utils'; 23import { SpSystemTrace } from '../../../SpSystemTrace'; 24import { getTabGpuMemoryData } from '../../../../database/sql/Memory.sql'; 25 26@element('tabpane-gpu-memory-vmtracker') 27export class TabPaneGpuMemoryVmTracker extends BaseElement { 28 private gpuMemoryTableTbl: LitTable | null | undefined; 29 private gpuMemorySource: Array<GpuMemory> = []; 30 private tableThead: HTMLDivElement | undefined | null; 31 private gpuMemoryTimeRange: HTMLDivElement | undefined | null; 32 private total: GpuMemory = new GpuMemory(); 33 34 set data(gpuMemoryValue: SelectionParam | unknown) { 35 // @ts-ignore 36 if (gpuMemoryValue.gpuMemoryTrackerData.length > 0) { 37 this.gpuMemoryTimeRange!.textContent = 38 // @ts-ignore 39 'Selected range: ' + ((gpuMemoryValue.rightNs - gpuMemoryValue.leftNs) / 1000000.0).toFixed(5) + ' ms'; 40 this.gpuMemoryTableTbl!.loading = true; 41 this.queryDataByDB(gpuMemoryValue); 42 this.init(); 43 } 44 } 45 46 initElements(): void { 47 this.gpuMemoryTableTbl = this.shadowRoot?.querySelector<LitTable>('#damTable'); 48 this.tableThead = this.gpuMemoryTableTbl?.shadowRoot?.querySelector('.thead') as HTMLDivElement; 49 this.gpuMemoryTimeRange = this.shadowRoot?.querySelector('#gpu-memory-time-range') as HTMLDivElement; 50 this.gpuMemoryTableTbl!.addEventListener('column-click', (e) => { 51 // @ts-ignore 52 this.sortGpuMemoryByColumn(e.detail.key, e.detail.sort); 53 }); 54 } 55 56 connectedCallback(): void { 57 super.connectedCallback(); 58 resizeObserver(this.parentElement!, this.gpuMemoryTableTbl!); 59 } 60 61 queryDataByDB(val: SelectionParam | unknown): void { 62 getTabGpuMemoryData( 63 // @ts-ignore 64 val.leftNs, 65 // @ts-ignore 66 val.rightNs, 67 MemoryConfig.getInstance().iPid, 68 MemoryConfig.getInstance().snapshotDur 69 ).then((data) => { 70 this.gpuMemoryTableTbl!.loading = false; 71 if (data.length !== null && data.length > 0) { 72 this.total = new GpuMemory(); 73 this.total.thread = '*All*'; 74 this.total.gpuName = '*All*'; 75 data.forEach((item) => { 76 if (item.threadName !== null) { 77 item.thread = `${item.threadName}(${item.threadId})`; 78 } else { 79 item.thread = `Thread(${item.threadId})`; 80 } 81 this.total.avgSize += item.avgSize; 82 if (this.total.minSize < 0) { 83 this.total.minSize = item.minSize; 84 } 85 if (this.total.maxSize < 0) { 86 this.total.maxSize = item.maxSize; 87 } 88 this.total.minSize = Math.min(this.total.minSize, item.minSize); 89 this.total.maxSize = Math.max(this.total.maxSize, item.maxSize); 90 91 item.gpuName = SpSystemTrace.DATA_DICT.get(item.gpuNameId) || ''; 92 item.avgSizes = Utils.getBinaryByteWithUnit(Math.round(item.avgSize)); 93 item.minSizes = Utils.getBinaryByteWithUnit(item.minSize); 94 item.maxSizes = Utils.getBinaryByteWithUnit(item.maxSize); 95 }); 96 this.total.avgSizes = Utils.getBinaryByteWithUnit(Math.round(this.total.avgSize / data.length)); 97 this.total.minSizes = Utils.getBinaryByteWithUnit(this.total.minSize); 98 this.total.maxSizes = Utils.getBinaryByteWithUnit(this.total.maxSize); 99 this.gpuMemorySource = data; 100 this.gpuMemorySource.sort(function (gpuMemoryLeftData: GpuMemory, gpuMemoryRightData: GpuMemory) { 101 return gpuMemoryRightData.avgSize - gpuMemoryLeftData.avgSize; 102 }); 103 this.gpuMemoryTableTbl!.recycleDataSource = [...this.gpuMemorySource]; 104 } else { 105 this.gpuMemoryTableTbl!.recycleDataSource = []; 106 this.gpuMemorySource = []; 107 } 108 }); 109 } 110 111 private init(): void { 112 const thTable = this.tableThead!.querySelector('.th'); 113 const list = thTable!.querySelectorAll('div'); 114 if (this.tableThead!.hasAttribute('sort')) { 115 this.tableThead!.removeAttribute('sort'); 116 list.forEach((item) => { 117 item.querySelectorAll('svg').forEach((svg) => { 118 svg.style.display = 'none'; 119 }); 120 }); 121 } 122 } 123 124 initHtml(): string { 125 return ` 126 <style> 127 .gpu-memory-table{ 128 flex-direction: row; 129 margin-bottom: 5px; 130 } 131 :host{ 132 display: flex; 133 flex-direction: column; 134 padding: 10px 10px; 135 } 136 </style> 137 <div class="gpu-memory-table" style="display: flex;height: 20px;align-items: center;flex-direction: row;margin-bottom: 5px"> 138 <div style="flex: 1"></div> 139 <label id="gpu-memory-time-range" style="width: auto;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label> 140 </div> 141 <div style="overflow: auto"> 142 <lit-table id="damTable" class="damTable"> 143 <lit-table-column order title="GpuName" data-index="gpuName" key="gpuName" align="flex-start" width="1fr" > 144 </lit-table-column> 145 <lit-table-column order title="Thread(tid)" data-index="thread" key="thread" align="flex-start" width="1fr" > 146 </lit-table-column> 147 <lit-table-column order title="AvgSize" data-index="avgSizes" key="avgSize" align="flex-start" width="1fr" > 148 </lit-table-column>5 149 <lit-table-column order title="MaxSize" data-index="maxSizes" key="maxSize" align="flex-start" width="1fr" > 150 </lit-table-column> 151 <lit-table-column order title="MinSize" data-index="minSizes" key="minSize" align="flex-start" width="1fr" > 152 </lit-table-column> 153 </lit-table> 154 </div> 155 `; 156 } 157 158 sortGpuMemoryByColumn(column: string, sort: number): void { 159 switch (sort) { 160 case 0: 161 this.gpuMemoryTableTbl!.recycleDataSource = [...this.gpuMemorySource]; 162 break; 163 default: 164 let array = [...this.gpuMemorySource]; 165 switch (column) { 166 case 'gpuName': 167 array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 168 return sort === 1 169 ? `${gpuMemoryLeftData.gpuName}`.localeCompare(`${gpuMemoryRightData.gpuName}`) 170 : `${gpuMemoryRightData.gpuName}`.localeCompare(`${gpuMemoryLeftData.gpuName}`); 171 }); 172 break; 173 case 'avgSize': 174 array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 175 return sort === 1 176 ? gpuMemoryLeftData.avgSize - gpuMemoryRightData.avgSize 177 : gpuMemoryRightData.avgSize - gpuMemoryLeftData.avgSize; 178 }); 179 break; 180 case 'minSize': 181 array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 182 return sort === 1 183 ? gpuMemoryLeftData.minSize - gpuMemoryRightData.minSize 184 : gpuMemoryRightData.minSize - gpuMemoryLeftData.minSize; 185 }); 186 break; 187 case 'maxSize': 188 array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 189 return sort === 1 190 ? gpuMemoryLeftData.maxSize - gpuMemoryRightData.maxSize 191 : gpuMemoryRightData.maxSize - gpuMemoryLeftData.maxSize; 192 }); 193 break; 194 case 'thread': 195 array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 196 return sort === 1 197 ? `${gpuMemoryLeftData.thread}`.localeCompare(`${gpuMemoryRightData.thread}`) 198 : `${gpuMemoryRightData.thread}`.localeCompare(`${gpuMemoryLeftData.thread}`); 199 }); 200 break; 201 } 202 this.gpuMemoryTableTbl!.recycleDataSource = [...array]; 203 break; 204 } 205 } 206} 207