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):
send(CommandType.NoMoreTrialJobs, json_tricks.dumps(ret))
return None
assert self.generated_hyper_configs
params = self.generated_hyper_configs.pop()
params = self.generated_hyper_configs.pop(0)
ret = {
'parameter_id': params[0],
'parameter_source': 'algorithm',
......
......@@ -340,7 +340,7 @@ class Hyperband(MsgDispatcherBase):
self.curr_s -= 1
assert self.generated_hyper_configs
params = self.generated_hyper_configs.pop()
params = self.generated_hyper_configs.pop(0)
ret = {
'parameter_id': params[0],
'parameter_source': 'algorithm',
......
......@@ -39,7 +39,7 @@
"lodash": "^4.17.13",
"lodash.template": "^4.5.0",
"js-yaml": "^3.13.1",
"webpack-dev-server": "^3.1.11",
"webpack-dev-server": "3.0.0",
"merge": "^1.2.1",
"cryptiles": "^4.1.2",
"hoek": "^4.2.1"
......
......@@ -103,7 +103,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
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">
<div className="just-for-log">
<MonacoEditor
......@@ -115,7 +115,7 @@ class ExperimentDrawer extends React.Component<ExpDrawerProps, ExpDrawerState> {
/>
</div>
<Row className="buttons">
<Col span={12}>
<Col span={12} className="download">
<Button
type="primary"
onClick={this.downExperimentParameters}
......
......@@ -142,10 +142,10 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
visible={isVisble}
width="76%"
height={heights}
// className="logDrawer"
// className="logDrawer"
>
<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}> */}
{/* <TabPane tab="Dispatcher Log" key="dispatcher"> */}
<TabPane tab={this.dispatcherHTML()} key="dispatcher">
......@@ -153,7 +153,7 @@ class LogDrawer extends React.Component<LogDrawerProps, LogDrawerState> {
<MonacoHTML content={dispatcherLogStr} loading={isLoadispatcher} />
</div>
<Row className="buttons">
<Col span={12}>
<Col span={12} className="download">
<Button
type="primary"
onClick={this.downloadDispatcher}
......
......@@ -3,9 +3,12 @@ import { Link } from 'react-router';
import axios from 'axios';
import { MANAGER_IP } from '../static/const';
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 { Option } = Select;
const FormItem = Form.Item;
import LogDrawer from './Modal/LogDrawer';
import ExperimentDrawer from './Modal/ExperimentDrawer';
import '../static/style/slideBar.scss';
......@@ -21,7 +24,7 @@ interface SliderState {
activeKey: string;
}
interface SliderProps {
interface SliderProps extends FormComponentProps {
changeInterval: (value: number) => void;
changeFresh: (value: string) => void;
}
......@@ -122,9 +125,8 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
const { version } = this.state;
const feedBackLink = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
return (
<Menu onClick={this.handleMenuClick} className="menuModal">
<Menu.Item key="overview"><Link to={'/oview'}>Overview</Link></Menu.Item>
<Menu.Item key="detail"><Link to={'/detail'}>Trials detail</Link></Menu.Item>
<Menu onClick={this.handleMenuClick} className="menu-list" style={{ width: 216 }}>
{/* <Menu onClick={this.handleMenuClick} className="menu-list" style={{width: window.innerWidth}}> */}
<Menu.Item key="feedback">
<a href={feedBackLink} target="_blank">Feedback</a>
</Menu.Item>
......@@ -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 = () => {
const { isdisabledFresh } = this.state;
return (
<div className="interval">
{this.refreshInterval()}
<Button
className="fresh"
onClick={this.fresh}
......@@ -158,16 +196,6 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
>
<Icon type="sync" /><span>Refresh</span>
</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>
);
}
......@@ -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)
closeLogDrawer = () => {
if (this._isMounted === true) {
......@@ -208,81 +342,15 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
}
render() {
const { version, menuVisible, isvisibleLogDrawer, activeKey, isvisibleExperimentDrawer } = this.state;
const feed = `https://github.com/Microsoft/nni/issues/new?labels=${version}`;
const mobile = (<MediaQuery maxWidth={884}>{this.mobileHTML()}</MediaQuery>);
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 (
<Row>
<Row>
<Col span={18}>
<MediaQuery query="(min-width: 1299px)">
<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>
<div>
{mobile}
{tablet}
{desktop}
{/* the drawer for dispatcher & nnimanager log message */}
<LogDrawer
isVisble={isvisibleLogDrawer}
......@@ -293,9 +361,9 @@ class SlideBar extends React.Component<SliderProps, SliderState> {
isVisble={isvisibleExperimentDrawer}
closeExpDrawer={this.closeExpDrawer}
/>
</Row>
</div>
);
}
}
export default SlideBar;
\ No newline at end of file
export default Form.create<FormComponentProps>()(SlideBar);
\ No newline at end of file
import * as React from 'react';
import {
Row, Col, Popover, Button, message
} from 'antd';
import { Row, Col, Popover, Button, message } from 'antd';
import axios from 'axios';
import { MANAGER_IP, CONTROLTYPE } from '../../static/const';
import { Experiment, TrialNumber } from '../../static/interface';
......@@ -303,7 +301,7 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
<LogDrawer
isVisble={isShowLogDrawer}
closeDrawer={this.closeDrawer}
activeTab="dispatcher"
activeTab="dispatcher"
/>
</Row>
);
......
......@@ -15,7 +15,6 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> {
render() {
const { record } = this.props;
const interArr = record.description.intermediate;
const status = record.status;
let lastVal;
let wei = 0;
if (interArr !== undefined) {
......@@ -29,8 +28,11 @@ class IntermediateVal extends React.Component<IntermediateValProps, {}> {
result = `${lastVal.toFixed(6)}`;
}
}
if (status === 'SUCCEEDED') {
result = `${result} (FINAL)`;
// some trial haven't final result
if (record.acc !== undefined) {
if (record.acc.default !== undefined) {
result = `${result} (FINAL)`;
}
} else {
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>
yAxis: {
name: 'Default metric',
type: 'value',
scale: true
},
series: [{
symbolSize: 6,
......
......@@ -78,7 +78,7 @@ class Para extends React.Component<ParaProps, ParaState> {
getParallelAxis =
(
dimName: Array<string>, parallelAxis: Array<Dimobj>,
accPara: Array<number>, eachTrialParams: Array<string>,
accPara: Array<number>, eachTrialParams: Array<string>,
lengthofTrials: number
) => {
// get data for every lines. if dim is choice type, number -> toString()
......@@ -276,7 +276,10 @@ class Para extends React.Component<ParaProps, ParaState> {
}
});
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);
});
}
......
......@@ -48,5 +48,4 @@ q:before, q:after {
table {
border-collapse: collapse;
border-spacing: 0;
}
}
\ No newline at end of file
......@@ -26,7 +26,7 @@
}
.buttons{
margin-top: 15px;
margin-top: 11px;
.close{
text-align: right;
}
......
......@@ -3,54 +3,6 @@ $barHeight: 56px;
$drowBgColor: #f2f2f2;
/* drowdown and select hover bgcolor */
$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 */
.fresh{
......@@ -63,20 +15,25 @@ $drowHoverBgColor: #e2e2e2;
color: #fff;
}
.link li{
float: left;
}
.dropdown{
margin-right: 10px;
/* make dropdown content box position in blue bar bottom */
padding-bottom: 14px;
.down-icon{
font-size: 20px !important;
padding-right: 2px;
}
}
.interval{
position: fixed;
right: 6%;
top: 12px;
display: inline-block;
font-size: 16px;
color: #fff;
.ant-form{
display: inline-block;
}
form .ant-select{
width: 166px;
}
.ant-select-selection{
background-color: transparent;
border: none;
......@@ -87,10 +44,19 @@ $drowHoverBgColor: #e2e2e2;
.ant-select-arrow{
color: #fff;
}
.fresh{
margin-right: 10px;
}
.ant-btn-ghost{
padding: 0 10px;
}
.ant-btn-ghost[disabled]{
background-color: transparent;
background-color: #005b98;
color: #fff;
}
}
/* set select bgcolor */
.ant-select-dropdown-menu{
......@@ -126,26 +92,141 @@ $drowHoverBgColor: #e2e2e2;
}
}
.menu-list{
position: relative;
top: 13px;
}
/* nav style*/
.little{
width: 90%;
.menu{
margin-left: 33px;
.more{
.ant-dropdown{
.menuModal{
position: relative;
top: 12px;
}
}
.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;
font-size: 24px;
margin-top: 16px;
text-decoration: none;
}
.more-mobile{
margin-right: 10%;
font-size: 22px;
position: relative;
top: 1px;
}
.more:hover{
.more-mobile:hover{
cursor: pointer;
}
}
.logo{
.center{
text-align: center;
img{
height: 38px;
}
}
.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{
width: 198px;
/* public style in nav in threee mode*/
.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
import time
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
def run():
def naive_test():
'''run naive integration test'''
to_remove = ['tuner_search_space.json', 'tuner_result.txt', 'assessor_result.txt']
to_remove = list(map(lambda file: 'naive_test/' + file, to_remove))
......@@ -38,7 +38,7 @@ def run():
print('Spawning trials...')
nnimanager_log_path = fetch_nni_log_path(EXPERIMENT_URL)
nnimanager_log_path = get_nni_log_path(EXPERIMENT_URL)
current_trial = 0
for _ in range(120):
......@@ -79,11 +79,36 @@ def run():
expected = set(open('naive_test/expected_assessor_result.txt'))
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__':
installed = (sys.argv[-1] != '--preinstall')
setup_experiment(installed)
try:
run()
naive_test()
stop_experiment_test()
# TODO: check the output of rest server
print(GREEN + 'PASS' + CLEAR)
except Exception as error:
......@@ -91,5 +116,3 @@ if __name__ == '__main__':
print('%r' % error)
traceback.print_exc()
sys.exit(1)
finally:
subprocess.run(['nnictl', 'stop'])
......@@ -23,15 +23,11 @@ import sys
import time
import traceback
from utils import get_yml_content, dump_yml_content, setup_experiment, fetch_nni_log_path, is_experiment_done
GREEN = '\33[32m'
RED = '\33[31m'
CLEAR = '\33[0m'
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
TUNER_LIST = ['GridSearch', 'BatchTuner', 'TPE', 'Random', 'Anneal', 'Evolution']
ASSESSOR_LIST = ['Medianstop']
EXPERIMENT_URL = 'http://localhost:8080/api/v1/nni/experiment'
def switch(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'])
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):
time.sleep(3)
......
......@@ -22,9 +22,11 @@ import contextlib
import collections
import json
import os
import socket
import sys
import subprocess
import requests
import time
import ruamel.yaml as yaml
EXPERIMENT_DONE_SIGNAL = '"Experiment done"'
......@@ -76,10 +78,13 @@ def setup_experiment(installed=True):
pypath = ':'.join([sdk_path, cmd_path])
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'''
experiment_profile = requests.get(experiment_url)
experiment_id = json.loads(experiment_profile.text)['id']
experiment_id = get_experiment_id(experiment_url)
experiment_path = os.path.join(os.path.expanduser('~'), 'nni', 'experiments', experiment_id)
nnimanager_log_path = os.path.join(experiment_path, 'log', 'nnimanager.log')
......@@ -98,7 +103,6 @@ def is_experiment_done(nnimanager_log_path):
def get_experiment_status(status_url):
nni_status = requests.get(status_url).json()
#print(nni_status)
return nni_status['status']
def get_succeeded_trial_num(trial_jobs_url):
......@@ -139,3 +143,17 @@ def deep_update(source, overrides):
else:
source[key] = overrides[key]
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 = {
'optimize_mode': setChoice('optimize_mode', 'maximize', 'minimize'),
Optional('population_size'): setNumberRange('population_size', int, 0, 99999),
},
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
},
('BatchTuner', 'GridSearch', 'Random'): {
'builtinTunerName': setChoice('builtinTunerName', 'BatchTuner', 'GridSearch', 'Random'),
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
},
'NetworkMorphism': {
......@@ -99,6 +101,7 @@ tuner_schema_dict = {
Optional('input_channel'): setType('input_channel', int),
Optional('n_output_node'): setType('n_output_node', int),
},
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
},
'MetisTuner': {
......@@ -110,6 +113,7 @@ tuner_schema_dict = {
Optional('selection_num_starting_points'): setType('selection_num_starting_points', int),
Optional('cold_start_num'): setType('cold_start_num', int),
},
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
},
'GPTuner': {
......@@ -125,6 +129,7 @@ tuner_schema_dict = {
Optional('selection_num_warm_up'): setType('selection_num_warm_up', int),
Optional('selection_num_starting_points'): setType('selection_num_starting_points', int),
},
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
Optional('gpuNum'): setNumberRange('gpuNum', int, 0, 99999),
},
'customized': {
......@@ -132,6 +137,7 @@ tuner_schema_dict = {
'classFileName': setType('classFileName', str),
'className': setType('className', str),
Optional('classArgs'): dict,
Optional('includeIntermediateResults'): setType('includeIntermediateResults', bool),
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