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 {
...
@@ -27,6 +27,11 @@ interface TrialDetailState {
entriesInSelect
:
string
;
entriesInSelect
:
string
;
searchSpace
:
string
;
searchSpace
:
string
;
isMultiPhase
:
boolean
;
isMultiPhase
:
boolean
;
isTableLoading
:
boolean
;
whichGraph
:
string
;
hyperCounts
:
number
;
// user click the hyper-parameter counts
durationCounts
:
number
;
intermediateCounts
:
number
;
}
}
class
TrialsDetail
extends
React
.
Component
<
{},
TrialDetailState
>
{
class
TrialsDetail
extends
React
.
Component
<
{},
TrialDetailState
>
{
...
@@ -70,9 +75,14 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -70,9 +75,14 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
experimentLogCollection
:
false
,
experimentLogCollection
:
false
,
entriesTable
:
20
,
entriesTable
:
20
,
entriesInSelect
:
'
20
'
,
entriesInSelect
:
'
20
'
,
isHasSearch
:
false
,
searchSpace
:
''
,
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> {
...
@@ -85,6 +95,9 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
])
])
.
then
(
axios
.
spread
((
res
,
res1
)
=>
{
.
then
(
axios
.
spread
((
res
,
res1
)
=>
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
)
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
)
{
if
(
this
.
_isMounted
===
true
)
{
this
.
setState
(()
=>
({
isTableLoading
:
true
}));
}
const
trialJobs
=
res
.
data
;
const
trialJobs
=
res
.
data
;
const
metricSource
=
res1
.
data
;
const
metricSource
=
res1
.
data
;
const
trialTable
:
Array
<
TableObj
>
=
[];
const
trialTable
:
Array
<
TableObj
>
=
[];
...
@@ -175,6 +188,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -175,6 +188,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
}
if
(
this
.
_isMounted
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
this
.
setState
(()
=>
({
isTableLoading
:
false
,
tableListSource
:
trialTable
tableListSource
:
trialTable
}));
}));
}
}
...
@@ -239,26 +253,26 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -239,26 +253,26 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
}
handleEntriesSelect
=
(
value
:
string
)
=>
{
handleEntriesSelect
=
(
value
:
string
)
=>
{
switch
(
value
)
{
// user select isn't 'all'
case
'
20
'
:
if
(
value
!==
'
all
'
)
{
this
.
setState
(()
=>
({
entriesTable
:
20
}));
if
(
this
.
_isMounted
)
{
break
;
this
.
setState
(()
=>
({
entriesTable
:
parseInt
(
value
,
10
)
}))
;
case
'
50
'
:
}
this
.
setState
(()
=>
({
entriesTable
:
50
}));
}
else
{
break
;
const
{
tableListSource
}
=
this
.
state
;
case
'
100
'
:
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
entriesTable
:
100
}));
this
.
setState
(()
=>
({
break
;
entriesInSelect
:
'
all
'
,
case
'
all
'
:
entriesTable
:
tableListSource
.
length
const
{
tableListSource
}
=
this
.
state
;
}))
;
if
(
this
.
_isMounted
)
{
}
this
.
setState
(()
=>
({
}
entriesInSelect
:
'
all
'
,
}
entriesTable
:
tableListSource
.
length
}));
handleWhichTabs
=
(
activeKey
:
string
)
=>
{
}
// const which = JSON.parse(activeKey);
break
;
if
(
this
.
_isMounted
)
{
default
:
this
.
setState
(()
=>
({
whichGraph
:
activeKey
}));
}
}
}
}
...
@@ -315,18 +329,21 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -315,18 +329,21 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
const
{
const
{
tableListSource
,
searchResultSource
,
isHasSearch
,
isMultiPhase
,
tableListSource
,
searchResultSource
,
isHasSearch
,
isMultiPhase
,
entriesTable
,
experimentPlatform
,
searchSpace
,
experimentLogCollection
entriesTable
,
experimentPlatform
,
searchSpace
,
experimentLogCollection
,
whichGraph
,
isTableLoading
}
=
this
.
state
;
}
=
this
.
state
;
const
source
=
isHasSearch
?
searchResultSource
:
tableListSource
;
const
source
=
isHasSearch
?
searchResultSource
:
tableListSource
;
return
(
return
(
<
div
>
<
div
>
<
div
className
=
"trial"
id
=
"tabsty"
>
<
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"
>
<
TabPane
tab
=
{
this
.
titleOfacc
}
key
=
"1"
>
<
Row
className
=
"graph"
>
<
Row
className
=
"graph"
>
<
DefaultPoint
<
DefaultPoint
height
=
{
432
}
height
=
{
432
}
showSource
=
{
source
}
showSource
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
/>
</
Row
>
</
Row
>
</
TabPane
>
</
TabPane
>
...
@@ -335,14 +352,16 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -335,14 +352,16 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<
Para
<
Para
dataSource
=
{
source
}
dataSource
=
{
source
}
expSearchSpace
=
{
searchSpace
}
expSearchSpace
=
{
searchSpace
}
whichGraph
=
{
whichGraph
}
/>
/>
</
Row
>
</
Row
>
</
TabPane
>
</
TabPane
>
<
TabPane
tab
=
{
this
.
titleOfDuration
}
key
=
"3"
>
<
TabPane
tab
=
{
this
.
titleOfDuration
}
key
=
"3"
>
<
Duration
source
=
{
source
}
/>
<
Duration
source
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
{
/* <Duration source={source} whichGraph={whichGraph} clickCounts={durationCounts} /> */
}
</
TabPane
>
</
TabPane
>
<
TabPane
tab
=
{
this
.
titleOfIntermediate
}
key
=
"4"
>
<
TabPane
tab
=
{
this
.
titleOfIntermediate
}
key
=
"4"
>
<
Intermediate
source
=
{
source
}
/>
<
Intermediate
source
=
{
source
}
whichGraph
=
{
whichGraph
}
/>
</
TabPane
>
</
TabPane
>
</
Tabs
>
</
Tabs
>
</
div
>
</
div
>
...
@@ -388,6 +407,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
...
@@ -388,6 +407,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<
TableList
<
TableList
entries
=
{
entriesTable
}
entries
=
{
entriesTable
}
tableSource
=
{
source
}
tableSource
=
{
source
}
isTableLoading
=
{
isTableLoading
}
isMultiPhase
=
{
isMultiPhase
}
isMultiPhase
=
{
isMultiPhase
}
platform
=
{
experimentPlatform
}
platform
=
{
experimentPlatform
}
updateList
=
{
this
.
getDetailSource
}
updateList
=
{
this
.
getDetailSource
}
...
...
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
TableObj
,
DetailAccurPoint
,
TooltipForAccuracy
}
from
'
../../static/interface
'
;
import
{
TableObj
,
DetailAccurPoint
,
TooltipForAccuracy
}
from
'
../../static/interface
'
;
require
(
'
echarts/lib/chart/scatter
'
);
require
(
'
echarts/lib/chart/scatter
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
@@ -8,11 +9,13 @@ require('echarts/lib/component/title');
...
@@ -8,11 +9,13 @@ require('echarts/lib/component/title');
interface
DefaultPointProps
{
interface
DefaultPointProps
{
showSource
:
Array
<
TableObj
>
;
showSource
:
Array
<
TableObj
>
;
height
:
number
;
height
:
number
;
whichGraph
:
string
;
}
}
interface
DefaultPointState
{
interface
DefaultPointState
{
defaultSource
:
object
;
defaultSource
:
object
;
accNodata
:
string
;
accNodata
:
string
;
succeedTrials
:
number
;
}
}
class
DefaultPoint
extends
React
.
Component
<
DefaultPointProps
,
DefaultPointState
>
{
class
DefaultPoint
extends
React
.
Component
<
DefaultPointProps
,
DefaultPointState
>
{
...
@@ -22,91 +25,130 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -22,91 +25,130 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
defaultSource
:
{},
defaultSource
:
{},
accNodata
:
'
No data
'
accNodata
:
''
,
succeedTrials
:
10000000
};
};
}
}
defaultMetric
=
(
s
how
Source
:
Array
<
TableObj
>
)
=>
{
defaultMetric
=
(
s
ucceed
Source
:
Array
<
TableObj
>
)
=>
{
const
accSource
:
Array
<
DetailAccurPoint
>
=
[];
const
accSource
:
Array
<
DetailAccurPoint
>
=
[];
Object
.
keys
(
showSource
).
map
(
item
=>
{
const
showSource
:
Array
<
TableObj
>
=
succeedSource
.
filter
(
filterByStatus
);
const
temp
=
showSource
[
item
];
const
lengthOfSource
=
showSource
.
length
;
if
(
temp
.
status
===
'
SUCCEEDED
'
&&
temp
.
acc
!==
undefined
)
{
const
tooltipDefault
=
lengthOfSource
===
0
?
'
No data
'
:
''
;
if
(
temp
.
acc
.
default
!==
undefined
)
{
if
(
this
.
_isMounted
===
true
)
{
const
searchSpace
=
temp
.
description
.
parameters
;
this
.
setState
(()
=>
({
accSource
.
push
({
succeedTrials
:
lengthOfSource
,
acc
:
temp
.
acc
.
default
,
accNodata
:
tooltipDefault
index
:
temp
.
sequenceId
,
}));
searchSpace
:
JSON
.
stringify
(
searchSpace
)
}
});
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
}));
}
}
});
}
else
{
const
resultList
:
Array
<
number
|
string
>
[]
=
[];
const
resultList
:
Array
<
number
|
string
>
[]
=
[];
Object
.
keys
(
accSource
).
map
(
item
=>
{
Object
.
keys
(
showSource
).
map
(
item
=>
{
const
items
=
accSource
[
item
];
const
temp
=
showSource
[
item
];
let
temp
:
Array
<
number
|
string
>
;
if
(
temp
.
acc
!==
undefined
)
{
temp
=
[
items
.
index
,
items
.
acc
,
JSON
.
parse
(
items
.
searchSpace
)];
if
(
temp
.
acc
.
default
!==
undefined
)
{
resultList
.
push
(
temp
);
const
searchSpace
=
temp
.
description
.
parameters
;
});
accSource
.
push
({
acc
:
temp
.
acc
.
default
,
const
allAcuracy
=
{
index
:
temp
.
sequenceId
,
grid
:
{
searchSpace
:
JSON
.
stringify
(
searchSpace
)
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
},
()
=>
{
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
// update parent component state
componentWillReceiveProps
(
nextProps
:
DefaultPointProps
)
{
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
()
{
componentDidMount
()
{
...
@@ -116,7 +158,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -116,7 +158,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
componentWillUnmount
()
{
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
this
.
_isMounted
=
false
;
}
}
render
()
{
render
()
{
const
{
height
}
=
this
.
props
;
const
{
height
}
=
this
.
props
;
const
{
defaultSource
,
accNodata
}
=
this
.
state
;
const
{
defaultSource
,
accNodata
}
=
this
.
state
;
...
@@ -131,6 +173,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
...
@@ -131,6 +173,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}
}
}
}
theme
=
"my_theme"
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
notMerge
=
{
true
}
// update now
// lazyUpdate={true}
/>
/>
<
div
className
=
"showMess"
>
{
accNodata
}
</
div
>
<
div
className
=
"showMess"
>
{
accNodata
}
</
div
>
</
div
>
</
div
>
...
...
src/webui/src/components/trial-detail/Duration.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
TableObj
}
from
'
src/static/interface
'
;
import
{
TableObj
}
from
'
src/static/interface
'
;
import
{
filterDuration
}
from
'
src/static/function
'
;
require
(
'
echarts/lib/chart/bar
'
);
require
(
'
echarts/lib/chart/bar
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/title
'
);
require
(
'
echarts/lib/component/title
'
);
...
@@ -12,6 +13,7 @@ interface Runtrial {
...
@@ -12,6 +13,7 @@ interface Runtrial {
interface
DurationProps
{
interface
DurationProps
{
source
:
Array
<
TableObj
>
;
source
:
Array
<
TableObj
>
;
whichGraph
:
string
;
}
}
interface
DurationState
{
interface
DurationState
{
...
@@ -26,13 +28,64 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -26,13 +28,64 @@ class Duration extends React.Component<DurationProps, DurationState> {
super
(
props
);
super
(
props
);
this
.
state
=
{
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
)
=>
{
getOption
=
(
dataObj
:
Runtrial
)
=>
{
return
{
return
{
tooltip
:
{
tooltip
:
{
trigger
:
'
axis
'
,
trigger
:
'
axis
'
,
axisPointer
:
{
axisPointer
:
{
...
@@ -45,7 +98,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -45,7 +98,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
left
:
'
1%
'
,
left
:
'
1%
'
,
right
:
'
4%
'
right
:
'
4%
'
},
},
dataZoom
:
[{
dataZoom
:
[{
type
:
'
slider
'
,
type
:
'
slider
'
,
name
:
'
trial
'
,
name
:
'
trial
'
,
...
@@ -74,17 +127,16 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -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
trialId
:
Array
<
string
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
const
trialJobs
=
source
.
filter
(
filterDuration
);
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
const
temp
=
trialJobs
[
item
];
const
temp
=
trialJobs
[
item
];
if
(
temp
.
status
!==
'
WAITING
'
)
{
trialId
.
push
(
temp
.
sequenceId
);
trialId
.
push
(
temp
.
sequenceId
);
trialTime
.
push
(
temp
.
duration
);
trialTime
.
push
(
temp
.
duration
);
}
});
});
trialRun
.
push
({
trialRun
.
push
({
trialId
:
trialId
,
trialId
:
trialId
,
...
@@ -97,18 +149,43 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -97,18 +149,43 @@ class Duration extends React.Component<DurationProps, DurationState> {
}
}
}
}
componentWillReceiveProps
(
nextProps
:
DurationProps
)
{
const
trialJobs
=
nextProps
.
source
;
this
.
drawDurationGraph
(
trialJobs
);
}
componentDidMount
()
{
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
_isMounted
=
true
;
// init: user don't search
const
{
source
}
=
this
.
props
;
const
{
source
}
=
this
.
props
;
this
.
drawDurationGraph
(
source
);
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
()
{
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
this
.
_isMounted
=
false
;
}
}
...
@@ -121,6 +198,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
...
@@ -121,6 +198,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
option
=
{
durationSource
}
option
=
{
durationSource
}
style
=
{
{
width
:
'
95%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
style
=
{
{
width
:
'
95%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
theme
=
"my_theme"
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
/>
/>
</
div
>
</
div
>
);
);
...
...
src/webui/src/components/trial-detail/Intermeidate.tsx
View file @
40bae6e2
...
@@ -11,16 +11,21 @@ interface Intermedia {
...
@@ -11,16 +11,21 @@ interface Intermedia {
data
:
Array
<
number
|
object
>
;
// intermediate data
data
:
Array
<
number
|
object
>
;
// intermediate data
hyperPara
:
object
;
// each trial hyperpara value
hyperPara
:
object
;
// each trial hyperpara value
}
}
interface
IntermediateState
{
interface
IntermediateState
{
detailSource
:
Array
<
TableObj
>
;
interSource
:
object
;
interSource
:
object
;
filterSource
:
Array
<
TableObj
>
;
filterSource
:
Array
<
TableObj
>
;
eachIntermediateNum
:
number
;
// trial's intermediate number count
eachIntermediateNum
:
number
;
// trial's intermediate number count
isLoadconfirmBtn
:
boolean
;
isLoadconfirmBtn
:
boolean
;
isFilter
:
boolean
;
isFilter
:
boolean
;
length
:
number
;
clickCounts
:
number
;
// user filter intermediate click confirm btn's counts
}
}
interface
IntermediateProps
{
interface
IntermediateProps
{
source
:
Array
<
TableObj
>
;
source
:
Array
<
TableObj
>
;
whichGraph
:
string
;
}
}
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
...
@@ -34,39 +39,25 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -34,39 +39,25 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
constructor
(
props
:
IntermediateProps
)
{
constructor
(
props
:
IntermediateProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
detailSource
:
[],
interSource
:
{},
interSource
:
{},
filterSource
:
[],
filterSource
:
[],
eachIntermediateNum
:
1
,
eachIntermediateNum
:
1
,
isLoadconfirmBtn
:
false
,
isLoadconfirmBtn
:
false
,
isFilter
:
false
isFilter
:
false
,
};
length
:
100000
,
}
clickCounts
:
0
initMediate
=
()
=>
{
const
option
=
{
grid
:
{
left
:
'
5%
'
,
top
:
40
,
containLabel
:
true
},
xAxis
:
{
type
:
'
category
'
,
boundaryGap
:
false
,
},
yAxis
:
{
type
:
'
value
'
,
name
:
'
Scape
'
}
};
};
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
interSource
:
option
}));
}
}
}
drawIntermediate
=
(
source
:
Array
<
TableObj
>
)
=>
{
drawIntermediate
=
(
source
:
Array
<
TableObj
>
)
=>
{
if
(
source
.
length
>
0
)
{
if
(
source
.
length
>
0
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
length
:
source
.
length
,
detailSource
:
source
}));
}
const
trialIntermediate
:
Array
<
Intermedia
>
=
[];
const
trialIntermediate
:
Array
<
Intermedia
>
=
[];
Object
.
keys
(
source
).
map
(
item
=>
{
Object
.
keys
(
source
).
map
(
item
=>
{
const
temp
=
source
[
item
];
const
temp
=
source
[
item
];
...
@@ -140,7 +131,24 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
...
@@ -140,7 +131,24 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
}));
}));
}
}
}
else
{
}
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>
...
@@ -183,8 +191,9 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this
.
setState
({
filterSource
:
filterSource
});
this
.
setState
({
filterSource
:
filterSource
});
}
}
this
.
drawIntermediate
(
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>
...
@@ -204,28 +213,73 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this
.
drawIntermediate
(
source
);
this
.
drawIntermediate
(
source
);
}
}
componentWillReceiveProps
(
nextProps
:
IntermediateProps
)
{
componentWillReceiveProps
(
nextProps
:
IntermediateProps
,
nextState
:
IntermediateState
)
{
const
{
isFilter
,
filterSource
}
=
this
.
state
;
const
{
isFilter
,
filterSource
}
=
nextState
;
if
(
isFilter
===
true
)
{
const
{
whichGraph
,
source
}
=
nextProps
;
const
pointVal
=
this
.
pointInput
!==
null
?
this
.
pointInput
.
value
:
''
;
const
minVal
=
this
.
minValInput
!==
null
?
this
.
minValInput
.
value
:
''
;
if
(
whichGraph
===
'
4
'
)
{
if
(
pointVal
===
''
&&
minVal
===
''
)
{
if
(
isFilter
===
true
)
{
this
.
drawIntermediate
(
nextProps
.
source
);
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
{
}
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
()
{
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
this
.
_isMounted
=
false
;
}
}
render
()
{
render
()
{
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
return
(
return
(
<
div
>
<
div
>
{
/* style in para.scss */
}
{
/* style in para.scss */
}
...
...
src/webui/src/components/trial-detail/Para.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
filterByStatus
}
from
'
../../static/function
'
;
import
{
Row
,
Col
,
Select
,
Button
,
message
}
from
'
antd
'
;
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
;
const
Option
=
Select
.
Option
;
require
(
'
echarts/lib/chart/parallel
'
);
require
(
'
echarts/lib/chart/parallel
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
@@ -11,6 +12,7 @@ require('../../static/style/para.scss');
...
@@ -11,6 +12,7 @@ require('../../static/style/para.scss');
require
(
'
../../static/style/button.scss
'
);
require
(
'
../../static/style/button.scss
'
);
interface
ParaState
{
interface
ParaState
{
// paraSource: Array<TableObj>;
option
:
object
;
option
:
object
;
paraBack
:
ParaObj
;
paraBack
:
ParaObj
;
dimName
:
Array
<
string
>
;
dimName
:
Array
<
string
>
;
...
@@ -19,11 +21,15 @@ interface ParaState {
...
@@ -19,11 +21,15 @@ interface ParaState {
paraNodata
:
string
;
paraNodata
:
string
;
max
:
number
;
// graph color bar limit
max
:
number
;
// graph color bar limit
min
:
number
;
min
:
number
;
sutrialCount
:
number
;
// succeed trial numbers for SUC
clickCounts
:
number
;
isLoadConfirm
:
boolean
;
}
}
interface
ParaProps
{
interface
ParaProps
{
dataSource
:
Array
<
TableObj
>
;
dataSource
:
Array
<
TableObj
>
;
expSearchSpace
:
string
;
expSearchSpace
:
string
;
whichGraph
:
string
;
}
}
message
.
config
({
message
.
config
({
...
@@ -45,6 +51,8 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -45,6 +51,8 @@ class Para extends React.Component<ParaProps, ParaState> {
constructor
(
props
:
ParaProps
)
{
constructor
(
props
:
ParaProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
// paraSource: [],
// option: this.hyperParaPic,
option
:
{},
option
:
{},
dimName
:
[],
dimName
:
[],
paraBack
:
{
paraBack
:
{
...
@@ -58,98 +66,20 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -58,98 +66,20 @@ class Para extends React.Component<ParaProps, ParaState> {
percent
:
0
,
percent
:
0
,
paraNodata
:
''
,
paraNodata
:
''
,
min
:
0
,
min
:
0
,
max
:
1
max
:
1
,
sutrialCount
:
10000000
,
clickCounts
:
1
,
isLoadConfirm
:
false
};
};
}
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
reInit
();
}
getParallelAxis
=
getParallelAxis
=
(
(
dimName
:
Array
<
string
>
,
searchRange
:
SearchSpace
,
dimName
:
Array
<
string
>
,
parallelAxis
:
Array
<
Dimobj
>
,
accPara
:
Array
<
number
>
,
accPara
:
Array
<
number
>
,
eachTrialParams
:
Array
<
string
>
eachTrialParams
:
Array
<
string
>
,
paraYdata
:
number
[][]
)
=>
{
)
=>
{
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()
// get data for every lines. if dim is choice type, number -> toString()
const
paraYdata
:
number
[][]
=
[];
Object
.
keys
(
eachTrialParams
).
map
(
item
=>
{
Object
.
keys
(
eachTrialParams
).
map
(
item
=>
{
let
temp
:
Array
<
number
>
=
[];
let
temp
:
Array
<
number
>
=
[];
for
(
let
i
=
0
;
i
<
dimName
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
dimName
.
length
;
i
++
)
{
...
@@ -169,7 +99,7 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -169,7 +99,7 @@ class Para extends React.Component<ParaProps, ParaState> {
Object
.
keys
(
paraYdata
).
map
(
item
=>
{
Object
.
keys
(
paraYdata
).
map
(
item
=>
{
paraYdata
[
item
].
push
(
accPara
[
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
)
{
if
(
paraYdata
.
length
!==
0
)
{
const
len
=
paraYdata
[
0
].
length
-
1
;
const
len
=
paraYdata
[
0
].
length
-
1
;
paraYdata
.
sort
((
a
,
b
)
=>
b
[
len
]
-
a
[
len
]);
paraYdata
.
sort
((
a
,
b
)
=>
b
[
len
]
-
a
[
len
]);
...
@@ -191,28 +121,153 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -191,28 +121,153 @@ class Para extends React.Component<ParaProps, ParaState> {
this
.
swapGraph
(
paraData
,
swapAxisArr
);
this
.
swapGraph
(
paraData
,
swapAxisArr
);
}
}
this
.
getOption
(
paraData
);
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
>
=
[];
const
accPara
:
Array
<
number
>
=
[];
// specific value array
// specific value array
const
eachTrialParams
:
Array
<
string
>
=
[];
const
eachTrialParams
:
Array
<
string
>
=
[];
const
paraYdata
:
number
[][]
=
[];
// experiment interface search space obj
// experiment interface search space obj
const
searchRange
=
JSON
.
parse
(
searchSpace
);
const
searchRange
=
searchSpace
!==
undefined
?
JSON
.
parse
(
searchSpace
)
:
''
;
const
dimName
=
Object
.
keys
(
searchRange
);
const
dimName
=
Object
.
keys
(
searchRange
);
// trial-jobs interface list
if
(
this
.
_isMounted
===
true
)
{
Object
.
keys
(
dataSource
).
map
(
item
=>
{
this
.
setState
(()
=>
({
dimName
:
dimName
}));
const
temp
=
dataSource
[
item
];
}
if
(
temp
.
status
===
'
SUCCEEDED
'
)
{
accPara
.
push
(
temp
.
acc
.
default
);
const
parallelAxis
:
Array
<
Dimobj
>
=
[];
eachTrialParams
.
push
(
temp
.
description
.
parameters
);
// 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
)
{
if
(
lenOfDataSource
===
0
)
{
this
.
setState
({
max
:
Math
.
max
(...
accPara
),
min
:
Math
.
min
(...
accPara
)
},
()
=>
{
const
optionOfNull
=
{
this
.
getParallelAxis
(
dimName
,
searchRange
,
accPara
,
eachTrialParams
,
paraYdata
);
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> {
...
@@ -229,9 +284,10 @@ class Para extends React.Component<ParaProps, ParaState> {
// deal with response data into pic data
// deal with response data into pic data
getOption
=
(
dataObj
:
ParaObj
)
=>
{
getOption
=
(
dataObj
:
ParaObj
)
=>
{
// dataObj [[y1], [y2]... [default metric]]
const
{
max
,
min
}
=
this
.
state
;
const
{
max
,
min
}
=
this
.
state
;
le
t
parallelAxis
=
dataObj
.
parallelAxis
;
cons
t
parallelAxis
=
dataObj
.
parallelAxis
;
le
t
paralleData
=
dataObj
.
data
;
cons
t
paralleData
=
dataObj
.
data
;
let
visualMapObj
=
{};
let
visualMapObj
=
{};
if
(
max
===
min
)
{
if
(
max
===
min
)
{
visualMapObj
=
{
visualMapObj
=
{
...
@@ -251,7 +307,7 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -251,7 +307,7 @@ class Para extends React.Component<ParaProps, ParaState> {
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
]
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
]
};
};
}
}
le
t
optionown
=
{
cons
t
optionown
=
{
parallelAxis
,
parallelAxis
,
tooltip
:
{
tooltip
:
{
trigger
:
'
item
'
trigger
:
'
item
'
...
@@ -288,21 +344,11 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -288,21 +344,11 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
};
};
// please wait the data
// 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
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
this
.
setState
(()
=>
({
option
:
optionown
option
:
optionown
,
paraNodata
:
''
,
sutrialCount
:
paralleData
.
length
}));
}));
}
}
}
}
...
@@ -320,6 +366,68 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -320,6 +366,68 @@ class Para extends React.Component<ParaProps, ParaState> {
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
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
)
=>
{
sortDimY
=
(
a
:
Dimobj
,
b
:
Dimobj
)
=>
{
return
a
.
dim
-
b
.
dim
;
return
a
.
dim
-
b
.
dim
;
}
}
...
@@ -374,11 +482,39 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -374,11 +482,39 @@ class Para extends React.Component<ParaProps, ParaState> {
});
});
}
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
reInit
();
}
componentWillReceiveProps
(
nextProps
:
ParaProps
)
{
componentWillReceiveProps
(
nextProps
:
ParaProps
)
{
const
dataSource
=
nextProps
.
dataSource
;
const
{
dataSource
,
expSearchSpace
,
whichGraph
}
=
nextProps
;
const
expSearchSpace
=
nextProps
.
expSearchSpace
;
if
(
whichGraph
===
'
2
'
)
{
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
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
()
{
componentWillUnmount
()
{
...
@@ -386,7 +522,7 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -386,7 +522,7 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
render
()
{
render
()
{
const
{
option
,
paraNodata
,
dimName
}
=
this
.
state
;
const
{
option
,
paraNodata
,
dimName
,
isLoadConfirm
}
=
this
.
state
;
return
(
return
(
<
Row
className
=
"parameter"
>
<
Row
className
=
"parameter"
>
<
Row
>
<
Row
>
...
@@ -423,7 +559,8 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -423,7 +559,8 @@ class Para extends React.Component<ParaProps, ParaState> {
<
Button
<
Button
type
=
"primary"
type
=
"primary"
className
=
"changeBtu tableButton"
className
=
"changeBtu tableButton"
onClick
=
{
this
.
reInit
}
onClick
=
{
this
.
swapReInit
}
disabled
=
{
isLoadConfirm
}
>
>
Confirm
Confirm
</
Button
>
</
Button
>
...
@@ -434,7 +571,7 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -434,7 +571,7 @@ class Para extends React.Component<ParaProps, ParaState> {
<
ReactEcharts
<
ReactEcharts
option
=
{
option
}
option
=
{
option
}
style
=
{
this
.
chartMulineStyle
}
style
=
{
this
.
chartMulineStyle
}
lazyUpdate
=
{
true
}
//
lazyUpdate={true}
notMerge
=
{
true
}
// update now
notMerge
=
{
true
}
// update now
/>
/>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
40bae6e2
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
import
{
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
}
from
'
antd
'
;
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
}
from
'
antd
'
;
const
CheckboxGroup
=
Checkbox
.
Group
;
const
CheckboxGroup
=
Checkbox
.
Group
;
import
{
MANAGER_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
MANAGER_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
convertDuration
,
intermediateGraphOption
,
killJob
}
from
'
../../static/function
'
;
import
{
convertDuration
,
intermediateGraphOption
,
killJob
}
from
'
../../static/function
'
;
import
{
TableObj
,
TrialJob
}
from
'
../../static/interface
'
;
import
{
TableObj
,
TrialJob
}
from
'
../../static/interface
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
// import DefaultMetric from '../public-child/DefaultMetrc';
import
IntermediateVal
from
'
../public-child/IntermediateVal
'
;
// table default metric column
import
IntermediateVal
from
'
../public-child/IntermediateVal
'
;
import
'
../../static/style/search.scss
'
;
import
'
../../static/style/search.scss
'
;
require
(
'
../../static/style/tableStatus.css
'
);
require
(
'
../../static/style/tableStatus.css
'
);
require
(
'
../../static/style/logPath.scss
'
);
require
(
'
../../static/style/logPath.scss
'
);
...
@@ -33,6 +30,7 @@ interface TableListProps {
...
@@ -33,6 +30,7 @@ interface TableListProps {
platform
:
string
;
platform
:
string
;
logCollection
:
boolean
;
logCollection
:
boolean
;
isMultiPhase
:
boolean
;
isMultiPhase
:
boolean
;
isTableLoading
:
boolean
;
}
}
interface
TableListState
{
interface
TableListState
{
...
@@ -197,7 +195,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -197,7 +195,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
render
()
{
render
()
{
const
{
entries
,
tableSource
,
updateList
}
=
this
.
props
;
const
{
entries
,
tableSource
,
updateList
,
isTableLoading
}
=
this
.
props
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
}
=
this
.
state
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
}
=
this
.
state
;
let
showTitle
=
COLUMN
;
let
showTitle
=
COLUMN
;
let
bgColor
=
''
;
let
bgColor
=
''
;
...
@@ -420,6 +418,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
...
@@ -420,6 +418,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
dataSource
=
{
tableSource
}
dataSource
=
{
tableSource
}
className
=
"commonTableStyle"
className
=
"commonTableStyle"
pagination
=
{
{
pageSize
:
entries
}
}
pagination
=
{
{
pageSize
:
entries
}
}
loading
=
{
isTableLoading
}
/>
/>
{
/* Intermediate Result Modal */
}
{
/* Intermediate Result Modal */
}
<
Modal
<
Modal
...
...
src/webui/src/static/function.ts
View file @
40bae6e2
import
axios
from
'
axios
'
;
import
axios
from
'
axios
'
;
import
{
import
{
message
}
from
'
antd
'
;
message
}
from
'
antd
'
;
import
{
MANAGER_IP
}
from
'
./const
'
;
import
{
MANAGER_IP
}
from
'
./const
'
;
import
{
FinalResult
,
FinalType
}
from
'
./interface
'
;
import
{
FinalResult
,
FinalType
,
TableObj
}
from
'
./interface
'
;
const
convertTime
=
(
num
:
number
)
=>
{
const
convertTime
=
(
num
:
number
)
=>
{
if
(
num
%
3600
===
0
)
{
if
(
num
%
3600
===
0
)
{
...
@@ -131,7 +129,16 @@ const killJob = (key: number, id: string, status: string, updateList: Function)
...
@@ -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
{
export
{
convertTime
,
convertDuration
,
getFinalResult
,
convertTime
,
convertDuration
,
getFinalResult
,
getFinal
,
getFinal
,
intermediateGraphOption
,
killJob
intermediateGraphOption
,
killJob
,
filterByStatus
,
filterDuration
};
};
src/webui/src/static/interface.ts
View file @
40bae6e2
...
@@ -26,7 +26,7 @@ interface ErrorParameter {
...
@@ -26,7 +26,7 @@ interface ErrorParameter {
interface
Parameters
{
interface
Parameters
{
parameters
:
ErrorParameter
;
parameters
:
ErrorParameter
;
logPath
?:
string
;
logPath
?:
string
;
intermediate
?
:
Array
<
number
>
;
intermediate
:
Array
<
number
>
;
}
}
interface
Experiment
{
interface
Experiment
{
...
...
test/generate_ts_config.py
View file @
40bae6e2
...
@@ -86,7 +86,7 @@ def convert_command():
...
@@ -86,7 +86,7 @@ def convert_command():
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
parser
=
argparse
.
ArgumentParser
()
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_docker_image"
,
type
=
str
)
parser
.
add_argument
(
"--nni_manager_ip"
,
type
=
str
)
parser
.
add_argument
(
"--nni_manager_ip"
,
type
=
str
)
# args for PAI
# args for PAI
...
@@ -111,4 +111,5 @@ if __name__ == '__main__':
...
@@ -111,4 +111,5 @@ if __name__ == '__main__':
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
update_training_service_config
(
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:
...
@@ -14,7 +14,7 @@ jobs:
displayName
:
'
Install
dependencies
for
integration
tests'
displayName
:
'
Install
dependencies
for
integration
tests'
-
script
:
|
-
script
:
|
cd test
cd test
python generate_ts_config.py
python generate_ts_config.py
--ts local
displayName
:
'
generate
config
files'
displayName
:
'
generate
config
files'
-
script
:
|
-
script
:
|
cd test
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
...
@@ -24,9 +24,9 @@ import os
import
sys
import
sys
import
shutil
import
shutil
import
string
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
import
tempfile
from
nni.constants
import
ModuleName
from
nni.constants
import
ModuleName
,
AdvisorModuleName
from
nni_annotation
import
*
from
nni_annotation
import
*
from
.launcher_utils
import
validate_all_content
from
.launcher_utils
import
validate_all_content
from
.rest_utils
import
rest_put
,
rest_post
,
check_rest_server
,
check_rest_server_quick
,
check_response
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
...
@@ -344,13 +344,18 @@ def launch_experiment(args, experiment_config, mode, config_file_name, experimen
'''follow steps to start rest server and start experiment'''
'''follow steps to start rest server and start experiment'''
nni_config
=
Config
(
config_file_name
)
nni_config
=
Config
(
config_file_name
)
# check packages for tuner
# check packages for tuner
package_name
,
module_name
=
None
,
None
if
experiment_config
.
get
(
'tuner'
)
and
experiment_config
[
'tuner'
].
get
(
'builtinTunerName'
):
if
experiment_config
.
get
(
'tuner'
)
and
experiment_config
[
'tuner'
].
get
(
'builtinTunerName'
):
tuner_name
=
experiment_config
[
'tuner'
][
'builtinTunerName'
]
package_name
=
experiment_config
[
'tuner'
][
'builtinTunerName'
]
module_name
=
ModuleName
[
tuner_name
]
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
:
try
:
check_call
([
sys
.
executable
,
'-c'
,
'import %s'
%
(
module_name
)])
check_call
([
sys
.
executable
,
'-c'
,
'import %s'
%
(
module_name
)]
,
stdout
=
PIPE
,
stderr
=
PIPE
)
except
ModuleNotFound
Error
as
e
:
except
CalledProcess
Error
as
e
:
print_error
(
'
The tuner
%s should be installed through nnictl
'
%
(
tuner
_name
))
print_error
(
'%s should be installed through
\'
nnictl
package install --name %s
\'
'
%
(
package_name
,
package
_name
))
exit
(
1
)
exit
(
1
)
log_dir
=
experiment_config
[
'logDir'
]
if
experiment_config
.
get
(
'logDir'
)
else
None
log_dir
=
experiment_config
[
'logDir'
]
if
experiment_config
.
get
(
'logDir'
)
else
None
log_level
=
experiment_config
[
'logLevel'
]
if
experiment_config
.
get
(
'logLevel'
)
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