Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
e1ae623f
Unverified
Commit
e1ae623f
authored
Mar 22, 2019
by
SparkSnail
Committed by
GitHub
Mar 22, 2019
Browse files
Merge pull request #147 from Microsoft/master
merge master
parents
f796c60b
63697ec5
Changes
41
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
879 additions
and
535 deletions
+879
-535
src/sdk/pynni/nni/multi_phase/multi_phase_dispatcher.py
src/sdk/pynni/nni/multi_phase/multi_phase_dispatcher.py
+1
-1
src/sdk/pynni/nni/protocol.py
src/sdk/pynni/nni/protocol.py
+3
-6
src/sdk/pynni/tests/test_assessor.py
src/sdk/pynni/tests/test_assessor.py
+7
-6
src/sdk/pynni/tests/test_tuner.py
src/sdk/pynni/tests/test_tuner.py
+6
-5
src/webui/src/components/Overview.tsx
src/webui/src/components/Overview.tsx
+4
-5
src/webui/src/components/SlideBar.tsx
src/webui/src/components/SlideBar.tsx
+1
-1
src/webui/src/components/TrialsDetail.tsx
src/webui/src/components/TrialsDetail.tsx
+134
-230
src/webui/src/components/overview/Title1.tsx
src/webui/src/components/overview/Title1.tsx
+1
-1
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
+139
-0
src/webui/src/components/trial-detail/Duration.tsx
src/webui/src/components/trial-detail/Duration.tsx
+41
-58
src/webui/src/components/trial-detail/Intermeidate.tsx
src/webui/src/components/trial-detail/Intermeidate.tsx
+291
-0
src/webui/src/components/trial-detail/Para.tsx
src/webui/src/components/trial-detail/Para.tsx
+163
-171
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+9
-28
src/webui/src/static/interface.ts
src/webui/src/static/interface.ts
+18
-6
src/webui/src/static/style/overviewTitle.scss
src/webui/src/static/style/overviewTitle.scss
+13
-1
src/webui/src/static/style/para.scss
src/webui/src/static/style/para.scss
+27
-9
test/tuner_test.py
test/tuner_test.py
+2
-2
tools/nni_cmd/config_schema.py
tools/nni_cmd/config_schema.py
+2
-0
tools/nni_cmd/launcher.py
tools/nni_cmd/launcher.py
+2
-0
tools/nni_trial_tool/log_utils.py
tools/nni_trial_tool/log_utils.py
+15
-5
No files found.
src/sdk/pynni/nni/multi_phase/multi_phase_dispatcher.py
View file @
e1ae623f
...
...
@@ -75,7 +75,7 @@ def _pack_parameter(parameter_id, params, customized=False, trial_job_id=None, p
class
MultiPhaseMsgDispatcher
(
MsgDispatcherBase
):
def
__init__
(
self
,
tuner
,
assessor
=
None
):
super
()
super
(
MultiPhaseMsgDispatcher
,
self
).
__init__
(
)
self
.
tuner
=
tuner
self
.
assessor
=
assessor
if
assessor
is
None
:
...
...
src/sdk/pynni/nni/protocol.py
View file @
e1ae623f
...
...
@@ -42,11 +42,10 @@ class CommandType(Enum):
NoMoreTrialJobs
=
b
'NO'
KillTrialJob
=
b
'KI'
_lock
=
threading
.
Lock
()
try
:
_in_file
=
open
(
3
,
'rb'
)
_out_file
=
open
(
4
,
'wb'
)
_lock
=
threading
.
Lock
()
except
OSError
:
_msg
=
'IPC pipeline not exists, maybe you are importing tuner/assessor from trial code?'
import
logging
...
...
@@ -60,8 +59,7 @@ def send(command, data):
"""
global
_lock
try
:
if
multi_thread_enabled
():
_lock
.
acquire
()
_lock
.
acquire
()
data
=
data
.
encode
(
'utf8'
)
assert
len
(
data
)
<
1000000
,
'Command too long'
msg
=
b
'%b%06d%b'
%
(
command
.
value
,
len
(
data
),
data
)
...
...
@@ -69,8 +67,7 @@ def send(command, data):
_out_file
.
write
(
msg
)
_out_file
.
flush
()
finally
:
if
multi_thread_enabled
():
_lock
.
release
()
_lock
.
release
()
def
receive
():
...
...
src/sdk/pynni/tests/test_assessor.py
View file @
e1ae623f
...
...
@@ -73,11 +73,12 @@ class AssessorTestCase(TestCase):
assessor
=
NaiveAssessor
()
dispatcher
=
MsgDispatcher
(
None
,
assessor
)
try
:
dispatcher
.
run
()
except
Exception
as
e
:
self
.
assertIs
(
type
(
e
),
AssertionError
)
self
.
assertEqual
(
e
.
args
[
0
],
'Unsupported command: CommandType.NewTrialJob'
)
nni
.
msg_dispatcher_base
.
_worker_fast_exit_on_terminate
=
False
dispatcher
.
run
()
e
=
dispatcher
.
worker_exceptions
[
0
]
self
.
assertIs
(
type
(
e
),
AssertionError
)
self
.
assertEqual
(
e
.
args
[
0
],
'Unsupported command: CommandType.NewTrialJob'
)
self
.
assertEqual
(
_trials
,
[
'A'
,
'B'
,
'A'
])
self
.
assertEqual
(
_end_trials
,
[(
'A'
,
False
),
(
'B'
,
True
)])
...
...
@@ -90,4 +91,4 @@ class AssessorTestCase(TestCase):
if
__name__
==
'__main__'
:
main
()
\ No newline at end of file
main
()
src/sdk/pynni/tests/test_tuner.py
View file @
e1ae623f
...
...
@@ -88,11 +88,12 @@ class TunerTestCase(TestCase):
tuner
=
NaiveTuner
()
dispatcher
=
MsgDispatcher
(
tuner
)
try
:
dispatcher
.
run
()
except
Exception
as
e
:
self
.
assertIs
(
type
(
e
),
AssertionError
)
self
.
assertEqual
(
e
.
args
[
0
],
'Unsupported command: CommandType.KillTrialJob'
)
nni
.
msg_dispatcher_base
.
_worker_fast_exit_on_terminate
=
False
dispatcher
.
run
()
e
=
dispatcher
.
worker_exceptions
[
0
]
self
.
assertIs
(
type
(
e
),
AssertionError
)
self
.
assertEqual
(
e
.
args
[
0
],
'Unsupported command: CommandType.KillTrialJob'
)
_reverse_io
()
# now we are receiving from Tuner's outgoing stream
self
.
_assert_params
(
0
,
2
,
[
],
None
)
...
...
src/webui/src/components/Overview.tsx
View file @
e1ae623f
...
...
@@ -2,10 +2,7 @@ import * as React from 'react';
import
axios
from
'
axios
'
;
import
{
Row
,
Col
}
from
'
antd
'
;
import
{
MANAGER_IP
}
from
'
../static/const
'
;
import
{
Experiment
,
TableObj
,
Parameters
,
TrialNumber
}
from
'
../static/interface
'
;
import
{
Experiment
,
TableObj
,
Parameters
,
TrialNumber
}
from
'
../static/interface
'
;
import
{
getFinal
}
from
'
../static/function
'
;
import
SuccessTable
from
'
./overview/SuccessTable
'
;
import
Title1
from
'
./overview/Title1
'
;
...
...
@@ -117,7 +114,9 @@ class Overview extends React.Component<{}, OverviewState> {
clusterMetaData
:
clusterMetaData
?
clusterMetaData
:
undefined
});
// search space format loguniform max and min
const
searchSpace
=
JSON
.
parse
(
sessionData
.
params
.
searchSpace
);
const
temp
=
sessionData
.
params
.
searchSpace
;
const
searchSpace
=
temp
!==
undefined
?
JSON
.
parse
(
temp
)
:
{};
Object
.
keys
(
searchSpace
).
map
(
item
=>
{
const
key
=
searchSpace
[
item
].
_type
;
let
value
=
searchSpace
[
item
].
_value
;
...
...
src/webui/src/components/SlideBar.tsx
View file @
e1ae623f
...
...
@@ -141,6 +141,7 @@ class SlideBar extends React.Component<{}, SliderState> {
}
});
}
getNNIversion
=
()
=>
{
axios
(
`
${
MANAGER_IP
}
/version`
,
{
method
:
'
GET
'
...
...
@@ -233,7 +234,6 @@ class SlideBar extends React.Component<{}, SliderState> {
</
a
>
<
span
className
=
"version"
>
Version:
{
version
}
</
span
>
</
Col
>
</
Row
>
);
}
...
...
src/webui/src/components/TrialsDetail.tsx
View file @
e1ae623f
This diff is collapsed.
Click to expand it.
src/webui/src/components/overview/Title1.tsx
View file @
e1ae623f
...
...
@@ -2,7 +2,7 @@ import * as React from 'react';
interface
Title1Props
{
text
:
string
;
icon
:
string
;
icon
?
:
string
;
bgcolor
?:
string
;
}
...
...
src/webui/src/components/trial-detail/DefaultMetricPoint.tsx
0 → 100644
View file @
e1ae623f
import
*
as
React
from
'
react
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
TableObj
,
DetailAccurPoint
,
TooltipForAccuracy
}
from
'
../../static/interface
'
;
require
(
'
echarts/lib/chart/scatter
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/title
'
);
interface
DefaultPointProps
{
showSource
:
Array
<
TableObj
>
;
height
:
number
;
}
interface
DefaultPointState
{
defaultSource
:
object
;
accNodata
:
string
;
}
class
DefaultPoint
extends
React
.
Component
<
DefaultPointProps
,
DefaultPointState
>
{
public
_isMounted
=
false
;
constructor
(
props
:
DefaultPointProps
)
{
super
(
props
);
this
.
state
=
{
defaultSource
:
{},
accNodata
:
'
No data
'
};
}
defaultMetric
=
(
showSource
:
Array
<
TableObj
>
)
=>
{
const
accSource
:
Array
<
DetailAccurPoint
>
=
[];
Object
.
keys
(
showSource
).
map
(
item
=>
{
const
temp
=
showSource
[
item
];
if
(
temp
.
status
===
'
SUCCEEDED
'
&&
temp
.
acc
.
default
!==
undefined
)
{
const
searchSpace
=
temp
.
description
.
parameters
;
accSource
.
push
({
acc
:
temp
.
acc
.
default
,
index
:
temp
.
sequenceId
,
searchSpace
:
JSON
.
stringify
(
searchSpace
)
});
}
});
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
];
}
},
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
:
''
});
}
});
}
}
// update parent component state
componentWillReceiveProps
(
nextProps
:
DefaultPointProps
)
{
const
showSource
=
nextProps
.
showSource
;
this
.
defaultMetric
(
showSource
);
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
height
}
=
this
.
props
;
const
{
defaultSource
,
accNodata
}
=
this
.
state
;
return
(
<
div
>
<
ReactEcharts
option
=
{
defaultSource
}
style
=
{
{
width
:
'
100%
'
,
height
:
height
,
margin
:
'
0 auto
'
,
}
}
theme
=
"my_theme"
notMerge
=
{
true
}
// update now
/>
<
div
className
=
"showMess"
>
{
accNodata
}
</
div
>
</
div
>
);
}
}
export
default
DefaultPoint
;
\ No newline at end of file
src/webui/src/components/trial-detail/Duration.tsx
View file @
e1ae623f
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
const
echarts
=
require
(
'
echarts/lib/echarts
'
)
;
import
{
TableObj
}
from
'
src/static/interface
'
;
require
(
'
echarts/lib/chart/bar
'
);
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/title
'
);
echarts
.
registerTheme
(
'
my_theme
'
,
{
color
:
'
#3c8dbc
'
});
interface
Runtrial
{
trialId
:
Array
<
string
>
;
trialTime
:
Array
<
number
>
;
}
interface
DurationProps
{
source
:
Array
<
TableObj
>
;
}
interface
DurationState
{
durationSource
:
{};
}
class
Duration
extends
React
.
Component
<
{}
,
DurationState
>
{
class
Duration
extends
React
.
Component
<
DurationProps
,
DurationState
>
{
static
intervalDuration
=
1
;
public
_isMounted
=
false
;
constructor
(
props
:
{})
{
super
(
props
);
constructor
(
props
:
DurationProps
)
{
super
(
props
);
this
.
state
=
{
durationSource
:
{}
};
}
getOption
=
(
dataObj
:
Runtrial
)
=>
{
let
xAxis
=
dataObj
.
trialTime
;
let
yAxis
=
dataObj
.
trialId
;
let
option
=
{
return
{
tooltip
:
{
trigger
:
'
axis
'
,
axisPointer
:
{
...
...
@@ -50,6 +45,7 @@ class Duration extends React.Component<{}, DurationState> {
left
:
'
1%
'
,
right
:
'
4%
'
},
dataZoom
:
[{
type
:
'
slider
'
,
name
:
'
trial
'
,
...
...
@@ -69,65 +65,52 @@ class Duration extends React.Component<{}, DurationState> {
yAxis
:
{
name
:
'
Trial
'
,
type
:
'
category
'
,
data
:
yAxis
data
:
dataObj
.
trialId
},
series
:
[{
type
:
'
bar
'
,
data
:
xAxis
data
:
dataObj
.
trialTime
}]
};
return
option
;
}
drawRunGraph
=
()
=>
{
axios
(
`
${
MANAGER_IP
}
/trial-jobs`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
const
trialJobs
=
res
.
data
;
const
trialId
:
Array
<
string
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
if
(
trialJobs
[
item
].
status
!==
'
WAITING
'
)
{
let
duration
:
number
=
0
;
const
end
=
trialJobs
[
item
].
endTime
;
const
start
=
trialJobs
[
item
].
startTime
;
if
(
start
&&
end
)
{
duration
=
(
end
-
start
)
/
1000
;
}
else
{
duration
=
(
new
Date
().
getTime
()
-
start
)
/
1000
;
}
trialId
.
push
(
trialJobs
[
item
].
sequenceId
);
trialTime
.
push
(
duration
);
}
});
trialRun
.
push
({
trialId
:
trialId
,
trialTime
:
trialTime
});
if
(
this
.
_isMounted
&&
res
.
status
===
200
)
{
this
.
setState
({
durationSource
:
this
.
getOption
(
trialRun
[
0
])
});
}
}
drawDurationGraph
=
(
trialJobs
:
Array
<
TableObj
>
)
=>
{
const
trialId
:
Array
<
string
>
=
[];
const
trialTime
:
Array
<
number
>
=
[];
const
trialRun
:
Array
<
Runtrial
>
=
[];
Object
.
keys
(
trialJobs
).
map
(
item
=>
{
const
temp
=
trialJobs
[
item
];
if
(
temp
.
status
!==
'
WAITING
'
)
{
trialId
.
push
(
temp
.
sequenceId
);
trialTime
.
push
(
temp
.
duration
);
}
});
trialRun
.
push
({
trialId
:
trialId
,
trialTime
:
trialTime
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
durationSource
:
this
.
getOption
(
trialRun
[
0
])
});
}
}
componentDidMount
()
{
componentWillReceiveProps
(
nextProps
:
DurationProps
)
{
const
trialJobs
=
nextProps
.
source
;
this
.
drawDurationGraph
(
trialJobs
);
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
drawRunGraph
();
Duration
.
intervalDuration
=
window
.
setInterval
(
this
.
drawRunGraph
,
10000
);
// init: user don't search
const
{
source
}
=
this
.
props
;
this
.
drawDurationGraph
(
source
);
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
window
.
clearInterval
(
Duration
.
intervalDuration
);
}
render
()
{
...
...
@@ -136,7 +119,7 @@ class Duration extends React.Component<{}, DurationState> {
<
div
>
<
ReactEcharts
option
=
{
durationSource
}
style
=
{
{
width
:
'
100
%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
style
=
{
{
width
:
'
95
%
'
,
height
:
412
,
margin
:
'
0 auto
'
}
}
theme
=
"my_theme"
/>
</
div
>
...
...
src/webui/src/components/trial-detail/Intermeidate.tsx
0 → 100644
View file @
e1ae623f
import
*
as
React
from
'
react
'
;
import
{
Row
,
Col
,
Button
,
Switch
}
from
'
antd
'
;
import
{
TooltipForIntermediate
,
TableObj
}
from
'
../../static/interface
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
require
(
'
echarts/lib/component/tooltip
'
);
require
(
'
echarts/lib/component/title
'
);
interface
Intermedia
{
name
:
string
;
// id
type
:
string
;
data
:
Array
<
number
|
object
>
;
// intermediate data
hyperPara
:
object
;
// each trial hyperpara value
}
interface
IntermediateState
{
interSource
:
object
;
filterSource
:
Array
<
TableObj
>
;
eachIntermediateNum
:
number
;
// trial's intermediate number count
isLoadconfirmBtn
:
boolean
;
isFilter
:
boolean
;
}
interface
IntermediateProps
{
source
:
Array
<
TableObj
>
;
}
class
Intermediate
extends
React
.
Component
<
IntermediateProps
,
IntermediateState
>
{
static
intervalMediate
=
1
;
public
_isMounted
=
false
;
public
pointInput
:
HTMLInputElement
|
null
;
public
minValInput
:
HTMLInputElement
|
null
;
public
maxValInput
:
HTMLInputElement
|
null
;
constructor
(
props
:
IntermediateProps
)
{
super
(
props
);
this
.
state
=
{
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
'
}
};
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
interSource
:
option
}));
}
}
drawIntermediate
=
(
source
:
Array
<
TableObj
>
)
=>
{
if
(
source
.
length
>
0
)
{
const
trialIntermediate
:
Array
<
Intermedia
>
=
[];
Object
.
keys
(
source
).
map
(
item
=>
{
const
temp
=
source
[
item
];
trialIntermediate
.
push
({
name
:
temp
.
id
,
data
:
temp
.
description
.
intermediate
,
type
:
'
line
'
,
hyperPara
:
temp
.
description
.
parameters
});
});
// find max intermediate number
trialIntermediate
.
sort
((
a
,
b
)
=>
{
return
(
b
.
data
.
length
-
a
.
data
.
length
);
});
const
legend
:
Array
<
string
>
=
[];
// max length
const
length
=
trialIntermediate
[
0
].
data
.
length
;
const
xAxis
:
Array
<
number
>
=
[];
Object
.
keys
(
trialIntermediate
).
map
(
item
=>
{
const
temp
=
trialIntermediate
[
item
];
legend
.
push
(
temp
.
name
);
});
for
(
let
i
=
1
;
i
<=
length
;
i
++
)
{
xAxis
.
push
(
i
);
}
const
option
=
{
tooltip
:
{
trigger
:
'
item
'
,
enterable
:
true
,
position
:
function
(
point
:
Array
<
number
>
,
data
:
TooltipForIntermediate
)
{
if
(
data
.
dataIndex
<
length
/
2
)
{
return
[
point
[
0
],
80
];
}
else
{
return
[
point
[
0
]
-
300
,
80
];
}
},
formatter
:
function
(
data
:
TooltipForIntermediate
)
{
const
trialId
=
data
.
seriesName
;
let
obj
=
{};
const
temp
=
trialIntermediate
.
find
(
key
=>
key
.
name
===
trialId
);
if
(
temp
!==
undefined
)
{
obj
=
temp
.
hyperPara
;
}
return
'
<div class="tooldetailAccuracy">
'
+
'
<div>Trial Id:
'
+
trialId
+
'
</div>
'
+
'
<div>Intermediate:
'
+
data
.
data
+
'
</div>
'
+
'
<div>Parameters:
'
+
'
<pre>
'
+
JSON
.
stringify
(
obj
,
null
,
4
)
+
'
</pre>
'
+
'
</div>
'
+
'
</div>
'
;
}
},
grid
:
{
left
:
'
5%
'
,
top
:
40
,
containLabel
:
true
},
xAxis
:
{
type
:
'
category
'
,
name
:
'
Scape
'
,
boundaryGap
:
false
,
data
:
xAxis
},
yAxis
:
{
type
:
'
value
'
,
name
:
'
Intermediate
'
},
series
:
trialIntermediate
};
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
interSource
:
option
}));
}
}
else
{
this
.
initMediate
();
}
}
// confirm btn function [filter data]
filterLines
=
()
=>
{
if
(
this
.
_isMounted
)
{
const
filterSource
:
Array
<
TableObj
>
=
[];
this
.
setState
({
isLoadconfirmBtn
:
true
},
()
=>
{
const
{
source
}
=
this
.
props
;
// get input value
const
pointVal
=
this
.
pointInput
!==
null
?
this
.
pointInput
.
value
:
''
;
const
minVal
=
this
.
minValInput
!==
null
?
this
.
minValInput
.
value
:
''
;
const
maxVal
=
this
.
maxValInput
!==
null
?
this
.
maxValInput
.
value
:
''
;
// user not input message
if
(
pointVal
===
''
||
minVal
===
''
)
{
alert
(
'
Please input filter message
'
);
}
else
{
// user not input max value
const
position
=
JSON
.
parse
(
pointVal
);
const
min
=
JSON
.
parse
(
minVal
);
if
(
maxVal
===
''
)
{
Object
.
keys
(
source
).
map
(
item
=>
{
const
temp
=
source
[
item
];
const
val
=
temp
.
description
.
intermediate
[
position
-
1
];
if
(
val
>=
min
)
{
filterSource
.
push
(
temp
);
}
});
}
else
{
const
max
=
JSON
.
parse
(
maxVal
);
Object
.
keys
(
source
).
map
(
item
=>
{
const
temp
=
source
[
item
];
const
val
=
temp
.
description
.
intermediate
[
position
-
1
];
if
(
val
>=
min
&&
val
<=
max
)
{
filterSource
.
push
(
temp
);
}
});
}
if
(
this
.
_isMounted
)
{
this
.
setState
({
filterSource
:
filterSource
});
}
this
.
drawIntermediate
(
filterSource
);
}
this
.
setState
({
isLoadconfirmBtn
:
false
});
});
}
}
switchTurn
=
(
checked
:
boolean
)
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
({
isFilter
:
checked
});
}
if
(
checked
===
false
)
{
this
.
drawIntermediate
(
this
.
props
.
source
);
}
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
const
{
source
}
=
this
.
props
;
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
);
}
else
{
this
.
drawIntermediate
(
filterSource
);
}
}
else
{
this
.
drawIntermediate
(
nextProps
.
source
);
}
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
interSource
,
isLoadconfirmBtn
,
isFilter
}
=
this
.
state
;
return
(
<
div
>
{
/* style in para.scss */
}
<
Row
className
=
"meline intermediate"
>
<
Col
span
=
{
8
}
/>
<
Col
span
=
{
3
}
style
=
{
{
height
:
34
}
}
>
{
/* filter message */
}
<
span
>
filter
</
span
>
<
Switch
defaultChecked
=
{
false
}
onChange
=
{
this
.
switchTurn
}
/>
</
Col
>
{
isFilter
?
<
div
>
<
Col
span
=
{
3
}
>
<
span
>
Scape
</
span
>
<
input
placeholder
=
"point"
ref
=
{
input
=>
this
.
pointInput
=
input
}
className
=
"strange"
/>
</
Col
>
<
Col
className
=
"range"
span
=
{
10
}
>
<
span
>
Intermediate Result
</
span
>
<
input
placeholder
=
"number"
ref
=
{
input
=>
this
.
minValInput
=
input
}
/>
<
span
className
=
"heng"
>
-
</
span
>
<
input
placeholder
=
"number"
ref
=
{
input
=>
this
.
maxValInput
=
input
}
/>
<
Button
type
=
"primary"
className
=
"changeBtu tableButton"
onClick
=
{
this
.
filterLines
}
disabled
=
{
isLoadconfirmBtn
}
>
Confirm
</
Button
>
</
Col
>
</
div
>
:
<
Col
/>
}
</
Row
>
<
Row
>
<
ReactEcharts
option
=
{
interSource
}
style
=
{
{
width
:
'
100%
'
,
height
:
418
,
margin
:
'
0 auto
'
}
}
notMerge
=
{
true
}
// update now
/>
</
Row
>
</
div
>
);
}
}
export
default
Intermediate
;
\ No newline at end of file
src/webui/src/components/trial-detail/Para.tsx
View file @
e1ae623f
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
}
from
'
../../static/const
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
Row
,
Col
,
Select
,
Button
,
message
}
from
'
antd
'
;
import
{
ParaObj
,
VisualMapValue
,
Dimobj
}
from
'
../../static/interface
'
;
import
{
getFinalResult
}
from
'
../../static/function
'
;
import
{
ParaObj
,
Dimobj
,
TableObj
,
SearchSpace
}
from
'
../../static/interface
'
;
const
Option
=
Select
.
Option
;
require
(
'
echarts/lib/chart/parallel
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
...
@@ -20,12 +17,14 @@ interface ParaState {
swapAxisArr
:
Array
<
string
>
;
percent
:
number
;
paraNodata
:
string
;
visualValue
:
VisualMapValue
;
barColorMax
:
number
;
barColorMin
:
number
;
}
interface
SearchSpace
{
_value
:
Array
<
number
|
string
>
;
_type
:
string
;
interface
ParaProps
{
dataSource
:
Array
<
TableObj
>
;
expSearchSpace
:
string
;
defaultMetric
:
Array
<
number
>
|
undefined
;
}
message
.
config
({
...
...
@@ -33,12 +32,18 @@ message.config({
duration
:
2
,
});
class
Para
extends
React
.
Component
<
{}
,
ParaState
>
{
class
Para
extends
React
.
Component
<
ParaProps
,
ParaState
>
{
static
intervalIDPara
=
4
;
public
_isMounted
=
false
;
constructor
(
props
:
{})
{
private
chartMulineStyle
=
{
width
:
'
100%
'
,
height
:
392
,
margin
:
'
0 auto
'
,
padding
:
'
0 15 10 15
'
};
constructor
(
props
:
ParaProps
)
{
super
(
props
);
this
.
state
=
{
option
:
{},
...
...
@@ -53,28 +58,37 @@ class Para extends React.Component<{}, ParaState> {
swapAxisArr
:
[],
percent
:
0
,
paraNodata
:
''
,
visualValue
:
{
minAccuracy
:
0
,
maxAccuracy
:
1
}
barColorMax
:
this
.
props
.
defaultMetric
!==
undefined
?
this
.
props
.
defaultMetric
[
1
]
:
1
,
barColorMin
:
this
.
props
.
defaultMetric
!==
undefined
?
this
.
props
.
defaultMetric
[
0
]
:
1
};
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
this
.
reInit
();
}
getParallelAxis
=
(
dimName
:
Array
<
string
>
,
searchRange
:
SearchSpace
,
parallelAxis
:
Array
<
Dimobj
>
,
accPara
:
Array
<
number
>
,
accPara
:
Array
<
number
>
,
eachTrialParams
:
Array
<
string
>
,
paraYdata
:
number
[][]
)
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
dimName
:
dimName
,
visualValue
:
{
minAccuracy
:
accPara
.
length
!==
0
?
Math
.
min
(...
accPara
)
:
0
,
maxAccuracy
:
accPara
.
length
!==
0
?
Math
.
max
(...
accPara
)
:
1
}
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
]];
...
...
@@ -107,7 +121,24 @@ class Para extends React.Component<{}, ParaState> {
dim
:
i
,
name
:
dimName
[
i
],
type
:
'
category
'
,
data
:
data
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
...
...
@@ -143,100 +174,70 @@ class Para extends React.Component<{}, ParaState> {
}
paraYdata
.
push
(
temp
);
});
// add acc
Object
.
keys
(
paraYdata
).
map
(
item
=>
{
paraYdata
[
item
].
push
(
accPara
[
item
]);
});
// according acc to sort ydata
if
(
paraYdata
.
length
!==
0
)
{
const
len
=
paraYdata
[
0
].
length
-
1
;
paraYdata
.
sort
((
a
,
b
)
=>
b
[
len
]
-
a
[
len
]);
}
const
paraData
=
{
parallelAxis
:
parallelAxis
,
data
:
paraYdata
};
const
{
percent
,
swapAxisArr
}
=
this
.
state
;
// need to cut down the data
if
(
percent
!==
0
)
{
const
linesNum
=
paraData
.
data
.
length
;
const
len
=
Math
.
floor
(
linesNum
*
percent
);
paraData
.
data
.
length
=
len
;
}
// need to swap the yAxis
if
(
swapAxisArr
.
length
>=
2
)
{
this
.
swapGraph
(
paraData
,
swapAxisArr
);
}
this
.
getOption
(
paraData
);
}
hyperParaPic
=
()
=>
{
axios
.
all
([
axios
.
get
(
`
${
MANAGER_IP
}
/trial-jobs`
),
axios
.
get
(
`
${
MANAGER_IP
}
/experiment`
)
])
.
then
(
axios
.
spread
((
res
,
res1
)
=>
{
if
(
res
.
status
===
200
&&
res1
.
status
===
200
)
{
if
(
res
.
data
.
length
!==
0
)
{
const
accParaData
=
res
.
data
;
const
accPara
:
Array
<
number
>
=
[];
// specific value array
const
eachTrialParams
:
Array
<
string
>
=
[];
const
parallelAxis
:
Array
<
Dimobj
>
=
[];
const
paraYdata
:
number
[][]
=
[];
// experiment interface search space obj
const
searchRange
=
JSON
.
parse
(
res1
.
data
.
params
.
searchSpace
);
const
reallySearchKeys
=
Object
.
keys
(
searchRange
);
// trial-jobs interface list
Object
.
keys
(
accParaData
).
map
(
item
=>
{
if
(
accParaData
[
item
].
status
===
'
SUCCEEDED
'
)
{
const
finalData
=
accParaData
[
item
].
finalMetricData
;
if
(
finalData
&&
accParaData
[
item
].
hyperParameters
)
{
const
result
=
getFinalResult
(
finalData
);
accPara
.
push
(
result
);
// get dim and every line specific number
const
temp
=
JSON
.
parse
(
accParaData
[
item
].
hyperParameters
).
parameters
;
eachTrialParams
.
push
(
temp
);
}
}
});
const
dimName
=
reallySearchKeys
;
this
.
getParallelAxis
(
dimName
,
searchRange
,
parallelAxis
,
accPara
,
eachTrialParams
,
paraYdata
);
// add acc
Object
.
keys
(
paraYdata
).
map
(
item
=>
{
paraYdata
[
item
].
push
(
accPara
[
item
]);
});
// according acc to sort ydata
if
(
paraYdata
.
length
!==
0
)
{
const
len
=
paraYdata
[
0
].
length
-
1
;
paraYdata
.
sort
((
a
,
b
)
=>
b
[
len
]
-
a
[
len
]);
}
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
paraBack
:
{
parallelAxis
:
parallelAxis
,
data
:
paraYdata
}
}));
}
const
{
percent
,
swapAxisArr
,
paraBack
}
=
this
.
state
;
// need to cut down the data
if
(
percent
!==
0
)
{
const
linesNum
=
paraBack
.
data
.
length
;
const
len
=
Math
.
floor
(
linesNum
*
percent
);
paraBack
.
data
.
length
=
len
;
}
// need to swap the yAxis
if
(
swapAxisArr
.
length
>=
2
)
{
this
.
swapGraph
(
paraBack
,
swapAxisArr
);
}
this
.
getOption
(
paraBack
);
}
}
}));
hyperParaPic
=
(
dataSource
:
Array
<
TableObj
>
,
searchSpace
:
string
)
=>
{
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
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
);
}
});
this
.
getParallelAxis
(
dimName
,
searchRange
,
accPara
,
eachTrialParams
,
paraYdata
);
}
// get percent value number
percentNum
=
(
value
:
string
)
=>
{
window
.
clearInterval
(
Para
.
intervalIDPara
);
let
vals
=
parseFloat
(
value
);
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
(
{
percent
:
vals
})
)
;
this
.
setState
(
{
percent
:
vals
},
()
=>
{
this
.
reInit
();
});
}
this
.
hyperParaPic
();
Para
.
intervalIDPara
=
window
.
setInterval
(
this
.
hyperParaPic
,
10000
);
}
// deal with response data into pic data
getOption
=
(
dataObj
:
ParaObj
)
=>
{
const
{
visualValue
}
=
this
.
state
;
const
{
barColorMax
,
barColorMin
}
=
this
.
state
;
let
parallelAxis
=
dataObj
.
parallelAxis
;
let
paralleData
=
dataObj
.
data
;
const
maxAccuracy
=
visualValue
.
maxAccuracy
;
const
minAccuracy
=
visualValue
.
minAccuracy
;
let
visualMapObj
=
{};
if
(
maxAccuracy
===
minAccuracy
)
{
if
(
barColorMax
===
barColorMin
)
{
visualMapObj
=
{
type
:
'
continuous
'
,
precision
:
3
,
...
...
@@ -247,10 +248,9 @@ class Para extends React.Component<{}, ParaState> {
bottom
:
'
20px
'
,
type
:
'
continuous
'
,
precision
:
3
,
min
:
visualValue
.
minAccuracy
,
max
:
visualValue
.
maxAccuracy
,
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
],
calculable
:
true
min
:
barColorMin
,
max
:
barColorMax
,
color
:
[
'
#CA0000
'
,
'
#FFC400
'
,
'
#90EE90
'
]
};
}
let
optionown
=
{
...
...
@@ -317,11 +317,9 @@ class Para extends React.Component<{}, ParaState> {
}
}
swapBtn
=
()
=>
{
window
.
clearInterval
(
Para
.
intervalIDPara
);
this
.
hyperParaPic
();
Para
.
intervalIDPara
=
window
.
setInterval
(
this
.
hyperParaPic
,
10000
);
reInit
=
()
=>
{
const
{
dataSource
,
expSearchSpace
}
=
this
.
props
;
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
}
sortDimY
=
(
a
:
Dimobj
,
b
:
Dimobj
)
=>
{
...
...
@@ -330,79 +328,73 @@ class Para extends React.Component<{}, ParaState> {
// deal with after swap data into pic
swapGraph
=
(
paraBack
:
ParaObj
,
swapAxisArr
:
string
[])
=>
{
if
(
swapAxisArr
.
length
>=
2
)
{
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
;
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
;
}
});
// swap dim's number
Object
.
keys
(
paralDim
).
map
(
item
=>
{
if
(
bool3
)
{
if
(
paralDim
[
item
].
name
===
this
.
state
.
swapAxisArr
[
0
])
{
paralDim
[
item
].
dim
=
dim2
;
}
if
(
paralDim
[
item
].
name
===
this
.
state
.
swapAxisArr
[
1
])
{
paralDim
[
item
].
dim
=
dim1
;
}
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
][
dim
2
];
paraData
[
paraItem
][
dim
2
]
=
temp
;
})
;
}
}
}
);
paralDim
.
sort
(
this
.
sortDimY
);
// swap data array
Object
.
keys
(
paraData
).
map
(
paraItem
=>
{
temp
=
paraData
[
paraItem
][
dim
1
];
paraData
[
paraItem
][
dim
1
]
=
paraData
[
paraItem
][
dim2
]
;
paraData
[
paraItem
][
dim2
]
=
temp
;
}
);
}
componentDidMount
()
{
componentWillReceiveProps
(
nextProps
:
ParaProps
)
{
const
dataSource
=
nextProps
.
dataSource
;
const
expSearchSpace
=
nextProps
.
expSearchSpace
;
const
metricMax
=
nextProps
.
defaultMetric
!==
undefined
?
nextProps
.
defaultMetric
[
1
]
:
1
;
this
.
setState
({
barColorMax
:
metricMax
});
this
.
hyperParaPic
(
dataSource
,
expSearchSpace
);
this
.
_isMounted
=
true
;
// default draw all data pic
this
.
hyperParaPic
();
Para
.
intervalIDPara
=
window
.
setInterval
(
this
.
hyperParaPic
,
10000
);
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
window
.
clearInterval
(
Para
.
intervalIDPara
);
}
render
()
{
const
{
option
,
paraNodata
,
dimName
}
=
this
.
state
;
const
chartMulineStyle
=
{
width
:
'
100%
'
,
height
:
392
,
margin
:
'
0 auto
'
,
padding
:
'
0 15 10 15
'
};
return
(
<
Row
className
=
"parameter"
>
<
Row
>
...
...
@@ -439,7 +431,7 @@ class Para extends React.Component<{}, ParaState> {
<
Button
type
=
"primary"
className
=
"changeBtu tableButton"
onClick
=
{
this
.
swapBtn
}
onClick
=
{
this
.
reInit
}
>
Confirm
</
Button
>
...
...
@@ -449,8 +441,8 @@ class Para extends React.Component<{}, ParaState> {
<
Row
className
=
"searcHyper"
>
<
ReactEcharts
option
=
{
option
}
style
=
{
chartMulineStyle
}
//
lazyUpdate={true}
style
=
{
this
.
chartMulineStyle
}
lazyUpdate
=
{
true
}
notMerge
=
{
true
}
// update now
/>
<
div
className
=
"noneData"
>
{
paraNodata
}
</
div
>
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
e1ae623f
...
...
@@ -2,9 +2,8 @@ import * as React from 'react';
import
axios
from
'
axios
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
Row
,
Input
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
Checkbox
}
from
'
antd
'
;
const
{
TextArea
}
=
Input
;
const
CheckboxGroup
=
Checkbox
.
Group
;
import
{
MANAGER_IP
,
DOWNLOAD_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
convertDuration
,
intermediateGraphOption
,
killJob
}
from
'
../../static/function
'
;
...
...
@@ -29,9 +28,7 @@ echarts.registerTheme('my_theme', {
interface
TableListProps
{
entries
:
number
;
tableSource
:
Array
<
TableObj
>
;
searchResult
:
Array
<
TableObj
>
;
updateList
:
Function
;
isHasSearch
:
boolean
;
platform
:
string
;
}
...
...
@@ -78,6 +75,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
const
intermediateArr
:
number
[]
=
[];
// support intermediate result is dict
Object
.
keys
(
res
.
data
).
map
(
item
=>
{
const
temp
=
JSON
.
parse
(
res
.
data
[
item
].
data
);
if
(
typeof
temp
===
'
object
'
)
{
...
...
@@ -244,10 +242,8 @@ class TableList extends React.Component<TableListProps, TableListState> {
render
()
{
const
{
entries
,
tableSource
,
searchResult
,
isHasSearch
,
updateList
}
=
this
.
props
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
,
logMessage
,
logModal
}
=
this
.
state
;
const
{
entries
,
tableSource
,
updateList
}
=
this
.
props
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
}
=
this
.
state
;
let
showTitle
=
COLUMN
;
let
bgColor
=
''
;
const
trialJob
:
Array
<
TrialJob
>
=
[];
...
...
@@ -340,7 +336,10 @@ class TableList extends React.Component<TableListProps, TableListState> {
);
},
filters
:
trialJob
,
onFilter
:
(
value
:
string
,
record
:
TableObj
)
=>
record
.
status
.
indexOf
(
value
)
===
0
,
onFilter
:
(
value
:
string
,
record
:
TableObj
)
=>
{
return
record
.
status
.
indexOf
(
value
)
===
0
;
},
// onFilter: (value: string, record: TableObj) => record.status.indexOf(value) === 0,
sorter
:
(
a
:
TableObj
,
b
:
TableObj
):
number
=>
a
.
status
.
localeCompare
(
b
.
status
)
});
break
;
...
...
@@ -453,7 +452,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
<
Table
columns
=
{
showColumn
}
expandedRowRender
=
{
this
.
openRow
}
dataSource
=
{
isHasSearch
?
searchResult
:
tableSource
}
dataSource
=
{
tableSource
}
className
=
"commonTableStyle"
pagination
=
{
{
pageSize
:
entries
}
}
/>
...
...
@@ -475,24 +474,6 @@ class TableList extends React.Component<TableListProps, TableListState> {
theme
=
"my_theme"
/>
</
Modal
>
{
/* trial log modal */
}
<
Modal
title
=
"trial log"
visible
=
{
logModal
}
onCancel
=
{
this
.
hideLogModal
}
footer
=
{
null
}
destroyOnClose
=
{
true
}
width
=
"80%"
>
<
div
id
=
"trialLogContent"
style
=
{
{
height
:
window
.
innerHeight
*
0.6
}
}
>
<
TextArea
value
=
{
logMessage
}
disabled
=
{
true
}
className
=
"logcontent"
/>
</
div
>
</
Modal
>
</
div
>
{
/* Add Column Modal */
}
<
Modal
...
...
src/webui/src/static/interface.ts
View file @
e1ae623f
...
...
@@ -10,6 +10,11 @@ interface TableObj {
color
?:
string
;
}
interface
SearchSpace
{
_value
:
Array
<
number
|
string
>
;
_type
:
string
;
}
interface
FinalType
{
default
:
string
;
}
...
...
@@ -21,6 +26,7 @@ interface ErrorParameter {
interface
Parameters
{
parameters
:
ErrorParameter
;
logPath
?:
string
;
intermediate
?:
Array
<
number
>
;
}
interface
Experiment
{
...
...
@@ -54,6 +60,12 @@ interface DetailAccurPoint {
searchSpace
:
string
;
}
interface
TooltipForIntermediate
{
data
:
string
;
seriesName
:
string
;
dataIndex
:
number
;
}
interface
TooltipForAccuracy
{
data
:
Array
<
number
|
object
>
;
}
...
...
@@ -80,6 +92,10 @@ interface Dimobj {
min
?:
number
;
type
?:
string
;
data
?:
string
[];
boundaryGap
?:
boolean
;
axisTick
?:
object
;
axisLabel
?:
object
;
axisLine
?:
object
;
}
interface
ParaObj
{
...
...
@@ -87,11 +103,6 @@ interface ParaObj {
parallelAxis
:
Array
<
Dimobj
>
;
}
interface
VisualMapValue
{
maxAccuracy
:
number
;
minAccuracy
:
number
;
}
interface
FinalResult
{
data
:
string
;
}
...
...
@@ -100,5 +111,6 @@ export {
TableObj
,
Parameters
,
Experiment
,
AccurPoint
,
TrialNumber
,
TrialJob
,
DetailAccurPoint
,
TooltipForAccuracy
,
ParaObj
,
VisualMapValue
,
Dimobj
,
FinalResult
,
FinalType
ParaObj
,
Dimobj
,
FinalResult
,
FinalType
,
TooltipForIntermediate
,
SearchSpace
};
src/webui/src/static/style/overviewTitle.scss
View file @
e1ae623f
...
...
@@ -13,7 +13,6 @@ $titleBgcolor: #b3b3b3;
height
:
22px
;
margin-top
:
-8px
;
padding-left
:
14px
;
padding-right
:
14px
;
}
span
{
...
...
@@ -22,9 +21,22 @@ $titleBgcolor: #b3b3b3;
font-family
:
'Segoe'
;
color
:
#333
;
line-height
:
38px
;
margin-left
:
14px
;
}
i
{
font-size
:
24px
;
margin-left
:
14px
;
color
:
#545454
;
position
:
relative
;
top
:
2px
;
}
}
/* antd icon margin intermediate result style*/
#tabsty
.anticon
{
margin-right
:
0
;
}
.top10bg
{
background-color
:
$titleBgcolor
;
...
...
src/webui/src/static/style/para.scss
View file @
e1ae623f
.parameter
{
height
:
100%
;
height
:
100%
;
}
.meline
{
margin-top
:
15px
;
.meline
{
margin-top
:
15px
;
span
{
font-size
:
14px
;
margin-right
:
6px
;
}
span
{
font-size
:
14px
;
margin-right
:
6px
;
}
}
.searcHyper
{
...
...
@@ -24,4 +23,23 @@
font-size
:
13px
;
color
:
#999
;
}
}
\ No newline at end of file
}
/* Intermediate Result Style */
.intermediate
{
/* border: 1px solid blue; */
input
{
width
:
80px
;
height
:
32px
;
padding-left
:
8px
;
}
.strange
{
margin-top
:
2px
;
}
.range
{
.heng
{
margin-left
:
6px
;
margin-right
:
6px
;
}
}
}
test/tuner_test.py
View file @
e1ae623f
...
...
@@ -76,8 +76,8 @@ def run(dispatch_type):
dipsatcher_list
=
TUNER_LIST
if
dispatch_type
==
'Tuner'
else
ASSESSOR_LIST
for
dispatcher_name
in
dipsatcher_list
:
try
:
#
s
leep
5 seconds
here
,
to make sure previous stopped exp has enough time to exit to avoid port conflict
time
.
sleep
(
5
)
#
S
leep here to make sure previous stopped exp has enough time to exit to avoid port conflict
time
.
sleep
(
6
)
test_builtin_dispatcher
(
dispatch_type
,
dispatcher_name
)
print
(
GREEN
+
'Test %s %s: TEST PASS'
%
(
dispatcher_name
,
dispatch_type
)
+
CLEAR
)
except
Exception
as
error
:
...
...
tools/nni_cmd/config_schema.py
View file @
e1ae623f
...
...
@@ -36,6 +36,7 @@ Optional('nniManagerIp'): str,
Optional
(
'logDir'
):
os
.
path
.
isdir
,
Optional
(
'debug'
):
bool
,
Optional
(
'logLevel'
):
Or
(
'trace'
,
'debug'
,
'info'
,
'warning'
,
'error'
,
'fatal'
),
Optional
(
'logCollection'
):
Or
(
'http'
,
'none'
),
'useAnnotation'
:
bool
,
Optional
(
'advisor'
):
Or
({
'builtinAdvisorName'
:
Or
(
'Hyperband'
),
...
...
@@ -57,6 +58,7 @@ Optional('tuner'): Or({
Optional
(
'classArgs'
):
{
'optimize_mode'
:
Or
(
'maximize'
,
'minimize'
)
},
Optional
(
'includeIntermediateResults'
):
bool
,
Optional
(
'gpuNum'
):
And
(
int
,
lambda
x
:
0
<=
x
<=
99999
),
},{
'builtinTunerName'
:
Or
(
'BatchTuner'
,
'GridSearch'
),
...
...
tools/nni_cmd/launcher.py
View file @
e1ae623f
...
...
@@ -274,6 +274,8 @@ def set_experiment(experiment_config, mode, port, config_file_name):
#debug mode should disable version check
if
experiment_config
.
get
(
'debug'
)
is
not
None
:
request_data
[
'versionCheck'
]
=
not
experiment_config
.
get
(
'debug'
)
if
experiment_config
.
get
(
'logCollection'
):
request_data
[
'logCollection'
]
=
experiment_config
.
get
(
'logCollection'
)
request_data
[
'clusterMetaData'
]
=
[]
if
experiment_config
[
'trainingServicePlatform'
]
==
'local'
:
...
...
tools/nni_trial_tool/log_utils.py
View file @
e1ae623f
...
...
@@ -25,6 +25,7 @@ import logging
import
logging.handlers
import
time
import
threading
import
re
from
datetime
import
datetime
from
enum
import
Enum
,
unique
...
...
@@ -81,7 +82,7 @@ class RemoteLogger(object):
"""
NNI remote logger
"""
def
__init__
(
self
,
syslog_host
,
syslog_port
,
tag
,
std_output_type
,
log_level
=
logging
.
INFO
):
def
__init__
(
self
,
syslog_host
,
syslog_port
,
tag
,
std_output_type
,
log_collection
,
log_level
=
logging
.
INFO
):
'''
constructor
'''
...
...
@@ -94,12 +95,13 @@ class RemoteLogger(object):
self
.
orig_stdout
=
sys
.
__stdout__
else
:
self
.
orig_stdout
=
sys
.
__stderr__
self
.
log_collection
=
log_collection
def
get_pipelog_reader
(
self
):
'''
Get pipe for remote logger
'''
return
PipeLogReader
(
self
.
logger
,
logging
.
INFO
)
return
PipeLogReader
(
self
.
logger
,
self
.
log_collection
,
logging
.
INFO
)
def
write
(
self
,
buf
):
'''
...
...
@@ -117,7 +119,7 @@ class PipeLogReader(threading.Thread):
"""
The reader thread reads log data from pipe
"""
def
__init__
(
self
,
logger
,
log_level
=
logging
.
INFO
):
def
__init__
(
self
,
logger
,
log_collection
,
log_level
=
logging
.
INFO
):
"""Setup the object with a logger and a loglevel
and start the thread
"""
...
...
@@ -131,6 +133,8 @@ class PipeLogReader(threading.Thread):
self
.
orig_stdout
=
sys
.
__stdout__
self
.
_is_read_completed
=
False
self
.
process_exit
=
False
self
.
log_collection
=
log_collection
self
.
log_pattern
=
re
.
compile
(
r
'^NNISDK_MEb\'.*\'$'
)
def
_populateQueue
(
stream
,
queue
):
'''
...
...
@@ -143,8 +147,6 @@ class PipeLogReader(threading.Thread):
line
=
self
.
queue
.
get
(
True
,
5
)
try
:
self
.
logger
.
log
(
self
.
log_level
,
line
.
rstrip
())
self
.
orig_stdout
.
write
(
line
.
rstrip
()
+
'
\n
'
)
self
.
orig_stdout
.
flush
()
except
Exception
as
e
:
pass
except
Exception
as
e
:
...
...
@@ -165,9 +167,17 @@ class PipeLogReader(threading.Thread):
def
run
(
self
):
"""Run the thread, logging everything.
If the log_collection is 'none', the log content will not be enqueued
"""
for
line
in
iter
(
self
.
pipeReader
.
readline
,
''
):
self
.
orig_stdout
.
write
(
line
.
rstrip
()
+
'
\n
'
)
self
.
orig_stdout
.
flush
()
if
self
.
log_collection
==
'none'
:
# If not match metrics, do not put the line into queue
if
not
self
.
log_pattern
.
match
(
line
):
continue
self
.
queue
.
put
(
line
)
self
.
pipeReader
.
close
()
def
close
(
self
):
...
...
Prev
1
2
3
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