11import { Component , inject , Input , OnChanges , OnDestroy , SimpleChanges } from '@angular/core' ;
2+ import { Store } from '@ngrx/store' ;
23import { FileExtensionType } from 'org_xprof/frontend/app/common/constants/enums' ;
34import { DATA_SERVICE_INTERFACE_TOKEN , DataServiceV2Interface } from 'org_xprof/frontend/app/services/data_service_v2/data_service_v2_interface' ;
45import { Address } from 'org_xprof/frontend/app/services/source_code_service/source_code_service_interface' ;
6+ import { getTagsState } from 'org_xprof/frontend/app/store/selectors' ;
57import { ReplaySubject } from 'rxjs' ;
68import { takeUntil } from 'rxjs/operators' ;
79
10+ const CUSTOM_CALL_CATEGORY = 'custom-call' ;
11+
812enum 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