Skip to content

Commit db2604a

Browse files
zzzariescopybara-github
authored andcommitted
Updated source mapper component to support more compiler passes.
No-op changes as the corresponding data service is not implemented yet. But the PiperOrigin-RevId: 825430176
1 parent d0f3c71 commit db2604a

File tree

5 files changed

+170
-10
lines changed

5 files changed

+170
-10
lines changed

frontend/app/components/op_profile/op_profile_base.ng.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@
119119
[stackTrace]="stackTrace"
120120
[sessionId]="sessionId"
121121
[programId]="focusedOpProgramId"
122-
[opName]="focusedOpName"/>
122+
[opName]="focusedOpName"
123+
[opCategory]="focusedOpCategory"/>
123124
</as-split-area>
124125
</as-split>
125126
</mat-sidenav-content>

frontend/app/components/op_profile/op_profile_base.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export class OpProfileBase implements OnDestroy, OnInit, OnChanges {
4444
stackTrace = '';
4545
focusedOpProgramId = '';
4646
focusedOpName = '';
47+
focusedOpCategory = '';
4748
showStackTrace = false;
4849
useUncappedFlops = false;
4950

@@ -91,6 +92,7 @@ export class OpProfileBase implements OnDestroy, OnInit, OnChanges {
9192
this.stackTrace = node?.xla?.sourceInfo?.stackFrame || '';
9293
this.focusedOpProgramId = node?.xla?.programId || '';
9394
this.focusedOpName = node?.name || '';
95+
this.focusedOpCategory = node?.xla?.category || '';
9496
}
9597

9698
ngOnChanges(changes: SimpleChanges) {

frontend/app/components/source_mapper/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ xprof_ng_module(
1616
deps = [
1717
"@npm//@angular/core",
1818
"@npm//@angular/forms",
19+
"@npm//@ngrx/store",
1920
"@npm//rxjs",
2021
"@org_xprof//frontend/app/common/angular:angular_material_expansion",
2122
"@org_xprof//frontend/app/common/angular:angular_material_form_field",
@@ -28,6 +29,7 @@ xprof_ng_module(
2829
"@org_xprof//frontend/app/components/stack_trace_snippet:message",
2930
"@org_xprof//frontend/app/services/data_service_v2:data_service_v2_interface",
3031
"@org_xprof//frontend/app/services/source_code_service:source_code_service_interface",
32+
"@org_xprof//frontend/app/store",
3133
],
3234
)
3335

frontend/app/components/source_mapper/source_mapper.ng.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
</mat-select>
1010
</mat-form-field>
1111
<stack-trace-snippet
12-
[sourceFileAndLineNumber]="sourceFileAndLineNumber"
13-
[stackTrace]="stackTrace"
12+
[sourceFileAndLineNumber]="adaptedSourceFileAndLineNumber"
13+
[stackTrace]="adaptedStackTrace"
1414
[sourceContextWindow]="sourceContextWindow"
1515
/>
1616
</div>
1717

1818
<div class="ir-text-container">
1919
<mat-form-field class="ir-type-select" (click)="$event.stopPropagation()" appearance="outline">
2020
<mat-label>Compiler Pass</mat-label>
21-
<mat-select [(ngModel)]="selectedCompilerPass">
21+
<mat-select [ngModel]="selectedCompilerPass" (ngModelChange)="onCompilerPassChange($event)">
2222
<mat-option *ngFor="let pass of compilerPasses" [value]="pass">
2323
{{pass}}
2424
</mat-option>

frontend/app/components/source_mapper/source_mapper.ts

Lines changed: 161 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import {Component, inject, Input, OnChanges, OnDestroy, SimpleChanges} from '@angular/core';
2+
import {Store} from '@ngrx/store';
23
import {FileExtensionType} from 'org_xprof/frontend/app/common/constants/enums';
34
import {DATA_SERVICE_INTERFACE_TOKEN, DataServiceV2Interface} from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2_interface';
45
import {Address} from 'org_xprof/frontend/app/services/source_code_service/source_code_service_interface';
6+
import {getTagsState} from 'org_xprof/frontend/app/store/selectors';
57
import {ReplaySubject} from 'rxjs';
68
import {takeUntil} from 'rxjs/operators';
79

10+
const CUSTOM_CALL_CATEGORY = 'custom-call';
11+
812
enum CompilerPass {
913
HLO_OPTIMIZED = 'HLO(optimized)',
10-
MOSAIC_LLO = 'Mosaic llo',
14+
MOSAIC_ORIGINAL = 'Mosaic original',
1115
}
1216

1317
/**
@@ -27,37 +31,107 @@ export class SourceMapper implements OnDestroy, OnChanges {
2731
private readonly dataService: DataServiceV2Interface =
2832
inject(DATA_SERVICE_INTERFACE_TOKEN);
2933

34+
/**
35+
* The source file and line number of the HLO op.
36+
* This is used to find the source code snippet.
37+
* Processed from xla source info.
38+
*/
3039
@Input() sourceFileAndLineNumber: string|undefined = undefined;
31-
@Input() stackTrace: string|undefined = undefined;
3240
/**
33-
* The number of lines to show around the stack frame.
41+
* The stack trace of the HLO op.
42+
* Processed from xla stack frame info.
3443
*/
44+
@Input() stackTrace: string|undefined = undefined;
45+
// The number of lines to show around the stack frame.
3546
@Input() sourceContextWindow = 40;
3647
@Input() sessionId = '';
48+
// The program id of the HLO op.
3749
@Input() programId = '';
50+
// The name of the HLO op.
3851
@Input() opName = '';
52+
// The category of the HLO op.
53+
@Input() opCategory = '';
3954

4055
sourceCodeSnippetAddresses: readonly Address[] = [];
4156
hloTextByProgramId = new Map<string, string>();
42-
// TODO(yinzz): add CompilerPass.MOSAIC_LLO
43-
compilerPasses = [CompilerPass.HLO_OPTIMIZED];
57+
mosaicTextByKernelName = new Map<string, string>();
58+
mosaicSourceFileAndLineNumberByKernelName = new Map<string, string>();
4459
selectedCompilerPass = CompilerPass.HLO_OPTIMIZED;
4560
sourceFileNames: string[] = [];
4661
selectedSourceFileName = '';
62+
tags: string[] = [];
63+
64+
// TODO: create data service to fetch source info and ir text for selected
65+
// kernel (matching with hlo op name) by using llo dump and utils.
66+
67+
constructor(private readonly store: Store<{}>) {
68+
this.store.select(getTagsState)
69+
.pipe(takeUntil(this.destroyed))
70+
.subscribe((tags: string[]) => {
71+
if (!tags || tags.length === 0) return;
72+
this.tags = tags;
73+
});
74+
}
4775

4876
ngOnChanges(changes: SimpleChanges) {
4977
if (changes['sessionId'] &&
5078
changes['sessionId'].currentValue !== this.sessionId) {
5179
this.hloTextByProgramId.clear();
80+
this.mosaicTextByKernelName.clear();
81+
this.mosaicSourceFileAndLineNumberByKernelName.clear();
5282
}
5383
if (changes['programId']) {
5484
this.maybeUpdateHloTextCache();
5585
}
86+
if (changes['opName'] && changes['opName'].currentValue !== this.opName) {
87+
this.maybeUpdateMosaicTextCache();
88+
this.maybeUpdateMosaicSourceFileAndLineNumberCache();
89+
}
5690
if (changes['sourceFileAndLineNumber'] || changes['stackTrace']) {
5791
this.parseSourceFileNames();
5892
}
5993
}
6094

95+
get adaptedStackTrace(): string {
96+
switch (this.selectedCompilerPass) {
97+
case CompilerPass.HLO_OPTIMIZED:
98+
return this.stackTrace || '';
99+
case CompilerPass.MOSAIC_ORIGINAL:
100+
return this.getPallasKernelStackTrace();
101+
default:
102+
return '';
103+
}
104+
}
105+
106+
get adaptedSourceFileAndLineNumber(): string {
107+
switch (this.selectedCompilerPass) {
108+
case CompilerPass.HLO_OPTIMIZED:
109+
return this.sourceFileAndLineNumber || '';
110+
case CompilerPass.MOSAIC_ORIGINAL:
111+
return this.pallasKernelSourceFileAndLineNumber;
112+
default:
113+
return '';
114+
}
115+
}
116+
117+
get compilerPasses(): string[] {
118+
const basePasses = [CompilerPass.HLO_OPTIMIZED];
119+
// llo_debug tag is identifier for llo debug proto captured.
120+
// the proto contains llo bundles for kernels, and source info for mosaic
121+
// passes.
122+
if (this.hasLloDebugTag) {
123+
// CustomCall op category is identifier for a pallas kernel.
124+
if (this.isCustomCall) {
125+
basePasses.push(CompilerPass.MOSAIC_ORIGINAL);
126+
}
127+
}
128+
return basePasses;
129+
}
130+
131+
get hasLloDebugTag() {
132+
return this.tags.includes('llo_debug');
133+
}
134+
61135
get irTextLink(): string {
62136
return '';
63137
}
@@ -70,6 +144,8 @@ export class SourceMapper implements OnDestroy, OnChanges {
70144
switch (this.selectedCompilerPass) {
71145
case CompilerPass.HLO_OPTIMIZED:
72146
return this.hloTextByProgramId.get(this.programId) || '';
147+
case CompilerPass.MOSAIC_ORIGINAL:
148+
return this.mosaicTextByKernelName.get(this.opName) || '';
73149
default:
74150
return '';
75151
}
@@ -79,6 +155,20 @@ export class SourceMapper implements OnDestroy, OnChanges {
79155
return this.irText.split('\n');
80156
}
81157

158+
get isCustomCall() {
159+
return this.opCategory.includes(CUSTOM_CALL_CATEGORY);
160+
}
161+
162+
get pallasKernelSourceFileAndLineNumber() {
163+
return this.mosaicSourceFileAndLineNumberByKernelName.get(this.opName) ||
164+
'';
165+
}
166+
167+
// Not implemented yet.
168+
getPallasKernelStackTrace() {
169+
return '';
170+
}
171+
82172
isFocusLine(line: string): boolean {
83173
switch (this.selectedCompilerPass) {
84174
case CompilerPass.HLO_OPTIMIZED:
@@ -92,7 +182,13 @@ export class SourceMapper implements OnDestroy, OnChanges {
92182
switch (this.selectedCompilerPass) {
93183
case CompilerPass.HLO_OPTIMIZED:
94184
return this.irTextLines.findIndex(
95-
(line) => line.includes(`${this.opName} =`)) ||
185+
(line: string) => line.includes(`${this.opName} =`)) ||
186+
0;
187+
case CompilerPass.MOSAIC_ORIGINAL:
188+
// Assumptions: the MLIR text contains the key word kernel in the kernel
189+
// definition line.
190+
return this.irTextLines.findIndex(
191+
(line: string) => line.includes('kernel')) ||
96192
0;
97193
default:
98194
return 0;
@@ -150,6 +246,65 @@ export class SourceMapper implements OnDestroy, OnChanges {
150246
});
151247
}
152248

249+
maybeUpdateMosaicTextCache() {
250+
if (!this.opName || this.sessionId === '' ||
251+
this.selectedCompilerPass !== CompilerPass.MOSAIC_ORIGINAL) {
252+
return;
253+
}
254+
const text = this.mosaicTextByKernelName.get(this.opName);
255+
if (text) {
256+
return;
257+
}
258+
this.dataService
259+
.getCustomCallText(
260+
this.sessionId,
261+
'',
262+
this.opName,
263+
this.programId,
264+
)
265+
.pipe(takeUntil(this.destroyed))
266+
.subscribe((data: string) => {
267+
if (data) {
268+
this.mosaicTextByKernelName.set(this.opName, data);
269+
}
270+
});
271+
}
272+
273+
maybeUpdateMosaicSourceFileAndLineNumberCache() {
274+
if (!this.opName || this.sessionId === '' ||
275+
this.selectedCompilerPass !== CompilerPass.MOSAIC_ORIGINAL) {
276+
return;
277+
}
278+
const sourceFileAndLineNumber =
279+
this.mosaicSourceFileAndLineNumberByKernelName.get(this.opName);
280+
if (sourceFileAndLineNumber) {
281+
return;
282+
}
283+
this.dataService.getLloSourceInfo(this.sessionId, this.opName)
284+
.pipe(takeUntil(this.destroyed))
285+
.subscribe((sourceInfo) => {
286+
if (sourceInfo) {
287+
this.mosaicSourceFileAndLineNumberByKernelName.set(
288+
this.opName, sourceInfo);
289+
}
290+
});
291+
}
292+
293+
onCompilerPassChange(newCompilerPass: CompilerPass) {
294+
this.selectedCompilerPass = newCompilerPass;
295+
switch (this.selectedCompilerPass) {
296+
case CompilerPass.HLO_OPTIMIZED:
297+
this.maybeUpdateHloTextCache();
298+
break;
299+
case CompilerPass.MOSAIC_ORIGINAL:
300+
this.maybeUpdateMosaicTextCache();
301+
this.maybeUpdateMosaicSourceFileAndLineNumberCache();
302+
break;
303+
default:
304+
break;
305+
}
306+
}
307+
153308
ngOnDestroy(): void {
154309
this.destroyed.next();
155310
this.destroyed.complete();

0 commit comments

Comments
 (0)