Skip to content

Commit 40fbb32

Browse files
committed
wip: perf data integration
1 parent b72de7e commit 40fbb32

File tree

4 files changed

+264
-39
lines changed

4 files changed

+264
-39
lines changed

frontend/packages/common/MLIRLayerAnalysis.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
const enumEdges = (data, edgesDown, edgesUp) => {
2-
console.log("enumEdges",data)
32
if (Array.isArray(data)) {
43
data.forEach((child) => {
54
enumEdges(child, edgesDown, edgesUp)
65
})
76
} else if (data.type === "op") {
87
if (data.mappedId) {
9-
console.log("setting", data.id, data.mappedId)
108
edgesUp[data.id] = data.mappedId
119
if (!edgesDown[data.mappedId]){
1210
edgesDown[data.mappedId] = []

frontend/packages/insights/src/App.js

Lines changed: 190 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
import './App.css';
22
import React, {useEffect, useState} from "react";
33
import 'bootstrap/dist/css/bootstrap.min.css';
4-
import {Button, Col, Container, Form, Navbar, Row} from 'react-bootstrap';
4+
import {Button, Col, Container, Form, Navbar, Row, Tab, Tabs} from 'react-bootstrap';
55
import {MLIRViewer} from "@lingodb/common/MLIRViewer";
66
import {RelationalPlanViewer} from "@lingodb/common/RelationalPlanViewer";
77
import {TraceViewer} from "@lingodb/common/TraceViewer";
88
import {analyzeLayers, getBaseReference, goUp} from "@lingodb/common/MLIRLayerAnalysis";
9+
import {SubOpPlanViewer} from "@lingodb/common/SubOpPlanViewer";
10+
import {PerfSymbolTable} from "./PerfSymbolTable";
11+
import {PerfAsmViewer} from "./PerfAsmViewer";
912

1013
const App = () => {
1114
const [data, setData] = useState(null);
12-
const [mlirData, setMlirData] = useState(null);
15+
const [relalgMLIRData, setRelalgMLIRData] = useState(null);
16+
const [subopMLIRData, setSubOpMLIRData] = useState(null);
17+
const [llvmMLIRData, setLlvmMLIRData] = useState(null);
18+
const [imperativeMLIRData, setImperativeMLIRData] = useState(null);
1319
const [hasTrace, setHasTrace] = useState(false);
1420
const [hasPlan, setHasPlan] = useState(false);
21+
const [hasSubOpPlan, setHasSubOpPlan] = useState(false);
22+
const [hasPerf, setHasPerf] = useState(false);
23+
24+
const [perfSymbols, setPerfSymbols] = useState(null);
1525
const [hasLayers, setHasLayers] = useState(false);
1626
const [layerInfo, setLayerInfo] = useState(undefined)
1727
const [selectedOps, setSelectedOps] = useState([]);
28+
const [selectedLLVMOps, setSelectedLLVMOps] = useState([]);
1829
const handleFileUpload = (event) => {
1930
const file = event.target.files[0];
2031
const reader = new FileReader();
@@ -33,54 +44,94 @@ const App = () => {
3344

3445
const [relalgBaseRef, setRelalgBaseRef] = useState(null);
3546
useEffect(() => {
36-
if (data == null) {
37-
setMlirData(null)
38-
setHasTrace(false)
39-
setHasPlan(false)
40-
setHasLayers(false)
41-
} else {
42-
if(data.fileType==="traceOnly"){
43-
setHasTrace(true)
47+
if (data == null) {
48+
setRelalgMLIRData(null)
49+
setHasTrace(false)
4450
setHasPlan(false)
51+
setHasSubOpPlan(false)
52+
setHasPerf(false)
4553
setHasLayers(false)
46-
}else if (data.fileType==="insights"){
47-
setHasTrace(true)
48-
setHasPlan(true)
49-
setHasLayers(true)
50-
}
51-
if (data.fileType==="insights") {
52-
const relalgModule = data.layers[data.layers.findIndex((layer) => layer.passInfo.argument === "relalg-introduce-tmp") + 1]
53-
setMlirData(relalgModule)
54-
console.log(relalgModule)
55-
let newLayerInfo=analyzeLayers(data.layers)
56-
setLayerInfo(newLayerInfo)
57-
const newRelAlgBaseRef = getBaseReference(relalgModule.passInfo.file)
58-
setRelalgBaseRef(newRelAlgBaseRef)
54+
} else {
55+
if (data.fileType === "traceOnly") {
56+
setHasTrace(true)
57+
setHasPlan(false)
58+
setHasSubOpPlan(false)
59+
setHasPerf(false)
60+
61+
setHasLayers(false)
62+
} else if (data.fileType === "insights") {
63+
setHasTrace(true)
64+
setHasPlan(true)
65+
setHasLayers(true)
66+
setHasSubOpPlan(true)
67+
}
68+
if (data.fileType === "insights") {
69+
const relalgModule = data.layers[data.layers.findIndex((layer) => layer.passInfo.argument === "relalg-introduce-tmp") + 1]
70+
const subopModule = data.layers[data.layers.findIndex((layer) => layer.passInfo.argument === "subop-prepare-lowering")]
71+
const imperativeModule = data.layers[data.layers.findIndex((layer) => layer.passInfo.argument === "subop-prepare-lowering") + 1]
72+
const llvmModule = data.layers[data.layers.length - 1]
73+
setImperativeMLIRData(imperativeModule)
74+
setLlvmMLIRData(llvmModule)
75+
setRelalgMLIRData(relalgModule)
76+
setSubOpMLIRData(subopModule)
77+
let newLayerInfo = analyzeLayers(data.layers)
78+
setLayerInfo(newLayerInfo)
79+
const newRelAlgBaseRef = getBaseReference(relalgModule.passInfo.file)
80+
setRelalgBaseRef(newRelAlgBaseRef)
81+
if (data.perf) {
82+
83+
setHasPerf(true)
84+
let totalSamples = data.perf.overview.reduce((a, c) => a + c.samples, 0)
85+
let localPerfSymbols = data.perf.overview.map((r) => {
86+
return {...r, percentage: r.samples / totalSamples, symbol: r.symbol.substring(0, 100)}
87+
})
88+
localPerfSymbols.sort((a, b) => b.percentage - a.percentage)
89+
setPerfSymbols(localPerfSymbols)
90+
console.log(data.perf.generated)
91+
92+
}
93+
}
5994
}
6095
}
61-
}, [data])
96+
,
97+
[data]
98+
)
6299

63100
const handleTraceSelect = (trace) => {
64101
if (trace.category === "Execution" && trace.name === "Step" && hasLayers) {
65102
console.log(trace.extra.location)
66-
setSelectedOps(goUp(trace.extra.location,relalgBaseRef, layerInfo))
103+
setSelectedOps(goUp(trace.extra.location, relalgBaseRef, layerInfo))
67104
}
68105
}
69106

70107
const handleUnloadData = () => {
71108
setData(null);
72109
setSelectedOps([])
73-
setMlirData(null)
110+
setRelalgMLIRData(null)
74111
setLayerInfo(null)
75112
setRelalgBaseRef(null)
76113
setHasTrace(false)
77114
setHasPlan(false)
115+
setHasSubOpPlan(false)
78116
setHasLayers(false)
79117

80118
};
81119

82-
83-
120+
const [activeLeftTab, setActiveLeftTab] = useState("queryPlan")
121+
const [activeRightTab, setActiveRightTab] = useState("mlir_relalg")
122+
const handleLeftTabSelect = (selectedTab) => {
123+
setActiveLeftTab(selectedTab)
124+
}
125+
const handleRightTabSelect = (selectedTab) => {
126+
setActiveRightTab(selectedTab)
127+
}
128+
const handleInstrClick = (instr) => {
129+
if (instr.loc) {
130+
console.log("selected llvm", [instr.loc])
131+
setSelectedLLVMOps([instr.loc])
132+
}
133+
setActiveRightTab("mlir_llvm")
134+
}
84135
//return <TraceViewer></TraceViewer>
85136
return (
86137
<div>
@@ -105,21 +156,123 @@ const App = () => {
105156
</Navbar>
106157
<Container fluid className="pt-5 mt-3">
107158
<Row>
108-
<Col className="p-3" style={{height: (window.innerHeight - 80) / 3, backgroundColor: '#f8f9fa'}}>
109-
{hasTrace && <TraceViewer height={(window.innerHeight - 80) / 3} width={window.innerWidth - 20}
110-
traceData={data.trace} onSelect={handleTraceSelect}></TraceViewer>}
159+
<Col className="p-3"
160+
style={{height: (window.innerHeight - 80) / 3, backgroundColor: '#f8f9fa'}}>
161+
{hasTrace &&
162+
<TraceViewer height={(window.innerHeight - 80) / 3} width={window.innerWidth - 20}
163+
traceData={data.trace} onSelect={handleTraceSelect}></TraceViewer>}
111164
</Col>
112165
</Row>
113166
<Row>
114167
<Col className="p-3" style={{backgroundColor: '#f8f9fa'}}>
115-
{hasPlan &&
116-
<RelationalPlanViewer height={2 * (window.innerHeight - 90) / 3} width={(window.innerWidth - 100) / 2}
117-
input={data.plan} onOperatorSelect={(id) => setSelectedOps([id])} selectedOps={selectedOps}></RelationalPlanViewer>}
168+
<Tabs activeKey={activeLeftTab} onSelect={handleLeftTabSelect}>
169+
<Tab eventKey="queryPlan" title="Query-Plan">
170+
171+
</Tab>
172+
<Tab eventKey="subopPlan" title="SubOp-Visualization">
173+
</Tab>
174+
<Tab eventKey="perf" title="Perf">
175+
</Tab>
176+
</Tabs>
177+
<div style={{
178+
visibility: activeLeftTab === "queryPlan" ? "visible" : "hidden",
179+
position: 'absolute'
180+
}}>
181+
{hasPlan &&
182+
<RelationalPlanViewer height={2 * (window.innerHeight - 90) / 3}
183+
width={(window.innerWidth - 100) / 2}
184+
input={data.plan}
185+
onOperatorSelect={(id) => setSelectedOps([id])}
186+
selectedOps={selectedOps}></RelationalPlanViewer>}
187+
</div>
188+
<div style={{
189+
visibility: activeLeftTab === "subopPlan" ? "visible" : "hidden",
190+
position: 'absolute'
191+
}}>
192+
{hasSubOpPlan &&
193+
<SubOpPlanViewer height={2 * (window.innerHeight - 90) / 3}
194+
width={(window.innerWidth - 100) / 2}
195+
input={data.subopplan} onOperatorSelect={(id) => {
196+
}}
197+
selectedOps={[]}></SubOpPlanViewer>}
198+
</div>
199+
<div style={{
200+
visibility: activeLeftTab === "perf" ? "visible" : "hidden",
201+
position: 'absolute'
202+
}}>
203+
{hasPerf &&
204+
<PerfSymbolTable data={perfSymbols}/>}
205+
</div>
206+
118207
</Col>
119208
<Col className="p-3" style={{backgroundColor: '#f8f9fa'}}>
120-
{hasLayers &&
121-
<MLIRViewer height={2 * (window.innerHeight - 90) / 3} width={(window.innerWidth - 100) / 2}
122-
layer={mlirData} selectedOps={selectedOps}></MLIRViewer>}
209+
{hasLayers && <div><Tabs activeKey={activeRightTab} onSelect={handleRightTabSelect}>
210+
<Tab eventKey="mlir_relalg" title="RelAlg">
211+
<MLIRViewer height={2 * (window.innerHeight - 90) / 3}
212+
width={(window.innerWidth - 100) / 2}
213+
layer={relalgMLIRData} selectedOps={selectedOps}></MLIRViewer>
214+
</Tab>
215+
<Tab eventKey="mlir_subop" title="SubOp">
216+
217+
</Tab>
218+
<Tab eventKey="mlir_imperative" title="Imperative">
219+
220+
</Tab>
221+
<Tab eventKey="mlir_llvm" title="LLVM">
222+
223+
</Tab>
224+
{hasPerf && <Tab eventKey="asm" title="ASM">
225+
226+
</Tab>}
227+
</Tabs>
228+
<div style={{
229+
visibility: activeRightTab === "mlir_relalg" ? "visible" : "hidden",
230+
position: 'absolute'
231+
}}>
232+
233+
<MLIRViewer height={2 * (window.innerHeight - 90) / 3}
234+
width={(window.innerWidth - 100) / 2}
235+
layer={relalgMLIRData} selectedOps={selectedOps}></MLIRViewer>
236+
</div>
237+
<div style={{
238+
visibility: activeRightTab === "mlir_subop" ? "visible" : "hidden",
239+
position: 'absolute'
240+
}}>
241+
242+
<MLIRViewer height={2 * (window.innerHeight - 90) / 3}
243+
width={(window.innerWidth - 100) / 2}
244+
layer={subopMLIRData} selectedOps={[]}></MLIRViewer>
245+
</div>
246+
<div style={{
247+
visibility: activeRightTab === "mlir_imperative" ? "visible" : "hidden",
248+
position: 'absolute'
249+
}}>
250+
251+
<MLIRViewer height={2 * (window.innerHeight - 90) / 3}
252+
width={(window.innerWidth - 100) / 2}
253+
layer={imperativeMLIRData} selectedOps={[]}></MLIRViewer>
254+
</div>
255+
<div style={{
256+
visibility: activeRightTab === "mlir_llvm" ? "visible" : "hidden",
257+
position: 'absolute'
258+
}}>
259+
260+
<MLIRViewer height={2 * (window.innerHeight - 90) / 3}
261+
width={(window.innerWidth - 100) / 2}
262+
layer={llvmMLIRData} selectedOps={selectedLLVMOps}
263+
perfInfo={data.perf.generated}></MLIRViewer>
264+
</div>
265+
<div style={{
266+
visibility: activeRightTab === "asm" ? "visible" : "hidden",
267+
position: 'absolute'
268+
}}>
269+
{hasPerf && <PerfAsmViewer height={2 * (window.innerHeight - 90) / 3}
270+
width={(window.innerWidth - 100) / 2}
271+
data={data.perf.generated}
272+
onInstrClick={handleInstrClick}></PerfAsmViewer>}
273+
</div>
274+
</div>
275+
}
123276
</Col>
124277
</Row>
125278
</Container>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import {useEffect, useRef} from "react";
2+
3+
4+
5+
const Instruction = ({data, selectionState, onInstrClick}) => {
6+
return (<div id={data.id} onClick={(e) => {
7+
e.stopPropagation();
8+
onInstrClick(data)
9+
}} style={{backgroundColor: selectionState(data)}}>
10+
<div style={{minWidth:50, display:"inline-block"}}>{data.samples}</div><div style={{display:"inline", fontFamily:"monospace", textDecoration: data.loc?"underline":"default"}}>{data.asm}</div>
11+
</div>)
12+
13+
}
14+
15+
const Func = ({data, selectionState, onInstrClick}) => {
16+
return (<div style={{display: "inline"}}>
17+
{data.func}
18+
<div style={{paddingLeft: "10px"}}>
19+
{data.assembly.map((child, index) => {
20+
return (<Instruction data={child} selectionState={selectionState} onInstrClick={onInstrClick}></Instruction>)
21+
})}
22+
</div>
23+
</div>)
24+
}
25+
26+
27+
export const PerfAsmViewer = ({data, selectedOps, width, height, onInstrClick}) => {
28+
const scrollableDivRef = useRef(null);
29+
const getBackground = (data) => {
30+
/*if (data.type === "op" && selectedOps.includes(data.id)) {
31+
return "yellow"
32+
}*/
33+
return "white"
34+
}
35+
/*useEffect(() => {
36+
if (selectedOps.length > 0 && scrollableDivRef) {
37+
let currentElement=document.getElementById(selectedOps[0])
38+
currentElement.scrollIntoView({behavior: "smooth", block: "center"});
39+
}
40+
}, [selectedOps]);*/
41+
return (<div ref={scrollableDivRef} style={{maxWidth: width, maxHeight: height, overflow: "auto"}}>
42+
{
43+
data.map((f)=><Func data={f} selectionState={getBackground} onInstrClick={onInstrClick}/> )
44+
}
45+
</div>)
46+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {Table} from "react-bootstrap";
2+
3+
export const PerfSymbolTable = ({data})=>{
4+
return (
5+
<div style={{height: '50vh', overflow: 'auto'}}>
6+
<Table striped bordered>
7+
<thead>
8+
<tr>
9+
<th>File</th>
10+
<th>Symbol</th>
11+
<th>Percentage</th>
12+
13+
</tr>
14+
</thead>
15+
<tbody>
16+
{data.map((row, index) => (
17+
<tr key={index}>
18+
<td >{row.file}</td>
19+
<td >{row.symbol}</td>
20+
<td >{(row.percentage*100).toFixed(1)}</td>
21+
22+
</tr>
23+
))}
24+
</tbody>
25+
</Table>
26+
</div>
27+
);
28+
}

0 commit comments

Comments
 (0)