"include/ck/utility/array.hpp" did not exist on "0c05f4279f65f35185d2335da27118f327ebfc62"
Unverified Commit b63b283e authored by SparkSnail's avatar SparkSnail Committed by GitHub
Browse files

Merge pull request #194 from microsoft/master

merge master
parents 803b6e47 9d47087e
...@@ -427,7 +427,7 @@ class BOHB(MsgDispatcherBase): ...@@ -427,7 +427,7 @@ class BOHB(MsgDispatcherBase):
send(CommandType.NoMoreTrialJobs, json_tricks.dumps(ret)) send(CommandType.NoMoreTrialJobs, json_tricks.dumps(ret))
return None return None
assert self.generated_hyper_configs assert self.generated_hyper_configs
params = self.generated_hyper_configs.pop() params = self.generated_hyper_configs.pop(0)
ret = { ret = {
'parameter_id': params[0], 'parameter_id': params[0],
'parameter_source': 'algorithm', 'parameter_source': 'algorithm',
......
...@@ -340,7 +340,7 @@ class Hyperband(MsgDispatcherBase): ...@@ -340,7 +340,7 @@ class Hyperband(MsgDispatcherBase):
self.curr_s -= 1 self.curr_s -= 1
assert self.generated_hyper_configs assert self.generated_hyper_configs
params = self.generated_hyper_configs.pop() params = self.generated_hyper_configs.pop(0)
ret = { ret = {
'parameter_id': params[0], 'parameter_id': params[0],
'parameter_source': 'algorithm', 'parameter_source': 'algorithm',
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
"lodash": "^4.17.13", "lodash": "^4.17.13",
"lodash.template": "^4.5.0", "lodash.template": "^4.5.0",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"webpack-dev-server": "^3.1.11", "webpack-dev-server": "3.0.0",
"merge": "^1.2.1", "merge": "^1.2.1",
"cryptiles": "^4.1.2", "cryptiles": "^4.1.2",
"hoek": "^4.2.1" "hoek": "^4.2.1"
......
...@@ -103,7 +103,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> { ...@@ -103,7 +103,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
height={heights} height={heights}
> >
<div className="card-container log-tab-body" style={{ height: heights }}> <div className="card-container log-tab-body" style={{ height: heights }}>
<Tabs type="card"> <Tabs type="card" style={{ height: heights + 19 }}>
<TabPane tab="Experiment Parameters" key="Experiment"> <TabPane tab="Experiment Parameters" key="Experiment">
<div className="just-for-log"> <div className="just-for-log">
<MonacoEditor <MonacoEditor
...@@ -115,7 +115,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> { ...@@ -115,7 +115,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
/> />
</div> </div>
<Row className="buttons"> <Row className="buttons">
<Col span={12}> <Col span={12} className="download">
<Button <Button
type="primary" type="primary"
onClick={this.downExperimentParameters} onClick={this.downExperimentParameters}
......
...@@ -142,10 +142,10 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -142,10 +142,10 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
visible={isVisble} visible={isVisble}
width="76%" width="76%"
height={heights} height={heights}
// className="logDrawer" // className="logDrawer"
> >
<div className="card-container log-tab-body" style={{ height: heights }}> <div className="card-container log-tab-body" style={{ height: heights }}>
<Tabs type="card" defaultActiveKey={activeTab}> <Tabs type="card" defaultActiveKey={activeTab} style={{ height: heights + 19 }}>
{/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */} {/* <Tabs type="card" onTabClick={this.selectwhichLog} defaultActiveKey={activeTab}> */}
{/* <TabPane tab="Dispatcher Log" key="dispatcher"> */} {/* <TabPane tab="Dispatcher Log" key="dispatcher"> */}
<TabPane tab={this.dispatcherHTML()} key="dispatcher"> <TabPane tab={this.dispatcherHTML()} key="dispatcher">
...@@ -153,7 +153,7 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> { ...@@ -153,7 +153,7 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
<MonacoHTML content={dispatcherLogStr} loading={isLoadispatcher} /> <MonacoHTML content={dispatcherLogStr} loading={isLoadispatcher} />
</div> </div>
<Row className="buttons"> <Row className="buttons">
<Col span={12}> <Col span={12} className="download">
<Button <Button
type="primary" type="primary"
onClick={this.downloadDispatcher} onClick={this.downloadDispatcher}
......
...@@ -3,9 +3,12 @@ import { Link } from 'react-router'; ...@@ -3,9 +3,12 @@ import { Link } from 'react-router';
import axios from 'axios'; import axios from 'axios';
import { MANAGER_IP } from '../static/const'; import { MANAGER_IP } from '../static/const';
import MediaQuery from 'react-responsive'; import MediaQuery from 'react-responsive';
import { Row, Col, Menu, Dropdown, Icon, Select, Button } from 'antd'; import { Row, Col, Menu, Dropdown, Icon, Select, Button, Form } from 'antd';
import { FormComponentProps } from 'antd/lib/form';
import { OVERVIEWTABS, DETAILTABS, NNILOGO } from './stateless-component/NNItabs';
const { SubMenu } = Menu; const { SubMenu } = Menu;
const { Option } = Select; const { Option } = Select;
const FormItem = Form.Item;
import LogDrawer from './Modal/LogDrawer'; import LogDrawer from './Modal/LogDrawer';
import ExperimentDrawer from './Modal/ExperimentDrawer'; import ExperimentDrawer from './Modal/ExperimentDrawer';
import '../static/style/slideBar.scss'; import '../static/style/slideBar.scss';
...@@ -21,7 +24,7 @@ interface SliderState { ...@@ -21,7 +24,7 @@ interface SliderState {
activeKey: string; activeKey: string;
} }
interface SliderProps { interface SliderProps extends FormComponentProps {
changeInterval: (value: number) => void; changeInterval: (value: number) => void;
changeFresh: (value: string) => void; changeFresh: (value: string) => void;
} }
...@@ -122,9 +125,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -122,9 +125,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
const { version } = this.state; const { version } = this.state;
const feedBackLink = `https://github.com/Microsoft/nni/issues/new?labels=${version}`; const feedBackLink = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
return ( return (
<Menu onClick={this.handleMenuClick} className="menuModal"> <Menu onClick={this.handleMenuClick} className="menu-list" style={{ width: 216 }}>
<Menu.Item key="overview"><Link to={'/oview'}>Overview</Link></Menu.Item> {/* <Menu onClick={this.handleMenuClick} className="menu-list" style={{width: window.innerWidth}}> */}
<Menu.Item key="detail"><Link to={'/detail'}>Trials detail</Link></Menu.Item>
<Menu.Item key="feedback"> <Menu.Item key="feedback">
<a href={feedBackLink} target="_blank">Feedback</a> <a href={feedBackLink} target="_blank">Feedback</a>
</Menu.Item> </Menu.Item>
...@@ -146,10 +148,46 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -146,10 +148,46 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
); );
} }
mobileTabs = () => {
return (
// <Menu className="menuModal" style={{width: 880, position: 'fixed', left: 0, top: 56}}>
<Menu className="menuModal" style={{ padding: '0 10px' }}>
<Menu.Item key="overview"><Link to={'/oview'}>Overview</Link></Menu.Item>
<Menu.Item key="detail"><Link to={'/detail'}>Trials detail</Link></Menu.Item>
</Menu>
);
}
refreshInterval = () => {
const {
form: { getFieldDecorator },
// form: { getFieldDecorator, getFieldValue },
} = this.props;
return (
<Form>
<FormItem style={{ marginBottom: 0 }}>
{getFieldDecorator('interval', {
initialValue: 'Refresh every 10s',
})(
<Select onSelect={this.getInterval}>
<Option value="close">Disable Auto Refresh</Option>
<Option value="10">Refresh every 10s</Option>
<Option value="20">Refresh every 20s</Option>
<Option value="30">Refresh every 30s</Option>
<Option value="60">Refresh every 1min</Option>
</Select>,
)}
</FormItem>
</Form>
);
}
select = () => { select = () => {
const { isdisabledFresh } = this.state; const { isdisabledFresh } = this.state;
return ( return (
<div className="interval"> <div className="interval">
{this.refreshInterval()}
<Button <Button
className="fresh" className="fresh"
onClick={this.fresh} onClick={this.fresh}
...@@ -158,16 +196,6 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -158,16 +196,6 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
> >
<Icon type="sync" /><span>Refresh</span> <Icon type="sync" /><span>Refresh</span>
</Button> </Button>
<Select
onSelect={this.getInterval}
defaultValue="Refresh every 10s"
>
<Option value="close">Disable Auto Refresh</Option>
<Option value="10">Refresh every 10s</Option>
<Option value="20">Refresh every 20s</Option>
<Option value="30">Refresh every 30s</Option>
<Option value="60">Refresh every 1min</Option>
</Select>
</div> </div>
); );
} }
...@@ -184,6 +212,112 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -184,6 +212,112 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
} }
} }
desktopHTML = () => {
const { version, menuVisible } = this.state;
const feed = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
return (
<Row className="nav">
<Col span={8}>
<span className="desktop-logo">{NNILOGO}</span>
<span className="left-right-margin">{OVERVIEWTABS}</span>
<span>{DETAILTABS}</span>
</Col>
<Col span={16} className="desktop-right">
<span>{this.select()}</span>
<span>
<Dropdown
className="dropdown"
overlay={this.menu()}
onVisibleChange={this.handleVisibleChange}
visible={menuVisible}
trigger={['click']}
>
<a className="ant-dropdown-link" href="#">
<Icon type="download" className="down-icon" />
<span>Download</span>
{
menuVisible
?
<Icon type="up" className="margin-icon"/>
:
<Icon type="down" className="margin-icon"/>
}
</a>
</Dropdown>
</span>
<span className="feedback">
<a href={feed} target="_blank">
<img
src={require('../static/img/icon/issue.png')}
alt="NNI github issue"
/>
Feedback
</a>
</span>
<span className="version">Version: {version}</span>
</Col>
</Row>
);
}
tabeltHTML = () => {
return (
<Row className="nav">
<Col className="tabelt-left" span={14}>
<span>
<Dropdown overlay={this.navigationBar()} trigger={['click']}>
<Icon type="unordered-list" className="more" />
</Dropdown>
</span>
<span className="left-right-margin tabelt-img">{NNILOGO}</span>
<span>{OVERVIEWTABS}</span>
<span className="left-margin">{DETAILTABS}</span>
</Col>
<Col className="tabelt-right" span={10}>
{this.select()}
</Col>
</Row>
);
}
mobileHTML = () => {
const { isdisabledFresh } = this.state;
return (
<Row className="nav">
<Col className="left" span={8}>
<span>
<Dropdown className="more-mobile" overlay={this.navigationBar()} trigger={['click']}>
<Icon type="unordered-list" className="more" />
</Dropdown>
</span>
<span>
<Dropdown overlay={this.mobileTabs()} trigger={['click']}>
<a className="ant-dropdown-link" href="#">
<span>NNI <Icon type="down" /></span>
</a>
</Dropdown>
</span>
</Col>
<Col className="center" span={8}>
<img
src={require('../static/img/logo2.png')}
alt="NNI logo"
/>
</Col>
{/* the class interval have other style ! */}
<Col className="right interval" span={8}>
<Button
className="fresh"
onClick={this.fresh}
type="ghost"
disabled={isdisabledFresh}
>
<Icon type="sync" /><span>Refresh</span>
</Button>
</Col>
</Row>
);
}
// close log drawer (nnimanager.dispatcher) // close log drawer (nnimanager.dispatcher)
closeLogDrawer = () => { closeLogDrawer = () => {
if (this._isMounted === true) { if (this._isMounted === true) {
...@@ -208,81 +342,15 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -208,81 +342,15 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
} }
render() { render() {
const { version, menuVisible, isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state; const mobile = (<MediaQuery maxWidth={884}>{this.mobileHTML()}</MediaQuery>);
const feed = `https://github.com/Microsoft/nni/issues/new?labels=${version}`; const tablet = (<MediaQuery minWidth={885} maxWidth={1241}>{this.tabeltHTML()}</MediaQuery>);
const desktop = (<MediaQuery minWidth={1242}>{this.desktopHTML()}</MediaQuery>);
const { isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state;
return ( return (
<Row> <div>
<Row> {mobile}
<Col span={18}> {tablet}
<MediaQuery query="(min-width: 1299px)"> {desktop}
<Row className="nav">
<ul className="link">
<li className="logo">
<Link to={'/oview'}>
<img
src={require('../static/img/logo2.png')}
style={{ width: 88 }}
alt="NNI logo"
/>
</Link>
</li>
<li className="tab firstTab">
<Link to={'/oview'} activeClassName="high">
Overview
</Link>
</li>
<li className="tab">
<Link to={'/detail'} activeClassName="high">
Trials detail
</Link>
</li>
<li className="feedback">
<Dropdown
className="dropdown"
overlay={this.menu()}
onVisibleChange={this.handleVisibleChange}
visible={menuVisible}
trigger={['click']}
>
<a className="ant-dropdown-link" href="#">
Download <Icon type="down" />
</a>
</Dropdown>
<a href={feed} target="_blank">
<img
src={require('../static/img/icon/issue.png')}
alt="NNI github issue"
/>
Feedback
</a>
<span className="version">Version: {version}</span>
</li>
</ul>
</Row>
</MediaQuery>
</Col>
<Col span={18}>
<MediaQuery query="(max-width: 1299px)">
<Row className="little">
<Col span={1} className="menu">
<Dropdown overlay={this.navigationBar()} trigger={['click']}>
<Icon type="unordered-list" className="more" />
</Dropdown>
</Col>
<Col span={14} className="logo">
<Link to={'/oview'}>
<img
src={require('../static/img/logo2.png')}
style={{ width: 80 }}
alt="NNI logo"
/>
</Link>
</Col>
</Row>
</MediaQuery>
</Col>
<Col span={3}> {this.select()} </Col>
</Row>
{/* the drawer for dispatcher & nnimanager log message */} {/* the drawer for dispatcher & nnimanager log message */}
<LogDrawer <LogDrawer
isVisble={isvisibleLogDrawer} isVisble={isvisibleLogDrawer}
...@@ -293,9 +361,9 @@ class SlideBar extends React.Component<SliderProps, SliderState> { ...@@ -293,9 +361,9 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
isVisble={isvisibleExperimentDrawer} isVisble={isvisibleExperimentDrawer}
closeExpDrawer={this.closeExpDrawer} closeExpDrawer={this.closeExpDrawer}
/> />
</Row> </div>
); );
} }
} }
export default SlideBar; export default Form.create<FormComponentProps>()(SlideBar);
\ No newline at end of file \ No newline at end of file
import * as React from 'react'; import * as React from 'react';
import { import { Row, Col, Popover, Button, message } from 'antd';
Row, Col, Popover, Button, message
} from 'antd';
import axios from 'axios'; import axios from 'axios';
import { MANAGER_IP, CONTROLTYPE } from '../../static/const'; import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
import { Experiment, TrialNumber } from '../../static/interface'; import { Experiment, TrialNumber } from '../../static/interface';
...@@ -303,7 +301,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> { ...@@ -303,7 +301,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
<LogDrawer <LogDrawer
isVisble={isShowLogDrawer} isVisble={isShowLogDrawer}
closeDrawer={this.closeDrawer} closeDrawer={this.closeDrawer}
activeTab="dispatcher" activeTab="dispatcher"
/> />
</Row> </Row>
); );
......
...@@ -15,7 +15,6 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> { ...@@ -15,7 +15,6 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> {
render() { render() {
const { record } = this.props; const { record } = this.props;
const interArr = record.description.intermediate; const interArr = record.description.intermediate;
const status = record.status;
let lastVal; let lastVal;
let wei = 0; let wei = 0;
if (interArr !== undefined) { if (interArr !== undefined) {
...@@ -29,8 +28,11 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> { ...@@ -29,8 +28,11 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> {
result = `${lastVal.toFixed(6)}`; result = `${lastVal.toFixed(6)}`;
} }
} }
if (status === 'SUCCEEDED') { // some trial haven't final result
result = `${result} (FINAL)`; if (record.acc !== undefined) {
if (record.acc.default !== undefined) {
result = `${result} (FINAL)`;
}
} else { } else {
result = `${result} (LATEST)`; result = `${result} (LATEST)`;
} }
......
import * as React from 'react';
import { Link } from 'react-router';
const OVERVIEWTABS = (
<Link to={'/oview'} activeClassName="high-light" className="common-tabs">
Overview
</Link>
);
const DETAILTABS = (
<Link to={'/detail'} activeClassName="high-light" className="common-tabs">
Trials detail
</Link>
);
const NNILOGO = (
<Link to={'/oview'}>
<img
src={require('../../static/img/logo2.png')}
alt="NNI logo"
style={{height: 40}}
/>
</Link>
);
export { OVERVIEWTABS, DETAILTABS, NNILOGO };
\ No newline at end of file
...@@ -114,6 +114,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> ...@@ -114,6 +114,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
yAxis: { yAxis: {
name: 'Default metric', name: 'Default metric',
type: 'value', type: 'value',
scale: true
}, },
series: [{ series: [{
symbolSize: 6, symbolSize: 6,
......
...@@ -78,7 +78,7 @@ class Para extends React.Component<ParaProps, ParaState> { ...@@ -78,7 +78,7 @@ class Para extends React.Component<ParaProps, ParaState> {
getParallelAxis = getParallelAxis =
( (
dimName: Array<string>, parallelAxis: Array<Dimobj>, dimName: Array<string>, parallelAxis: Array<Dimobj>,
accPara: Array<number>, eachTrialParams: Array<string>, accPara: Array<number>, eachTrialParams: Array<string>,
lengthofTrials: number lengthofTrials: number
) => { ) => {
// get data for every lines. if dim is choice type, number -> toString() // get data for every lines. if dim is choice type, number -> toString()
...@@ -276,7 +276,10 @@ class Para extends React.Component<ParaProps, ParaState> { ...@@ -276,7 +276,10 @@ class Para extends React.Component<ParaProps, ParaState> {
} }
}); });
if (this._isMounted) { if (this._isMounted) {
this.setState({ max: Math.max(...accPara), min: Math.min(...accPara) }, () => { // if not return final result
const maxVal = accPara.length === 0 ? 1 : Math.max(...accPara);
const minVal = accPara.length === 0 ? 1 : Math.min(...accPara);
this.setState({ max: maxVal, min: minVal }, () => {
this.getParallelAxis(dimName, parallelAxis, accPara, eachTrialParams, lenOfDataSource); this.getParallelAxis(dimName, parallelAxis, accPara, eachTrialParams, lenOfDataSource);
}); });
} }
......
...@@ -48,5 +48,4 @@ q:before, q:after { ...@@ -48,5 +48,4 @@ q:before, q:after {
table { table {
border-collapse: collapse; border-collapse: collapse;
border-spacing: 0; border-spacing: 0;
} }
\ No newline at end of file
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
} }
.buttons{ .buttons{
margin-top: 15px; margin-top: 11px;
.close{ .close{
text-align: right; text-align: right;
} }
......
...@@ -3,54 +3,6 @@ $barHeight: 56px; ...@@ -3,54 +3,6 @@ $barHeight: 56px;
$drowBgColor: #f2f2f2; $drowBgColor: #f2f2f2;
/* drowdown and select hover bgcolor */ /* drowdown and select hover bgcolor */
$drowHoverBgColor: #e2e2e2; $drowHoverBgColor: #e2e2e2;
.nav{
list-style: none;
width: 95%;
height: $barHeight;
margin: 0 auto;
position: relative;
.tab{
line-height: $barHeight;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
a{
font-size: 18px;
color: #b8c7ce;
text-decoration: none;
}
}
.firstTab{
margin: 0 20px;
}
.logo{
margin-top: 2px;
max-width: 128px;
}
}
.tab a:hover, .tab a.high{
color: white;
border-bottom: 1px solid #fff;
}
.feedback{
position: fixed;
right: 26%;
line-height: $barHeight;
font-size: 16px;
color: #fff;
a{
color: #fff;
text-decoration: none;
margin-left: 10px;
}
img{
width: 20px;
margin-right: 8px;
}
.version{
margin-left: 16px;
}
}
/* refresh button */ /* refresh button */
.fresh{ .fresh{
...@@ -63,20 +15,25 @@ $drowHoverBgColor: #e2e2e2; ...@@ -63,20 +15,25 @@ $drowHoverBgColor: #e2e2e2;
color: #fff; color: #fff;
} }
.link li{
float: left;
}
.dropdown{ .dropdown{
margin-right: 10px;
/* make dropdown content box position in blue bar bottom */ /* make dropdown content box position in blue bar bottom */
padding-bottom: 14px; padding-bottom: 14px;
.down-icon{
font-size: 20px !important;
padding-right: 2px;
}
} }
.interval{ .interval{
position: fixed; display: inline-block;
right: 6%;
top: 12px;
font-size: 16px; font-size: 16px;
color: #fff; color: #fff;
.ant-form{
display: inline-block;
}
form .ant-select{
width: 166px;
}
.ant-select-selection{ .ant-select-selection{
background-color: transparent; background-color: transparent;
border: none; border: none;
...@@ -87,10 +44,19 @@ $drowHoverBgColor: #e2e2e2; ...@@ -87,10 +44,19 @@ $drowHoverBgColor: #e2e2e2;
.ant-select-arrow{ .ant-select-arrow{
color: #fff; color: #fff;
} }
.fresh{
margin-right: 10px;
}
.ant-btn-ghost{
padding: 0 10px;
}
.ant-btn-ghost[disabled]{ .ant-btn-ghost[disabled]{
background-color: transparent; background-color: #005b98;
color: #fff; color: #fff;
} }
} }
/* set select bgcolor */ /* set select bgcolor */
.ant-select-dropdown-menu{ .ant-select-dropdown-menu{
...@@ -126,26 +92,141 @@ $drowHoverBgColor: #e2e2e2; ...@@ -126,26 +92,141 @@ $drowHoverBgColor: #e2e2e2;
} }
} }
.menu-list{
position: relative;
top: 13px;
}
/* nav style*/ .ant-dropdown{
.little{ .menuModal{
width: 90%; position: relative;
.menu{ top: 12px;
margin-left: 33px; }
.more{ }
.ant-select-selection-selected-value{
font-size: 16px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.ant-dropdown-menu-submenu-title{
font-size: 16px;
}
.ant-dropdown-menu-item:hover, .ant-dropdown-menu-submenu-title:hover{
background-color: transparent;
}
.nav{
width: 95%;
height: $barHeight;
margin: 0 auto;
line-height: $barHeight;
/* mobile start*/
.left{
text-align: left;
/* more menu */
font-size: 18px;
color: #fff;
a, a:visited{
color: #fff; color: #fff;
font-size: 24px; text-decoration: none;
margin-top: 16px; }
.more-mobile{
margin-right: 10%;
font-size: 22px;
position: relative;
top: 1px;
} }
.more:hover{ .more-mobile:hover{
cursor: pointer; cursor: pointer;
} }
} }
.logo{ .center{
text-align: center;
img{
height: 38px;
}
}
.right{
text-align: right; text-align: right;
button{
margin-top: 12px;
}
}
/* mobile end */
/* tabelt mode */
.tabelt-left{
height: $barHeight;
.tabelt-img img{
position: relative;
top: -5px;
}
}
.tabelt-right{
text-align: right;
}
/* desktop mode */
.desktop-logo{
position: relative;
top: -3px;
}
.desktop-right{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
text-align: right;
line-height: $barHeight;
font-size: 16px;
color: #fff;
a{
color: #fff;
text-decoration: none;
}
img{
width: 20px;
margin-right: 8px;
}
.feedback{
font-size: 16px;
margin: 0 20px;
}
.version{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
}
.margin-icon{
margin-left: 8px;
}
} }
} }
.menuModal{ /* public style in nav in threee mode*/
width: 198px; .more{
color: #fff;
font-size: 24px;
}
.more:hover{
cursor: pointer;
}
/* overview and detail tabs common style */
a.common-tabs{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
color: #b8c7ce;
text-decoration: none;
}
.common-tabs:visited, .high-light:hover{
color: #fff;
text-decoration: none;
}
.common-tabs:hover, .high-light{
color: #fff;
border-bottom: 1px solid #fff;
}
.left-right-margin{
margin-left: 20px;
margin-right: 20px;
} }
.left-margin{
margin-left: 20px;
}
\ No newline at end of file
...@@ -24,10 +24,10 @@ import sys ...@@ -24,10 +24,10 @@ import sys
import time import time
import traceback import traceback
from utils import is_experiment_done, fetch_nni_log_path, read_last_line, remove_files, setup_experiment from utils import is_experiment_done, get_experiment_id, get_nni_log_path, read_last_line, remove_files, setup_experiment, detect_port, snooze
from utils import GREEN, RED, CLEAR, EXPERIMENT_URL from utils import GREEN, RED, CLEAR, EXPERIMENT_URL
def run(): def naive_test():
'''run naive integration test''' '''run naive integration test'''
to_remove = ['tuner_search_space.json', 'tuner_result.txt', 'assessor_result.txt'] to_remove = ['tuner_search_space.json', 'tuner_result.txt', 'assessor_result.txt']
to_remove = list(map(lambda file: 'naive_test/' + file, to_remove)) to_remove = list(map(lambda file: 'naive_test/' + file, to_remove))
...@@ -38,7 +38,7 @@ def run(): ...@@ -38,7 +38,7 @@ def run():
print('Spawning trials...') print('Spawning trials...')
nnimanager_log_path = fetch_nni_log_path(EXPERIMENT_URL) nnimanager_log_path = get_nni_log_path(EXPERIMENT_URL)
current_trial = 0 current_trial = 0
for _ in range(120): for _ in range(120):
...@@ -79,11 +79,36 @@ def run(): ...@@ -79,11 +79,36 @@ def run():
expected = set(open('naive_test/expected_assessor_result.txt')) expected = set(open('naive_test/expected_assessor_result.txt'))
assert assessor_result == expected, 'Bad assessor result' assert assessor_result == expected, 'Bad assessor result'
subprocess.run(['nnictl', 'stop'])
snooze()
def stop_experiment_test():
'''Test `nnictl stop` command, including `nnictl stop exp_id` and `nnictl stop all`.
Simple `nnictl stop` is not tested here since it is used in all other test code'''
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8080'], check=True)
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8888'], check=True)
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8989'], check=True)
# test cmd 'nnictl stop id`
experiment_id = get_experiment_id(EXPERIMENT_URL)
proc = subprocess.run(['nnictl', 'stop', experiment_id])
assert proc.returncode == 0, '`nnictl stop %s` failed with code %d' % (experiment_id, proc.returncode)
snooze()
assert not detect_port(8080), '`nnictl stop %s` failed to stop experiments' % experiment_id
# test cmd `nnictl stop all`
proc = subprocess.run(['nnictl', 'stop', 'all'])
assert proc.returncode == 0, '`nnictl stop all` failed with code %d' % proc.returncode
snooze()
assert not detect_port(8888) and not detect_port(8989), '`nnictl stop all` failed to stop experiments'
if __name__ == '__main__': if __name__ == '__main__':
installed = (sys.argv[-1] != '--preinstall') installed = (sys.argv[-1] != '--preinstall')
setup_experiment(installed) setup_experiment(installed)
try: try:
run() naive_test()
stop_experiment_test()
# TODO: check the output of rest server # TODO: check the output of rest server
print(GREEN + 'PASS' + CLEAR) print(GREEN + 'PASS' + CLEAR)
except Exception as error: except Exception as error:
...@@ -91,5 +116,3 @@ if __name__ == '__main__': ...@@ -91,5 +116,3 @@ if __name__ == '__main__':
print('%r' % error) print('%r' % error)
traceback.print_exc() traceback.print_exc()
sys.exit(1) sys.exit(1)
finally:
subprocess.run(['nnictl', 'stop'])
...@@ -23,15 +23,11 @@ import sys ...@@ -23,15 +23,11 @@ import sys
import time import time
import traceback import traceback
from utils import get_yml_content, dump_yml_content, setup_experiment, fetch_nni_log_path, is_experiment_done from utils import get_yml_content, dump_yml_content, setup_experiment, get_nni_log_path, is_experiment_done
from utils import GREEN, RED, CLEAR, EXPERIMENT_URL
GREEN = '\33[32m'
RED = '\33[31m'
CLEAR = '\33[0m'
TUNER_LIST = ['GridSearch', 'BatchTuner', 'TPE', 'Random', 'Anneal', 'Evolution'] TUNER_LIST = ['GridSearch', 'BatchTuner', 'TPE', 'Random', 'Anneal', 'Evolution']
ASSESSOR_LIST = ['Medianstop'] ASSESSOR_LIST = ['Medianstop']
EXPERIMENT_URL = 'http://localhost:8080/api/v1/nni/experiment'
def switch(dispatch_type, dispatch_name): def switch(dispatch_type, dispatch_name):
...@@ -63,7 +59,7 @@ def test_builtin_dispatcher(dispatch_type, dispatch_name): ...@@ -63,7 +59,7 @@ def test_builtin_dispatcher(dispatch_type, dispatch_name):
proc = subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml']) proc = subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml'])
assert proc.returncode == 0, '`nnictl create` failed with code %d' % proc.returncode assert proc.returncode == 0, '`nnictl create` failed with code %d' % proc.returncode
nnimanager_log_path = fetch_nni_log_path(EXPERIMENT_URL) nnimanager_log_path = get_nni_log_path(EXPERIMENT_URL)
for _ in range(20): for _ in range(20):
time.sleep(3) time.sleep(3)
......
...@@ -22,9 +22,11 @@ import contextlib ...@@ -22,9 +22,11 @@ import contextlib
import collections import collections
import json import json
import os import os
import socket
import sys import sys
import subprocess import subprocess
import requests import requests
import time
import ruamel.yaml as yaml import ruamel.yaml as yaml
EXPERIMENT_DONE_SIGNAL = '"Experiment done"' EXPERIMENT_DONE_SIGNAL = '"Experiment done"'
...@@ -76,10 +78,13 @@ def setup_experiment(installed=True): ...@@ -76,10 +78,13 @@ def setup_experiment(installed=True):
pypath = ':'.join([sdk_path, cmd_path]) pypath = ':'.join([sdk_path, cmd_path])
os.environ['PYTHONPATH'] = pypath os.environ['PYTHONPATH'] = pypath
def fetch_nni_log_path(experiment_url): def get_experiment_id(experiment_url):
experiment_id = requests.get(experiment_url).json()['id']
return experiment_id
def get_nni_log_path(experiment_url):
'''get nni's log path from nni's experiment url''' '''get nni's log path from nni's experiment url'''
experiment_profile = requests.get(experiment_url) experiment_id = get_experiment_id(experiment_url)
experiment_id = json.loads(experiment_profile.text)['id']
experiment_path = os.path.join(os.path.expanduser('~'), 'nni', 'experiments', experiment_id) experiment_path = os.path.join(os.path.expanduser('~'), 'nni', 'experiments', experiment_id)
nnimanager_log_path = os.path.join(experiment_path, 'log', 'nnimanager.log') nnimanager_log_path = os.path.join(experiment_path, 'log', 'nnimanager.log')
...@@ -98,7 +103,6 @@ def is_experiment_done(nnimanager_log_path): ...@@ -98,7 +103,6 @@ def is_experiment_done(nnimanager_log_path):
def get_experiment_status(status_url): def get_experiment_status(status_url):
nni_status = requests.get(status_url).json() nni_status = requests.get(status_url).json()
#print(nni_status)
return nni_status['status'] return nni_status['status']
def get_succeeded_trial_num(trial_jobs_url): def get_succeeded_trial_num(trial_jobs_url):
...@@ -139,3 +143,17 @@ def deep_update(source, overrides): ...@@ -139,3 +143,17 @@ def deep_update(source, overrides):
else: else:
source[key] = overrides[key] source[key] = overrides[key]
return source return source
def detect_port(port):
'''Detect if the port is used'''
socket_test = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
socket_test.connect(('127.0.0.1', int(port)))
socket_test.close()
return True
except:
return False
def snooze():
'''Sleep to make sure previous stopped exp has enough time to exit'''
time.sleep(6)
\ No newline at end of file
...@@ -84,10 +84,12 @@ tuner_schema_dict = { ...@@ -84,10 +84,12 @@ tuner_schema_dict = {
'optimize_mode': setChoice('optimize_mode', 'maximize', 'minimize'), 'optimize_mode': setChoice('optimize_mode', 'maximize', 'minimize'),
Optional('population_size'): setNumberRange('population_size', int, 0, 99999), Optional('population_size'): setNumberRange('population_size', int, 0, 99999),
}, },
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
}, },
('BatchTuner', 'GridSearch', 'Random'): { ('BatchTuner', 'GridSearch', 'Random'): {
'builtinTunerName': setChoice('builtinTunerName', 'BatchTuner', 'GridSearch', 'Random'), 'builtinTunerName': setChoice('builtinTunerName', 'BatchTuner', 'GridSearch', 'Random'),
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
}, },
'NetworkMorphism': { 'NetworkMorphism': {
...@@ -99,6 +101,7 @@ tuner_schema_dict = { ...@@ -99,6 +101,7 @@ tuner_schema_dict = {
Optional('input_channel'): setType('input_channel', int), Optional('input_channel'): setType('input_channel', int),
Optional('n_output_node'): setType('n_output_node', int), Optional('n_output_node'): setType('n_output_node', int),
}, },
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
}, },
'MetisTuner': { 'MetisTuner': {
...@@ -110,6 +113,7 @@ tuner_schema_dict = { ...@@ -110,6 +113,7 @@ tuner_schema_dict = {
Optional('selection_num_starting_points'): setType('selection_num_starting_points', int), Optional('selection_num_starting_points'): setType('selection_num_starting_points', int),
Optional('cold_start_num'): setType('cold_start_num', int), Optional('cold_start_num'): setType('cold_start_num', int),
}, },
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
}, },
'GPTuner': { 'GPTuner': {
...@@ -125,6 +129,7 @@ tuner_schema_dict = { ...@@ -125,6 +129,7 @@ tuner_schema_dict = {
Optional('selection_num_warm_up'): setType('selection_num_warm_up', int), Optional('selection_num_warm_up'): setType('selection_num_warm_up', int),
Optional('selection_num_starting_points'): setType('selection_num_starting_points', int), Optional('selection_num_starting_points'): setType('selection_num_starting_points', int),
}, },
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
}, },
'customized': { 'customized': {
...@@ -132,6 +137,7 @@ tuner_schema_dict = { ...@@ -132,6 +137,7 @@ tuner_schema_dict = {
'classFileName': setType('classFileName', str), 'classFileName': setType('classFileName', str),
'className': setType('className', str), 'className': setType('className', str),
Optional('classArgs'): dict, Optional('classArgs'): dict,
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999), Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
} }
} }
......
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