Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
40bae6e2
Unverified
Commit
40bae6e2
authored
May 26, 2019
by
SparkSnail
Committed by
GitHub
May 26, 2019
Browse files
Merge pull request #172 from microsoft/master
merge master
parents
c7ca4510
d8e1c4af
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
705 additions
and
296 deletions
+705
-296
src/webui/src/components/TrialsDetail.tsx
src/webui/src/components/TrialsDetail.tsx
+46
-26
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
+115
-72
src/webui/src/components/trial-detail/Duration.tsx
src/webui/src/components/trial-detail/Duration.tsx
+94
-16
src/webui/src/components/trial-detail/Intermeidate.tsx
src/webui/src/components/trial-detail/Intermeidate.tsx
+91
-37
src/webui/src/components/trial-detail/Para.tsx
src/webui/src/components/trial-detail/Para.tsx
+259
-122
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+5
-6
src/webui/src/static/function.ts
src/webui/src/static/function.ts
+13
-6
src/webui/src/static/interface.ts
src/webui/src/static/interface.ts
+1
-1
test/generate_ts_config.py
test/generate_ts_config.py
+3
-2
test/pipelines-it-local-windows.yml
test/pipelines-it-local-windows.yml
+1
-1
test/pipelines-it-pai-windows.yml
test/pipelines-it-pai-windows.yml
+65
-0
tools/nni_cmd/launcher.py
tools/nni_cmd/launcher.py
+12
-7
No files found.
src/webui/src/components/TrialsDetail.tsx
View file @
40bae6e2
...
...
@@ -27,6 +27,11 @@ interface TrialDetailState {
entriesInSelect
:
string
;
searchSpace
:
string
;
isMultiPhase
:
boolean
;
isTableLoading
:
boolean
;
whichGraph
:
string
;
hyperCounts
:
number
;
// user click the hyper-parameter counts
durationCounts
:
number
;
intermediateCounts
:
number
;
}
class
TrialsDetail
extends
React
.
Component
<
{},
TrialDetailState
>
{
...
...
@@ -70,9 +75,14 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
experimentLogCollection
:
false
,
entriesTable
:
20
,
entriesInSelect
:
'
20
'
,
isHasSearch
:
false
,
searchSpace
:
''
,
isMultiPhase
:
false
whichGraph
:
'
1
'
,
isHasSearch
:
false
,
isMultiPhase
:
false
,
isTableLoading
:
false
,
hyperCounts
:
0
,
durationCounts
:
0
,
intermediateCounts
:
0
};
}
...
...
@@ -85,6 +95,9 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
])
.
then
(
axios
.
spread
((
res
,
res1
)
=>
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
)
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isTableLoading
:
true
}));
}
const
trialJobs
=
res
.
data
;
const
metricSource
=
res1
.
data
;
const
trialTable
:
Array
<
TableObj
>
=
[];
...
...
@@ -175,6 +188,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
isTableLoading
:
false
,
tableListSource
:
trialTable
}));
}
...
...
@@ -239,26 +253,26 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
handleEntriesSelect
=
(
value
:
string
)
=>
{
switch
(
value
)
{
case
'
20
'
:
this
.
setState
(()
=>
({
entriesTable
:
20
}));
break
;
case
'
50
'
:
this
.
setState
(()
=>
({
entriesTable
:
50
}));
break
;
case
'
100
'
:
this
.
setState
(()
=>
({
entriesTable
:
100
}));
break
;
case
'
all
'
:
const
{
tableListSource
}
=
this
.
state
;
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
entriesInSelect
:
'
all
'
,
entriesTable
:
tableListSource
.
length
}));
}
break
;
default
:
// user select isn't 'all'
if
(
value
!==
'
all
'
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
entriesTable
:
parseInt
(
value
,
10
)
}))
;
}
}
else
{
const
{
tableListSource
}
=
this
.
state
;
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
entriesInSelect
:
'
all
'
,
entriesTable
:
tableListSource
.
length
}))
;
}
}
}
handleWhichTabs
=
(
activeKey
:
string
)
=>
{
// const which = JSON.parse(activeKey);
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
whichGraph
:
activeKey
}));
}
}
...
...
@@ -315,18 +329,21 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
const
{
tableListSource
,
searchResultSource
,
isHasSearch
,
isMultiPhase
,
entriesTable
,
experimentPlatform
,
searchSpace
,
experimentLogCollection
entriesTable
,
experimentPlatform
,
searchSpace
,
experimentLogCollection
,
whichGraph
,
isTableLoading
}
=
this
.
state
;
const
source
=
isHasSearch
?
searchResultSource
:
tableListSource
;
return
(
<
div
>
<
div
className
=
"trial"
id
=
"tabsty"
>
<
Tabs
type
=
"card"
>
<
Tabs
type
=
"card"
onChange
=
{
this
.
handleWhichTabs
}
>
{
/* <TabPane tab={this.titleOfacc} key="1" destroyInactiveTabPane={true}> */
}
<
TabPane
tab
=
{
this
.
titleOfacc
}
key
=
"1"
>
<
Row
className
=
"graph"
>
<
DefaultPoint
height
=
{
432
}
showSource
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
</
Row
>
</
TabPane
>
...
...
@@ -335,14 +352,16 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<
Para
dataSource
=
{
source
}
expSearchSpace
=
{
searchSpace
}
whichGraph
=
{
whichGraph
}
/>
</
Row
>
</
TabPane
>
<
TabPane
tab
=
{
this
.
titleOfDuration
}
key
=
"3"
>
<
Duration
source
=
{
source
}
/>
<
Duration
source
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
{
/* <Duration source={source} whichGraph={whichGraph} clickCounts={durationCounts} /> */
}
</
TabPane
>
<
TabPane
tab
=
{
this
.
titleOfIntermediate
}
key
=
"4"
>
<
Intermediate
source
=
{
source
}
/>
<
Intermediate
source
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
</
TabPane
>
</
Tabs
>
</
div
>
...
...
@@ -388,6 +407,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<
TableList
entries
=
{
entriesTable
}
tableSource
=
{
source
}
isTableLoading
=
{
isTableLoading
}
isMultiPhase
=
{
isMultiPhase
}
platform
=
{
experimentPlatform
}
updateList
=
{
this
.
getDetailSource
}
...
...
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
TableObj
,
DetailAccurPoint
,
TooltipForAccuracy
}
from
'
../../static/interface
'
;
require
(
'
echarts/lib/chart/scatter
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
...
@@ -8,11 +9,13 @@ require('echarts/lib/component/title');
interface
DefaultPointProps
{
showSource
:
Array
<
TableObj
>
;
height
:
number
;
whichGraph
:
string
;
}
interface
DefaultPointState
{
defaultSource
:
object
;
accNodata
:
string
;
succeedTrials
:
number
;
}
class
DefaultPoint
extends
React
.
Component
<
DefaultPointProps
,
DefaultPointState
>
{
...
...
@@ -22,91 +25,130 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
super
(
props
);
this
.
state
=
{
defaultSource
:
{},
accNodata
:
'
No data
'
accNodata
:
''
,
succeedTrials
:
10000000
};
}
defaultMetric
=
(
s
how
Source
:
Array
<
TableObj
>
)
=>
{
defaultMetric
=
(
s
ucceed
Source
:
Array
<
TableObj
>
)
=>
{
const
accSource
:
Array
<
DetailAccurPoint
>
=
[];
Object
.
keys
(
showSource
).
map
(
item
=>
{
const
temp
=
showSource
[
item
];
if
(
temp
.
status
===
'
SUCCEEDED
'
&&
temp
.
acc
!==
undefined
)
{
if
(
temp
.
acc
.
default
!==
undefined
)
{
const
searchSpace
=
temp
.
description
.
parameters
;
accSource
.
push
({
acc
:
temp
.
acc
.
default
,
index
:
temp
.
sequenceId
,
searchSpace
:
JSON
.
stringify
(
searchSpace
)
});
const
showSource
:
Array
<
TableObj
>
=
succeedSource
.
filter
(
filterByStatus
);
const
lengthOfSource
=
showSource
.
length
;
const
tooltipDefault
=
lengthOfSource
===
0
?
'
No data
'
:
''
;
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
succeedTrials
:
lengthOfSource
,
accNodata
:
tooltipDefault
}));
}
if
(
lengthOfSource
===
0
)
{
const
nullGraph
=
{
grid
:
{
left
:
'
8%
'
},
xAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
},
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
}
};
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
defaultSource
:
nullGraph
}));
}
});
const
resultList
:
Array
<
number
|
string
>
[]
=
[];
Object
.
keys
(
accSource
).
map
(
item
=>
{
const
items
=
accSource
[
item
];
let
temp
:
Array
<
number
|
string
>
;
temp
=
[
items
.
index
,
items
.
acc
,
JSON
.
parse
(
items
.
searchSpace
)];
resultList
.
push
(
temp
);
});
const
allAcuracy
=
{
grid
:
{
left
:
'
8%
'
},
tooltip
:
{
trigger
:
'
item
'
,
enterable
:
true
,
position
:
function
(
point
:
Array
<
number
>
,
data
:
TooltipForAccuracy
)
{
if
(
data
.
data
[
0
]
<
resultList
.
length
/
2
)
{
return
[
point
[
0
],
80
];
}
else
{
return
[
point
[
0
]
-
300
,
80
];
}
else
{
const
resultList
:
Array
<
number
|
string
>
[]
=
[];
Object
.
keys
(
showSource
).
map
(
item
=>
{
const
temp
=
showSource
[
item
];
if
(
temp
.
acc
!==
undefined
)
{
if
(
temp
.
acc
.
default
!==
undefined
)
{
const
searchSpace
=
temp
.
description
.
parameters
;
accSource
.
push
({
acc
:
temp
.
acc
.
default
,
index
:
temp
.
sequenceId
,
searchSpace
:
JSON
.
stringify
(
searchSpace
)
});
}
},
formatter
:
function
(
data
:
TooltipForAccuracy
)
{
const
result
=
'
<div class="tooldetailAccuracy">
'
+
'
<div>Trial No.:
'
+
data
.
data
[
0
]
+
'
</div>
'
+
'
<div>Default metric:
'
+
data
.
data
[
1
]
+
'
</div>
'
+
'
<div>Parameters:
'
+
'
<pre>
'
+
JSON
.
stringify
(
data
.
data
[
2
],
null
,
4
)
+
'
</pre>
'
+
'
</div>
'
+
'
</div>
'
;
return
result
;
}
},
xAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
},
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
},
series
:
[{
symbolSize
:
6
,
type
:
'
scatter
'
,
data
:
resultList
}]
};
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
({
defaultSource
:
allAcuracy
},
()
=>
{
if
(
resultList
.
length
===
0
)
{
this
.
setState
({
accNodata
:
'
No data
'
});
}
else
{
this
.
setState
({
accNodata
:
''
});
}
});
Object
.
keys
(
accSource
).
map
(
item
=>
{
const
items
=
accSource
[
item
];
let
temp
:
Array
<
number
|
string
>
;
temp
=
[
items
.
index
,
items
.
acc
,
JSON
.
parse
(
items
.
searchSpace
)];
resultList
.
push
(
temp
);
});
const
allAcuracy
=
{
grid
:
{
left
:
'
8%
'
},
tooltip
:
{
trigger
:
'
item
'
,
enterable
:
true
,
position
:
function
(
point
:
Array
<
number
>
,
data
:
TooltipForAccuracy
)
{
if
(
data
.
data
[
0
]
<
resultList
.
length
/
2
)
{
return
[
point
[
0
],
80
];
}
else
{
return
[
point
[
0
]
-
300
,
80
];
}
},
formatter
:
function
(
data
:
TooltipForAccuracy
)
{
const
result
=
'
<div class="tooldetailAccuracy">
'
+
'
<div>Trial No.:
'
+
data
.
data
[
0
]
+
'
</div>
'
+
'
<div>Default metric:
'
+
data
.
data
[
1
]
+
'
</div>
'
+
'
<div>Parameters:
'
+
'
<pre>
'
+
JSON
.
stringify
(
data
.
data
[
2
],
null
,
4
)
+
'
</pre>
'
+
'
</div>
'
+
'
</div>
'
;
return
result
;
}
},
xAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
},
yAxis
:
{
name
:
'
Default metric
'
,
type
:
'
value
'
,
},
series
:
[{
symbolSize
:
6
,
type
:
'
scatter
'
,
data
:
resultList
}]
};
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
defaultSource
:
allAcuracy
}));
}
}
}
// update parent component state
componentWillReceiveProps
(
nextProps
:
DefaultPointProps
)
{
const
showSource
=
nextProps
.
showSource
;
this
.
defaultMetric
(
showSource
);
const
{
whichGraph
,
showSource
}
=
nextProps
;
if
(
whichGraph
===
'
1
'
)
{
this
.
defaultMetric
(
showSource
);
}
}
shouldComponentUpdate
(
nextProps
:
DefaultPointProps
,
nextState
:
DefaultPointState
)
{
const
{
whichGraph
}
=
nextProps
;
const
succTrial
=
this
.
state
.
succeedTrials
;
const
{
succeedTrials
}
=
nextState
;
if
(
whichGraph
===
'
1
'
)
{
if
(
succeedTrials
!==
succTrial
)
{
return
true
;
}
}
// only whichGraph !== '1', default metric can't update
return
false
;
}
componentDidMount
()
{
...
...
@@ -116,7 +158,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
height
}
=
this
.
props
;
const
{
defaultSource
,
accNodata
}
=
this
.
state
;
...
...
@@ -131,6 +173,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}
}
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
// lazyUpdate={true}
/>
<
div
className
=
"showMess"
>
{
accNodata
}
</
div
>
</
div
>
...
...
src/webui/src/components/trial-detail/Duration.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
TableObj
}
from
'
src/static/interface
'
;
import
{
filterDuration
}
from
'
src/static/function
'
;
require
(
'
echarts/lib/chart/bar
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/title
'
);
...
...
@@ -12,6 +13,7 @@ interface Runtrial {
interface
DurationProps
{
source
:
Array
<
TableObj
>
;
whichGraph
:
string
;
}
interface
DurationState
{
...
...
@@ -26,13 +28,64 @@ class Duration extends React.Component<DurationProps, DurationState> {
super
(
props
);
this
.
state
=
{
durationSource
:
{}
durationSource
:
this
.
initDuration
(
this
.
props
.
source
),
};
}
initDuration
=
(
source
:
Array
<
TableObj
>
)
=>
{
const
trialId
:
Array
<
string
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialJobs
=
source
.
filter
(
filterDuration
);
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
const
temp
=
trialJobs
[
item
];
trialId
.
push
(
temp
.
sequenceId
);
trialTime
.
push
(
temp
.
duration
);
});
return
{
tooltip
:
{
trigger
:
'
axis
'
,
axisPointer
:
{
type
:
'
shadow
'
}
},
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
:
trialId
},
series
:
[{
type
:
'
bar
'
,
data
:
trialTime
}]
};
}
getOption
=
(
dataObj
:
Runtrial
)
=>
{
return
{
return
{
tooltip
:
{
trigger
:
'
axis
'
,
axisPointer
:
{
...
...
@@ -45,7 +98,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
left
:
'
1%
'
,
right
:
'
4%
'
},
dataZoom
:
[{
type
:
'
slider
'
,
name
:
'
trial
'
,
...
...
@@ -74,17 +127,16 @@ class Duration extends React.Component<DurationProps, DurationState> {
};
}
drawDurationGraph
=
(
trialJobs
:
Array
<
TableObj
>
)
=>
{
drawDurationGraph
=
(
source
:
Array
<
TableObj
>
)
=>
{
// why this function run two times when props changed?
const
trialId
:
Array
<
string
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
const
trialJobs
=
source
.
filter
(
filterDuration
);
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
const
temp
=
trialJobs
[
item
];
if
(
temp
.
status
!==
'
WAITING
'
)
{
trialId
.
push
(
temp
.
sequenceId
);
trialTime
.
push
(
temp
.
duration
);
}
trialId
.
push
(
temp
.
sequenceId
);
trialTime
.
push
(
temp
.
duration
);
});
trialRun
.
push
({
trialId
:
trialId
,
...
...
@@ -97,18 +149,43 @@ class Duration extends React.Component<DurationProps, DurationState> {
}
}
componentWillReceiveProps
(
nextProps
:
DurationProps
)
{
const
trialJobs
=
nextProps
.
source
;
this
.
drawDurationGraph
(
trialJobs
);
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
// init: user don't search
const
{
source
}
=
this
.
props
;
const
{
source
}
=
this
.
props
;
this
.
drawDurationGraph
(
source
);
}
componentWillReceiveProps
(
nextProps
:
DurationProps
)
{
const
{
whichGraph
,
source
}
=
nextProps
;
if
(
whichGraph
===
'
3
'
)
{
this
.
drawDurationGraph
(
source
);
}
}
shouldComponentUpdate
(
nextProps
:
DurationProps
,
nextState
:
DurationState
)
{
const
{
whichGraph
,
source
}
=
nextProps
;
if
(
whichGraph
===
'
3
'
)
{
const
beforeSource
=
this
.
props
.
source
;
if
(
whichGraph
!==
this
.
props
.
whichGraph
)
{
return
true
;
}
if
(
source
.
length
!==
beforeSource
.
length
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
duration
!==
beforeSource
[
beforeSource
.
length
-
1
].
duration
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
status
!==
beforeSource
[
beforeSource
.
length
-
1
].
status
)
{
return
true
;
}
}
return
false
;
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
...
...
@@ -121,6 +198,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
option
=
{
durationSource
}
style
=
{
{
width
:
'
95%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
/>
</
div
>
);
...
...
src/webui/src/components/trial-detail/Intermeidate.tsx
View file @
40bae6e2
...
...
@@ -11,16 +11,21 @@ interface Intermedia {
data
:
Array
<
number
|
object
>
;
// intermediate data
hyperPara
:
object
;
// each trial hyperpara value
}
interface
IntermediateState
{
detailSource
:
Array
<
TableObj
>
;
interSource
:
object
;
filterSource
:
Array
<
TableObj
>
;
eachIntermediateNum
:
number
;
// trial's intermediate number count
isLoadconfirmBtn
:
boolean
;
isFilter
:
boolean
;
length
:
number
;
clickCounts
:
number
;
// user filter intermediate click confirm btn's counts
}
interface
IntermediateProps
{
source
:
Array
<
TableObj
>
;
whichGraph
:
string
;
}
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
...
...
@@ -34,39 +39,25 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
constructor
(
props
:
IntermediateProps
)
{
super
(
props
);
this
.
state
=
{
detailSource
:
[],
interSource
:
{},
filterSource
:
[],
eachIntermediateNum
:
1
,
isLoadconfirmBtn
:
false
,
isFilter
:
false
};
}
initMediate
=
()
=>
{
const
option
=
{
grid
:
{
left
:
'
5%
'
,
top
:
40
,
containLabel
:
true
},
xAxis
:
{
type
:
'
category
'
,
boundaryGap
:
false
,
},
yAxis
:
{
type
:
'
value
'
,
name
:
'
Scape
'
}
isFilter
:
false
,
length
:
100000
,
clickCounts
:
0
};
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
interSource
:
option
}));
}
}
drawIntermediate
=
(
source
:
Array
<
TableObj
>
)
=>
{
if
(
source
.
length
>
0
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
length
:
source
.
length
,
detailSource
:
source
}));
}
const
trialIntermediate
:
Array
<
Intermedia
>
=
[];
Object
.
keys
(
source
).
map
(
item
=>
{
const
temp
=
source
[
item
];
...
...
@@ -140,7 +131,24 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
}));
}
}
else
{
this
.
initMediate
();
const
nullData
=
{
grid
:
{
left
:
'
5%
'
,
top
:
40
,
containLabel
:
true
},
xAxis
:
{
type
:
'
category
'
,
boundaryGap
:
false
,
},
yAxis
:
{
type
:
'
value
'
,
name
:
'
Scape
'
}
};
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
interSource
:
nullData
}));
}
}
}
...
...
@@ -183,8 +191,9 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this
.
setState
({
filterSource
:
filterSource
});
}
this
.
drawIntermediate
(
filterSource
);
const
counts
=
this
.
state
.
clickCounts
+
1
;
this
.
setState
({
isLoadconfirmBtn
:
false
,
clickCounts
:
counts
});
}
this
.
setState
({
isLoadconfirmBtn
:
false
});
});
}
}
...
...
@@ -204,28 +213,73 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this
.
drawIntermediate
(
source
);
}
componentWillReceiveProps
(
nextProps
:
IntermediateProps
)
{
const
{
isFilter
,
filterSource
}
=
this
.
state
;
if
(
isFilter
===
true
)
{
const
pointVal
=
this
.
pointInput
!==
null
?
this
.
pointInput
.
value
:
''
;
const
minVal
=
this
.
minValInput
!==
null
?
this
.
minValInput
.
value
:
''
;
if
(
pointVal
===
''
&&
minVal
===
''
)
{
this
.
drawIntermediate
(
nextProps
.
source
);
componentWillReceiveProps
(
nextProps
:
IntermediateProps
,
nextState
:
IntermediateState
)
{
const
{
isFilter
,
filterSource
}
=
nextState
;
const
{
whichGraph
,
source
}
=
nextProps
;
if
(
whichGraph
===
'
4
'
)
{
if
(
isFilter
===
true
)
{
const
pointVal
=
this
.
pointInput
!==
null
?
this
.
pointInput
.
value
:
''
;
const
minVal
=
this
.
minValInput
!==
null
?
this
.
minValInput
.
value
:
''
;
if
(
pointVal
===
''
&&
minVal
===
''
)
{
this
.
drawIntermediate
(
source
);
}
else
{
this
.
drawIntermediate
(
filterSource
);
}
}
else
{
this
.
drawIntermediate
(
filterS
ource
);
this
.
drawIntermediate
(
s
ource
);
}
}
else
{
this
.
drawIntermediate
(
nextProps
.
source
);
}
}
shouldComponentUpdate
(
nextProps
:
IntermediateProps
,
nextState
:
IntermediateState
)
{
const
{
whichGraph
}
=
nextProps
;
const
beforeGraph
=
this
.
props
.
whichGraph
;
if
(
whichGraph
===
'
4
'
)
{
const
{
source
}
=
nextProps
;
const
{
isFilter
,
length
,
clickCounts
}
=
nextState
;
const
beforeLength
=
this
.
state
.
length
;
const
beforeSource
=
this
.
state
.
detailSource
;
const
beforeClickCounts
=
this
.
state
.
clickCounts
;
if
(
isFilter
!==
this
.
state
.
isFilter
)
{
return
true
;
}
if
(
clickCounts
!==
beforeClickCounts
)
{
return
true
;
}
if
(
isFilter
===
false
)
{
if
(
whichGraph
!==
beforeGraph
)
{
return
true
;
}
if
(
length
!==
beforeLength
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
description
.
intermediate
.
length
!==
beforeSource
[
beforeSource
.
length
-
1
].
description
.
intermediate
.
length
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
duration
!==
beforeSource
[
beforeSource
.
length
-
1
].
duration
)
{
return
true
;
}
if
(
source
[
source
.
length
-
1
].
status
!==
beforeSource
[
beforeSource
.
length
-
1
].
status
)
{
return
true
;
}
}
}
return
false
;
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
return
(
<
div
>
{
/* style in para.scss */
}
...
...
src/webui/src/components/trial-detail/Para.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
Row
,
Col
,
Select
,
Button
,
message
}
from
'
antd
'
;
import
{
ParaObj
,
Dimobj
,
TableObj
,
SearchSpace
}
from
'
../../static/interface
'
;
import
{
ParaObj
,
Dimobj
,
TableObj
}
from
'
../../static/interface
'
;
const
Option
=
Select
.
Option
;
require
(
'
echarts/lib/chart/parallel
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
...
@@ -11,6 +12,7 @@ require('../../static/style/para.scss');
require
(
'
../../static/style/button.scss
'
);
interface
ParaState
{
// paraSource: Array<TableObj>;
option
:
object
;
paraBack
:
ParaObj
;
dimName
:
Array
<
string
>
;
...
...
@@ -19,11 +21,15 @@ interface ParaState {
paraNodata
:
string
;
max
:
number
;
// graph color bar limit
min
:
number
;
sutrialCount
:
number
;
// succeed trial numbers for SUC
clickCounts
:
number
;
isLoadConfirm
:
boolean
;
}
interface
ParaProps
{
dataSource
:
Array
<
TableObj
>
;
expSearchSpace
:
string
;
whichGraph
:
string
;
}
message
.
config
({
...
...
@@ -45,6 +51,8 @@ class Para extends React.Component<ParaProps, ParaState> {
constructor
(
props
:
ParaProps
)
{
super
(
props
);
this
.
state
=
{
// paraSource: [],
// option: this.hyperParaPic,
option
:
{},
dimName
:
[],
paraBack
:
{
...
...
@@ -58,98 +66,20 @@ class Para extends React.Component<ParaProps, ParaState> {
percent
:
0
,
paraNodata
:
''
,
min
:
0
,
max
:
1
max
:
1
,
sutrialCount
:
10000000
,
clickCounts
:
1
,
isLoadConfirm
:
false
};
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
reInit
();
}
getParallelAxis
=
(
dimName
:
Array
<
string
>
,
searchRange
:
SearchSpace
,
accPara
:
Array
<
number
>
,
eachTrialParams
:
Array
<
string
>
,
paraYdata
:
number
[][]
dimName
:
Array
<
string
>
,
parallelAxis
:
Array
<
Dimobj
>
,
accPara
:
Array
<
number
>
,
eachTrialParams
:
Array
<
string
>
)
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
dimName
:
dimName
}));
}
const
parallelAxis
:
Array
<
Dimobj
>
=
[];
// search space range and specific value [only number]
for
(
let
i
=
0
;
i
<
dimName
.
length
;
i
++
)
{
const
searchKey
=
searchRange
[
dimName
[
i
]];
switch
(
searchKey
.
_type
)
{
case
'
uniform
'
:
case
'
quniform
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
max
:
searchKey
.
_value
[
1
],
min
:
searchKey
.
_value
[
0
]
});
break
;
case
'
randint
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
max
:
searchKey
.
_value
[
0
]
-
1
,
min
:
0
});
break
;
case
'
choice
'
:
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
,
boundaryGap
:
true
,
axisLine
:
{
lineStyle
:
{
type
:
'
dotted
'
,
// axis type,solid,dashed,dotted
width
:
1
}
},
axisTick
:
{
show
:
true
,
interval
:
0
,
alignWithLabel
:
true
,
},
axisLabel
:
{
show
:
true
,
interval
:
0
,
// rotate: 30
},
});
break
;
// support log distribute
case
'
loguniform
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
type
:
'
log
'
,
});
break
;
default
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
]
});
}
}
// get data for every lines. if dim is choice type, number -> toString()
const
paraYdata
:
number
[][]
=
[];
Object
.
keys
(
eachTrialParams
).
map
(
item
=>
{
let
temp
:
Array
<
number
>
=
[];
for
(
let
i
=
0
;
i
<
dimName
.
length
;
i
++
)
{
...
...
@@ -169,7 +99,7 @@ class Para extends React.Component<ParaProps, ParaState> {
Object
.
keys
(
paraYdata
).
map
(
item
=>
{
paraYdata
[
item
].
push
(
accPara
[
item
]);
});
// according acc to sort ydata
// according acc to sort ydata
// sort to find top percent dataset
if
(
paraYdata
.
length
!==
0
)
{
const
len
=
paraYdata
[
0
].
length
-
1
;
paraYdata
.
sort
((
a
,
b
)
=>
b
[
len
]
-
a
[
len
]);
...
...
@@ -191,28 +121,153 @@ class Para extends React.Component<ParaProps, ParaState> {
this
.
swapGraph
(
paraData
,
swapAxisArr
);
}
this
.
getOption
(
paraData
);
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
paraBack
:
paraData
}));
}
}
hyperParaPic
=
(
dataSource
:
Array
<
TableObj
>
,
searchSpace
:
string
)
=>
{
hyperParaPic
=
(
source
:
Array
<
TableObj
>
,
searchSpace
:
string
)
=>
{
// filter succeed trials [{}, {}, {}]
const
dataSource
:
Array
<
TableObj
>
=
source
.
filter
(
filterByStatus
);
const
lenOfDataSource
:
number
=
dataSource
.
length
;
const
accPara
:
Array
<
number
>
=
[];
// specific value array
const
eachTrialParams
:
Array
<
string
>
=
[];
const
paraYdata
:
number
[][]
=
[];
// experiment interface search space obj
const
searchRange
=
JSON
.
parse
(
searchSpace
);
const
searchRange
=
searchSpace
!==
undefined
?
JSON
.
parse
(
searchSpace
)
:
''
;
const
dimName
=
Object
.
keys
(
searchRange
);
// trial-jobs interface list
Object
.
keys
(
dataSource
).
map
(
item
=>
{
const
temp
=
dataSource
[
item
];
if
(
temp
.
status
===
'
SUCCEEDED
'
)
{
accPara
.
push
(
temp
.
acc
.
default
);
eachTrialParams
.
push
(
temp
.
description
.
parameters
);
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
dimName
:
dimName
}));
}
const
parallelAxis
:
Array
<
Dimobj
>
=
[];
// search space range and specific value [only number]
for
(
let
i
=
0
;
i
<
dimName
.
length
;
i
++
)
{
const
searchKey
=
searchRange
[
dimName
[
i
]];
switch
(
searchKey
.
_type
)
{
case
'
uniform
'
:
case
'
quniform
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
max
:
searchKey
.
_value
[
1
],
min
:
searchKey
.
_value
[
0
]
});
break
;
case
'
randint
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
max
:
searchKey
.
_value
[
0
]
-
1
,
min
:
0
});
break
;
case
'
choice
'
:
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
,
boundaryGap
:
true
,
axisLine
:
{
lineStyle
:
{
type
:
'
dotted
'
,
// axis type,solid,dashed,dotted
width
:
1
}
},
axisTick
:
{
show
:
true
,
interval
:
0
,
alignWithLabel
:
true
,
},
axisLabel
:
{
show
:
true
,
interval
:
0
,
// rotate: 30
},
});
break
;
// support log distribute
case
'
loguniform
'
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
],
type
:
'
log
'
,
});
break
;
default
:
parallelAxis
.
push
({
dim
:
i
,
name
:
dimName
[
i
]
});
}
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
max
:
Math
.
max
(...
accPara
),
min
:
Math
.
min
(...
accPara
)
},
()
=>
{
this
.
getParallelAxis
(
dimName
,
searchRange
,
accPara
,
eachTrialParams
,
paraYdata
);
}
if
(
lenOfDataSource
===
0
)
{
const
optionOfNull
=
{
parallelAxis
,
tooltip
:
{
trigger
:
'
item
'
},
parallel
:
{
parallelAxisDefault
:
{
tooltip
:
{
show
:
true
},
axisLabel
:
{
formatter
:
function
(
value
:
string
)
{
const
length
=
value
.
length
;
if
(
length
>
16
)
{
const
temp
=
value
.
split
(
''
);
for
(
let
i
=
16
;
i
<
temp
.
length
;
i
+=
17
)
{
temp
[
i
]
+=
'
\n
'
;
}
return
temp
.
join
(
''
);
}
else
{
return
value
;
}
}
},
}
},
visualMap
:
{
type
:
'
continuous
'
,
min
:
0
,
max
:
1
,
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
]
}
};
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
({
paraNodata
:
'
No data
'
,
option
:
optionOfNull
,
sutrialCount
:
0
});
}
}
else
{
Object
.
keys
(
dataSource
).
map
(
item
=>
{
const
temp
=
dataSource
[
item
];
eachTrialParams
.
push
(
temp
.
description
.
parameters
);
// may be a succeed trial hasn't final result
// all detail page may be break down if havn't if
if
(
temp
.
acc
!==
undefined
)
{
if
(
temp
.
acc
.
default
!==
undefined
)
{
accPara
.
push
(
temp
.
acc
.
default
);
}
}
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
max
:
Math
.
max
(...
accPara
),
min
:
Math
.
min
(...
accPara
)
},
()
=>
{
this
.
getParallelAxis
(
dimName
,
parallelAxis
,
accPara
,
eachTrialParams
);
});
}
}
}
...
...
@@ -229,9 +284,10 @@ class Para extends React.Component<ParaProps, ParaState> {
// deal with response data into pic data
getOption
=
(
dataObj
:
ParaObj
)
=>
{
// dataObj [[y1], [y2]... [default metric]]
const
{
max
,
min
}
=
this
.
state
;
le
t
parallelAxis
=
dataObj
.
parallelAxis
;
le
t
paralleData
=
dataObj
.
data
;
cons
t
parallelAxis
=
dataObj
.
parallelAxis
;
cons
t
paralleData
=
dataObj
.
data
;
let
visualMapObj
=
{};
if
(
max
===
min
)
{
visualMapObj
=
{
...
...
@@ -251,7 +307,7 @@ class Para extends React.Component<ParaProps, ParaState> {
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
]
};
}
le
t
optionown
=
{
cons
t
optionown
=
{
parallelAxis
,
tooltip
:
{
trigger
:
'
item
'
...
...
@@ -288,21 +344,11 @@ class Para extends React.Component<ParaProps, ParaState> {
}
};
// please wait the data
if
(
this
.
_isMounted
)
{
if
(
paralleData
.
length
===
0
)
{
this
.
setState
({
paraNodata
:
'
No data
'
});
}
else
{
this
.
setState
({
paraNodata
:
''
});
}
}
// draw search space graph
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
option
:
optionown
option
:
optionown
,
paraNodata
:
''
,
sutrialCount
:
paralleData
.
length
}));
}
}
...
...
@@ -320,6 +366,68 @@ class Para extends React.Component<ParaProps, ParaState> {
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
}
swapReInit
=
()
=>
{
const
{
clickCounts
}
=
this
.
state
;
const
val
=
clickCounts
+
1
;
if
(
this
.
_isMounted
)
{
this
.
setState
({
isLoadConfirm
:
true
,
clickCounts
:
val
,
});
}
const
{
paraBack
,
swapAxisArr
}
=
this
.
state
;
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
===
swapAxisArr
[
0
])
{
paralDim
[
item
].
dim
=
dim2
;
}
if
(
paralDim
[
item
].
name
===
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
;
});
this
.
getOption
(
paraBack
);
// please wait the data
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
isLoadConfirm
:
false
}));
}
}
sortDimY
=
(
a
:
Dimobj
,
b
:
Dimobj
)
=>
{
return
a
.
dim
-
b
.
dim
;
}
...
...
@@ -374,11 +482,39 @@ class Para extends React.Component<ParaProps, ParaState> {
});
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
reInit
();
}
componentWillReceiveProps
(
nextProps
:
ParaProps
)
{
const
dataSource
=
nextProps
.
dataSource
;
const
expSearchSpace
=
nextProps
.
expSearchSpace
;
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
const
{
dataSource
,
expSearchSpace
,
whichGraph
}
=
nextProps
;
if
(
whichGraph
===
'
2
'
)
{
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
}
}
shouldComponentUpdate
(
nextProps
:
ParaProps
,
nextState
:
ParaState
)
{
const
{
whichGraph
}
=
nextProps
;
const
beforeGraph
=
this
.
props
.
whichGraph
;
if
(
whichGraph
===
'
2
'
)
{
if
(
whichGraph
!==
beforeGraph
)
{
return
true
;
}
const
{
sutrialCount
,
clickCounts
}
=
nextState
;
const
beforeCount
=
this
.
state
.
sutrialCount
;
const
beforeClickCount
=
this
.
state
.
clickCounts
;
if
(
sutrialCount
!==
beforeCount
)
{
return
true
;
}
if
(
clickCounts
!==
beforeClickCount
)
{
return
true
;
}
}
return
false
;
}
componentWillUnmount
()
{
...
...
@@ -386,7 +522,7 @@ class Para extends React.Component<ParaProps, ParaState> {
}
render
()
{
const
{
option
,
paraNodata
,
dimName
}
=
this
.
state
;
const
{
option
,
paraNodata
,
dimName
,
isLoadConfirm
}
=
this
.
state
;
return
(
<
Row
className
=
"parameter"
>
<
Row
>
...
...
@@ -423,7 +559,8 @@ class Para extends React.Component<ParaProps, ParaState> {
<
Button
type
=
"primary"
className
=
"changeBtu tableButton"
onClick
=
{
this
.
reInit
}
onClick
=
{
this
.
swapReInit
}
disabled
=
{
isLoadConfirm
}
>
Confirm
</
Button
>
...
...
@@ -434,7 +571,7 @@ class Para extends React.Component<ParaProps, ParaState> {
<
ReactEcharts
option
=
{
option
}
style
=
{
this
.
chartMulineStyle
}
lazyUpdate
=
{
true
}
//
lazyUpdate={true}
notMerge
=
{
true
}
// update now
/>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
}
from
'
antd
'
;
import
{
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
}
from
'
antd
'
;
const
CheckboxGroup
=
Checkbox
.
Group
;
import
{
MANAGER_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
convertDuration
,
intermediateGraphOption
,
killJob
}
from
'
../../static/function
'
;
import
{
TableObj
,
TrialJob
}
from
'
../../static/interface
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
// import DefaultMetric from '../public-child/DefaultMetrc';
import
IntermediateVal
from
'
../public-child/IntermediateVal
'
;
import
IntermediateVal
from
'
../public-child/IntermediateVal
'
;
// table default metric column
import
'
../../static/style/search.scss
'
;
require
(
'
../../static/style/tableStatus.css
'
);
require
(
'
../../static/style/logPath.scss
'
);
...
...
@@ -33,6 +30,7 @@ interface TableListProps {
platform
:
string
;
logCollection
:
boolean
;
isMultiPhase
:
boolean
;
isTableLoading
:
boolean
;
}
interface
TableListState
{
...
...
@@ -197,7 +195,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
render
()
{
const
{
entries
,
tableSource
,
updateList
}
=
this
.
props
;
const
{
entries
,
tableSource
,
updateList
,
isTableLoading
}
=
this
.
props
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
}
=
this
.
state
;
let
showTitle
=
COLUMN
;
let
bgColor
=
''
;
...
...
@@ -420,6 +418,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
dataSource
=
{
tableSource
}
className
=
"commonTableStyle"
pagination
=
{
{
pageSize
:
entries
}
}
loading
=
{
isTableLoading
}
/>
{
/* Intermediate Result Modal */
}
<
Modal
...
...
src/webui/src/static/function.ts
View file @
40bae6e2
import
axios
from
'
axios
'
;
import
{
message
}
from
'
antd
'
;
import
{
message
}
from
'
antd
'
;
import
{
MANAGER_IP
}
from
'
./const
'
;
import
{
FinalResult
,
FinalType
}
from
'
./interface
'
;
import
{
FinalResult
,
FinalType
,
TableObj
}
from
'
./interface
'
;
const
convertTime
=
(
num
:
number
)
=>
{
if
(
num
%
3600
===
0
)
{
...
...
@@ -131,7 +129,16 @@ const killJob = (key: number, id: string, status: string, updateList: Function)
});
};
const
filterByStatus
=
(
item
:
TableObj
)
=>
{
return
item
.
status
===
'
SUCCEEDED
'
;
};
// a waittiong trial may havn't start time
const
filterDuration
=
(
item
:
TableObj
)
=>
{
return
item
.
status
!==
'
WAITING
'
;
};
export
{
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
intermediateGraphOption
,
killJob
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
intermediateGraphOption
,
killJob
,
filterByStatus
,
filterDuration
};
src/webui/src/static/interface.ts
View file @
40bae6e2
...
...
@@ -26,7 +26,7 @@ interface ErrorParameter {
interface
Parameters
{
parameters
:
ErrorParameter
;
logPath
?:
string
;
intermediate
?
:
Array
<
number
>
;
intermediate
:
Array
<
number
>
;
}
interface
Experiment
{
...
...
test/generate_ts_config.py
View file @
40bae6e2
...
...
@@ -86,7 +86,7 @@ def convert_command():
if
__name__
==
'__main__'
:
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
"--ts"
,
type
=
str
,
choices
=
[
'pai'
,
'kubeflow'
,
'remote'
],
default
=
'pai'
)
parser
.
add_argument
(
"--ts"
,
type
=
str
,
choices
=
[
'pai'
,
'kubeflow'
,
'remote'
,
'local'
],
default
=
'pai'
)
parser
.
add_argument
(
"--nni_docker_image"
,
type
=
str
)
parser
.
add_argument
(
"--nni_manager_ip"
,
type
=
str
)
# args for PAI
...
...
@@ -111,4 +111,5 @@ if __name__ == '__main__':
args
=
parser
.
parse_args
()
update_training_service_config
(
args
)
convert_command
()
if
args
.
ts
==
'local'
:
convert_command
()
test/pipelines-it-local-windows.yml
View file @
40bae6e2
...
...
@@ -14,7 +14,7 @@ jobs:
displayName
:
'
Install
dependencies
for
integration
tests'
-
script
:
|
cd test
python generate_ts_config.py
python generate_ts_config.py
--ts local
displayName
:
'
generate
config
files'
-
script
:
|
cd test
...
...
test/pipelines-it-pai-windows.yml
0 → 100644
View file @
40bae6e2
jobs
:
-
job
:
'
build_docker_image'
timeoutInMinutes
:
0
pool
:
vmImage
:
'
Ubuntu
16.04'
steps
:
-
script
:
python3 -m pip install --upgrade pip setuptools --user
displayName
:
'
Install
python
tools'
-
script
:
|
cd deployment/pypi
echo 'building prerelease package...'
make build
ls $(Build.SourcesDirectory)/deployment/pypi/dist/
condition
:
eq( variables['build_docker_img'], 'true' )
displayName
:
'
build
nni
bdsit_wheel'
-
script
:
|
if [ $(build_docker_img) = 'true' ]
then
cd deployment/pypi
docker login -u $(docker_hub_user) -p $(docker_hub_pwd)
echo 'updating docker file for installing nni from local...'
# update Dockerfile to install NNI in docker image from whl file built in last step
sed -ie 's/RUN python3 -m pip --no-cache-dir install nni/COPY .\/dist\/* .\nRUN python3 -m pip install nni-*.whl/' ../docker/Dockerfile
cat ../docker/Dockerfile
export IMG_TAG=`date -u +%y%m%d%H%M`
echo 'build and upload docker image'
docker build -f ../docker/Dockerfile -t $(test_docker_img_name):$IMG_TAG .
docker push $(test_docker_img_name):$IMG_TAG
export TEST_IMG=$(test_docker_img_name):$IMG_TAG
cd ../../
else
export TEST_IMG=$(existing_docker_img)
fi
echo "##vso[task.setvariable variable=TEST_IMG]$TEST_IMG"
displayName
:
'
build
docker
image'
-
script
:
echo $TEST_IMG
echo "##vso[task.setvariable variable=docker_image;isOutput=true]$TEST_IMG"
name
:
setvariableStep
displayName
:
'
set
image
variable'
-
job
:
'
integration_test_pai'
timeoutInMinutes
:
0
dependsOn
:
build_docker_image
variables
:
docker_image
:
$[ dependencies.build_docker_image.outputs['setvariableStep.docker_image'] ]
steps
:
-
script
:
|
set PATH=$(ENV_PATH)
python --version
powershell.exe -file install.ps1
displayName
:
'
Install
nni
toolkit
via
source
code'
-
script
:
|
cd test
set PATH=$(ENV_PATH)
python --version
python generate_ts_config.py --ts pai --pai_host $(pai_host) --pai_user $(pai_user) --pai_pwd $(pai_pwd) --vc $(pai_virtual_cluster) --nni_docker_image $(docker_image) --data_dir $(data_dir) --output_dir $(output_dir) --nni_manager_ip $(nni_manager_ip)
python config_test.py --ts pai --exclude multi_phase,smac,bohb
displayName
:
'
Examples
and
advanced
features
tests
on
pai'
\ No newline at end of file
tools/nni_cmd/launcher.py
View file @
40bae6e2
...
...
@@ -24,9 +24,9 @@ import os
import
sys
import
shutil
import
string
from
subprocess
import
Popen
,
PIPE
,
call
,
check_output
,
check_call
from
subprocess
import
Popen
,
PIPE
,
call
,
check_output
,
check_call
,
CalledProcessError
import
tempfile
from
nni.constants
import
ModuleName
from
nni.constants
import
ModuleName
,
AdvisorModuleName
from
nni_annotation
import
*
from
.launcher_utils
import
validate_all_content
from
.rest_utils
import
rest_put
,
rest_post
,
check_rest_server
,
check_rest_server_quick
,
check_response
...
...
@@ -344,13 +344,18 @@ def launch_experiment(args, experiment_config, mode, config_file_name, experimen
'''follow steps to start rest server and start experiment'''
nni_config
=
Config
(
config_file_name
)
# check packages for tuner
package_name
,
module_name
=
None
,
None
if
experiment_config
.
get
(
'tuner'
)
and
experiment_config
[
'tuner'
].
get
(
'builtinTunerName'
):
tuner_name
=
experiment_config
[
'tuner'
][
'builtinTunerName'
]
module_name
=
ModuleName
[
tuner_name
]
package_name
=
experiment_config
[
'tuner'
][
'builtinTunerName'
]
module_name
=
ModuleName
.
get
(
package_name
)
elif
experiment_config
.
get
(
'advisor'
)
and
experiment_config
[
'advisor'
].
get
(
'builtinAdvisorName'
):
package_name
=
experiment_config
[
'advisor'
][
'builtinAdvisorName'
]
module_name
=
AdvisorModuleName
.
get
(
package_name
)
if
package_name
and
module_name
:
try
:
check_call
([
sys
.
executable
,
'-c'
,
'import %s'
%
(
module_name
)])
except
ModuleNotFound
Error
as
e
:
print_error
(
'
The tuner
%s should be installed through nnictl
'
%
(
tuner
_name
))
check_call
([
sys
.
executable
,
'-c'
,
'import %s'
%
(
module_name
)]
,
stdout
=
PIPE
,
stderr
=
PIPE
)
except
CalledProcess
Error
as
e
:
print_error
(
'%s should be installed through
\'
nnictl
package install --name %s
\'
'
%
(
package_name
,
package
_name
))
exit
(
1
)
log_dir
=
experiment_config
[
'logDir'
]
if
experiment_config
.
get
(
'logDir'
)
else
None
log_level
=
experiment_config
[
'logLevel'
]
if
experiment_config
.
get
(
'logLevel'
)
else
None
...
...
Prev
1
2
Next
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