未验证 提交 4a2b1b67 编写于 作者: R RotPublic 提交者: GitHub

Add profiler frontend code

上级 b279127d
......@@ -27,8 +27,8 @@ module.exports = {
},
plugins: ['license-header'],
rules: {
'sort-imports': 'warn',
'no-console': 'warn'
// 'sort-imports': 'warn',
// 'no-console': 'warn'
// 'license-header/header': ['error', './license-header.js']
},
overrides: [
......@@ -39,7 +39,7 @@ module.exports = {
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'error'
'@typescript-eslint/no-explicit-any': 'off'
}
},
{
......@@ -66,7 +66,7 @@ module.exports = {
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-explicit-any': 'off',
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off'
}
......
......@@ -39,17 +39,19 @@
"dist"
],
"dependencies": {
"@material-ui/core": "^4.12.4",
"@snowpack/plugin-sass": "^1.4.0",
"@tippyjs/react": "4.2.5",
"@visualdl/icons": "2.2.1",
"@visualdl/netron": "2.2.1",
"@visualdl/wasm": "2.2.1",
"antd": "^4.21.0",
"bignumber.js": "9.0.1",
"classnames": "2.3.1",
"d3": "7.0.1",
"d3-format": "3.0.1",
"echarts": "4.9.0",
"echarts-gl": "1.1.2",
"eslint-plugin-simple-import-sort": "^7.0.0",
"echarts": "^5.3.3",
"echarts-gl": "^2.0.9",
"eventemitter3": "4.0.7",
"file-saver": "2.0.5",
"i18next": "20.6.0",
......@@ -79,11 +81,13 @@
"react-table-sticky": "1.1.3",
"react-toastify": "8.0.2",
"redux": "4.1.1",
"snowpack-plugin-less": "^1.0.7",
"styled-components": "5.3.1",
"swr": "1.0.1",
"three": "0.132.2",
"tippy.js": "6.3.1",
"umap-js": "1.3.3"
"umap-js": "1.3.3",
"use-deep-compare-effect": "^1.8.1"
},
"devDependencies": {
"@baiducloud/sdk": "1.0.0-rc.31",
......@@ -97,7 +101,6 @@
"@types/chai": "4.2.21",
"@types/d3": "7.0.0",
"@types/d3-format": "3.0.1",
"@types/echarts": "4.9.10",
"@types/file-saver": "2.0.3",
"@types/lodash": "4.14.172",
"@types/mime-types": "2.1.1",
......
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><path fill="#2932E1" d="M7,0 L7,0 C3.13400755,0 0,3.13400755 0,7 C0,7 0,7 0,7 L0,7 C0,10.8660098 3.13400755,14.0000173 7,14.0000173 L7,14.0000173 C10.8660084,14.0000173 14.000016,10.8660098 14.000016,7 L14.000016,7 C14.000016,3.13400861 10.8660084,0 7,0 L7,0 Z M6.88930852,9.94833549 C7.21622667,9.93576419 7.4914375,10.1905932 7.50400904,10.5175113 L7.50400904,10.5175113 L7.50400904,10.5630368 C7.49143774,10.889955 7.21622667,11.1447842 6.88930852,11.1322127 C6.56239037,11.1196414 6.30756117,10.8444303 6.32013266,10.5175122 L6.32013266,10.5175122 L6.33060888,10.4267388 C6.38223791,10.1609864 6.61095033,9.95903965 6.88930852,9.94833549 Z M6.9921336,2.8909989 C7.68252171,2.88978156 8.34332932,3.17117818 8.82088573,3.66975376 C9.26013624,4.1326293 9.4841365,4.72762999 9.45088646,5.34538071 C9.41763643,5.97800645 9.2233862,6.47763203 8.25213507,7.44800816 C7.80955955,7.89058367 7.51369546,8.23393407 7.43598487,8.5348303 L7.41825909,8.63363464 C7.39588787,8.85742952 7.22604721,9.0338123 7.01087397,9.07031116 L6.929,9.077 L6.88013332,9.07463556 C6.60994121,9.04746842 6.41268863,8.80677451 6.43913281,8.53650993 C6.50563288,7.85400914 7.00613347,7.3027585 7.55738411,6.75150786 C8.38667919,5.92221277 8.44786265,5.62462765 8.46532207,5.3451887 L8.4682602,5.29288053 C8.48225838,4.99167784 8.38830495,4.69712169 8.20611596,4.46089356 L8.10775983,4.34787949 C7.81734836,4.04532465 7.41588559,3.87462425 6.99650854,3.87537894 L6.99475857,3.87537894 C6.23199702,3.87764582 5.60604809,4.45989683 5.53424846,5.20405559 L5.52738186,5.34538065 C5.52738186,5.61720929 5.30702243,5.83756872 5.03519379,5.83756872 C4.76336515,5.83756872 4.54300572,5.61720929 4.54300572,5.34538065 C4.54300572,4.75554246 4.74854346,4.19830682 5.12708727,3.7553218 L5.25963149,3.6120037 C5.67192267,3.19623274 6.21843686,2.94437592 6.79789833,2.898576 L6.9921336,2.8909989 Z"/></svg>
\ No newline at end of file
......@@ -13,6 +13,7 @@
"graphDynamic": "dynamic",
"graphStatic": "static",
"high-dimensional": "High Dimensional",
"profiler":"performance analysis",
"histogram": "Histogram",
"hyper-parameter": "Hyper Parameters",
"image": "Image",
......
{
"Overview-view": "Overview",
"time-consuming": "Execution Summary",
"Expand-view": "Details",
"stage-view": "Details",
"training-step-time": "Execution Time Breakdown",
"performance-consumption": "Event Summary",
"consumption-distribution": "Event Time Breakdown",
"custom-events": "UserDefined Summary",
"Configuration-details": "Configuration",
"number-processes": "Number of Worker(s)",
"Equipment-type": "Device Type",
"Device-Details": "Device Summary",
"Process-utilization": "Process Utilization",
"system-utilization": "System Utilization",
"computing-power": "Compute Capability",
"Utilization": "Utilization",
"Traffic-Processor-Efficiency": "Est. SM Efficiency",
"Traffic-processor-occupancy": "Est. Achieved Occupancy",
"usage-time": "Kernel Time using Tensor Cores",
"step": "step",
"timeConsuming": "time consuming",
"Number-calls": "Calls",
"duration": "duration",
"Overall-proportion": "Overall proportion",
"stage": "Event Name",
"number-calls": "Calls",
"total-time": "Total Time",
"average-time": "Average Time",
"longest-time": "Max Time",
"shortest-time":"Min Time",
"percentage":"Percentage",
"Operator-view":"Operator View",
"Time-profile":"Operator Pie",
"Kernel-profile":"Kernel Pie",
"Time-details":"Operator Table",
"show-all-operators":"All operators",
"show-Top-operators":"Top operators to show",
"By-operator-name":"Operator Name",
"operator-shape":"Operator Name + Input Shape",
"input-shape":"input shape",
"call-volume":"Calls",
"operator":"Operator Name",
"CPU-time":"CPU",
"GPU-time":"GPU",
"nuclear-view":"Kernel View",
"show-all-kernels":"show all kernels",
"show-Top-kernels":"Show Top Kernels",
"group-by-core":"Kernel Name",
"Group-operator":"Kernel Name + Attributes",
"nuclear-name":"Kernel Name",
"sm-average":"Mean Blocks Per SM",
"average-occupancy":"Mean Achieved Occupancy",
"use-tensor-core":"Kernel Used Tensor Cores",
"Distribution-view":"Distributed View",
"Device-Information":"Device Information",
"comparisons":"Computation/Communication Overview",
"training-steps":"Step",
"memory-view":"Memory View",
"equipment":"Device",
"timestamp":"timestamp",
"memory-size":"memory size",
"event-name":"Event Name",
"memory-usage":"memory usage",
"storage-type":"Memory Type",
"MemorAddr":"Memory address",
"EventName":"Event Name",
"AllocationCount":"Allcation Counts",
"FreeCount":"Release Counts",
"AllocationSize":"Allocation Size",
"FreeSize":"Release Size",
"IncreasedSize":"Increased Size",
"AllocatedEvent":"Allocation Event",
"AllocatedTimestamp":"Allocation Time",
"FreeEvent":"Release Event",
"FreeTimestamp":"Release Time",
"Duration":"Duratrion",
"Size":"Size",
"search-event-name":"search event name",
"Search-Kernal":"Search kernel name",
"Search-operator":"Search operator name",
"data-flow":"Runs",
"view":"Views",
"process":"Workers",
"process-span":"Spans",
"time-unit":"Timeunit",
"Allocated":"Allocated",
"Reserved":"Reserved",
"PeakAllocated":"Peak Allocated",
"PeakReserved":"Peak Reserved",
"NoGPUdata":"No GPU data yet",
"Cor-operator":"Operator",
"thread-grid":"Grid",
"thread-block":"Block",
"Thread-registers":"Register Per Thread",
"Shared-memory":"Shared Memory",
"Yes":"Yes",
"No":"No",
"performance-analysis":"Profiler",
"Tensorcore-usage":"Tensor Cores Utilization",
"Kernel-details":"Kernel Table",
"proportion":"proportion"
}
\ No newline at end of file
......@@ -13,6 +13,7 @@
"graphDynamic": "动态",
"graphStatic": "静态",
"high-dimensional": "数据降维",
"profiler": "性能分析",
"histogram": "直方图",
"hyper-parameter": "超参可视化",
"image": "图像",
......
{
"Overview-view": "总览视图",
"time-consuming": "运行耗时",
"Expand-view": "展开查看耗时详情",
"stage-view": "各阶段耗时详情",
"training-step-time": "训练步数耗时",
"performance-consumption": "性能消耗",
"consumption-distribution": "模型各阶段消耗分布",
"custom-events": "自定义事件耗时",
"Configuration-details": "配置详情",
"number-processes": "进程数",
"Equipment-type": "设备类型",
"Device-Details": "设备详情",
"Process-utilization": "进程利用率",
"system-utilization": "系统利用率",
"computing-power": "算力",
"Utilization": "利用率",
"Traffic-Processor-Efficiency": "流处理器效率",
"Traffic-processor-occupancy": "流处理器占用率",
"usage-time": "Tensor Cores使用时间占比",
"step": "步",
"timeConsuming": "耗时",
"Number-calls": "调用量(次)",
"duration": "持续时间",
"Overall-proportion": "整体占比",
"stage": "事件名称",
"number-calls": "调用次数",
"total-time": "总耗时",
"average-time": "平均耗时",
"longest-time": "最长耗时",
"shortest-time":"最短耗时",
"percentage":"百分比",
"Operator-view":"算子视图",
"Time-profile":"耗时概况",
"Kernel-profile":"耗时概况",
"Time-details":"算子详情",
"Kernel-details":"核详情",
"show-all-operators":"显示全部算子",
"show-Top-operators":"显示Top算子",
"By-operator-name":"按算子名称",
"operator-shape":"按算子名称+输入形状",
"input-shape":"输入形状",
"call-volume":"调用量",
"operator":"算子名称",
"CPU-time":"CPU耗时",
"GPU-time":"GPU耗时",
"nuclear-view":"核视图",
"show-all-kernels":"显示全部内核",
"show-Top-kernels":"显示Top内核",
"group-by-core":"按核名称分组",
"Group-operator":"按核名称+核属性分组",
"nuclear-name":"核名称",
"sm-average":"sm平均线程块数量",
"average-occupancy":"平均占用率",
"use-tensor-core":"是否使用Tensor Cores",
"Distribution-view":"分布式视图",
"Device-Information":"设备信息",
"comparisons":"Computation和communication的耗时对比",
"training-steps":"训练步数",
"memory-view":"显存视图",
"equipment":"设备",
"timestamp":"时间戳",
"memory-size":"内存大小",
"event-name":"事件名称",
"memory-usage":"内存使用量",
"storage-type":"存储类型",
"MemorAddr":"存储地址",
"EventName":"事件名",
"AllocationCount":"分配次数",
"FreeCount":"释放次数",
"AllocationSize":"分配大小",
"FreeSize":"释放大小",
"IncreasedSize":"净增量",
"AllocatedEvent":"分配事件",
"AllocatedTimestamp":"分配时间",
"FreeEvent":"释放事件",
"FreeTimestamp":"释放时间",
"Duration":"持续时间",
"Size":"大小",
"search-event-name":"搜素事件名",
"Search-operator":"搜索算子名称",
"Search-Kernal":"搜索核名称",
"performance-analysis":"性能分析",
"data-flow":"数据流",
"view":"视图",
"process":"进程",
"process-span":"数据索引",
"time-unit":"时间单位",
"Allocated":"已分配",
"Reserved":"已预留",
"PeakAllocated":"最大已分配",
"PeakReserved":"最大已预留",
"NoGPUdata":"暂无GPU数据",
"Cor-operator":"对应算子",
"thread-grid":"线程网格",
"thread-block":"线程块",
"Thread-registers":"线程平均寄存器数量",
"Shared-memory":"共享显存量",
"Yes":"是",
"No":"否",
"Tensorcore-usage":"Tensor core利用率",
"proportion":"占比"
}
\ No newline at end of file
此差异已折叠。
export async function render() {
document.location.href = 'index.html';
}
<!DOCTYPE html>
<!--
Copyright (c) 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.24/webcomponents.min.js"></script>
<script>
'use strict';
function onTraceViewerImportFail() {
document.addEventListener('DOMContentLoaded', function () {
document.body.textContent =
'tracing/bin/trace_viewer_full.html is missing. ' +
'Run vulcanize_trace_viewer from $TRACE_VIEWER and reload.';
});
}
</script>
<link rel="import" href="trace_viewer_full.html" onerror="onTraceViewerImportFail(event)">
<style>
html,
body {
box-sizing: border-box;
overflow: hidden;
margin: 0px;
padding: 0;
width: 100%;
height: 100%;
}
#trace-viewer {
width: 100%;
height: 100%;
}
#trace-viewer:focus {
outline: none;
}
</style>
<script>
'use strict';
(function () {
let viewer;
let name;
let model;
// You can set this to true if you want to hide the WebComponentsV0 polyfill
// warning.
window.__hideTraceViewerPolyfillWarning = true;
window.addEventListener("message", event => {
const data = event.data || {}
// console.log(data)
// name = data.name || 'unknown'
console.log('datas',data)
// name = data.name || 'unknown'
name = 'traceViewers'
onResult(data.data)
})
function onResult(result) {
model = new tr.Model();
const i = new tr.importer.Import(model);
const p = i.importTracesWithProgressDialog([result]);
p.then(onModelLoaded, onImportFail);
}
function onModelLoaded() {
viewer.model = model;
viewer.viewTitle = name;
}
function onImportFail() {
const overlay = new tr.ui.b.Overlay();
overlay.textContent = `Import '${name}' failed`;
overlay.title = 'Import error';
overlay.visible = true;
}
document.addEventListener('WebComponentsReady', function () {
const container = document.createElement('track-view-container');
container.id = 'track_view_container';
viewer = document.createElement('tr-ui-timeline-view');
viewer.track_view_container = container;
Polymer.dom(viewer).appendChild(container);
viewer.id = 'trace-viewer';
viewer.globalMode = true;
Polymer.dom(document.body).appendChild(viewer);
if (window.parent) {
window.parent.postMessage({ msg: 'ready' }, '*')
}
});
}());
</script>
</head>
<body>
</body>
</html>
......@@ -37,6 +37,7 @@ function isWorkspace() {
const iconsPath = path.dirname(resolve.sync(cwd, '@visualdl/icons'));
const netronPath = path.dirname(resolve.sync(cwd, '@visualdl/netron'));
const TracePath = path.dirname(resolve.sync(cwd, './public/static'));
const wasmPath = path.dirname(resolve.sync(cwd, '@visualdl/wasm'));
const dest = path.resolve(cwd, './dist/__snowpack__/link/packages');
......@@ -65,6 +66,8 @@ export default {
plugins: [
'@snowpack/plugin-react-refresh',
'@snowpack/plugin-dotenv',
'snowpack-plugin-less',
'@snowpack/plugin-sass',
[
'@snowpack/plugin-typescript',
{
......@@ -97,6 +100,10 @@ export default {
source: [path.join(netronPath, '**/*')],
destination: path.join(dest, 'netron/dist')
},
{
source: [path.join(TracePath, '**/*')],
destination: path.join(dest, 'trace/dist')
},
{
source: [path.join(wasmPath, '*.{js,wasm}')],
destination: path.join(dest, 'wasm/dist')
......@@ -111,7 +118,8 @@ export default {
},
packageOptions: {
polyfillNode: true,
knownEntrypoints: ['chai', '@testing-library/react', 'fetch-mock/esm/client', 'react-is']
// knownEntrypoints: ['chai', '@testing-library/react', 'fetch-mock/esm/client', 'react-is','rc-util/es/hooks/useId','rc-util/es/Portal','rc-util/es/Dom/contains','rc-util/es/Dom/css','rc-util/es/getScrollBarSize','rc-util/es/PortalWrapper','rc-select/es/hooks/useId','rc-util/es/Dom/isVisible','rc-util/es/Dom/focus','rc-util/es/Dom/focus']
knownEntrypoints: ['chai', '@testing-library/react', 'fetch-mock/esm/client', 'react-is', 'antd']
},
buildOptions: {
out: 'dist',
......
......@@ -15,12 +15,12 @@
*/
// cSpell:words pageview inited
import 'antd/dist/antd.css';
import React, {FunctionComponent, Suspense, useCallback, useEffect, useMemo} from 'react';
import {Redirect, Route, BrowserRouter as Router, Switch, useLocation} from 'react-router-dom';
import {THEME, matchMedia} from '~/utils/theme';
import {actions, selectors} from '~/store';
import {headerHeight, position, size, zIndexes} from '~/utils/style';
import {headerHeight, position, size, zIndexes, setRem} from '~/utils/style';
import {useDispatch, useSelector} from 'react-redux';
import ErrorBoundary from '~/components/ErrorBoundary';
......@@ -93,7 +93,12 @@ const App: FunctionComponent = () => {
},
[dispatch, selectedTheme]
);
// useEffect(() => {
// setRem();
// window.onresize = function () {
// setRem();
// };
// }, []);
useEffect(() => {
if (!THEME) {
matchMedia.addEventListener('change', toggleTheme);
......
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><path fill="#2932E1" d="M7,0 L7,0 C3.13400755,0 0,3.13400755 0,7 C0,7 0,7 0,7 L0,7 C0,10.8660098 3.13400755,14.0000173 7,14.0000173 L7,14.0000173 C10.8660084,14.0000173 14.000016,10.8660098 14.000016,7 L14.000016,7 C14.000016,3.13400861 10.8660084,0 7,0 L7,0 Z M6.88930852,9.94833549 C7.21622667,9.93576419 7.4914375,10.1905932 7.50400904,10.5175113 L7.50400904,10.5175113 L7.50400904,10.5630368 C7.49143774,10.889955 7.21622667,11.1447842 6.88930852,11.1322127 C6.56239037,11.1196414 6.30756117,10.8444303 6.32013266,10.5175122 L6.32013266,10.5175122 L6.33060888,10.4267388 C6.38223791,10.1609864 6.61095033,9.95903965 6.88930852,9.94833549 Z M6.9921336,2.8909989 C7.68252171,2.88978156 8.34332932,3.17117818 8.82088573,3.66975376 C9.26013624,4.1326293 9.4841365,4.72762999 9.45088646,5.34538071 C9.41763643,5.97800645 9.2233862,6.47763203 8.25213507,7.44800816 C7.80955955,7.89058367 7.51369546,8.23393407 7.43598487,8.5348303 L7.41825909,8.63363464 C7.39588787,8.85742952 7.22604721,9.0338123 7.01087397,9.07031116 L6.929,9.077 L6.88013332,9.07463556 C6.60994121,9.04746842 6.41268863,8.80677451 6.43913281,8.53650993 C6.50563288,7.85400914 7.00613347,7.3027585 7.55738411,6.75150786 C8.38667919,5.92221277 8.44786265,5.62462765 8.46532207,5.3451887 L8.4682602,5.29288053 C8.48225838,4.99167784 8.38830495,4.69712169 8.20611596,4.46089356 L8.10775983,4.34787949 C7.81734836,4.04532465 7.41588559,3.87462425 6.99650854,3.87537894 L6.99475857,3.87537894 C6.23199702,3.87764582 5.60604809,4.45989683 5.53424846,5.20405559 L5.52738186,5.34538065 C5.52738186,5.61720929 5.30702243,5.83756872 5.03519379,5.83756872 C4.76336515,5.83756872 4.54300572,5.61720929 4.54300572,5.34538065 C4.54300572,4.75554246 4.74854346,4.19830682 5.12708727,3.7553218 L5.25963149,3.6120037 C5.67192267,3.19623274 6.21843686,2.94437592 6.79789833,2.898576 L6.9921336,2.8909989 Z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd" transform="matrix(-1 0 0 1 14 0)"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#666" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<path d="M14.45 24v0c-0.001 0.015-0.001 0.032-0.001 0.050 0 0.746 0.605 1.351 1.351 1.351 0.729 0 1.322-0.577 1.35-1.298l0-0.003v-0.1c0-0.746-0.604-1.35-1.35-1.35s-1.35 0.604-1.35 1.35v0zM15.84 20.71h-0.11c-0.568-0.060-1.006-0.536-1.006-1.114 0-0.041 0.002-0.081 0.006-0.121l-0 0.005c0.15-1.56 1.29-2.82 2.55-4.080 2-2 2.050-2.65 2.090-3.33 0.002-0.035 0.002-0.077 0.002-0.118 0-0.795-0.318-1.516-0.833-2.042l0 0.001c-0.639-0.648-1.527-1.050-2.508-1.050-0.011 0-0.022 0-0.034 0h0.002c-1.853 0.006-3.354 1.507-3.36 3.359v0.001c-0.056 0.577-0.538 1.024-1.125 1.024s-1.069-0.447-1.125-1.019l-0-0.005c-0-0.021-0-0.045-0-0.069 0-1.537 0.627-2.928 1.64-3.93l0-0c1.008-1.019 2.407-1.65 3.953-1.65 0.017 0 0.033 0 0.049 0l-0.003-0c0.002 0 0.005 0 0.008 0 1.639 0 3.119 0.682 4.17 1.778l0.002 0.002c0.895 0.917 1.447 2.171 1.447 3.555 0 0.097-0.003 0.193-0.008 0.288l0.001-0.013c-0.070 1.44-0.52 2.59-2.74 4.8-1.17 1.17-1.91 2.020-1.91 2.75-0.072 0.563-0.545 0.994-1.119 1h-0.001zM25.72 25.71v0c-2.476 2.472-5.895 4-9.671 4-0.017 0-0.035-0-0.052-0h0.003c-0.017 0-0.037 0-0.058 0-3.773 0-7.189-1.529-9.662-4l0 0c-2.472-2.482-4-5.906-4-9.687 0-0.015 0-0.030 0-0.045v0.002c0.031-7.57 6.175-13.695 13.75-13.695 3.781 0 7.205 1.526 9.691 3.996l-0.001-0.001c2.472 2.476 4 5.895 4 9.671 0 0.017-0 0.035-0 0.052v-0.003c0 0.021 0 0.045 0 0.070 0 3.769-1.529 7.181-4 9.65l-0 0zM16 0v0c-8.837 0-16 7.163-16 16s7.163 16 16 16c8.837 0 16-7.163 16-16v0c0-8.837-7.163-16-16-16v0z"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#666" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#DDD" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd" transform="matrix(-1 0 0 1 14 0)"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#DDD" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><path fill="#999" d="M7,0 L7,0 C3.13400755,0 0,3.13400755 0,7 C0,7 0,7 0,7 L0,7 C0,10.8660098 3.13400755,14.0000173 7,14.0000173 L7,14.0000173 C10.8660084,14.0000173 14.000016,10.8660098 14.000016,7 L14.000016,7 C14.000016,3.13400861 10.8660084,0 7,0 L7,0 Z M11.2525134,11.2525131 L11.2525135,11.252513 C10.7048627,11.8023117 10.0555162,12.2403604 9.3406363,12.5422645 C8.59951044,12.8572648 7.81200953,13.0156582 7.00000858,13.0156582 L7.00000849,13.0156582 C5.40441679,13.0195737 3.8734111,12.3857487 2.74750354,11.255138 L2.74750336,11.2551378 C2.1976117,10.7072286 1.75955748,10.0575786 1.45775186,9.34238556 L1.45775216,9.34238626 C1.14368421,8.60148325 0.982666252,7.80472237 0.98435912,7.00000854 L0.98435912,6.9999854 C0.980679249,5.40427065 1.61483393,3.87323762 2.74576591,2.74748045 L2.74576566,2.7474807 C3.29341649,2.19768201 3.94276295,1.75963326 4.65764288,1.4577292 L4.65764309,1.45772911 C5.398542,1.14366937 6.19529332,0.982655511 7.00000714,0.98435248 L7.0000074,0.98435248 C8.59572214,0.980666565 10.1267552,1.61481504 11.2525123,2.74574565 L11.2525123,2.74574559 C11.802311,3.29339642 12.2403597,3.94274288 12.5422638,4.65762281 C12.8572642,5.40049868 13.0156535,6.18799959 13.0156535,7.00000054 L13.0156535,7.00011144 C13.0190805,8.59596291 12.384582,10.1269959 11.2533055,11.252589 L11.2525134,11.2525131 Z M6.93000837,9.07726056 L6.88013331,9.07463556 L6.88013332,9.07463556 C6.60994121,9.04746842 6.41268863,8.80677451 6.43913281,8.53650993 C6.50563288,7.85400914 7.00613347,7.3027585 7.55738411,6.75150786 C8.43851013,5.87038183 8.45251015,5.5895065 8.46826017,5.29288116 L8.4682602,5.29288053 C8.48459141,4.94147739 8.35398848,4.59912094 8.10775978,4.34787943 L8.10775983,4.34787949 C7.81734836,4.04532465 7.41588559,3.87462425 6.99650854,3.87537894 L6.99475854,3.87537894 L6.99475857,3.87537894 C6.18432442,3.8777875 5.52833889,4.53494377 5.52738186,5.34538065 L5.52738186,5.34538065 C5.52738186,5.61720929 5.30702243,5.83756872 5.03519379,5.83756872 C4.76336515,5.83756872 4.54300572,5.61720929 4.54300572,5.34538065 C4.54300572,4.69000489 4.79675601,4.07487917 5.25963155,3.61200363 L5.25963149,3.6120037 C5.7177328,3.15003597 6.34154154,2.89043137 6.9921335,2.8909989 L6.9921336,2.8909989 C7.68252171,2.88978156 8.34332932,3.17117818 8.82088573,3.66975376 C9.26013624,4.1326293 9.4841365,4.72762999 9.45088646,5.34538071 C9.41763643,5.97800645 9.2233862,6.47763203 8.25213507,7.44800816 C7.7603845,7.93975873 7.44975914,8.30900916 7.4182591,8.63363454 L7.41825909,8.63363464 C7.39309146,8.88540388 7.18128284,9.07716719 6.92825852,9.07726056 L6.93000837,9.07726056 Z M6.32013266,10.5175122 L6.32013266,10.5175122 C6.30756117,10.8444303 6.56239037,11.1196414 6.88930852,11.1322127 C7.21622667,11.1447842 7.49143774,10.889955 7.50400904,10.5630368 C7.50459238,10.5478673 7.50459238,10.532681 7.50400905,10.5175115 L7.50400904,10.5175113 C7.4914375,10.1905932 7.21622667,9.93576419 6.88930852,9.94833549 C6.58002164,9.960229 6.33202584,10.2082245 6.32013266,10.5175113 L6.32013266,10.5175122 Z"/></svg>
\ No newline at end of file
......@@ -20,16 +20,16 @@ import React, {useEffect, useImperativeHandle} from 'react';
import {WithStyled, primaryColor} from '~/utils/style';
import useECharts, {Options, Wrapper, useChartTheme} from '~/hooks/useECharts';
import type {EChartOption} from 'echarts';
import type {EChartsOption} from 'echarts';
import GridLoader from 'react-spinners/GridLoader';
import defaultsDeep from 'lodash/defaultsDeep';
type BarChartProps = {
options?: EChartOption;
options?: EChartsOption;
title?: string;
direction?: 'vertical' | 'horizontal';
categories?: string[];
data?: Partial<NonNullable<EChartOption<EChartOption.SeriesBar>['series']>>;
data?: any;
loading?: boolean;
onInit?: Options['onInit'];
};
......@@ -74,25 +74,25 @@ const BarChart = React.forwardRef<BarChartRef, BarChartProps & WithStyled>(
formatter: null
}
};
const chartOptions: EChartOption = defaultsDeep(
const seriesData = data?.map((item: any, index: number) =>
defaultsDeep(
item,
{
itemStyle: {
color: color[index % color.length]
}
},
series
)
);
const chartOptions: EChartsOption = defaultsDeep(
{
title: {
text: title ?? ''
},
xAxis: isHorizontal ? valueAxis : categoryAxis,
yAxis: isHorizontal ? categoryAxis : valueAxis,
series: data?.map((item, index) =>
defaultsDeep(
item,
{
itemStyle: {
color: color[index % color.length]
}
},
series
)
)
series: seriesData
},
options,
theme,
......
/* eslint-disable sort-imports */
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as chart from '~/utils/chart';
import React, {useEffect, useImperativeHandle} from 'react';
import {primaryColor} from '~/utils/style';
import useECharts, {Options, Wrapper, useChartTheme} from '~/hooks/useECharts';
import type {EChartsOption} from 'echarts';
import GridLoader from 'react-spinners/GridLoader';
import defaultsDeep from 'lodash/defaultsDeep';
import {useTranslation} from 'react-i18next';
interface Callingtimes {
key: string[];
value: number[];
}
type BarsChartProps = {
options?: EChartsOption;
title?: string;
data?: Callingtimes;
loading?: boolean;
zoom?: boolean;
onInit?: Options['onInit'];
className?: string;
units?: string;
isLegend?: boolean;
text?: number;
};
export enum XAxisType {
value = 'value',
log = 'log',
time = 'time'
}
export enum YAxisType {
value = 'value',
log = 'log'
}
export type BarChartRef = {
restore(): void;
saveAsImage(): void;
};
const Charts = React.forwardRef<BarChartRef, BarsChartProps>(
({options, data, title, loading, zoom, className, onInit, text, isLegend, units}, ref) => {
const {i18n} = useTranslation();
const {t} = useTranslation(['profiler', 'common']);
const {
ref: echartRef,
echart,
wrapper,
saveAsImage
} = useECharts<HTMLDivElement>({
loading: !!loading,
zoom,
autoFit: true,
onInit
});
const theme = useChartTheme();
useImperativeHandle(ref, () => ({
restore: () => {
echart?.dispatchAction({
type: 'restore'
});
},
saveAsImage: () => {
saveAsImage(title);
}
}));
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
if (data) {
// const {} = chart;
const chartData = data;
const color = ['#2932E1', '#00CC88', '#981EFF', '#FF6D6D', '#25C9FF', '#E71ED5', '#FFAA00', '#00307D'];
const title =
text === 1
? t('Number-calls')
: text === 2
? t('duration') + `(${units})`
: t('Overall-proportion') + `(%)`;
const values = [];
for (let index = 0; index < chartData.value.length; index++) {
values.push({
value: chartData.value[index],
itemStyle: {
color: color[index]
}
});
}
const chartOptions: EChartsOption = defaultsDeep({
title: {
bottom: '5%',
left: 'center',
show: true,
text: title,
textStyle: {
color: '#666666',
fontStyle: 'PingFangSC-Regular',
fontWeight: '400',
fontSize: 12
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
extraCssText:
'padding:15px;padding-right:41px;line-height:30px;width:auto;height:auto;background:rgba(0,0,0,0.75);box-shadow:1px 5px 20px 0px rgba(1,11,19,0.2);border-radius:6px;border:none;',
formatter: function (params: any) {
let str = ''; //声明一个变量用来存储数据
str +=
'<div style="font-size:14px;color:#FFFFFF;font-weight:500;margin-left:17px;">' +
params[0].name +
'</div>';
str += '<div class="tooltipContent">';
for (let index = 0; index < params.length; index++) {
const element = params[index];
str += '<div class="tooltipitems">';
str +=
'<span style="font-size:12px;display:inline-block;margin-right:5px;width:12px;height:12px;border-radius:50%;background-color:' +
element.color +
';"></span>' +
'<span style="color: #FFFFFF;">' +
element.name +
'</span>' +
'</span> : <span style="color: #FFFFFF;">' +
element.data.value +
'</span>';
str += '</div>';
}
str += '</div>';
return str;
}
},
legend: {
show: isLegend,
data: ['Kernel', 'Memcpy', 'Memset', 'Communication', 'Runtime'],
top: 0,
right: 0,
itemGap: 20,
textStyle: {
fontSize: 14,
color: '#666666'
},
itemWidth: 17,
itemHeight: 5
},
grid: {
left: '0',
right: '0',
top: '4',
bottom: '50',
containLabel: true
},
xAxis: [
{
type: 'category',
data: chartData.key,
axisTick: {
alignWithLabel: false,
show: false
},
axisLabel: {
show: false
},
axisLine: {
lineStyle: {
color: '#CCCCCC'
}
}
}
],
yAxis: [
{
type: 'value',
axisTick: {
show: false
},
axisLabel: {
color: '#666666'
},
axisLine: {
lineStyle: {
color: '#CCCCCC'
}
}
}
],
series: [
{
type: 'bar',
barWidth: '30%',
data: values
}
]
});
echart?.setOption(chartOptions, {notMerge: true});
}
}, [options, data, title, theme, i18n.language, echart, isLegend, units, text]);
return (
<Wrapper ref={wrapper} className={className}>
{!echart && (
<div className="loading">
<GridLoader color={primaryColor} size="10px" />
</div>
)}
<div className="echarts" ref={echartRef}></div>
</Wrapper>
);
}
);
export default Charts;
......@@ -22,6 +22,11 @@ import styled from 'styled-components';
const Section = styled.section`
display: flex;
font-family: PingFangSC-Regular;
aside {
position: static;
height: auto;
}
`;
const Article = styled.article`
......@@ -40,18 +45,35 @@ const Aside = styled.aside`
overflow-y: auto;
${transitionProps('background-color')}
`;
const ProfilerAside = styled.aside`
flex: none;
background-color: var(--background-color);
height: auto;
position: static;
overflow-x: hidden;
overflow-y: auto;
${transitionProps('background-color')}
`;
type ContentProps = {
aside?: React.ReactNode;
leftAside?: React.ReactNode;
loading?: boolean;
isProfiler?: boolean;
};
const Content: FunctionComponent<ContentProps & WithStyled> = ({children, aside, leftAside, loading, className}) => (
const Content: FunctionComponent<ContentProps & WithStyled> = ({
children,
aside,
leftAside,
loading,
className,
isProfiler
}) => (
<Section className={className}>
{leftAside && <Aside>{leftAside}</Aside>}
<Article>{children}</Article>
{aside && <Aside>{aside}</Aside>}
{aside && isProfiler ? <ProfilerAside>{aside}</ProfilerAside> : aside ? <Aside>{aside}</Aside> : null}
{loading && <BodyLoading />}
</Section>
);
......
......@@ -23,7 +23,7 @@ import {rem, size} from '~/utils/style';
import Chart from '~/components/Chart';
import {Chart as ChartLoader} from '~/components/Loader/ChartPage';
import ChartToolbox from '~/components/ChartToolbox';
import type {EChartOption} from 'echarts';
import type {EChartsOption} from 'echarts';
import TooltipTable from '~/components/TooltipTable';
import {cycleFetcher} from '~/utils/fetch';
import {format} from 'd3-format';
......@@ -138,7 +138,7 @@ const PRCurveChart: FunctionComponent<PRCurveChartProps> = ({type, runs, tag, ru
);
const formatter = useCallback(
(params: EChartOption.Tooltip.Format | EChartOption.Tooltip.Format[]) => {
(params: any) => {
const series = Array.isArray(params) ? params[0].data : params.data;
const points = nearestPoint(
selectedData.map(s => s[2]),
......
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as chart from '~/utils/chart';
import React, {useEffect, useCallback} from 'react';
import {primaryColor} from '~/utils/style';
import useECharts, {Options, Wrapper, useChartTheme} from '~/hooks/useECharts';
import {color} from '~/utils/chart';
import {renderToStaticMarkup} from 'react-dom/server';
import TooltipTable from '~/components/TooltipTable';
import type {EChartsOption} from 'echarts';
import GridLoader from 'react-spinners/GridLoader';
import defaultsDeep from 'lodash/defaultsDeep';
import {useTranslation} from 'react-i18next';
import type {curveType} from '~/components/ProfilerPage/MemoryView/type';
type DistributedChartProps = {
options?: EChartsOption;
titles?: string;
data?: curveType;
loading?: boolean;
zoom?: boolean;
className?: string;
onInit?: Options['onInit'];
};
type lineData = (number | string)[][];
export interface Run {
label: string;
colors: [string, string];
}
export enum XAxisType {
value = 'value',
log = 'log',
time = 'time'
}
export enum YAxisType {
value = 'value',
log = 'log'
}
export type LineChartRef = {
restore(): void;
saveAsImage(): void;
};
const DistributedChart = React.forwardRef<LineChartRef, DistributedChartProps>(
({options, data, titles, loading, zoom, className, onInit}, ref) => {
const {t} = useTranslation(['profiler', 'common']);
const {i18n} = useTranslation();
const {
ref: echartRef,
echart,
wrapper
} = useECharts<HTMLDivElement>({
loading: !!loading,
zoom,
autoFit: true,
onInit
});
const theme = useChartTheme();
const formatter = useCallback(
(params: any) => {
if (params.length) {
const n = params.length / 4 - 1;
let index = 0;
const datas: any = [];
const runs: any = [];
while (index < params.length) {
const element = params[index];
if (element) {
runs.push({label: element.seriesName, colors: [element.color]});
datas.push(element.value);
}
if (n >= 0) {
index += 1 + n;
} else {
index += 1;
}
}
const columns = [
{label: t('timestamp')},
{label: t('memory-size') + '(KB)'},
{label: t('event-name')}
];
return renderToStaticMarkup(
<TooltipTable run={t('common:runs')} runs={runs as Run[]} columns={columns} data={datas} />
);
}
},
[t]
);
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
if (!data) {
return;
}
// debugger
const chartData = data;
const seriesData = Object.keys(data.name).map(items => {
const Data: any = data;
const series = Data[items] as lineData;
return {
name: t(items),
step: 'true',
type: 'line',
smooth: true,
showSymbol: false,
symbol: 'circle',
symbolSize: 4,
emphasis: {
focus: 'series',
itemStyle: {
opacity: 1,
borderWidth: 2,
borderColor: '#fff',
shadowColor: color[0],
shadowBlur: 2
}
},
animationDuration: 100,
data: series,
encode: {
x: [0],
y: [1]
}
};
});
if (chartData) {
const title = `Peak Memory Usage: ${titles}KB`;
const chartOptions: EChartsOption = defaultsDeep({
color: [
'#2932E1',
'#00CC88',
'#981EFF',
'#066BFF',
'#00E2FF',
'#FFAA00',
'#E71ED5',
'#FF6600',
'#0DEBB0',
'#D50505'
],
// backgroundColor: 'rgb(128, 128, 128, .04)',
title: {
top: '0',
left: '15',
show: true,
text: title,
textStyle: {
color: '#666666',
fontStyle: 'PingFangSC-Regular',
fontWeight: '400',
fontSize: 14
}
},
legend: {
type: 'plain',
top: 0,
right: 0,
itemGap: 14,
textStyle: {
fontSize: 14,
color: '#666666'
},
icon: 'path://M14.5,0h-12C1.1,0,0,1.1,0,2.5S1.1,5,2.5,5h12C15.9,5,17,3.9,17,2.5S15.9,0,14.5,0z',
itemWidth: 17,
itemHeight: 5
},
tooltip: {
trigger: 'axis',
formatter,
hideDelay: 300,
backgroundColor: 'rgba(0, 0, 0, 0.6)',
borderColor: 'rgba(0, 0, 0, 0.6)',
textStyle: {color: '#fff'},
enterable: true
},
grid: {
left: '0',
right: '20',
bottom: '0',
top: '62',
containLabel: true
},
xAxis: {
crossStyle: {
color: '#2932e1',
type: 'dashed'
},
label: {show: true},
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#CCCCCC'
}
},
axisLabel: {
color: '#666666',
fontSize: 12
}
},
yAxis: {
type: 'value',
name: t('memory-usage') + '(kB)',
position: 'left',
// offset: 0,
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#CCCCCC'
}
},
axisLabel: {
color: '#666666',
fontSize: 12
}
// splitNumber: 5
},
dataZoom: [
{
type: 'inside',
xAxisIndex: 0
}
],
// toolbox: {
// show: false,
// showTitle: false,
// itemSize: 0,
// feature: {
// dataZoom: {
// show: true,
// xAxisIndex: 0
// }
// }
// },
series: seriesData
});
echart?.setOption(chartOptions, {notMerge: true});
}
}, [options, data, titles, theme, i18n.language, echart, formatter, t]);
return (
<Wrapper ref={wrapper} className={className}>
{!echart && (
<div className="loading">
<GridLoader color={primaryColor} size="10px" />
</div>
)}
<div className="echarts" ref={echartRef}></div>
</Wrapper>
);
}
);
export default DistributedChart;
......@@ -16,7 +16,7 @@
// cSpell:words npts
import type {EChartOption, ECharts, EChartsConvertFinder} from 'echarts';
import type {EChartsOption, ECharts} from 'echarts';
import type {HistogramData, OffsetData, OverlayData, OverlayDataItem} from '~/resource/histogram';
import LineChart, {LineChartRef} from '~/components/LineChart';
import {Modes, options as chartOptions} from '~/resource/histogram';
......@@ -142,13 +142,13 @@ const HistogramChart: FunctionComponent<HistogramChartProps> = ({run, tag, mode,
const formatter = useMemo(
() => ({
[Modes.Overlay]: (params: EChartOption.Tooltip.Format | EChartOption.Tooltip.Format[]) => {
[Modes.Overlay]: (params: any) => {
if (!data || highlight == null) {
return '';
}
const series = (params as EChartOption.Tooltip.Format[]).find(
s => s.data[1] === (data as OverlayData).data[highlight][0][1]
);
const series = params.find((s: any) => {
return s.data[1] === (data as OverlayData).data[highlight][0][1];
});
return series?.seriesName ?? '';
},
[Modes.Offset]: (dot: [number, number, number]) => dot[2]
......@@ -210,15 +210,15 @@ const HistogramChart: FunctionComponent<HistogramChartProps> = ({run, tag, mode,
);
const mousemove = useCallback((echarts: ECharts, {offsetX, offsetY}: {offsetX: number; offsetY: number}) => {
const series = echarts.getOption().series;
const series: any = echarts.getOption().series;
const pt: [number, number] = [offsetX, offsetY];
if (series) {
type Distance = number;
type Index = number;
const npts: [number, number, Distance, Index][] = series.map((s, i) =>
const npts: [number, number, Distance, Index][] = series.map((s: any, i: number) =>
(s.data as OverlayDataItem[])?.reduce(
(m, [, , x, y]) => {
const px = echarts.convertToPixel('grid' as EChartsConvertFinder, [x, y]) as [number, number];
const px = echarts.convertToPixel('grid', [x, y]) as [number, number];
const d = distance(px, pt);
if (d < m[2]) {
return [x, y, d, i];
......@@ -257,8 +257,8 @@ const HistogramChart: FunctionComponent<HistogramChartProps> = ({run, tag, mode,
<StyledLineChart
ref={echart as React.RefObject<LineChartRef>}
title={title}
data={chartData as EChartOption<EChartOption.SeriesLine>['series']}
options={options as EChartOption}
data={chartData}
options={options as EChartsOption}
loading={loading}
onInit={onInit}
/>
......@@ -270,7 +270,7 @@ const HistogramChart: FunctionComponent<HistogramChartProps> = ({run, tag, mode,
ref={echart as React.RefObject<StackChartRef>}
title={title}
data={chartData as StackChartProps['data']}
options={options as EChartOption}
options={options as EChartsOption}
loading={loading}
/>
);
......
......@@ -54,6 +54,7 @@ const NumberInput: FunctionComponent<NumberInputProps & WithStyled> = ({
if (Number.isNaN(v)) {
setInputValue(Number.isFinite(value) ? value + '' : '');
} else {
debugger;
setInputValue(v + '');
}
}, [inputValue, value]);
......
/* eslint-disable sort-imports */
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
......@@ -16,20 +17,20 @@
import * as chart from '~/utils/chart';
import React, {useEffect, useImperativeHandle} from 'react';
import React, {useEffect, useImperativeHandle, useState} from 'react';
import {WithStyled, primaryColor} from '~/utils/style';
import useECharts, {Options, Wrapper, useChartTheme} from '~/hooks/useECharts';
import type {EChartOption} from 'echarts';
import type {EChartsOption, XAXisComponentOption, YAXisComponentOption} from 'echarts';
import GridLoader from 'react-spinners/GridLoader';
import defaultsDeep from 'lodash/defaultsDeep';
import {formatTime} from '~/utils';
import {useTranslation} from 'react-i18next';
type LineChartProps = {
options?: EChartOption;
options?: EChartsOption;
title?: string;
data?: Partial<NonNullable<EChartOption<EChartOption.SeriesLine>['series']>>;
data?: any;
loading?: boolean;
zoom?: boolean;
onInit?: Options['onInit'];
......@@ -53,6 +54,7 @@ export type LineChartRef = {
const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
({options, data, title, loading, zoom, className, onInit}, ref) => {
// const [chartOption, setchartOption] = useState<EChartsOption>();
const {i18n} = useTranslation();
const {
......@@ -79,12 +81,12 @@ const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
saveAsImage(title);
}
}));
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {color, colorAlt, series, ...defaults} = chart;
let chartOptions: EChartOption = defaultsDeep(
const {color, series, ...defaults} = chart;
if (!echart) {
return;
}
let chartOptions: EChartsOption = defaultsDeep(
{
title: {
text: title ?? ''
......@@ -98,7 +100,18 @@ const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
yAxis: {
splitNumber: 4
},
series: data?.map((item, index) =>
toolbox: {
show: true,
showTitle: false,
itemSize: 0,
feature: {
dataZoom: {
show: true
// xAxisIndex: 0
}
}
},
series: data?.map((item: any, index: number) =>
defaultsDeep(
{
// show symbol if there is only one point
......@@ -120,7 +133,7 @@ const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
theme,
defaults
);
if ((chartOptions?.xAxis as EChartOption.XAxis).type === 'time') {
if ((chartOptions?.xAxis as XAXisComponentOption)?.type === 'time') {
chartOptions = defaultsDeep(
{
xAxis: {
......@@ -132,7 +145,7 @@ const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
chartOptions
);
}
if ((chartOptions?.yAxis as EChartOption.YAxis).type === 'time') {
if ((chartOptions?.yAxis as YAXisComponentOption).type === 'time') {
chartOptions = defaultsDeep(
{
yAxis: {
......@@ -145,7 +158,14 @@ const LineChart = React.forwardRef<LineChartRef, LineChartProps & WithStyled>(
);
}
echart?.setOption(chartOptions, {notMerge: true});
}, [options, data, title, theme, i18n.language, echart]);
echart?.dispatchAction({
type: 'takeGlobalCursor',
key: 'dataZoomSelect',
dataZoomSelectActive: true
});
// debugger
console.log('chartOptions', chartOptions);
}, [options, theme, data, title, i18n.language, echart]);
return (
<Wrapper ref={wrapper} className={className}>
......
export interface tensorcorePie {
column_name: string[];
events: Event[];
}
export interface Event {
name: string;
calls: number;
ratio: number;
}
export interface kernelPie {
column_name: string[];
events: kernelEvent[];
}
export interface kernelEvent {
name: string;
calls: number;
total_time: number;
avg_time: number;
max_time: number;
min_time: number;
'mean blocks per sm': number;
'mean est achieved occupancy': number;
'tensor core used': boolean;
ratio: number;
}
export interface tableDataType {
events: tableEvent[];
column_name: string[];
}
export interface tableEvent {
name: string;
calls: number;
total_time: number;
avg_time: number;
max_time: number;
min_time: number;
'mean blocks per sm': number;
'mean est achieved occupancy': number;
'tensor core used': boolean;
ratio: number;
operator?:string;
grid?:string;
}
/* eslint-disable sort-imports */
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, {FunctionComponent, useState, useEffect, useCallback} from 'react';
import StackColumnChart from '~/components/StackColumnChart';
import styled from 'styled-components';
import {useTranslation} from 'react-i18next';
import {fetcher} from '~/utils/fetch';
import {Configure, EchartPie, ArgumentOperation, Title, ViewWrapper, FullWidthSelect} from '../../components';
import {asideWidth, rem} from '~/utils/style';
import type {infoType, histogramType} from './type';
import {Popover} from 'antd';
import logo from '~/assets/images/question-circle.svg';
asideWidth;
const Configures = styled(Configure)`
.border {
border-top: none;
}
`;
const Card = styled.div`
width: 100%;
height: ${rem(142)};
border: 1px solid #dddddd;
font-family: PingFangSC-Regular;
font-size: ${rem(14)};
font-weight: 400;
display: flex;
.item_list {
flex: 1;
display: flex;
align-items: center;
div:nth-of-type(1) {
padding-left: ${rem(20)};
}
div:nth-of-type(3) {
border-right: none;
}
.items {
padding-left: ${rem(30)};
padding-right: ${rem(30)};
}
.items:nth-of-type(2) {
border-right: 1px solid #dddddd;
border-left: 1px solid #dddddd;
}
}
.info_list {
flex: 1;
.items:nth-of-type(1) {
margin-top: ${rem(14)};
}
.items {
display: flex;
margin-top: ${rem(8)};
justify-content: center;
.label {
width: ${rem(220)};
padding-right: ${rem(30)};
text-align: right;
color: #666666;
}
.info {
width: ${rem(220)};
text-align: left;
color: #000000;
}
}
}
`;
const EchartPies = styled(EchartPie)`
padding: ${rem(24)};
border: 1px solid #dddddd;
height: ${rem(366)};
`;
export type NuclearViewProps = {
runs: string;
views: string;
workers: string;
spans: string;
units: string;
descriptions: any;
};
type SelectListItem<T> = {
value: T;
label: string;
};
const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH;
const NuclearView: FunctionComponent<NuclearViewProps> = ({runs, views, workers, spans, units, descriptions}) => {
const {t} = useTranslation(['profiler', 'common']);
const [computation, setComputation] = useState<histogramType>();
const [distributedData, setDistributedData] = useState<infoType[]>();
const [stepsList, setStepsList] = useState<SelectListItem<string>[]>();
const [steps, setSteps] = useState<string>();
useEffect(() => {
if (runs && workers && spans) {
fetcher('/profiler/distributed/info' + `?run=${runs}` + `&worker=${workers}` + `&span=${spans}`).then(
(res: unknown) => {
const result = res as infoType[];
setDistributedData(result);
}
);
fetcher('/profiler/distributed/steps' + `?run=${runs}` + `&worker=${workers}` + `&span=${spans}`).then(
(res: unknown) => {
const stepData = res as string[] | number[];
const stepList = stepData.map(item => {
return {label: item + '', value: item + ''};
});
setStepsList(stepList);
setSteps(stepData[0] + '');
}
);
}
}, [runs, workers, spans]);
useEffect(() => {
if (runs && workers && spans && steps && units) {
fetcher(
'/profiler/distributed/histogram' +
`?run=${runs}` +
`&worker=${workers}` +
`&span=${spans}` +
`&step=${steps}` +
`&time_unit=${units}`
).then((res: unknown) => {
const Data = res as histogramType;
setComputation(Data);
});
}
}, [runs, workers, spans, views, steps, units]);
const gettTooltip: (name: string) => JSX.Element = useCallback(
(name: string) => {
const tooltips = (
<div
style={{
width: rem(700),
color: '#333333',
fontWeight: 400
}}
dangerouslySetInnerHTML={{__html: descriptions ? descriptions[name] : ''}}
></div>
);
return tooltips;
},
[descriptions]
);
const getPopupContainers = (trigger: any) => {
return trigger.parentElement;
};
return (
<ViewWrapper>
<Title>{t('Distribution-view')}</Title>
<Configures style={{marginTop: `${rem(24)}`}}>
<div className="titleContent">
<div className="titles">
<div>{t('Device-Information')}</div>
</div>
</div>
<div>
{distributedData &&
distributedData.map((items, index) => {
return (
<Card className={index === 1 ? 'border' : ''} key={index}>
<div className="item_list">
<div className="items">{items.worker_name}</div>
<div className="items">{items.process_id}</div>
<div className="items">{items.device_id}</div>
</div>
<div className="info_list">
<div className="items">
<div className="label">Name:</div>
<div className="info">{items.name}</div>
</div>
<div className="items">
<div className="label">Memory:</div>
<div className="info">{items.memory}</div>
</div>
<div className="items">
<div className="label">ComputeCapability:</div>
<div className="info">{items.computeCapability}</div>
</div>
<div className="items">
<div className="label">Utilization:</div>
<div className="info">{items.utilization}</div>
</div>
</div>
</Card>
);
})}
</div>
</Configures>
<Configure style={{marginBottom: `${rem(20)}`}}>
<div className="titleContent" style={{marginBottom: rem(15)}}>
<div className="titles" style={{marginBottom: `${rem(0)}`}}>
<div>{t('comparisons')}</div>
<Popover
content={gettTooltip('distributed_histogram')}
getPopupContainer={getPopupContainers}
placement="right"
>
<ArgumentOperation>
<img src={PUBLIC_PATH + logo} alt="" />
</ArgumentOperation>
</Popover>
</div>
<div className="searchContent">
<div className="select_label">{t('training-steps')}</div>
<div className="select_wrapper">
<FullWidthSelect list={stepsList} value={steps} onChange={setSteps} />
</div>
</div>
</div>
<EchartPies>
<StackColumnChart
className={'Content'}
data={computation}
isWorkerName={true}
units={units}
istotal={true}
></StackColumnChart>
</EchartPies>
</Configure>
</ViewWrapper>
);
};
export default NuclearView;
export interface infoType {
worker_name: string;
process_id: string;
device_id: string;
name: string;
memory: string;
computeCapability: string;
utilization: string;
}
export interface histogramType {
order: string[];
worker_name: string[];
data: number[][];
}
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, {FunctionComponent} from 'react';
import {Trans, useTranslation} from 'react-i18next';
import Error from '~/components/Error';
const DocumentMap: Record<string, string> = {
zh: 'https://github.com/PaddlePaddle/VisualDL/blob/develop/docs/components/README_CN.md#Hparams--超参可视化',
en: 'https://github.com/PaddlePaddle/VisualDL/tree/develop/docs/components#Hparams--HyperParameters-Visualization'
};
const Empty: FunctionComponent = () => {
const {i18n} = useTranslation('hyper-parameter');
return (
<Error>
<Trans i18nKey="hyper-parameter:empty">
<h4>No Hparams Data was Found.</h4>
<p>You can try the following solutions:</p>
<ul>
<li>make sure that you have used `add_scalar` to record the metrics.</li>
<li>make sure that the `metrics_list` of `add_hparams` includes the `tag` of `add_scalar`.</li>
</ul>
<p>
For detailed tutorials, please refer to the&nbsp;
<a
href={DocumentMap[i18n.language || String(i18n.options.fallbackLng)] ?? DocumentMap.en}
target="_blank"
rel="noreferrer"
>
VisualDL Hparams Instructions
</a>
.
</p>
</Trans>
</Error>
);
};
export default Empty;
export interface devicesType {
device: string;
min_size: number;
max_size: number;
max_allocation_size: string;
}
export interface curveType {
name: Name;
Allocated: (number | string)[][];
Reserved: (number | string)[][];
PeakAllocated: (number | string)[][];
PeakReserved: (number | string)[][];
}
export interface Name {
Allocated: string;
Reserved: string;
PeakAllocated: string;
PeakReserved: string;
}
export interface memory_events_type {
column_name: string[];
data: Datum[];
}
export interface Datum {
MemoryType: string;
AllocatedEvent: string;
AllocatedTimestamp: number;
Duration: number;
Size: number;
FreeEvent: string;
FreeTimestamp: number;
}
export interface op_memory_events_type {
column_name: string[];
data: op_datum[];
}
export interface op_datum {
EventName: string;
MemoryType: string;
AllocationCount: number;
FreeCount: number;
AllocationSize: number;
FreeSize: number;
IncreasedSize: number;
}
/* eslint-disable react-hooks/exhaustive-deps */
/**
* Copyright 2020 Baidu Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, {FunctionComponent, useCallback, useEffect, useState} from 'react';
import Input from '~/components/Input';
import type {WithStyled} from '~/utils/style';
interface NumberInputProps {
value?: number;
defaultValue: number;
placeholder?: string;
disabled?: boolean;
onChange?: (value: number) => unknown;
}
const NumberInput: FunctionComponent<NumberInputProps & WithStyled> = ({
value,
defaultValue,
placeholder,
className,
disabled,
onChange
}) => {
const [inputValue, setInputValue] = useState(Number.isFinite(defaultValue) ? defaultValue + '' : '');
useEffect(() => setInputValue(Number.isFinite(value) ? value + '' : ''), [value]);
useEffect(() => {
if (inputValue === '' && value !== defaultValue) {
debugger;
onChange?.(defaultValue);
return;
}
const v = inputValue;
if (!Number.isNaN(v)) {
onChange?.(Number(v));
debugger;
setInputValue(v + '');
}
}, [defaultValue, onChange, value, inputValue]);
// useEffect(()=>{
// },[inputValue])
const check = useCallback(() => {
const v = Number.parseFloat(inputValue);
if (Number.isNaN(v)) {
setInputValue(Number.isFinite(value) ? value + '' : '');
onChange?.(0);
} else {
setInputValue(v + '');
onChange?.(v);
}
}, [inputValue, onChange]);
return (
<Input
value={inputValue}
placeholder={placeholder}
disabled={disabled}
className={className}
onBlur={check}
onChange={setInputValue}
/>
);
};
export default NumberInput;
import type {ColumnsType} from 'antd/lib/table';
import React from 'react';
import type {EChartsOption} from 'echarts';
export const options: EChartsOption = {
grid: {
left: '0',
right: '0',
bottom: '30',
top: '62',
containLabel: true
},
yAxis: {
name: ''
},
dataZoom: [
//给x轴设置滚动条
{
start: 0, //默认为0
end: 20, //默认为100
type: 'slider',
show: true,
xAxisIndex: [0],
handleSize: 0, //滑动条的 左右2个滑动条的大小
height: 8, //组件高度
left: 50, //左边的距离
right: 40, //右边的距离
bottom: 10, //右边的距离
// handleColor: '#ddd', //h滑动图标的颜色
handleStyle: {
borderColor: '#cacaca',
borderWidth: 1,
shadowBlur: 2,
// background: '#ddd',
shadowColor: '#ddd'
},
fillerColor: '#2932E1',
backgroundColor: '#ddd', //两边未选中的滑动条区域的颜色
showDataShadow: false, //是否显示数据阴影 默认auto
showDetail: false, //即拖拽时候是否显示详细数值信息 默认true
// handleIcon:
// 'M-292,322.2c-3.2,0-6.4-0.6-9.3-1.9c-2.9-1.2-5.4-2.9-7.6-5.1s-3.9-4.8-5.1-7.6c-1.3-3-1.9-6.1-1.9-9.3c0-3.2,0.6-6.4,1.9-9.3c1.2-2.9,2.9-5.4,5.1-7.6s4.8-3.9,7.6-5.1c3-1.3,6.1-1.9,9.3-1.9c3.2,0,6.4,0.6,9.3,1.9c2.9,1.2,5.4,2.9,7.6,5.1s3.9,4.8,5.1,7.6c1.3,3,1.9,6.1,1.9,9.3c0,3.2-0.6,6.4-1.9,9.3c-1.2,2.9-2.9,5.4-5.1,7.6s-4.8,3.9-7.6,5.1C-285.6,321.5-288.8,322.2-292,322.2z',
filterMode: 'filter'
}
]
};
export interface operatorPie {
column_name: string[];
cpu: Cpu[];
gpu: Cpu[];
}
export interface Cpu {
name: string;
calls: number;
total_time: number;
avg_time: number;
max_time: number;
min_time: number;
ratio: number;
}
export interface tableType {
events: Event[];
column_name: string[];
}
export interface Event {
name: string;
calls: number;
cpu_total_time: number;
cpu_avg_time: number;
cpu_max_time: number;
cpu_min_time: number;
cpu_ratio: number;
gpu_total_time: number;
gpu_avg_time: number;
gpu_max_time: number;
gpu_min_time: number;
gpu_ratio: number;
input_shape?: string[];
children?: Child[];
}
export interface Child {
name: string;
calls: number;
cpu_total_time: number;
cpu_avg_time: number;
cpu_max_time: number;
cpu_min_time: number;
cpu_ratio: number;
gpu_total_time: number;
gpu_avg_time: number;
gpu_max_time: number;
gpu_min_time: number;
gpu_ratio: number;
}
export interface pie_expand {
order: string[];
phase_type: string[];
data: number[][];
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
import React, {useRef, useEffect} from 'react';
import {fetcher} from '~/utils/fetch';
import {position, rem, size, primaryColor} from '~/utils/style';
import styled from 'styled-components';
import GridLoader from 'react-spinners/GridLoader';
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
// import tracing from '/__snowpack__/link/packages/netron/dist/index.html';
const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH;
const toolboxHeight = rem(40);
const Content = styled.div`
position: relative;
height: calc(100% - ${toolboxHeight});
> .loading {
${size('100%')}
${position('absolute', 0, null, null, 0)}
display: flex;
justify-content: center;
align-items: center;
}
> iframe {
${size('100%', '100%')}
border: none;
}
> .powered-by {
display: block;
${position('absolute', null, null, rem(20), rem(30))}
color: var(--graph-copyright-color);
font-size: ${rem(14)};
user-select: none;
img {
height: 1em;
filter: var(--graph-copyright-logo-filter);
vertical-align: middle;
}
}
`;
export interface IProps {
runs: string;
workers: string;
spans: string;
views: string;
// iframeRef: React.RefObject<HTMLIFrameElement>;
}
const TracingView: React.FC<IProps> = props => {
const {runs, workers, spans, views} = props;
const iframeRef = useRef<HTMLIFrameElement>(null);
const [traceData, setTraceData] = React.useState<Promise<string> | null>(null);
const [traceViewReady, setTraceViewReady] = React.useState(false);
useEffect(() => {
if (runs && workers && spans) {
fetcher('/profiler/trace' + `?run=${runs}` + `&worker=${workers}` + `&span=${spans}`).then((res: any) => {
setTraceData(res);
});
}
}, [runs, workers, spans, views]);
React.useEffect(() => {
function callback(event: MessageEvent) {
const data = event.data || {};
if (data.msg === 'ready') {
setTraceViewReady(true);
}
}
window.addEventListener('message', callback);
return () => {
window.removeEventListener('message', callback);
};
}, []);
React.useEffect(() => {
if (traceData && traceViewReady) {
const data = JSON.stringify(traceData);
iframeRef.current?.contentWindow?.postMessage({msg: 'data', data}, '*');
iframeRef.current?.focus();
}
}, [traceData, traceViewReady]);
const SetIframeActive = () => {
iframeRef.current?.focus();
};
return (
<Content>
{!traceViewReady && (
<div className="loading">
<GridLoader color={primaryColor} size="10px" />
</div>
)}
<ClickAwayListener onClickAway={SetIframeActive}>
<iframe
ref={iframeRef}
src={PUBLIC_PATH + '/__snowpack__/link/packages/trace/dist/trace_embedding.html'}
frameBorder={0}
scrolling="no"
marginWidth={0}
marginHeight={0}
></iframe>
</ClickAwayListener>
</Content>
);
};
export default TracingView;
/* eslint-disable sort-imports */
import React, {Fragment, FunctionComponent} from 'react';
import {rem} from '~/utils/style';
import {Configure, ArgumentOperation} from '../../components';
import {useTranslation} from 'react-i18next';
import styled from 'styled-components';
import logo from '~/assets/images/question-circle.svg';
const PUBLIC_PATH: string = import.meta.env.SNOWPACK_PUBLIC_PATH;
import {Popover} from 'antd';
import type {environmentType} from './types';
const Processes = styled.div`
background: #f3f8fe;
border-radius: ${rem(4)};
padding-left: ${rem(20)};
height: ${rem(60)};
display: flex;
align-items: center;
`;
const Processes_items = styled.div`
display: flex;
padding-right: ${rem(50)};
border-right: 1px solid #dddddd;
`;
const Processes_label = styled.div`
margin-right: ${rem(20)};
color: #666666;
font-size: 14px;
line-height: ${rem(30)};
`;
const Processes_content = styled.div`
font-size: 18px;
color: #333333;
line-height: ${rem(32)};
`;
const CPU = styled.div`
border: 1px solid #dddddd;
border-radius: ${rem(4)};
height: ${rem(150)};
width: 100%;
padding-top: ${rem(24)};
padding-left: ${rem(20)};
padding-bottom: ${rem(20)};
display: flex;
.CPU_content {
flex: 1;
padding-right: ${rem(30)};
border-right: 1px solid #dddddd;
}
.CPU_title {
font-family: PingFangSC-Semibold;
font-size: 16px;
color: #333333;
text-align: left;
line-height: ${rem(16)};
font-weight: 600;
margin-bottom: ${rem(20)};
}
.GPU_content {
flex: 2;
padding-left: ${rem(20)};
padding-right: ${rem(20)};
.Gpudetail {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-family: PingFangSC-Medium;
font-size: 16px;
color: #999999;
text-align: left;
line-height: ${rem(24)};
font-weight: 500;
}
}
.GPU_title {
font-family: PingFangSC-Semibold;
font-size: 16px;
color: #333333;
text-align: left;
line-height: ${rem(16)};
font-weight: 600;
margin-bottom: ${rem(20)};
margin-left: ${rem(49)};
display: flex;
justify-content: space-between;
.title_list {
font-size: 12px;
color: #666666;
display: flex;
.list_items {
padding-right: ${rem(10)};
padding-left: ${rem(10)};
border-right: 1px solid #dddddd;
}
}
}
.itemlist {
display: flex;
.items {
margin-right: ${rem(82)};
.percentage {
text-align: center;
font-size: 28px;
color: #333333;
}
.items_label {
font-size: 12px;
color: #999999;
text-align: center;
}
}
.items_last {
margin-right: 0px;
}
}
.GPU_itemlist {
display: flex;
.items {
flex: 1;
.percentage {
text-align: center;
font-size: 28px;
color: #333333;
}
.items_label {
font-size: ${rem(12)};
color: #999999;
text-align: center;
}
}
.itemt_last {
margin-right: 0px;
}
}
`;
export type EnvironmentProps = {
environment: environmentType;
hasGpu: boolean;
descriptions: string;
};
const Environment: FunctionComponent<EnvironmentProps> = ({environment, hasGpu, descriptions}) => {
const {t} = useTranslation(['profiler', 'common']);
const tooltips = (
<div
style={{
width: rem(700),
color: '#333333',
fontWeight: 400
}}
dangerouslySetInnerHTML={{__html: descriptions ? descriptions : ''}}
></div>
);
const getPopupContainers = (trigger: any) => {
return trigger.parentElement;
};
return (
<Fragment>
<Configure>
<div className="titleContent">
<div className="titles">
<div>{t('profiler:Configuration-details')}</div>
</div>
</div>
<Processes>
<Processes_items>
<Processes_label>{t('number-processes')}</Processes_label>
<Processes_content>{environment?.num_workers}</Processes_content>
</Processes_items>
<Processes_items style={{paddingLeft: `${rem(50)}`, borderRight: 'none'}}>
<Processes_label>{t('Equipment-type')}</Processes_label>
<Processes_content>{environment?.device_type}</Processes_content>
</Processes_items>
</Processes>
</Configure>
<Configure>
<div className="titleContent">
<div className="titles">
<div>{t('Device-Details')}</div>
<Popover
content={tooltips}
overlayClassName={'newTooltip'}
getPopupContainer={getPopupContainers}
placement="right"
>
<ArgumentOperation>
<img src={PUBLIC_PATH + logo} alt="" />
</ArgumentOperation>
</Popover>
</div>
</div>
<CPU>
<div className="CPU_content">
<div className="CPU_title">CPU</div>
<div className="itemlist">
<div className="items">
<div className="percentage">{environment?.CPU.process_utilization}%</div>
<div className="items_label">{t('Process-utilization')}</div>
</div>
<div className="items items_last">
<div className="percentage">{environment?.CPU.system_utilization}%</div>
<div className="items_label">{t('system-utilization')}</div>
</div>
</div>
</div>
{hasGpu ? (
<div className="GPU_content">
<div className="GPU_title">
<div>GPU</div>
<div className="title_list">
<div className="list_items">
{environment?.GPU?.name ? environment?.GPU?.name : '--'}
</div>
<div className="list_items">
{environment?.GPU?.memory ? environment?.GPU?.memory : '--'}
</div>
<div className="list_items" style={{borderRight: 'none'}}>
{t('computing-power')}
{environment?.GPU?.compute_capability !== undefined
? environment?.GPU?.compute_capability
: '--'}
</div>
</div>
</div>
<div className="GPU_itemlist">
<div className="items">
<div className="percentage">
{environment?.GPU?.utilization !== undefined
? environment?.GPU?.utilization + '%'
: '--'}
</div>
<div className="items_label">{t('Utilization')}</div>
</div>
<div className="items">
<div className="percentage">
{environment?.GPU?.sm_efficiency !== undefined
? environment?.GPU?.sm_efficiency + '%'
: '--'}
</div>
<div className="items_label">{t('Traffic-Processor-Efficiency')}</div>
</div>
<div className="items">
<div className="percentage">
{environment?.GPU?.achieved_occupancy !== undefined
? environment?.GPU?.achieved_occupancy + '%'
: '--'}
</div>
<div className="items_label">{t('Traffic-processor-occupancy')}</div>
</div>
<div className="items items_last">
<div className="percentage">
{environment?.GPU?.tensor_core_percentage !== undefined
? environment?.GPU?.tensor_core_percentage + '%'
: '--'}
</div>
<div className="items_label">{t('usage-time')}</div>
</div>
</div>
</div>
) : (
<div className="GPU_content">
<div className="Gpudetail">
<div>{t('NoGPUdata')}</div>
</div>
</div>
)}
</CPU>
</Configure>
</Fragment>
);
};
export default Environment;
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable sort-imports */
import React, {Fragment, FunctionComponent} from 'react';
import {rem} from '~/utils/style';
import {useTranslation} from 'react-i18next';
import styled from 'styled-components';
import BarsChart from '~/components/BarsChart';
import {Tabs} from 'antd';
import type {performanceType, Callingtimes} from './types';
const PerformanceContent = styled.div`
border: 1px solid #dddddd;
border-radius: ${rem(4)};
width: 100%;
height: ${rem(378)};
.titles {
height: ${rem(63)};
display: flex;
justify-content: flex-end;
padding-right: ${rem(30)};
.legend {
display: flex;
align-items: center;
margin-left: ${rem(20)};
.labels {
width: ${rem(17)};
height: ${rem(5)};
border-radius: ${rem(2.5)};
background: yellow;
line-height: ${rem(22)};
}
.legend_name {
margin-left: ${rem(8)};
font-family: PingFangSC-Regular;
font-size: 14px;
color: #666666;
letter-spacing: 0;
line-height: ${rem(14)};
font-weight: 400;
}
}
}
.chartContent {
width: 100%;
height: ${rem(315)};
display: flex;
padding: ${rem(0)} ${rem(24)};
.chart {
.Content {
height: 100%;
}
flex: 1;
margin-right: ${rem(43)};
}
}
`;
export type EnvironmentProps = {
performanceData: performanceType;
units: string;
};
const {TabPane} = Tabs;
const PerformanceContents: FunctionComponent<EnvironmentProps> = ({performanceData, units}) => {
const color = ['#2932E1', '#00CC88', '#981EFF', '#FF6D6D', '#25C9FF', '#E71ED5', '#FFAA00', '#00307D'];
return (
<Fragment>
<Tabs defaultActiveKey="1" centered>
{performanceData &&
performanceData.order.map((item: string, index: number) => {
return (
<TabPane tab={item} key={index}>
<PerformanceContent>
<div className="titles">
{(performanceData as any)[item]?.calling_times?.key.map(
(items: string, index: number) => {
return (
<div className="legend" key={index}>
<div
className="labels"
style={{background: `${color[index]}`}}
></div>
<div className="legend_name">{items}</div>
</div>
);
}
)}
</div>
<div className="chartContent">
<div className="chart">
<BarsChart
className={'Content'}
data={(performanceData as any)[item]?.calling_times as Callingtimes}
text={1}
isLegend={false}
></BarsChart>
</div>
<div className="chart">
<BarsChart
className={'Content'}
data={(performanceData as any)[item]?.durations as Callingtimes}
text={2}
isLegend={false}
units={units}
></BarsChart>
</div>
<div className="chart" style={{marginRight: `${rem(0)}`}}>
<BarsChart
className={'Content'}
data={(performanceData as any)[item]?.ratios as Callingtimes}
text={3}
isLegend={true}
></BarsChart>
</div>
</div>
</PerformanceContent>
</TabPane>
);
})}
</Tabs>
</Fragment>
);
};
export default PerformanceContents;
export interface environmentType {
device_type: string;
CPU: CPU;
GPU: GPU;
num_workers: number;
}
interface GPU {
name: string;
memory: number;
compute_capability: string;
utilization: string;
sm_efficiency: string;
achieved_occupancy: string;
tensor_core_percentage: string;
}
interface CPU {
process_utilization: string;
system_utilization: string;
}
export interface consumingType {
column_name: string[];
cpu: Cpu[];
gpu: Cpu[];
}
export interface stringObj {
GPUname: string;
GPUcalls: number;
GPUtotal_time: string;
GPUavg_time: string;
GPUmax_time: string;
GPUmin_time: string;
GPUratio: string;
}
export interface tableType {
name: string;
calls: number;
total_time: number;
max_time: number;
min_time: number;
avg_time: number;
ratio: number;
GPUtotal_time: number;
GPUmax_time: number;
GPUmin_time: number;
GPUavg_time: number;
GPUratio: number;
}
export interface Cpu {
name: string;
calls: number;
total_time: number;
avg_time: number;
max_time: number;
min_time: number;
ratio: number;
}
export interface Gpu {
GPUtotal_time: number;
GPUmax_time: number;
GPUmin_time: number;
GPUavg_time: number;
GPUratio: number;
}
export interface trainType {
order: string[];
steps: number[];
data: number[][];
}
export interface perspectiveType {
column_name: string[];
events: Event[];
}
export interface Event {
name: string;
calls: number;
cpu_total_time: number;
cpu_avg_time: number;
cpu_max_time: number;
cpu_min_time: number;
cpu_ratio: number;
gpu_total_time: number;
gpu_avg_time: number;
gpu_max_time: number;
gpu_min_time: number;
gpu_ratio: number;
}
export interface performanceType {
order: string[];
Kernel: Kernel;
Memcpy: Kernel;
Memset: Kernel;
}
export interface Kernel {
calling_times: Callingtimes;
durations: Callingtimes;
ratios: Callingtimes;
}
export interface Callingtimes {
key: string[];
value: number[];
}
export interface distributedData {
order: string[];
phase_type: string[];
data: number[][];
}
export interface DataType {
name: string;
calls: number;
total_time: number;
max_time: number;
min_time: number;
avg_time: number;
ratio: number;
GPUtotal_time: number;
GPUmax_time: number;
GPUmin_time: number;
GPUavg_time: number;
GPUratio: number;
}
export interface DataType2 {
name: string;
calls: number;
cpu_total_time: number;
cpu_avg_time: number;
cpu_max_time: number;
cpu_min_time: number;
cpu_ratio: number;
gpu_total_time: number;
gpu_avg_time: number;
gpu_max_time: number;
gpu_min_time: number;
gpu_ratio: number;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -20,7 +20,7 @@ import GraphComponent, {GraphRef} from '~/components/GraphPage/GraphDynamic';
import React, {FunctionComponent, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import Select, {SelectProps} from '~/components/Select';
import {actions, selectors} from '~/store';
import {primaryColor, rem, size} from '~/utils/style';
import {rem} from '~/utils/style';
import {useDispatch, useSelector} from 'react-redux';
import Check from '~/components/Check';
import Button from '~/components/Button';
......
此差异已折叠。
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd" transform="matrix(-1 0 0 1 14 0)"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#DDD" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14"><g fill="none" fill-rule="evenodd"><circle cx="7" cy="7" r="7" fill="#F3F8FE"/><polygon fill="#DDD" points="8.281 7 5 10 5.547 10.5 9.375 7 5.547 3.5 5 4"/></g></svg>
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册