Commit 252f36f8 authored by Deshui Yu's avatar Deshui Yu
Browse files

NNI dogfood version 1

parent 781cea26
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/icon.jpg">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Neural Network Intelligence</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
\ No newline at end of file
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
\ No newline at end of file
.header_title{
width: 100%;
height: 60px;
background-color: rgb(60,141,188) ;
user-select: none;
text-align: center;
position: fixed;
left: 0;
top: 0;
z-index: 999;
}
.header_title img{
height: 60px;
}
.right{
position: absolute;
left: 250px;
top: 50px;
width: calc(100% - 250px);
/* padding-left: 20px; */
/* background: rgb(236,240,245); */
}
import * as React from 'react';
import './App.css';
import SlideBar from './components/SlideBar';
class App extends React.Component<{}, {}> {
render () {
return (
<div className="App">
<header className="header_title"><img src={require('./logo.jpg')} alt=""/></header>
<div className="content">
<SlideBar />
<div className="right">{this.props.children}</div>
</div>
</div>
);
}
}
export default App;
import * as React from 'react';
import axios from 'axios';
import { MANAGER_IP } from '../const';
import ReactEcharts from 'echarts-for-react';
const echarts = require('echarts/lib/echarts');
echarts.registerTheme('my_theme', {
color: '#3c8dbc'
});
require('echarts/lib/chart/scatter');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('../style/accuracy.css');
const accStyle = {
width: '100%',
height: 600,
margin: '0 auto'
};
interface ChartState {
option: object;
accNodata: string;
}
interface AccurPoint {
yAxis: Array<number>;
}
class Accuracy extends React.Component<{}, ChartState> {
public _isMounted = false;
public intervalID = 0;
constructor(props: {}) {
super(props);
this.state = {
option: {},
accNodata: ''
};
}
getOption = (dataObj: AccurPoint) => {
const yAxis = dataObj.yAxis;
const xAxis: Array<number> = [];
for (let i = 1; i <= yAxis.length; i++) {
xAxis.push(i);
}
return {
tooltip: {
trigger: 'item'
},
xAxis: {
name: 'Trial',
type: 'category',
data: xAxis
},
yAxis: {
name: 'Accuracy',
type: 'value',
min: 0,
max: 1,
data: yAxis
},
series: [{
symbolSize: 6,
type: 'scatter',
data: yAxis
}]
};
}
drawPointGraph = () => {
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'GET'
})
.then(res => {
if (res.status === 200 && this._isMounted) {
const accData = res.data;
const accArr: Array<number> = [];
const accY: Array<AccurPoint> = [];
Object.keys(accData).map(item => {
if (accData[item].status === 'SUCCEEDED' && accData[item].finalMetricData) {
accArr.push(parseFloat(accData[item].finalMetricData.data));
}
});
accY.push({yAxis: accArr});
let optionObj = this.getOption(accY[0]);
this.setState({ option: optionObj }, () => {
if (accArr.length === 0) {
this.setState({
accNodata: 'No data'
});
} else {
this.setState({
accNodata: ''
});
}
});
}
});
}
componentDidMount() {
this._isMounted = true;
this.drawPointGraph();
this.intervalID = window.setInterval(this.drawPointGraph, 10000);
}
componentWillUnmount() {
this._isMounted = false;
window.clearInterval(this.intervalID);
}
render() {
const { accNodata, option } = this.state;
return (
<div className="graph">
<div className="trial">
<div className="title">
<div>Trial Accuracy</div>
</div>
<div>
<ReactEcharts
option={option}
style={accStyle}
theme="my_theme"
/>
<div className="showMess">{accNodata}</div>
</div>
</div>
</div>
);
}
}
export default Accuracy;
\ No newline at end of file
import * as React from 'react';
import { Input, Button, message } from 'antd';
import axios from 'axios';
import { MANAGER_IP, CONTROLTYPE } from '../const';
const { TextArea } = Input;
import '../style/control.css';
interface ExperimentParams {
authorName: string;
experimentName: string;
trialConcurrency: number;
maxExecDuration: number;
maxTrialNum: number;
searchSpace: string;
tuner: {
tunerCommand: string;
tunerCwd: string;
tunerCheckpointDirectory: string;
tunerGpuNum?: number;
};
assessor?: {
assessorCommand: string;
assessorCwd: string;
assessorCheckpointDirectory: string;
assessorGpuNum?: number;
};
}
interface Experiments {
params: ExperimentParams;
id: string;
startTime?: Date;
endTime?: Date;
revision: number;
execDuration: number;
}
interface TrialNumber {
maxExecDuration: number;
trialConcurrency: number;
}
interface ControlState {
addisabled: boolean;
addTrial: string;
updateSearch: string;
trialNum: TrialNumber;
trialMess: string;
updisabled: boolean;
upTrialdis: boolean;
experiment: Experiments;
}
class Control extends React.Component<{}, ControlState> {
public _isMounted = false;
constructor(props: {}) {
super(props);
this.state = {
addisabled: false,
upTrialdis: false,
addTrial: '',
updateSearch: '',
updisabled: false,
trialNum: {
maxExecDuration: 0,
trialConcurrency: 0
},
trialMess: '',
// experiment origin data obj
experiment: {
params: {
authorName: '',
experimentName: '',
trialConcurrency: 0,
maxExecDuration: 0,
maxTrialNum: 0,
searchSpace: '',
tuner: {
tunerCommand: '',
tunerCwd: '',
tunerCheckpointDirectory: '',
}
},
id: '',
revision: 0,
execDuration: 0,
}
};
}
updateTrialNumLoad = () => {
if (this._isMounted) {
this.setState({
upTrialdis: true,
});
}
}
updateTrialNumNormal = () => {
if (this._isMounted) {
this.setState({
upTrialdis: false,
});
}
}
addButtonLoad = () => {
if (this._isMounted) {
this.setState({
addisabled: true
});
}
}
addButtonNormal = () => {
if (this._isMounted) {
this.setState({
addisabled: false,
});
}
}
updateSearchLoad = () => {
if (this._isMounted) {
this.setState({
updisabled: true,
});
}
}
updateSearchNormal = () => {
if (this._isMounted) {
this.setState({
updisabled: false,
});
}
}
getTrialNum = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
if (this._isMounted) {
this.setState({
trialMess: event.target.value
});
}
}
getAddTrialval = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
if (this._isMounted) {
this.setState({
addTrial: event.target.value
});
}
}
updateSearchCon = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
if (this._isMounted) {
this.setState({
updateSearch: event.target.value
});
}
}
// get add trial example
getAddExample = () => {
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'GET'
}).then(res => {
if (res.status === 200 && this._isMounted) {
if (res.data.length !== 0) {
const addTrialExam = JSON.parse(res.data[0].hyperParameters).parameters;
this.setState({
addTrial: JSON.stringify(addTrialExam, null, 4)
});
}
}
});
}
// get update search_space file and experiment
getUpdateExample = () => {
axios(`${MANAGER_IP}/experiment`, {
method: 'GET'
}).then(res => {
if (res.status === 200 && this._isMounted) {
const sespaceExam = JSON.parse(res.data.params.searchSpace);
const trialnum: Array<TrialNumber> = [];
trialnum.push({
maxExecDuration: res.data.params.maxExecDuration,
trialConcurrency: res.data.params.trialConcurrency
});
this.setState(() => ({
updateSearch: JSON.stringify(sespaceExam, null, 4),
trialNum: trialnum[0],
trialMess: JSON.stringify(trialnum[0], null, 4),
experiment: res.data
}));
}
});
}
// update trial number parameters
trialParameterMess = (exper: Experiments, str: string) => {
this.getUpdateExample();
axios(`${MANAGER_IP}/experiment`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
data: exper,
params: {
update_type: str,
}
}).then(res => {
if (res.status === 200) {
message.success(`Update ${str.toLocaleLowerCase()} successfully`);
} else {
message.error(`Update ${str.toLocaleLowerCase()} failed`);
}
});
}
updateTrialMess = () => {
const { trialMess } = this.state;
if (trialMess !== '' || trialMess !== null) {
this.updateTrialNumLoad();
const { experiment } = this.state;
const newExperiment = JSON.parse(JSON.stringify(experiment));
const trialObj = JSON.parse(trialMess);
const orimaxDuration = experiment.params.maxExecDuration;
const oriconTrial = experiment.params.trialConcurrency;
const flagMax = (trialObj.maxExecDuration !== orimaxDuration);
const flagCon = (trialObj.trialConcurrency !== oriconTrial);
if (flagCon && flagMax) {
newExperiment.params.trialConcurrency = trialObj.trialConcurrency;
newExperiment.params.maxExecDuration = trialObj.maxExecDuration;
this.trialParameterMess(newExperiment, CONTROLTYPE[1]);
this.trialParameterMess(newExperiment, CONTROLTYPE[2]);
} else if (flagCon) {
newExperiment.params.trialConcurrency = trialObj.trialConcurrency;
this.trialParameterMess(newExperiment, CONTROLTYPE[1]);
} else if (flagMax) {
newExperiment.params.maxExecDuration = trialObj.maxExecDuration;
this.trialParameterMess(newExperiment, CONTROLTYPE[2]);
} else {
message.info('you have not modified this file');
}
this.updateTrialNumNormal();
} else {
message.error('The text can not be empty');
}
}
userSubmitJob = () => {
const { addTrial } = this.state;
if (addTrial === null || addTrial === '') {
message.error('The text can not be empty');
} else {
this.addButtonLoad();
// new experiment obj
const parameter = [];
parameter.push({
parameters: addTrial
});
const sendPara = JSON.stringify(parameter[0]);
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: sendPara
}).then(res => {
if (res.status === 200) {
message.success('Submit successfully');
} else {
message.error('Submit failed');
}
this.addButtonNormal();
});
}
}
userUpdateSeaspace = () => {
this.updateSearchLoad();
this.getUpdateExample();
const { updateSearch } = this.state;
if (updateSearch !== '' || updateSearch !== null) {
const { experiment } = this.state;
const newExperiment = JSON.parse(JSON.stringify(experiment));
newExperiment.params.searchSpace = updateSearch;
this.trialParameterMess(newExperiment, CONTROLTYPE[0]);
this.updateSearchNormal();
} else {
message.error('The text can not be empty');
}
}
componentDidMount() {
this._isMounted = true;
this.getAddExample();
this.getUpdateExample();
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const { addTrial, addisabled, updateSearch, updisabled,
trialMess, upTrialdis
} = this.state;
return (
<div className="user">
<div className="userCon">
<div className="addtrial">
<div className="addtitle">
<span className="line">|</span>
Experiment parameters
</div>
<div className="userInput">
<TextArea
value={trialMess}
autosize={{ minRows: 9 }}
onChange={this.getTrialNum}
/>
</div>
<div className="addBtubox">
<Button
className="userSubmit"
type="primary"
onClick={this.updateTrialMess}
disabled={upTrialdis}
>
Update
</Button>
</div>
</div>
<div className="clear" />
<div className="addtrial">
<div className="addtitle">
<span className="line">|</span>
Add New Trail
</div>
<div className="userInput">
<TextArea
id="userInputJob"
value={addTrial}
autosize={{ minRows: 9 }}
onChange={this.getAddTrialval}
/>
</div>
<div className="addBtubox">
<Button
className="userSubmit"
type="primary"
onClick={this.userSubmitJob}
disabled={addisabled}
>
Submit
</Button>
</div>
</div>
{/* clear float */}
<div className="clear" />
<div className="searchbox">
<div className="updatesear">
<span className="line">|</span>
user update search_space file
</div>
<div className="userInput">
<TextArea
id="InputUpdate"
autosize={{ minRows: 20 }}
value={updateSearch}
onChange={this.updateSearchCon}
/>
</div>
<div className="addBtubox">
<Button
className="buttonbac"
type="primary"
onClick={this.userUpdateSeaspace}
disabled={updisabled}
>
Update
</Button>
</div>
</div>
</div>
</div>
);
}
}
export default Control;
\ No newline at end of file
import * as React from 'react';
import axios from 'axios';
import { MANAGER_IP } from '../const';
import {
message,
Tabs,
Button
} from 'antd';
const TabPane = Tabs.TabPane;
import '../style/logdetail.css';
interface LogState {
trialId: string;
slotLog: string;
processLog: string;
}
class Logdetail extends React.Component<{}, LogState> {
public _isMounted = false;
constructor(props: {}) {
super(props);
this.state = {
trialId: '',
slotLog: '',
processLog: ''
};
}
getJobLog = () => {
Object.keys(this.props).map(item => {
if (item === 'location') {
if (this._isMounted) {
this.setState({ trialId: this.props[item].state }, () => {
const { trialId } = this.state;
let id = trialId;
axios(`${MANAGER_IP}/jobLog`, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
data: {
id
}
})
.then(res => {
if (res.status === 200 && this._isMounted) {
this.setState({
slotLog: res.data.trial_slot_log,
processLog: res.data.trial_process_log
});
}
});
});
}
}
});
}
getPaiDetail = (id: string) => {
axios(`${MANAGER_IP}/jobPaiPage`, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
data: {
id
}
})
.then(res => {
if (res.status === 200) {
message.success('Successful send');
setTimeout(this.openPage(res.data.url), 100);
}
});
}
openPage = (pailog: string) => {
window.open(pailog);
}
paiLog = () => {
axios(`${MANAGER_IP}/paiPage`, {
method: 'POST'
})
.then(res => {
if (res.status === 200) {
setTimeout(this.openPage(res.data.url), 200);
}
});
}
componentDidMount() {
this._isMounted = true;
this.getJobLog();
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const { trialId, slotLog, processLog } = this.state;
return (
<div className="log">
<div>
<Tabs type="card">
<TabPane tab="trial_slot_log" key="1">
<pre>{slotLog}</pre>
</TabPane>
<TabPane tab="trial_process_log" key="2">
<pre>{processLog}</pre>
</TabPane>
</Tabs>
</div>
<div className="pai">
<Button
type="primary"
className="tableButton marginTab"
onClick={this.getPaiDetail.bind(this, trialId)}
>
pai
</Button>
<Button
type="primary"
className="tableButton"
onClick={this.paiLog}
>
main job log
</Button>
</div>
</div>
);
}
}
export default Logdetail;
\ No newline at end of file
import * as React from 'react';
import axios from 'axios';
import { MANAGER_IP } from '../const';
import ReactEcharts from 'echarts-for-react';
import { Select, Button, message } from 'antd';
const Option = Select.Option;
require('echarts/lib/chart/parallel');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('echarts/lib/component/visualMap');
require('../style/para.css');
const chartMulineStyle = {
width: '100%',
height: 600,
margin: '0 auto',
padding: 15
};
interface Dimobj {
dim: number;
name: string;
max?: number;
min?: number;
type?: string;
data?: string[];
}
interface HoverName {
name: string;
}
interface ParaObj {
data: number[][];
parallelAxis: Array<Dimobj>;
}
interface ParaState {
option: object;
paraBack: ParaObj;
dimName: Array<string>;
swapAxisArr: Array<string>;
percent: number;
paraNodata: string;
}
message.config({
top: 250,
duration: 2,
});
class Para extends React.Component<{}, ParaState> {
public intervalIDPara = 4;
public _isMounted = false;
constructor(props: {}) {
super(props);
this.state = {
option: {},
dimName: [],
paraBack: {
parallelAxis: [{
dim: 0,
name: ''
}],
data: []
},
swapAxisArr: [],
percent: 0,
paraNodata: '',
};
}
hyperParaPic = () => {
axios
.all([
axios.get(`${MANAGER_IP}/trial-jobs`),
axios.get(`${MANAGER_IP}/experiment`)
])
.then(axios.spread((res, res1) => {
if (res.status === 200 && res1.status === 200) {
if (res.data.length !== 0) {
const accParaData = res.data;
const accPara: Array<number> = [];
// specific value array
const speValue: Array<string> = [];
// yAxis specific name
const speDimName: Array<string> = [];
const parallelAxis: Array<Dimobj> = [];
const paraYdata: number[][] = [];
Object.keys(accParaData).map(item => {
if (accParaData[item].hyperParameters !== undefined) {
const tem = JSON.parse(accParaData[item].hyperParameters).parameters;
// get dim and every line specific number
speDimName.push(tem);
}
if (accParaData[item].status === 'SUCCEEDED') {
if (accParaData[item].finalMetricData !== undefined) {
// get acc array
accPara.push(parseFloat(accParaData[item].finalMetricData.data));
// get dim and every line specific number
const temp = JSON.parse(accParaData[item].hyperParameters).parameters;
speValue.push(temp);
}
}
});
// get [batch_size...] name, default each trial is same
// if (speValue.length !== 0) {
const dimName = Object.keys(speDimName[0]);
if (this._isMounted) {
this.setState(() => ({
dimName: dimName
}));
}
// search space range and specific value [only number]
const searchRange = JSON.parse(res1.data.params.searchSpace);
for (let i = 0; i < dimName.length; i++) {
const searchKey = searchRange[dimName[i]];
if (searchKey._type === 'uniform') {
parallelAxis.push({
dim: i,
name: dimName[i],
max: searchKey._value[1],
min: searchKey._value[0]
});
} else { // choice
// data number ['0.2', '0.4', '0.6']
const data: Array<string> = [];
for (let j = 0; j < searchKey._value.length; j++) {
data.push(searchKey._value[j].toString());
}
parallelAxis.push({
dim: i,
name: dimName[i],
type: 'category',
data: data
});
}
}
// get data for every lines. if dim is choice type
// number -> toString()
Object.keys(speValue).map(item => {
let temp: Array<number> = [];
for (let i = 0; i < dimName.length; i++) {
if ('type' in parallelAxis[i]) {
temp.push(
speValue[item][dimName[i]].toString()
);
} else {
temp.push(
speValue[item][dimName[i]]
);
}
}
paraYdata.push(temp);
});
// add acc
Object.keys(paraYdata).map(item => {
paraYdata[item].push(accPara[item]);
});
this.setState(() => ({
paraBack: {
parallelAxis: parallelAxis,
data: paraYdata
}
}));
const { percent, swapAxisArr } = this.state;
const { paraBack } = this.state;
// need to cut down the data
if (percent !== 0) {
const linesNum = paraBack.data.length;
const len = Math.floor(linesNum * percent);
paraBack.data.length = len;
}
// need to swap the yAxis
if (swapAxisArr.length >= 2) {
this.swapGraph(paraBack, swapAxisArr);
}
// draw search space graph
if (this._isMounted) {
this.setState({
option: this.getOption(paraBack)
});
}
// }
}
}
}));
}
// get percent value number
percentNum = (value: string) => {
window.clearInterval(this.intervalIDPara);
let vals = parseFloat(value);
if (this._isMounted) {
this.setState(() => ({
percent: vals
}));
}
this.hyperParaPic();
this.intervalIDPara = window.setInterval(this.hyperParaPic, 10000);
}
// deal with response data into pic data
getOption = (dataObj: ParaObj) => {
let parallelAxis = dataObj.parallelAxis;
let paralleData = dataObj.data;
let optionown = {
parallelAxis,
tooltip: {
trigger: 'item',
formatter: function (params: HoverName) {
return params.name;
}
},
toolbox: {
show: true,
left: 'right',
iconStyle: {
normal: {
borderColor: '#ddd'
}
},
feature: {
},
z: 202
},
parallel: {
parallelAxisDefault: {
tooltip: {
show: true
}
}
},
visualMap: {
type: 'continuous',
min: 0,
max: 1,
realtime: false,
calculable: true,
precision: 1,
// gradient color
color: ['#fb7c7c', 'yellow', 'lightblue']
},
highlight: {
type: 'highlight'
},
series: {
type: 'parallel',
smooth: true,
lineStyle: {
width: 2
},
data: paralleData
}
};
// please wait the data
if (this._isMounted) {
if (paralleData.length === 0) {
this.setState({
paraNodata: 'No data'
});
} else {
this.setState({
paraNodata: ''
});
}
}
return optionown;
}
// get swap parallel axis
getSwapArr = (value: Array<string>) => {
if (this._isMounted) {
this.setState(() => ({ swapAxisArr: value }));
}
}
swapBtn = () => {
window.clearInterval(this.intervalIDPara);
this.hyperParaPic();
this.intervalIDPara = window.setInterval(this.hyperParaPic, 10000);
}
sortDimY = (a: Dimobj, b: Dimobj) => {
return a.dim - b.dim;
}
// deal with after swap data into pic
swapGraph = (paraBack: ParaObj, swapAxisArr: string[]) => {
if (swapAxisArr.length >= 2) {
const paralDim = paraBack.parallelAxis;
const paraData = paraBack.data;
let temp: number;
let dim1: number;
let dim2: number;
let bool1: boolean = false;
let bool2: boolean = false;
let bool3: boolean = false;
Object.keys(paralDim).map(item => {
const paral = paralDim[item];
switch (paral.name) {
case swapAxisArr[0]:
dim1 = paral.dim;
bool1 = true;
break;
case swapAxisArr[1]:
dim2 = paral.dim;
bool2 = true;
break;
default:
}
if (bool1 && bool2) {
bool3 = true;
}
});
// swap dim's number
Object.keys(paralDim).map(item => {
if (bool3) {
if (paralDim[item].name === this.state.swapAxisArr[0]) {
paralDim[item].dim = dim2;
}
if (paralDim[item].name === this.state.swapAxisArr[1]) {
paralDim[item].dim = dim1;
}
}
});
paralDim.sort(this.sortDimY);
// swap data array
Object.keys(paraData).map(paraItem => {
temp = paraData[paraItem][dim1];
paraData[paraItem][dim1] = paraData[paraItem][dim2];
paraData[paraItem][dim2] = temp;
});
}
}
componentDidMount() {
this._isMounted = true;
// default draw all data pic
this.hyperParaPic();
this.intervalIDPara = window.setInterval(this.hyperParaPic, 10000);
}
componentWillUnmount() {
this._isMounted = false;
window.clearInterval(this.intervalIDPara);
}
render() {
const { option, paraNodata, dimName } = this.state;
return (
<div className="para">
<div className="paraCon">
<div className="paraTitle">
<div className="paraLeft">Hyper Parameter</div>
<div className="paraRight">
<Select
className="parapercent"
style={{ width: '20%' }}
placeholder="100%"
optionFilterProp="children"
onSelect={this.percentNum}
>
<Option value="0.2">0.2</Option>
<Option value="0.5">0.5</Option>
<Option value="0.8">0.8</Option>
<Option value="1">1</Option>
</Select>
<Select
style={{ width: '60%' }}
mode="multiple"
placeholder="Please select two items to swap"
onChange={this.getSwapArr}
maxTagCount={2}
>
{
dimName.map((key, item) => {
return (
<Option key={key} value={dimName[item]}>{dimName[item]}</Option>
);
})
}
</Select>
<Button
type="primary"
className="changeBtu"
onClick={this.swapBtn}
>
sure
</Button>
</div>
</div>
<div className="paraGra">
<ReactEcharts
className="testt"
option={option}
style={chartMulineStyle}
// lazyUpdate={true}
notMerge={true} // update now
/>
<div className="paraNodata">{paraNodata}</div>
</div>
</div>
</div>
);
}
}
export default Para;
\ No newline at end of file
import * as React from 'react';
import axios from 'axios';
import { Table, Select, Row, Col, Icon } from 'antd';
import { MANAGER_IP, overviewItem, roundNum } from '../const';
import ReactEcharts from 'echarts-for-react';
const Option = Select.Option;
import JSONTree from 'react-json-tree';
require('echarts/lib/chart/line');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('../style/sessionpro.css');
interface TableObj {
key: number;
id: string;
duration: number;
start: string;
end: string;
status: string;
acc?: number;
description: object;
}
interface Parameters {
parameters: object;
logPath?: string;
}
interface Experiment {
id: string;
author: string;
experName: string;
runConcurren: number;
maxDuration: number;
execDuration: number;
MaxTrialNum: number;
startTime: string;
endTime: string;
}
interface SessionState {
tableData: Array<TableObj>;
searchSpace: object;
trialProfile: Experiment;
tunerAssessor: object;
selNum: number;
selStatus: string;
trialRun: Array<number>;
option: object;
noData: string;
}
class Sessionpro extends React.Component<{}, SessionState> {
public _isMounted = false;
public intervalID = 0;
public intervalProfile = 1;
constructor(props: {}) {
super(props);
this.state = {
searchSpace: {},
trialProfile: {
id: '',
author: '',
experName: '',
runConcurren: 0,
maxDuration: 0,
execDuration: 0,
MaxTrialNum: 0,
startTime: '',
endTime: ''
},
tunerAssessor: {},
tableData: [{
key: 0,
id: '',
duration: 0,
start: '',
end: '',
status: '',
acc: 0,
description: {}
}],
selNum: overviewItem,
selStatus: 'Complete',
trialRun: [],
option: {},
noData: ''
};
}
sortNumber = (a: number, b: number) => {
return a - b;
}
// draw cdf data
getOption = (data: Array<number>) => {
let len = data.length;
// let min = Math.floor(Math.min.apply(null, data));
let min = Math.floor(data[0]);
let max = Math.ceil(data[len - 1]);
let gap = (max - min) / 10;
let a = 0;
let b = 0;
let c = 0;
let d = 0;
let e = 0;
let f = 0;
let g = 0;
let h = 0;
let i = 0;
let j = 0;
let xAxis: number[] = [];
for (let m = 0; m < 10; m++) {
xAxis.push(min + gap * m);
}
data.map(item => {
switch (Math.floor((item - min) / gap)) {
case 0: a++; b++; c++; d++; e++; f++; g++; h++; i++; j++; break;
case 1: b++; c++; d++; e++; f++; g++; h++; i++; j++; break;
case 2: c++; d++; e++; f++; g++; h++; i++; j++; break;
case 3: d++; e++; f++; g++; h++; i++; j++; break;
case 4: e++; f++; g++; h++; i++; j++; break;
case 5: f++; g++; h++; i++; j++; break;
case 6: g++; h++; i++; j++; break;
case 7: h++; i++; j++; break;
case 8: i++; j++; break;
case 9: j++; break;
default: j++; break;
}
});
let prob = [a / len, b / len, c / len, d / len, e / len, f / len, g / len, h / len, i / len, j / len];
return {
tooltip: {
trigger: 'item'
},
title: {
left: 'center',
text: 'Succeeded Trials CDF',
top: 16
},
grid: {
left: '5%'
},
xAxis: {
name: 'trial running time/s',
type: 'category',
data: xAxis
},
yAxis: {
name: 'percent',
type: 'value',
min: 0,
max: 1
},
series: [
{
type: 'line',
smooth: true,
itemStyle: {
normal: {
color: 'skyblue'
}
},
data: prob
}
]
};
}
// show session
showSessionPro = () => {
axios(`${MANAGER_IP}/experiment`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
let sessionData = res.data;
let tunerAsstemp = [];
let trialPro = [];
trialPro.push({
id: sessionData.id,
author: sessionData.params.authorName,
experName: sessionData.params.experimentName,
runConcurren: sessionData.params.trialConcurrency,
maxDuration: sessionData.params.maxExecDuration,
execDuration: sessionData.execDuration,
MaxTrialNum: sessionData.params.maxTrialNum,
startTime: sessionData.startTime,
endTime: sessionData.endTime === undefined ? 'not over' : sessionData.endTime
});
tunerAsstemp.push({
tuner: sessionData.params.tuner,
assessor: sessionData.params.assessor
});
if (this._isMounted) {
this.setState({
trialProfile: trialPro[0],
searchSpace: JSON.parse(sessionData.params.searchSpace),
tunerAssessor: tunerAsstemp[0]
});
}
}
});
}
showTrials = () => {
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
// deal with complete trial data to draw CDF graph
let trialRunData: Array<number> = [];
const { selNum } = this.state;
const tableData = res.data;
const topTableData: Array<TableObj> = [];
Object.keys(tableData).map(item => {
if (tableData[item].status === 'SUCCEEDED') {
const desJobDetail: Parameters = {
parameters: {}
};
const startTime = Date.parse(tableData[item].startTime);
const duration = (Date.parse(tableData[item].endTime) - startTime) / 1000;
let acc;
if (tableData[item].finalMetricData) {
const accFloat = parseFloat(tableData[item].finalMetricData.data);
acc = roundNum(accFloat, 5);
} else {
acc = 0;
}
desJobDetail.parameters = JSON.parse(tableData[item].hyperParameters).parameters;
if (tableData[item].logPath !== undefined) {
desJobDetail.logPath = tableData[item].logPath;
}
topTableData.push({
key: topTableData.length,
id: tableData[item].id,
duration: duration,
start: tableData[item].startTime,
end: tableData[item].endTime,
status: tableData[item].status,
acc: acc,
description: desJobDetail
});
trialRunData.push(duration);
}
});
topTableData.sort((a: TableObj, b: TableObj) => {
if (a.acc && b.acc) {
return b.acc - a.acc;
} else {
return NaN;
}
});
topTableData.length = Math.min(selNum, topTableData.length);
if (this._isMounted) {
this.setState({
tableData: topTableData,
trialRun: trialRunData.sort(this.sortNumber)
});
}
// draw CDF
const { trialRun } = this.state;
if (this._isMounted) {
this.setState({
option: this.getOption(trialRun)
});
}
// CDF graph 'No data' judge
if (trialRun.length === 0) {
if (this._isMounted) {
this.setState({
noData: 'No data'
});
}
} else {
if (this._isMounted) {
this.setState({
noData: ''
});
}
}
}
});
}
handleChange = (value: string) => {
let num = parseFloat(value);
window.clearInterval(this.intervalID);
if (this._isMounted) {
this.setState({ selNum: num }, () => {
this.showTrials();
this.intervalID = window.setInterval(this.showTrials, 60000);
});
}
}
componentDidMount() {
this.showSessionPro();
this.showTrials();
this._isMounted = true;
this.intervalID = window.setInterval(this.showTrials, 10000);
this.intervalProfile = window.setInterval(this.showSessionPro, 60000);
}
componentWillUnmount() {
this._isMounted = false;
window.clearInterval(this.intervalID);
window.clearInterval(this.intervalProfile);
}
render() {
// show better job details
let bgColor = '';
const columns = [{
title: 'Id',
dataIndex: 'id',
key: 'id',
width: 150,
className: 'tableHead',
}, {
title: 'Duration/s',
dataIndex: 'duration',
key: 'duration',
width: '9%'
}, {
title: 'Start',
dataIndex: 'start',
key: 'start',
width: 150
}, {
title: 'End',
dataIndex: 'end',
key: 'end',
width: 150
}, {
title: 'Status',
dataIndex: 'status',
key: 'status',
width: 150,
className: 'tableStatus',
render: (text: string, record: TableObj) => {
bgColor = record.status;
return (
<span className={`${bgColor} commonStyle`}>{record.status}</span>
);
}
}, {
title: 'Loss/Accuracy',
dataIndex: 'acc',
key: 'acc',
width: 150
}];
const openRow = (record: TableObj) => {
return (
<pre id="description" className="jsontree">
<JSONTree
hideRoot={true}
shouldExpandNode={() => true} // default expandNode
getItemString={() => (<span />)} // remove the {} items
data={record.description}
/>
</pre>
);
};
const {
trialProfile, searchSpace, tunerAssessor, tableData, option, noData
} = this.state;
let running;
if (trialProfile.endTime === 'not over') {
running = trialProfile.maxDuration - trialProfile.execDuration;
} else {
running = 0;
}
return (
<div className="session" id="session">
<div className="head">
<div className="headCon">
<div className="author">
<div className="message">
<div className="proKey">
<span>Author</span>
<span className="messcont">{trialProfile.author}</span>
</div>
<span>Experiment&nbsp;Name</span>
<p className="messcont">{trialProfile.experName}</p>
</div>
<div className="logo">
<Icon className="bone" type="user" />
</div>
</div>
<div className="type">
<div className="message">
<div className="proKey">
<span>id</span>
<span className="messcont">{trialProfile.id}</span>
</div>
<p>
<span>Duration</span>
<span className="messcont">{trialProfile.maxDuration}s</span>
</p>
<p>
<span>Still&nbsp;running</span>
<span className="messcont">{running}s</span>
</p>
</div>
<div className="logo">
<Icon className="tyellow" type="bulb" />
</div>
</div>
<div className="runtime message">
<p className="proTime">
<span>Start Time</span><br />
<span className="messcont">{trialProfile.startTime}</span>
</p>
<span>End Time</span>
<p className="messcont">{trialProfile.endTime}</p>
{/* <div className="logo">
<Icon className="thrpink" type="clock-circle-o" />
</div> */}
</div>
<div className="cdf">
<div className="message">
<div className="proKey trialNum">
Concurrency&nbsp;Trial
<span className="messcont">{trialProfile.runConcurren}</span>
</div>
<p>
Max&nbsp;Trial&nbsp;Number
<span className="messcont">{trialProfile.MaxTrialNum}</span>
</p>
</div>
<div className="logo">
<Icon className="fogreen" type="picture" />
</div>
</div>
</div>
</div>
<div className="clear" />
<div className="jsonbox">
<div>
<h2 className="searchTitle title">Search Space</h2>
<pre className="searchSpace jsontree">
<JSONTree
hideRoot={true}
shouldExpandNode={() => true}
getItemString={() => (<span />)}
data={searchSpace}
/>
</pre>
</div>
<div>
<h2 className="searchTitle title">Trial Profile</h2>
<pre className="trialProfile jsontree">
<JSONTree
hideRoot={true}
shouldExpandNode={() => true}
getItemString={() => (<span />)}
data={tunerAssessor}
/>
</pre>
</div>
</div>
<div className="clear" />
<div className="comtable">
<div className="selectInline">
<Row>
<Col span={18}>
<h2>The trials that successed</h2>
</Col>
<Col span={6}>
<span className="tabuser1">top</span>
<Select
style={{ width: 200 }}
placeholder="5"
optionFilterProp="children"
onSelect={this.handleChange}
>
<Option value="20">20</Option>
<Option value="50">50</Option>
<Option value="100">100</Option>
</Select>
</Col>
</Row>
</div>
<Table
columns={columns}
expandedRowRender={openRow}
dataSource={tableData}
className="tables"
bordered={true}
scroll={{ x: '100%', y: 540 }}
/>
</div>
<div className="cdf">
<ReactEcharts
option={option}
style={{ height: 500, padding: '0px' }}
/>
<div className="addNodata">{noData}</div>
</div>
</div>
);
}
}
export default Sessionpro;
import * as React from 'react';
import { Link, IndexLink } from 'react-router';
import { Icon } from 'antd';
import '../style/slideBar.css';
class SlideBar extends React.Component<{}, {}> {
render() {
return (
<div className="slider">
<ul className="nav">
<li>
<IndexLink to={'/oview'} activeClassName="high">
<Icon className="icon" type="dot-chart" />Overview
<Icon className="floicon" type="right" />
</IndexLink>
</li>
<li>
<Link to={'/all'} activeClassName="high">
<Icon className="icon" type="message" />Optimization Progress
<Icon className="floicon" type="right" />
</Link>
</li>
<li>
<Link to={'/hyper'} activeClassName="high">
<Icon className="icon" type="rocket" />Hyper Parameter
<Icon className="floicon" type="right" />
</Link>
</li>
<li>
<Link to={'/trastaus'} activeClassName="high">
<Icon className="icon" type="bar-chart" />Trial Status
<Icon className="floicon" type="right" />
</Link>
</li>
<li>
<Link to={'/control'} activeClassName="high">
<Icon className="icon" type="form" />Control
<Icon className="floicon" type="right" />
</Link>
</li>
<li>
<Link to={'/tensor'} activeClassName="high">
<Icon className="icon" type="link" />Tensorboard
<Icon className="floicon" type="right" />
</Link>
</li>
</ul>
</div>
);
}
}
export default SlideBar;
\ No newline at end of file
import * as React from 'react';
import axios from 'axios';
import { message } from 'antd';
import { MANAGER_IP } from '../const';
import '../style/tensor.css';
interface TensorState {
urlTensor: string;
idTensor: string;
}
message.config({
top: 250,
duration: 2,
});
class Tensor extends React.Component<{}, TensorState> {
public _isMounted = false;
constructor(props: {}) {
super(props);
this.state = {
urlTensor: '',
idTensor: ''
};
}
geturl(): void {
Object.keys(this.props).forEach(item => {
if (item === 'location') {
let tensorId = this.props[item].state;
if (tensorId !== undefined && this._isMounted) {
this.setState({ idTensor: tensorId }, () => {
axios(`${MANAGER_IP}/tensorboard`, {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
params: {
job_ids: tensorId
}
}).then(res => {
if (res.status === 200) {
setTimeout(
() => {
const url = new URL(res.data.endPoint);
if (url.hostname === 'localhost') {
url.hostname = window.location.hostname;
}
this.setState(
{ urlTensor: url.href },
() => message.success('Successful send'));
},
1000);
} else {
message.error('fail to link to tensorboard');
}
});
});
} else {
message.warning('Please link to Trial Status page to select a trial!');
}
}
});
}
componentDidMount() {
this._isMounted = true;
this.geturl();
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const { urlTensor } = this.state;
return (
<div className="tensor">
<div className="title">TensorBoard</div>
<div className="tenhttpage">
<iframe
frameBorder="no"
src={urlTensor}
sandbox="allow-scripts allow-same-origin"
/>
</div>
</div>
);
}
}
export default Tensor;
\ No newline at end of file
import * as React from 'react';
import { browserHistory } from 'react-router';
import axios from 'axios';
import { Table, Button, Popconfirm, message } from 'antd';
import { MANAGER_IP, roundNum, trialJobStatus } from '../const';
import JSONTree from 'react-json-tree';
import ReactEcharts from 'echarts-for-react';
const echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/bar');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
require('../style/trialStatus.css');
echarts.registerTheme('my_theme', {
color: '#3c8dbc'
});
interface DescObj {
parameters: Object;
logPath?: string;
}
interface TableObj {
key: number;
id: string;
duration?: number;
start: string;
status: string;
description: DescObj;
end?: string;
acc?: number;
}
interface Runtrial {
trialId: Array<string>;
trialTime: Array<number>;
}
interface TrialJob {
text: string;
value: string;
}
interface TabState {
tableData: Array<TableObj>;
downhref: string;
option: object;
trialJobs: object;
}
class TrialStatus extends React.Component<{}, TabState> {
public intervalID = 0;
public intervalIDS = 1;
public _isMounted = false;
constructor(props: {}) {
super(props);
this.state = {
tableData: [{
key: 0,
id: '',
duration: 0,
start: '',
end: '',
status: '',
acc: 0,
description: {
parameters: {}
}
}],
downhref: 'javascript:;',
option: {},
trialJobs: {}
// trialJobs: this.getTrialJobs()
};
}
getOption = (dataObj: Runtrial) => {
let xAxis = dataObj.trialTime;
let yAxis = dataObj.trialId;
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
title: {
left: 'center',
text: 'Running Trial',
textStyle: {
fontSize: 18,
color: '#333'
}
},
grid: {
bottom: '3%',
containLabel: true,
left: '1%',
right: '4%'
},
dataZoom: [{
type: 'slider',
name: 'trial',
filterMode: 'filter',
yAxisIndex: 0,
orient: 'vertical'
}, {
type: 'slider',
name: 'trial',
filterMode: 'filter',
xAxisIndex: 0
}],
xAxis: {
name: 'Time',
type: 'value',
},
yAxis: {
name: 'Trial',
type: 'category',
data: yAxis
},
series: [{
type: 'bar',
data: xAxis
}]
};
return option;
}
drawRunGraph = () => {
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
const trialJobs = res.data;
const trialId: Array<string> = [];
const trialTime: Array<number> = [];
const trialRun: Array<Runtrial> = [];
Object.keys(trialJobs).map(item => {
if (trialJobs[item].status !== 'WAITING') {
let duration: number = 0;
const end = trialJobs[item].endTime;
const start = trialJobs[item].startTime;
if (start && end) {
duration = (Date.parse(end) - Date.parse(start)) / 1000;
} else {
duration = (new Date().getTime() - Date.parse(start)) / 1000;
}
trialId.push(trialJobs[item].id);
trialTime.push(duration);
}
});
trialRun.push({
trialId: trialId,
trialTime: trialTime
});
if (this._isMounted && res.status === 200) {
this.setState({
option: this.getOption(trialRun[0])
});
}
}
});
}
drawTable = () => {
axios(`${MANAGER_IP}/trial-jobs`, {
method: 'GET'
})
.then(res => {
if (res.status === 200) {
const trialJobs = res.data;
const trialTable: Array<TableObj> = [];
Object.keys(trialJobs).map(item => {
// only succeeded trials have finalMetricData
const id = trialJobs[item].id !== undefined
? trialJobs[item].id
: '';
const status = trialJobs[item].status !== undefined
? trialJobs[item].status
: '';
const acc = trialJobs[item].finalMetricData !== undefined
? roundNum(parseFloat(trialJobs[item].finalMetricData.data), 5)
: 0;
const startTime = trialJobs[item].startTime !== undefined
? trialJobs[item].startTime
: '';
const endTime = trialJobs[item].endTime !== undefined
? trialJobs[item].endTime
: '';
let desc: DescObj = {
parameters: {}
};
if (trialJobs[item].hyperParameters !== undefined) {
desc.parameters = JSON.parse(trialJobs[item].hyperParameters).parameters;
}
if (trialJobs[item].logPath !== undefined) {
desc.logPath = trialJobs[item].logPath;
}
let duration = 0;
if (startTime !== '' && endTime !== '') {
duration = (Date.parse(endTime) - Date.parse(startTime)) / 1000;
} else if (startTime !== '' && endTime === '') {
duration = (new Date().getTime() - Date.parse(startTime)) / 1000;
} else {
duration = 0;
}
trialTable.push({
key: trialTable.length,
id: id,
status: status,
start: startTime,
end: endTime,
duration: duration,
acc: acc,
description: desc
});
});
if (this._isMounted) {
this.setState({
tableData: trialTable
});
}
}
});
}
// kill job
killJob = (key: number, id: string, status: string) => {
if (status === 'RUNNING') {
axios(`${MANAGER_IP}/trial-jobs/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})
.then(res => {
if (res.status === 200) {
message.success('Cancel the job successfully');
// render the table
this.drawTable();
} else {
message.error('fail to cancel the job');
}
});
} else {
message.error('you just can kill the job that status is Running');
}
}
// get tensorflow address
getTensorpage = (id: string) => {
let path = {
pathname: '/tensor',
state: id
};
browserHistory.push(path);
}
componentDidMount() {
this._isMounted = true;
// the init of running chart
this.drawRunGraph();
// the init of trials status in the table
this.drawTable();
this.intervalID = window.setInterval(this.drawRunGraph, 10000);
this.intervalIDS = window.setInterval(this.drawTable, 10000);
}
componentWillUnmount() {
this._isMounted = false;
window.clearInterval(this.intervalID);
window.clearInterval(this.intervalIDS);
}
render() {
let bgColor = '';
const trialJob: Array<TrialJob> = [];
trialJobStatus.map(item => {
trialJob.push({
text: item,
value: item
});
});
const columns = [{
title: 'Id',
dataIndex: 'id',
key: 'id',
width: '10%',
className: 'tableHead',
// the sort of string
sorter: (a: TableObj, b: TableObj): number => a.id.localeCompare(b.id)
}, {
title: 'Duration/s',
dataIndex: 'duration',
key: 'duration',
width: '10%',
// the sort of number
sorter: (a: TableObj, b: TableObj) => (a.duration as number) - (b.duration as number)
}, {
title: 'Start',
dataIndex: 'start',
key: 'start',
width: '15%',
sorter: (a: TableObj, b: TableObj): number => a.start.localeCompare(b.start)
}, {
title: 'End',
dataIndex: 'end',
key: 'end',
width: '15%',
sorter: (a: TableObj, b: TableObj): number => (a.end as string).localeCompare(b.end as string)
}, {
title: 'Status',
dataIndex: 'status',
key: 'status',
width: '10%',
className: 'tableStatus',
render: (text: string, record: TableObj) => {
bgColor = record.status;
return (
<span className={`${bgColor} commonStyle`}>{record.status}</span>
);
},
filters: trialJob,
onFilter: (value: string, record: TableObj) => record.status.indexOf(value) === 0,
sorter: (a: TableObj, b: TableObj): number => a.status.localeCompare(b.status)
}, {
title: 'Loss/Accuracy',
dataIndex: 'acc',
key: 'acc',
width: '10%',
sorter: (a: TableObj, b: TableObj) => (a.acc as number) - (b.acc as number)
}, {
title: 'Operation',
dataIndex: 'operation',
key: 'operation',
width: '10%',
render: (text: string, record: TableObj) => {
return (
<Popconfirm
title="Are you sure to delete this trial?"
onConfirm={this.killJob.bind(this, record.key, record.id, record.status)}
>
<Button type="primary" className="tableButton">Kill</Button>
</Popconfirm>
);
},
}, {
title: 'Tensor',
dataIndex: 'tensor',
key: 'tensor',
width: '16%',
render: (text: string, record: TableObj) => {
return (
<Button
type="primary"
className="tableButton"
onClick={this.getTensorpage.bind(this, record.id)}
>
TensorBoard
</Button>
);
},
}
];
const openRow = (record: TableObj) => {
return (
<pre className="hyperpar">
<JSONTree
hideRoot={true}
shouldExpandNode={() => true} // default expandNode
getItemString={() => (<span />)} // remove the {} items
data={record.description}
/>
</pre>
);
};
const { option, tableData } = this.state;
return (
<div className="hyper" id="tableCenter">
<ReactEcharts
option={option}
style={{ width: '100%', height: 600, marginBottom: 15 }}
theme="my_theme"
/>
<Table
columns={columns}
expandedRowRender={openRow}
dataSource={tableData}
pagination={{ pageSize: 20 }}
className="tables"
bordered={true}
scroll={{ x: '100%', y: window.innerHeight * 0.78 }}
/>
</div>
);
}
}
export default TrialStatus;
\ No newline at end of file
export const MANAGER_IP = `${window.location.protocol}//${window.location.hostname}:51188/api/v1/nni`;
export const trialJobStatus = [
'UNKNOWN',
'WAITING',
'RUNNING',
'SUCCEEDED',
'FAILED',
'USER_CANCELED',
'SYS_CANCELED'
];
export const CONTROLTYPE = [
'SEARCH_SPACE',
'TRIAL_CONCURRENCY',
'MAX_EXEC_DURATION'
];
export const overviewItem = 5;
export const roundNum = (acc: number, n: number) => Math.round(acc * 10 ** n) / 10 ** n;
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
import 'babel-polyfill';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import { Router, Route, browserHistory, IndexRedirect } from 'react-router';
import registerServiceWorker from './registerServiceWorker';
import Accuracy from './components/Accuracy';
import Para from './components/Para';
import TrialStatus from './components/TrialStatus';
import Tensor from './components/Tensor';
import Control from './components/Control';
import Sessionpro from './components/Sessionpro';
import Logdetail from './components/Logdetail';
import './index.css';
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/log" component={Logdetail} />
<Route path="/" component={App}>
<IndexRedirect to="/oview" />
<Route path="/oview" component={Sessionpro} />
<Route path="/hyper" component={Para} />
<Route path="/trastaus" component={TrialStatus} />
<Route path="/tensor" component={Tensor} />
<Route path="/control" component={Control} />
<Route path="/all" component={Accuracy} />
</Route>
</Router>,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
// tslint:disable:no-console
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the 'N+1' visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(
process.env.PUBLIC_URL!,
window.location.toString()
);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (!isLocalhost) {
// Is not local host. Just register service worker
registerValidSW(swUrl);
} else {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);
}
});
}
}
function registerValidSW(swUrl: string) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker) {
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a 'New content is
// available; please refresh.' message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// 'Content is cached for offline use.' message.
console.log('Content is cached for offline use.');
}
}
};
}
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl: string) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type')!.indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
.graph{
margin-top: 50px;
}
.trial{
width: 80%;
margin: 0 auto;
border: 2px solid #ccc;
box-shadow: 0px 2px 0px rgba(204,204,204,.8);
}
.trial .title{
width: 100%;
height: 60px;
line-height: 60px;
font-size: 20px;
color: #333;
border-bottom: 1px solid #ccc;
padding-left: 20px;
box-shadow: 0px 1px 0px rgba(204,204,204,.8);
}
.title div{
width: 150px;
margin: 0 auto;
}
/* no data */
.noData>div:first-child{
position: relative;
}
.showMess{
position: absolute;
left: 49%;
top: 48%;
font-size: 13px;
color: rgba(0, 0, 0, 0.45)
/* border: 1px solid red; */
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment