From a75b8abcc1756fe82e896c8f9955aadcbdfe7d61 Mon Sep 17 00:00:00 2001 From: John Calderon Date: Tue, 21 Feb 2023 16:19:59 -0500 Subject: [PATCH 1/4] changed height --- skyline-vscode/react-ui/src/App.js | 386 +++++++++--------- .../react-ui/src/sections/Iterations.js | 126 +++--- skyline-vscode/react-ui/src/styles.css | 5 +- 3 files changed, 279 insertions(+), 238 deletions(-) diff --git a/skyline-vscode/react-ui/src/App.js b/skyline-vscode/react-ui/src/App.js index e4cfbd0..0b0c15b 100644 --- a/skyline-vscode/react-ui/src/App.js +++ b/skyline-vscode/react-ui/src/App.js @@ -1,23 +1,22 @@ -import './App.css'; -import './styles.css'; +import "./App.css"; +import "./styles.css"; -import React, { useState, useEffect } from 'react'; -import { Alert, Button, Card, Tab, Tabs, Container } from 'react-bootstrap'; +import React, { useState, useEffect } from "react"; +import { Alert, Button, Card, Tab, Tabs, Container } from "react-bootstrap"; -import ProjectInfo from './components/ProjectInfo' -import Habitat from './sections/Habitat' -import DeploymentTab from './sections/DeploymentTab' -import WelcomeScreen from './sections/WelcomeScreen'; -import PerfBarContainer from './sections/PerfBarContainer'; +import ProjectInfo from "./components/ProjectInfo"; +import Habitat from "./sections/Habitat"; +import DeploymentTab from "./sections/DeploymentTab"; +import WelcomeScreen from "./sections/WelcomeScreen"; +import PerfBarContainer from "./sections/PerfBarContainer"; -import ReactTooltip from 'react-tooltip'; +import ReactTooltip from "react-tooltip"; - -import { computePercentage, getTraceByLevel } from './utils/utils'; -import { profiling_data } from './data/mock_data'; -import EnergyConsumption from './sections/EnergyConsumption'; -import Iterations from './sections/Iterations'; -import MemThroughputContainer from './sections/MemThroughputContainer'; +import { computePercentage, getTraceByLevel } from "./utils/utils"; +import { profiling_data } from "./data/mock_data"; +import EnergyConsumption from "./sections/EnergyConsumption"; +import Iterations from "./sections/Iterations"; +import MemThroughputContainer from "./sections/MemThroughputContainer"; // https://stackoverflow.com/questions/54135313/webview-extension-in-typescript /** @@ -27,189 +26,212 @@ import MemThroughputContainer from './sections/MemThroughputContainer'; * @returns The VSCode API handle */ function acquireApi() { - // if (typeof this.acquireApi.api == 'undefined') { - if (typeof acquireApi.api === 'undefined') { - if (typeof acquireVsCodeApi === "function") { - let f = window['acquireVsCodeApi']; - let a = f(); - acquireApi.api = a; - } else { - acquireApi.api = null; - } + // if (typeof this.acquireApi.api == 'undefined') { + if (typeof acquireApi.api === "undefined") { + if (typeof acquireVsCodeApi === "function") { + let f = window["acquireVsCodeApi"]; + let a = f(); + acquireApi.api = a; + } else { + acquireApi.api = null; } + } - return acquireApi.api; + return acquireApi.api; } function restartProfiling() { - console.log("restartProfiling"); - let vscode = App.vscodeApi; - vscode.postMessage({ - command: "restart_profiling_clicked" - }); + console.log("restartProfiling"); + let vscode = App.vscodeApi; + vscode.postMessage({ + command: "restart_profiling_clicked", + }); } -const sendMock = false; +const sendMock = true; function App() { - const [analysisState, setAnalysisState] = useState(); - const [textChanged, setTextChanged] = useState(false); - const [timeBreakDown, setTimeBreakdown] = useState([]); + const [analysisState, setAnalysisState] = useState(); + const [textChanged, setTextChanged] = useState(false); + const [timeBreakDown, setTimeBreakdown] = useState([]); - const [vscodeApi, setVscodeApi] = useState(acquireApi()); - const [errorText, setErrorText] = useState(); - const [connectionStatus, setConnectionStatus] = useState(false); - const [numIterations,setNumIterations] = useState(100000); + const [vscodeApi, setVscodeApi] = useState(acquireApi()); + const [errorText, setErrorText] = useState(); + const [connectionStatus, setConnectionStatus] = useState(false); + const [numIterations, setNumIterations] = useState(100000); - App.vscodeApi = vscodeApi; + App.vscodeApi = vscodeApi; - const resetApp = function() { - setErrorText(""); - setAnalysisState(undefined); - } + const resetApp = function () { + setErrorText(""); + setAnalysisState(undefined); + }; - const connect = function() { - resetApp(); - let vscode = App.vscodeApi; - if(vscode){ - vscode.postMessage({ - command: "connect" - }); - } + const connect = function () { + resetApp(); + let vscode = App.vscodeApi; + if (vscode) { + vscode.postMessage({ + command: "connect", + }); } - - const processAnalysisState = function (state) { - setAnalysisState(state); - if (state.breakdown) { - let operation_tree = state.breakdown.operation_tree; - let { coarse, fine } = getTraceByLevel(operation_tree); - setTimeBreakdown({ - coarse: computePercentage(coarse, state.breakdown.iteration_run_time_ms), - fine: computePercentage(fine, state.breakdown.iteration_run_time_ms) - }); - ReactTooltip.rebuild(); - } + }; + + const processAnalysisState = function (state) { + setAnalysisState(state); + if (state.breakdown) { + let operation_tree = state.breakdown.operation_tree; + let { coarse, fine } = getTraceByLevel(operation_tree); + setTimeBreakdown({ + coarse: computePercentage( + coarse, + state.breakdown.iteration_run_time_ms + ), + fine: computePercentage(fine, state.breakdown.iteration_run_time_ms), + }); + ReactTooltip.rebuild(); } + }; + + useEffect(function () { + window.addEventListener("message", (event) => { + if (event.data["message_type"] === "connection") { + setConnectionStatus(event.data["status"]); + } else if (event.data["message_type"] === "analysis") { + processAnalysisState(event.data); + } else if (event.data["message_type"] === "text_change") { + setTextChanged(true); + } else if (event.data["message_type"] === "error") { + setErrorText(event.data["error_text"]); + } + }); - useEffect(function () { - window.addEventListener('message', event => { - if (event.data['message_type'] === "connection") { - setConnectionStatus(event.data['status']); - } else if (event.data['message_type'] === "analysis") { - processAnalysisState(event.data); - } else if (event.data['message_type'] === "text_change") { - setTextChanged(true); - } else if (event.data['message_type'] === 'error') { - setErrorText(event.data['error_text']); - } - }); - - - - if (sendMock) { - setTimeout(() => { - const mockResponse = profiling_data; - processAnalysisState(mockResponse); - }, 1000); - } - - return() => { - window.removeEventListener("message",()=>{}) //remove event listener before re-render to avoid memory leaks - } - }, []); - - if (!connectionStatus && !sendMock) { - return ( - <> - - Connection Error -

- Connection has been lost to the profiler. Please reconnect the profiler and double check your ports then click connect -

- -
- - ) - } - if (errorText) { - return ( - <> - - Analysis Error -

- An error has occurred during analysis. This could be a problem with Skyline or possibly your code. For more information, refer to the detailed message below: -

-
-

- - {errorText} - -

-
- -
- - ) - } - else if (analysisState && analysisState['throughput'] && Object.keys(analysisState['throughput']).length > 0) - { - return ( - <> - - - Project Information - - - { textChanged && - - Change is detected in the project. - - } - - - -

- - -
-
- { - return { - label: elem["percentage"] > 10 ? elem["name"] : "", - percentage: elem["percentage"], - clickable: false - } - }) : []} - renderPerfBars={timeBreakDown.fine} - /> - -
-
- - - -
-
-
- - - -
-
- - ); - } - else { - return ( - <> - - - ); + if (sendMock) { + setTimeout(() => { + const mockResponse = profiling_data; + processAnalysisState(mockResponse); + }, 1000); } + + return () => { + window.removeEventListener("message", () => {}); //remove event listener before re-render to avoid memory leaks + }; + }, []); + + if (!connectionStatus && !sendMock) { + return ( + <> + + Connection Error +

+ Connection has been lost to the profiler. Please reconnect the + profiler and double check your ports then click connect +

+ +
+ + ); + } + if (errorText) { + return ( + <> + + Analysis Error +

+ An error has occurred during analysis. This could be a problem with + Skyline or possibly your code. For more information, refer to the + detailed message below: +

+
+

+ {errorText} +

+
+ +
+ + ); + } else if ( + analysisState && + analysisState["throughput"] && + Object.keys(analysisState["throughput"]).length > 0 + ) { + return ( + <> + + + Project Information + + + {textChanged && ( + + Change is detected in the project.{" "} + + + )} + + + +

+ + +
+
+ { + return { + label: + elem["percentage"] > 10 ? elem["name"] : "", + percentage: elem["percentage"], + clickable: false, + }; + }) + : [] + } + renderPerfBars={timeBreakDown.fine} + /> + +
+
+ + + +
+
+
+ + + +
+
+ + ); + } else { + return ( + <> + + + ); + } } export default App; diff --git a/skyline-vscode/react-ui/src/sections/Iterations.js b/skyline-vscode/react-ui/src/sections/Iterations.js index 0018160..ad4f1ed 100644 --- a/skyline-vscode/react-ui/src/sections/Iterations.js +++ b/skyline-vscode/react-ui/src/sections/Iterations.js @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { Button, Form, FloatingLabel } from "react-bootstrap"; +import { Row, Col, Button, Form, FloatingLabel } from "react-bootstrap"; import styled from "styled-components"; import { numberFormat } from "../utils/utils"; @@ -15,13 +15,13 @@ const Iterations = ({ setNumIterations }) => { const name = e.target.name; let value = e.target.value; if (!value) { - setIterations((prevState)=>({ ...prevState, [name]: 0 })); + setIterations((prevState) => ({ ...prevState, [name]: 0 })); return; } const val = parseFloat(value); if (Number.isInteger(val)) { - setIterations((prevState)=>({ ...prevState, [name]: val })); + setIterations((prevState) => ({ ...prevState, [name]: val })); setMessage(null); } else { setMessage("You must only use integer numbers"); @@ -36,14 +36,15 @@ const Iterations = ({ setNumIterations }) => { iterations.iterPerEpoch && Number.isInteger(iterations.iterPerEpoch) ) { - if(iterations.epochs * iterations.iterPerEpoch>=1e21){ - setMessage("The total number of iterations should be less than 1e21"); - } - else{ + if (iterations.epochs * iterations.iterPerEpoch >= 1e21) { + setMessage("The total number of iterations should be less than 1e21"); + } else { setEstimation(true); setNumIterations(iterations.epochs * iterations.iterPerEpoch); setMessage(null); - setTimeout(()=>{setEstimation(false)},2000); + setTimeout(() => { + setEstimation(false); + }, 2000); } } }; @@ -51,63 +52,80 @@ const Iterations = ({ setNumIterations }) => { return ( <> -
-
-
-
Training Schedule
- - - - - - - {message && ( - - {message} - - )} - - - Total number of iterations:{" "} - {numberFormat(iterations.epochs * iterations.iterPerEpoch)} - - - - - -
+
+
+
+ +
Training Schedule
+ + + + + + + + + + + + + + + Total number of iterations:{" "} + {numberFormat( + iterations.epochs * iterations.iterPerEpoch + )} + + + {message && ( + + {message} + + )} + +
+ + + + + + + +
+
-
); }; const Wrapper = styled.main` - .warning-message{ + .warning-message { font-size: 14; font-weight: 700; color: "red"; - } - .iterations-text{ + .iterations-text { font-size: 14; font-weight: 700; } diff --git a/skyline-vscode/react-ui/src/styles.css b/skyline-vscode/react-ui/src/styles.css index 71efef5..b418790 100644 --- a/skyline-vscode/react-ui/src/styles.css +++ b/skyline-vscode/react-ui/src/styles.css @@ -313,7 +313,7 @@ atom-overlay.innpv-contexthighlight-overlay { } .innpv-perfbarcontainer-wrap { display: flex; - height: 100%; + height: 70vh; } .innpv-perfbarcontainer { height: 100%; @@ -443,11 +443,12 @@ atom-overlay.innpv-contexthighlight-overlay { } .innpv-contents-subrows { display: flex; - height: 100%; + height: 70vh; width: 100%; flex-direction: column; transition-property: opacity; transition-duration: 0.3s; + overflow: auto; } .innpv-contents-subrows .innpv-subpanel:first-child { border-bottom: 1px solid #eee; From 77d28f2ea5c175e80bea601eeebb658abc252280 Mon Sep 17 00:00:00 2001 From: John Calderon Date: Wed, 22 Feb 2023 17:02:14 -0500 Subject: [PATCH 2/4] changed habitat chart --- .../{HorizontalBarGraph.js => BarGraph.js} | 5 +- .../react-ui/src/components/ScatterGraph.js | 221 +++++++++++++++++- skyline-vscode/react-ui/src/data/mock_data.js | 24 +- skyline-vscode/react-ui/src/data/providers.js | 22 +- .../react-ui/src/sections/Habitat.js | 11 +- .../react-ui/src/sections/ProviderPanel.js | 4 +- skyline-vscode/react-ui/src/styles.css | 1 + 7 files changed, 244 insertions(+), 44 deletions(-) rename skyline-vscode/react-ui/src/components/{HorizontalBarGraph.js => BarGraph.js} (88%) diff --git a/skyline-vscode/react-ui/src/components/HorizontalBarGraph.js b/skyline-vscode/react-ui/src/components/BarGraph.js similarity index 88% rename from skyline-vscode/react-ui/src/components/HorizontalBarGraph.js rename to skyline-vscode/react-ui/src/components/BarGraph.js index 23176c5..1d902bd 100644 --- a/skyline-vscode/react-ui/src/components/HorizontalBarGraph.js +++ b/skyline-vscode/react-ui/src/components/BarGraph.js @@ -2,20 +2,20 @@ import React from "react"; import { ResponsiveContainer, BarChart, - CartesianGrid, XAxis, YAxis, Tooltip, Bar, } from "recharts"; -const BarGraph = ({ data, height, xlabel, ylabel, color }) => { +export const HorizontalBarGraph = ({ data, height, xlabel, ylabel, color }) => { let upperLimit = 0; data.forEach(element => { const predictedTime = parseFloat(Number(element.x)); upperLimit = predictedTime > upperLimit ? predictedTime: upperLimit }); upperLimit *=1.1; + data.sort((a, b) => a.x - b.x); return ( { ); }; -export default BarGraph; diff --git a/skyline-vscode/react-ui/src/components/ScatterGraph.js b/skyline-vscode/react-ui/src/components/ScatterGraph.js index 48658d4..d1c992e 100644 --- a/skyline-vscode/react-ui/src/components/ScatterGraph.js +++ b/skyline-vscode/react-ui/src/components/ScatterGraph.js @@ -9,23 +9,33 @@ import { ResponsiveContainer, Label, Legend, + Tooltip, + LabelList, } from "recharts"; -import { calculate_training_time,currencyFormat } from "../utils/utils"; +import { calculate_training_time, currencyFormat } from "../utils/utils"; +import { gpuPropertyList } from "../data/providers"; -const ScatterGraph = ({ data, onClickHandler, xlabel, ylabel, providers,numIterations }) => { +export const ProviderScatterGraph = ({ + data, + onClickHandler, + xlabel, + ylabel, + providers, + numIterations, +}) => { const finalData = []; - if (data.length>0){ - data.forEach((item)=>{ + if (data.length > 0) { + data.forEach((item) => { const time = calculate_training_time(numIterations, item); const cost = item.info.cost * time; finalData.push({ ...item, x: time, - y: cost - }) - }) + y: cost, + }); + }); } - + const formatYAxis = (value) => { return currencyFormat(value); }; @@ -33,9 +43,9 @@ const ScatterGraph = ({ data, onClickHandler, xlabel, ylabel, providers,numItera const fortmatXAxis = (value) => { const formatter = new Intl.NumberFormat("en-US", { notation: "compact", - }) + }); return formatter.format(value); - } + }; return ( <> @@ -94,4 +104,193 @@ const ScatterGraph = ({ data, onClickHandler, xlabel, ylabel, providers,numItera ); }; -export default ScatterGraph; +export const HabitatScatterGraph = ({ habitatData, height, color }) => { + const renderTooltip = (props) => { + const { active, payload } = props; + + if (active && payload && payload.length) { + const data = payload[0] && payload[0].payload; + + return ( +
+

{data.card}

+

+ time: + {data.time} +

+
+ ); + } + + return null; + }; + + const renderCustomizedLabel = (props) => { + const { x, y, width, height, value } = props; + console.log(x, y, width, height, value); + const y_offset = 5; + + return ( + + {value} + + ); + }; + + const habitatConsumerCards = []; + const habitatServerCards = []; + const sourceInHabitat = habitatData.find( + (item) => item[0].toLowerCase() === "source" + ); + const sourceCard = [ + { + time: parseFloat(Number(sourceInHabitat[1]).toFixed(2)), + card: "Local GPU", + index: 1, + size: 100, + }, + ]; + + gpuPropertyList.forEach((item) => { + const findInHabitat = habitatData.find( + (card) => card[0].toLowerCase() === item.name.toLowerCase() + ); + if (item.type === "server") { + habitatServerCards.push({ + time: parseFloat(Number(findInHabitat[1]).toFixed(2)), + card: findInHabitat[0], + index: 1, + size: 100, + }); + } else { + habitatConsumerCards.push({ + time: parseFloat(Number(findInHabitat[1]).toFixed(2)), + card: findInHabitat[0], + index: 1, + size: 100, + }); + } + }); + + const LOWER_LIMIT = + 0.8 * habitatData.reduce((a, b) => Math.min(a, b[1]), +Infinity); + const UPPER_LIMIT = + 1.2 * habitatData.reduce((a, b) => Math.max(a, b[1]), -Infinity); + + return ( + <> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ); +}; diff --git a/skyline-vscode/react-ui/src/data/mock_data.js b/skyline-vscode/react-ui/src/data/mock_data.js index 57d6147..3ca79ef 100644 --- a/skyline-vscode/react-ui/src/data/mock_data.js +++ b/skyline-vscode/react-ui/src/data/mock_data.js @@ -873,18 +873,18 @@ export const profiling_data = { ], }, habitat: [ - ["source", 22.029312], - ["P100",14.069682], - ["P4000", 127.268085], // 27.268085 - ["RTX2070", 16.088268], - ["RTX2080Ti", 11.826558], - ["T4", 22.029312], - ["V100", 10.182922], - ["A100", 10.068596], - ["RTX3090", 9.841998], - ["A40", 11.558072], - ["A4000", 14.67059], - ["RTX4000", 20.2342], + ["source", 21.767504], + ["P100",13.972405], + ["P4000", 26.889559], // 27.268085 + ["RTX2070", 15.942612], + ["RTX2080Ti", 11.753607], + ["T4", 21.767504], + ["V100", 10.154535], + ["A100", 10.081459], + ["RTX3090", 9.823705], + ["A40", 11.507118], + ["A4000", 14.537657], + ["RTX4000", 20.04405], ], energy: { current: { diff --git a/skyline-vscode/react-ui/src/data/providers.js b/skyline-vscode/react-ui/src/data/providers.js index cb3dbed..d216603 100644 --- a/skyline-vscode/react-ui/src/data/providers.js +++ b/skyline-vscode/react-ui/src/data/providers.js @@ -269,15 +269,15 @@ export const cloudProviders = { } export const gpuPropertyList = [ - { name: "p100", vmem: 16 }, - { name: "p4000", vmem: 8 }, - { name: "rtx2070", vmem: 8 }, - { name: "rtx2080ti", vmem: 11 }, - { name: "t4", vmem: 16 }, - { name: "v100", vmem: 16 }, - { name: "a100", vmem: 40 }, - { name: "rtx3090", vmem: 24}, - { name: "a40", vmem: 48}, - { name: "a4000", vmem: 16}, - { name: "rtx4000", vmem: 8} + { name: "p100", vmem: 16, type: "server" }, + { name: "p4000", vmem: 8, type: "server" }, + { name: "rtx2070", vmem: 8, type: "consumer" }, + { name: "rtx2080ti", vmem: 11, type: "consumer" }, + { name: "t4", vmem: 16, type: "server" }, + { name: "v100", vmem: 16, type: "server" }, + { name: "a100", vmem: 40, type: "server" }, + { name: "rtx3090", vmem: 24, type: "consumer" }, + { name: "a40", vmem: 48, type: "server" }, + { name: "a4000", vmem: 16, type: "server" }, + { name: "rtx4000", vmem: 8, type: "consumer" } ]; diff --git a/skyline-vscode/react-ui/src/sections/Habitat.js b/skyline-vscode/react-ui/src/sections/Habitat.js index 2c9ff37..7a5d92a 100644 --- a/skyline-vscode/react-ui/src/sections/Habitat.js +++ b/skyline-vscode/react-ui/src/sections/Habitat.js @@ -1,7 +1,7 @@ import Subheader from "../components/Subheader"; import { Container, Row, Spinner, Card } from "react-bootstrap"; -import BarGraph from "../components/HorizontalBarGraph"; - +import {HorizontalBarGraph} from "../components/BarGraph"; +import {HabitatScatterGraph} from "../components/ScatterGraph"; export default function Habitat({ habitatData }) { // The colors used for the visualization // The first n-1 colors should follow a blue gradient while the last @@ -46,13 +46,14 @@ export default function Habitat({ habitatData }) { )} - {habitatData !== [] && ( - + />} */} + {habitatData !== [] && ( + )}
diff --git a/skyline-vscode/react-ui/src/sections/ProviderPanel.js b/skyline-vscode/react-ui/src/sections/ProviderPanel.js index c868e42..cdb138b 100644 --- a/skyline-vscode/react-ui/src/sections/ProviderPanel.js +++ b/skyline-vscode/react-ui/src/sections/ProviderPanel.js @@ -1,6 +1,6 @@ import React, { useState, useEffect } from "react"; import Subheader from "../components/Subheader"; -import ScatterGraph from "../components/ScatterGraph"; +import {ProviderScatterGraph} from "../components/ScatterGraph"; import { Badge, ButtonGroup, @@ -243,7 +243,7 @@ const ProviderPanel = ({ numIterations, habitatData }) => { - Date: Thu, 23 Feb 2023 12:55:10 -0500 Subject: [PATCH 3/4] alternative horizontal bar graph --- .../react-ui/src/components/BarGraph.js | 32 ++- .../react-ui/src/components/ScatterGraph.js | 7 +- .../react-ui/src/sections/Habitat.js | 197 +++++++++++++----- 3 files changed, 172 insertions(+), 64 deletions(-) diff --git a/skyline-vscode/react-ui/src/components/BarGraph.js b/skyline-vscode/react-ui/src/components/BarGraph.js index 1d902bd..e9c3bca 100644 --- a/skyline-vscode/react-ui/src/components/BarGraph.js +++ b/skyline-vscode/react-ui/src/components/BarGraph.js @@ -6,30 +6,44 @@ import { YAxis, Tooltip, Bar, + Label, } from "recharts"; export const HorizontalBarGraph = ({ data, height, xlabel, ylabel, color }) => { let upperLimit = 0; - data.forEach(element => { + data.forEach((element) => { const predictedTime = parseFloat(Number(element.x)); - upperLimit = predictedTime > upperLimit ? predictedTime: upperLimit + upperLimit = predictedTime > upperLimit ? predictedTime : upperLimit; }); - upperLimit *=1.1; + upperLimit *= 1.1; data.sort((a, b) => a.x - b.x); return ( - - - + + - + ); }; - diff --git a/skyline-vscode/react-ui/src/components/ScatterGraph.js b/skyline-vscode/react-ui/src/components/ScatterGraph.js index d1c992e..516a74c 100644 --- a/skyline-vscode/react-ui/src/components/ScatterGraph.js +++ b/skyline-vscode/react-ui/src/components/ScatterGraph.js @@ -136,11 +136,10 @@ export const HabitatScatterGraph = ({ habitatData, height, color }) => { const { x, y, width, height, value } = props; console.log(x, y, width, height, value); const y_offset = 5; - return ( - - {value} - + + {value} + ); }; diff --git a/skyline-vscode/react-ui/src/sections/Habitat.js b/skyline-vscode/react-ui/src/sections/Habitat.js index 7a5d92a..6d25c0e 100644 --- a/skyline-vscode/react-ui/src/sections/Habitat.js +++ b/skyline-vscode/react-ui/src/sections/Habitat.js @@ -1,61 +1,156 @@ +import React, { useState } from "react"; + import Subheader from "../components/Subheader"; -import { Container, Row, Spinner, Card } from "react-bootstrap"; -import {HorizontalBarGraph} from "../components/BarGraph"; -import {HabitatScatterGraph} from "../components/ScatterGraph"; -export default function Habitat({ habitatData }) { - // The colors used for the visualization - // The first n-1 colors should follow a blue gradient while the last - // color is used for the current device. - const colors = [ - "#7986cb", - "#5c6bc0", - "#3f51b5", - "#3949ab", - "#303f9f", - "#283593", - "#1a237e", - "#ffc300", - ]; +import { Form, Container, Row, Col, Spinner, Card } from "react-bootstrap"; +import { HorizontalBarGraph } from "../components/BarGraph"; +import { HabitatScatterGraph } from "../components/ScatterGraph"; +import { gpuPropertyList } from "../data/providers"; + +// The colors used for the visualization +// The first n-1 colors should follow a blue gradient while the last +// color is used for the current device. +const colors = [ + "#7986cb", + "#5c6bc0", + "#3f51b5", + "#3949ab", + "#303f9f", + "#283593", + "#1a237e", + "#ffc300", +]; +const initialLoad = (habitatData) => { let habitatProperties = []; - for (var i = 0; i < habitatData.length; i++) { - habitatProperties.push({ - y: habitatData[i][0], - x: habitatData[i][1].toFixed(2), - fill: - habitatData[i][0] === "source" - ? colors[colors.length - 1] - : colors[i % (colors.length - 1)], - }); + gpuPropertyList.forEach((item, idx) => { + const findInHabitat = habitatData.find( + (card) => card[0].toLowerCase() === item.name.toLowerCase() + ); + if (item.type === "server") { + habitatProperties.push({ + x: parseFloat(Number(findInHabitat[1]).toFixed(2)), + y: findInHabitat[0], + fill: colors[idx % (colors.length - 1)], + type: "server", + }); + } else { + habitatProperties.push({ + x: parseFloat(Number(findInHabitat[1]).toFixed(2)), + y: findInHabitat[0], + fill: colors[idx % (colors.length - 1)], + type: "consumer", + }); + } + }); + + const sourceInHabitat = habitatData.find( + (item) => item[0].toLowerCase() === "source" + ); + + habitatProperties.push({ + x: parseFloat(Number(sourceInHabitat[1]).toFixed(2)), + y: sourceInHabitat[0], + fill: colors[colors.length - 1], + type: "source", + }); + + // for (var i = 0; i < habitatData.length; i++) { + // habitatProperties.push({ + // y: habitatData[i][0], + // x: habitatData[i][1].toFixed(2), + // fill: + // habitatData[i][0] === "source" + // ? colors[colors.length - 1] + // : colors[i % (colors.length - 1)], + // }); + // } + return habitatProperties; +}; + +export default function Habitat({ habitatData }) { + const [habitatState, setHabitatState] = useState({ + data: initialLoad(habitatData), + filter: "all", + }); + + const originalData = initialLoad(habitatData); + + const filterByCardType = (cardType) => { + const filteredData = originalData.filter(item=>{ + if(cardType !=='all'){ + return item.type === cardType || item.type === 'source' + } + return true; + }) + setHabitatState( + {data: filteredData, + filter:cardType} + ) } return ( -
- Habitat -
- {habitatData.length === 0 && ( - - - - - Loading Habitat - predictions. - - - - - )} - {/* {habitatData !== [] && } */} - {habitatData !== [] && ( - - )} + <> +
+ Habitat +
+ {habitatData.length === 0 && ( + + + + + Loading Habitat + predictions. + + + + + )} + {habitatData !== [] && ( + + + +
+
Filter by type of card
+ {filterByCardType(e.target.value)}}> + + + + +
+ +
+ +
+
Predicted Runtime
+
+ +
+
+ )} +
+
+ {habitatData !== [] && ( + + )} +
-
+ ); } From 6d476101e1d33d889fe2da164251b49b3c30a064 Mon Sep 17 00:00:00 2001 From: John Calderon Date: Thu, 23 Feb 2023 17:33:36 -0500 Subject: [PATCH 4/4] refactored habitat graph --- skyline-vscode/react-ui/src/App.js | 2 +- .../react-ui/src/components/ScatterGraph.js | 223 +++++++----------- skyline-vscode/react-ui/src/data/mock_data.js | 2 +- .../react-ui/src/sections/Habitat.js | 132 +---------- 4 files changed, 97 insertions(+), 262 deletions(-) diff --git a/skyline-vscode/react-ui/src/App.js b/skyline-vscode/react-ui/src/App.js index 0b0c15b..84c6858 100644 --- a/skyline-vscode/react-ui/src/App.js +++ b/skyline-vscode/react-ui/src/App.js @@ -48,7 +48,7 @@ function restartProfiling() { }); } -const sendMock = true; +const sendMock = false; function App() { const [analysisState, setAnalysisState] = useState(); diff --git a/skyline-vscode/react-ui/src/components/ScatterGraph.js b/skyline-vscode/react-ui/src/components/ScatterGraph.js index 516a74c..b592e36 100644 --- a/skyline-vscode/react-ui/src/components/ScatterGraph.js +++ b/skyline-vscode/react-ui/src/components/ScatterGraph.js @@ -104,7 +104,7 @@ export const ProviderScatterGraph = ({ ); }; -export const HabitatScatterGraph = ({ habitatData, height, color }) => { +export const HabitatScatterGraph = ({ habitatData, height }) => { const renderTooltip = (props) => { const { active, payload } = props; @@ -137,159 +137,114 @@ export const HabitatScatterGraph = ({ habitatData, height, color }) => { console.log(x, y, width, height, value); const y_offset = 5; return ( - + {value} ); }; + const NUMBER_OF_COLUMNS = 5; const habitatConsumerCards = []; const habitatServerCards = []; - const sourceInHabitat = habitatData.find( - (item) => item[0].toLowerCase() === "source" - ); - const sourceCard = [ - { - time: parseFloat(Number(sourceInHabitat[1]).toFixed(2)), - card: "Local GPU", - index: 1, - size: 100, - }, - ]; + const sourceInHabitat = []; + + habitatData.sort((a, b) => a[1] - b[1]); - gpuPropertyList.forEach((item) => { - const findInHabitat = habitatData.find( - (card) => card[0].toLowerCase() === item.name.toLowerCase() + habitatData.forEach((habitatItem,idx) => { + const findGPUProperty = gpuPropertyList.find( + (item) => item.name.toLowerCase() === habitatItem[0].toLowerCase() ); - if (item.type === "server") { - habitatServerCards.push({ - time: parseFloat(Number(findInHabitat[1]).toFixed(2)), - card: findInHabitat[0], - index: 1, - size: 100, - }); + if (findGPUProperty) { + if (findGPUProperty.type === "server") { + habitatServerCards.push({ + time: parseFloat(Number(habitatItem[1]).toFixed(2)), + card: habitatItem[0], + index: idx%NUMBER_OF_COLUMNS +0.5, + size: 100, + }); + } else { + habitatConsumerCards.push({ + time: parseFloat(Number(habitatItem[1]).toFixed(2)), + card: habitatItem[0], + index: idx%NUMBER_OF_COLUMNS+0.5, + size: 100, + }); + } } else { - habitatConsumerCards.push({ - time: parseFloat(Number(findInHabitat[1]).toFixed(2)), - card: findInHabitat[0], - index: 1, + sourceInHabitat.push({ + time: parseFloat(Number(habitatItem[1]).toFixed(2)), + card: "Local GPU", + index: idx%NUMBER_OF_COLUMNS+0.5, size: 100, }); } }); + console.log(sourceInHabitat) - const LOWER_LIMIT = - 0.8 * habitatData.reduce((a, b) => Math.min(a, b[1]), +Infinity); const UPPER_LIMIT = 1.2 * habitatData.reduce((a, b) => Math.max(a, b[1]), -Infinity); return ( <> -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + ); }; diff --git a/skyline-vscode/react-ui/src/data/mock_data.js b/skyline-vscode/react-ui/src/data/mock_data.js index 3ca79ef..7faef0f 100644 --- a/skyline-vscode/react-ui/src/data/mock_data.js +++ b/skyline-vscode/react-ui/src/data/mock_data.js @@ -875,7 +875,7 @@ export const profiling_data = { habitat: [ ["source", 21.767504], ["P100",13.972405], - ["P4000", 26.889559], // 27.268085 + ["P4000", 56.889559], // 27.268085 ["RTX2070", 15.942612], ["RTX2080Ti", 11.753607], ["T4", 21.767504], diff --git a/skyline-vscode/react-ui/src/sections/Habitat.js b/skyline-vscode/react-ui/src/sections/Habitat.js index 6d25c0e..3e15f12 100644 --- a/skyline-vscode/react-ui/src/sections/Habitat.js +++ b/skyline-vscode/react-ui/src/sections/Habitat.js @@ -1,100 +1,17 @@ -import React, { useState } from "react"; +import React from "react"; import Subheader from "../components/Subheader"; -import { Form, Container, Row, Col, Spinner, Card } from "react-bootstrap"; -import { HorizontalBarGraph } from "../components/BarGraph"; +import { Container, Row,Spinner, Card } from "react-bootstrap"; import { HabitatScatterGraph } from "../components/ScatterGraph"; -import { gpuPropertyList } from "../data/providers"; - -// The colors used for the visualization -// The first n-1 colors should follow a blue gradient while the last -// color is used for the current device. -const colors = [ - "#7986cb", - "#5c6bc0", - "#3f51b5", - "#3949ab", - "#303f9f", - "#283593", - "#1a237e", - "#ffc300", -]; - -const initialLoad = (habitatData) => { - let habitatProperties = []; - - gpuPropertyList.forEach((item, idx) => { - const findInHabitat = habitatData.find( - (card) => card[0].toLowerCase() === item.name.toLowerCase() - ); - if (item.type === "server") { - habitatProperties.push({ - x: parseFloat(Number(findInHabitat[1]).toFixed(2)), - y: findInHabitat[0], - fill: colors[idx % (colors.length - 1)], - type: "server", - }); - } else { - habitatProperties.push({ - x: parseFloat(Number(findInHabitat[1]).toFixed(2)), - y: findInHabitat[0], - fill: colors[idx % (colors.length - 1)], - type: "consumer", - }); - } - }); - - const sourceInHabitat = habitatData.find( - (item) => item[0].toLowerCase() === "source" - ); - - habitatProperties.push({ - x: parseFloat(Number(sourceInHabitat[1]).toFixed(2)), - y: sourceInHabitat[0], - fill: colors[colors.length - 1], - type: "source", - }); - - // for (var i = 0; i < habitatData.length; i++) { - // habitatProperties.push({ - // y: habitatData[i][0], - // x: habitatData[i][1].toFixed(2), - // fill: - // habitatData[i][0] === "source" - // ? colors[colors.length - 1] - // : colors[i % (colors.length - 1)], - // }); - // } - return habitatProperties; -}; export default function Habitat({ habitatData }) { - const [habitatState, setHabitatState] = useState({ - data: initialLoad(habitatData), - filter: "all", - }); - - const originalData = initialLoad(habitatData); - - const filterByCardType = (cardType) => { - const filteredData = originalData.filter(item=>{ - if(cardType !=='all'){ - return item.type === cardType || item.type === 'source' - } - return true; - }) - setHabitatState( - {data: filteredData, - filter:cardType} - ) - } return ( <>
Habitat
- {habitatData.length === 0 && ( + {habitatData.length === 0 ? ( @@ -105,48 +22,11 @@ export default function Habitat({ habitatData }) { - )} - {habitatData !== [] && ( - - - -
-
Filter by type of card
- {filterByCardType(e.target.value)}}> - - - - -
- -
- -
-
Predicted Runtime
-
- -
-
- )} -
-
- {habitatData !== [] && ( + ): + ( )}