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