Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
b63b283e
Unverified
Commit
b63b283e
authored
Jul 29, 2019
by
SparkSnail
Committed by
GitHub
Jul 29, 2019
Browse files
Merge pull request #194 from microsoft/master
merge master
parents
803b6e47
9d47087e
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
417 additions
and
196 deletions
+417
-196
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
+1
-1
src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py
src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py
+1
-1
src/webui/package.json
src/webui/package.json
+1
-1
src/webui/src/components/Modal/ExperimentDrawer.tsx
src/webui/src/components/Modal/ExperimentDrawer.tsx
+2
-2
src/webui/src/components/Modal/LogDrawer.tsx
src/webui/src/components/Modal/LogDrawer.tsx
+3
-3
src/webui/src/components/SlideBar.tsx
src/webui/src/components/SlideBar.tsx
+159
-91
src/webui/src/components/overview/Progress.tsx
src/webui/src/components/overview/Progress.tsx
+2
-4
src/webui/src/components/public-child/IntermediateVal.tsx
src/webui/src/components/public-child/IntermediateVal.tsx
+5
-3
src/webui/src/components/stateless-component/NNItabs.tsx
src/webui/src/components/stateless-component/NNItabs.tsx
+26
-0
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
+1
-0
src/webui/src/components/trial-detail/Para.tsx
src/webui/src/components/trial-detail/Para.tsx
+5
-2
src/webui/src/index.css
src/webui/src/index.css
+1
-2
src/webui/src/static/style/logDrawer.scss
src/webui/src/static/style/logDrawer.scss
+1
-1
src/webui/src/static/style/slideBar.scss
src/webui/src/static/style/slideBar.scss
+149
-68
test/naive_test.py
test/naive_test.py
+29
-6
test/tuner_test.py
test/tuner_test.py
+3
-7
test/utils.py
test/utils.py
+22
-4
tools/nni_cmd/config_schema.py
tools/nni_cmd/config_schema.py
+6
-0
No files found.
src/sdk/pynni/nni/bohb_advisor/bohb_advisor.py
View file @
b63b283e
...
...
@@ -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'
,
...
...
src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py
View file @
b63b283e
...
...
@@ -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'
,
...
...
src/webui/package.json
View file @
b63b283e
...
...
@@ -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"
...
...
src/webui/src/components/Modal/ExperimentDrawer.tsx
View file @
b63b283e
...
...
@@ -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
}
...
...
src/webui/src/components/Modal/LogDrawer.tsx
View file @
b63b283e
...
...
@@ -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
}
...
...
src/webui/src/components/SlideBar.tsx
View file @
b63b283e
...
...
@@ -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
src/webui/src/components/overview/Progress.tsx
View file @
b63b283e
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
>
);
...
...
src/webui/src/components/public-child/IntermediateVal.tsx
View file @
b63b283e
...
...
@@ -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)`
;
}
...
...
src/webui/src/components/stateless-component/NNItabs.tsx
0 → 100644
View file @
b63b283e
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
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
View file @
b63b283e
...
...
@@ -114,6 +114,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
scale
:
true
},
series
:
[{
symbolSize
:
6
,
...
...
src/webui/src/components/trial-detail/Para.tsx
View file @
b63b283e
...
...
@@ -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
);
});
}
...
...
src/webui/src/index.css
View file @
b63b283e
...
...
@@ -48,5 +48,4 @@ q:before, q:after {
table
{
border-collapse
:
collapse
;
border-spacing
:
0
;
}
}
\ No newline at end of file
src/webui/src/static/style/logDrawer.scss
View file @
b63b283e
...
...
@@ -26,7 +26,7 @@
}
.buttons
{
margin-top
:
1
5
px
;
margin-top
:
1
1
px
;
.close
{
text-align
:
right
;
}
...
...
src/webui/src/static/style/slideBar.scss
View file @
b63b283e
...
...
@@ -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
test/naive_test.py
View file @
b63b283e
...
...
@@ -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
=
f
et
ch
_nni_log_path
(
EXPERIMENT_URL
)
nnimanager_log_path
=
g
et_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'
])
test/tuner_test.py
View file @
b63b283e
...
...
@@ -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
=
f
et
ch
_nni_log_path
(
EXPERIMENT_URL
)
nnimanager_log_path
=
g
et_nni_log_path
(
EXPERIMENT_URL
)
for
_
in
range
(
20
):
time
.
sleep
(
3
)
...
...
test/utils.py
View file @
b63b283e
...
...
@@ -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
tools/nni_cmd/config_schema.py
View file @
b63b283e
...
...
@@ -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
),
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment