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
37843558
Unverified
Commit
37843558
authored
Jan 09, 2019
by
SparkSnail
Committed by
GitHub
Jan 09, 2019
Browse files
Merge pull request #113 from Microsoft/master
merge master
parents
85cb472e
c288a16e
Changes
41
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
650 additions
and
105 deletions
+650
-105
src/sdk/pynni/nni/common.py
src/sdk/pynni/nni/common.py
+1
-2
src/sdk/pynni/nni/msg_dispatcher.py
src/sdk/pynni/nni/msg_dispatcher.py
+1
-0
src/sdk/pynni/nni/msg_dispatcher_base.py
src/sdk/pynni/nni/msg_dispatcher_base.py
+22
-3
src/sdk/pynni/nni/platform/local.py
src/sdk/pynni/nni/platform/local.py
+2
-2
src/sdk/pynni/nni/tuner.py
src/sdk/pynni/nni/tuner.py
+1
-0
src/webui/src/App.css
src/webui/src/App.css
+5
-0
src/webui/src/App.tsx
src/webui/src/App.tsx
+6
-4
src/webui/src/components/Overview.tsx
src/webui/src/components/Overview.tsx
+5
-1
src/webui/src/components/TrialsDetail.tsx
src/webui/src/components/TrialsDetail.tsx
+28
-1
src/webui/src/components/logPath/PaiTrialChild.tsx
src/webui/src/components/logPath/PaiTrialChild.tsx
+55
-0
src/webui/src/components/logPath/PaiTrialLog.tsx
src/webui/src/components/logPath/PaiTrialLog.tsx
+72
-0
src/webui/src/components/logPath/TrialLog.tsx
src/webui/src/components/logPath/TrialLog.tsx
+30
-0
src/webui/src/components/overview/Progress.tsx
src/webui/src/components/overview/Progress.tsx
+42
-45
src/webui/src/components/overview/SuccessTable.tsx
src/webui/src/components/overview/SuccessTable.tsx
+121
-20
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+128
-26
src/webui/src/static/style/probar.scss
src/webui/src/static/style/probar.scss
+2
-1
src/webui/src/static/style/progress.scss
src/webui/src/static/style/progress.scss
+1
-0
src/webui/src/static/style/tableList.scss
src/webui/src/static/style/tableList.scss
+46
-0
test/async_sharing_test/config.yml
test/async_sharing_test/config.yml
+25
-0
test/async_sharing_test/main.py
test/async_sharing_test/main.py
+57
-0
No files found.
src/sdk/pynni/nni/common.py
View file @
37843558
...
...
@@ -66,8 +66,7 @@ def init_logger(logger_file_path):
elif
env_args
.
log_dir
is
not
None
:
logger_file_path
=
os
.
path
.
join
(
env_args
.
log_dir
,
logger_file_path
)
logger_file
=
open
(
logger_file_path
,
'w'
)
fmt
=
'[%(asctime)s] %(levelname)s (%(name)s) %(message)s'
fmt
=
'[%(asctime)s] %(levelname)s (%(name)s/%(threadName)s) %(message)s'
formatter
=
logging
.
Formatter
(
fmt
,
_time_format
)
handler
=
logging
.
StreamHandler
(
logger_file
)
...
...
src/sdk/pynni/nni/msg_dispatcher.py
View file @
37843558
...
...
@@ -97,6 +97,7 @@ class MsgDispatcher(MsgDispatcherBase):
def
handle_request_trial_jobs
(
self
,
data
):
# data: number or trial jobs
ids
=
[
_create_parameter_id
()
for
_
in
range
(
data
)]
_logger
.
debug
(
"requesting for generating params of {}"
.
format
(
ids
))
params_list
=
self
.
tuner
.
generate_multiple_parameters
(
ids
)
for
i
,
_
in
enumerate
(
params_list
):
...
...
src/sdk/pynni/nni/msg_dispatcher_base.py
View file @
37843558
...
...
@@ -19,10 +19,14 @@
# ==================================================================================================
#import json_tricks
import
os
import
logging
import
json_tricks
import
os
from
queue
import
Queue
import
sys
from
multiprocessing.dummy
import
Pool
as
ThreadPool
import
json_tricks
from
.common
import
init_logger
,
multi_thread_enabled
from
.recoverable
import
Recoverable
from
.protocol
import
CommandType
,
receive
...
...
@@ -34,6 +38,7 @@ class MsgDispatcherBase(Recoverable):
def
__init__
(
self
):
if
multi_thread_enabled
():
self
.
pool
=
ThreadPool
()
self
.
thread_results
=
[]
def
run
(
self
):
"""Run the tuner.
...
...
@@ -49,7 +54,11 @@ class MsgDispatcherBase(Recoverable):
if
command
is
None
or
command
is
CommandType
.
Terminate
:
break
if
multi_thread_enabled
():
self
.
pool
.
map_async
(
self
.
handle_request
,
[(
command
,
data
)])
result
=
self
.
pool
.
map_async
(
self
.
handle_request_thread
,
[(
command
,
data
)])
self
.
thread_results
.
append
(
result
)
if
any
([
thread_result
.
ready
()
and
not
thread_result
.
successful
()
for
thread_result
in
self
.
thread_results
]):
_logger
.
debug
(
'Caught thread exception'
)
break
else
:
self
.
handle_request
((
command
,
data
))
...
...
@@ -59,6 +68,16 @@ class MsgDispatcherBase(Recoverable):
_logger
.
info
(
'Terminated by NNI manager'
)
def
handle_request_thread
(
self
,
request
):
if
multi_thread_enabled
():
try
:
self
.
handle_request
(
request
)
except
Exception
as
e
:
_logger
.
exception
(
str
(
e
))
raise
else
:
pass
def
handle_request
(
self
,
request
):
command
,
data
=
request
...
...
src/sdk/pynni/nni/platform/local.py
View file @
37843558
...
...
@@ -36,7 +36,7 @@ if not os.path.exists(_outputdir):
os
.
makedirs
(
_outputdir
)
_nni_platform
=
os
.
environ
[
'NNI_PLATFORM'
]
if
_nni_platform
not
in
[
'pai'
,
'kubeflow'
]:
if
_nni_platform
not
in
[
'pai'
,
'kubeflow'
,
'frameworkcontroller'
]:
_log_file_path
=
os
.
path
.
join
(
_outputdir
,
'trial.log'
)
init_logger
(
_log_file_path
)
...
...
@@ -77,7 +77,7 @@ def get_next_parameter():
return
params
def
send_metric
(
string
):
if
_nni_platform
in
[
'pai'
,
'kubeflow'
]:
if
_nni_platform
in
[
'pai'
,
'kubeflow'
,
'frameworkcontroller'
]:
data
=
(
string
).
encode
(
'utf8'
)
assert
len
(
data
)
<
1000000
,
'Metric too long'
print
(
'NNISDK_ME%s'
%
(
data
))
...
...
src/sdk/pynni/nni/tuner.py
View file @
37843558
...
...
@@ -48,6 +48,7 @@ class Tuner(Recoverable):
result
=
[]
for
parameter_id
in
parameter_id_list
:
try
:
_logger
.
debug
(
"generating param for {}"
.
format
(
parameter_id
))
res
=
self
.
generate_parameters
(
parameter_id
)
except
nni
.
NoMoreTrialError
:
return
result
...
...
src/webui/src/App.css
View file @
37843558
...
...
@@ -17,12 +17,17 @@
.headerCon
{
min-width
:
1024px
;
}
.contentBox
{
width
:
100%
;
background
:
#f2f2f2
;
}
.content
{
width
:
86%
;
min-width
:
1024px
;
margin
:
0
auto
;
margin-top
:
74px
;
margin-bottom
:
30px
;
background
:
#fff
;
}
src/webui/src/App.tsx
View file @
37843558
...
...
@@ -6,18 +6,20 @@ import SlideBar from './components/SlideBar';
class
App
extends
React
.
Component
<
{},
{}
>
{
render
()
{
return
(
<
Row
className
=
"nni"
>
<
Row
className
=
"nni"
style
=
{
{
minHeight
:
window
.
innerHeight
}
}
>
<
Row
className
=
"header"
>
<
Col
span
=
{
1
}
/>
<
Col
className
=
"headerCon"
span
=
{
22
}
>
<
SlideBar
/>
</
Col
>
<
Col
span
=
{
1
}
/>
<
Col
span
=
{
1
}
/>
</
Row
>
<
Row
className
=
"contentBox"
>
<
Row
className
=
"content"
>
{
this
.
props
.
children
}
</
Row
>
</
Row
>
</
Row
>
);
}
}
...
...
src/webui/src/components/Overview.tsx
View file @
37843558
...
...
@@ -215,6 +215,7 @@ class Overview extends React.Component<{}, OverviewState> {
case
'
USER_CANCELED
'
:
case
'
SYS_CANCELED
'
:
case
'
EARLY_STOPPED
'
:
profile
.
stopTrial
+=
1
;
break
;
case
'
SUCCEEDED
'
:
...
...
@@ -461,7 +462,10 @@ class Overview extends React.Component<{}, OverviewState> {
</
Row
>
</
Col
>
<
Col
span
=
{
16
}
id
=
"succeTable"
>
<
SuccessTable
tableSource
=
{
tableData
}
/>
<
SuccessTable
tableSource
=
{
tableData
}
trainingPlatform
=
{
trialProfile
.
trainingServicePlatform
}
/>
</
Col
>
</
Row
>
</
div
>
...
...
src/webui/src/components/TrialsDetail.tsx
View file @
37843558
...
...
@@ -21,6 +21,7 @@ interface TrialDetailState {
isHasSearch
:
boolean
;
experimentStatus
:
string
;
entriesTable
:
number
;
experimentPlatform
:
string
;
}
class
TrialsDetail
extends
React
.
Component
<
{},
TrialDetailState
>
{
...
...
@@ -43,6 +44,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
experimentStatus
:
''
,
entriesTable
:
20
,
isHasSearch
:
false
,
experimentPlatform
:
''
};
}
// trial accuracy graph
...
...
@@ -370,6 +372,26 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
alert
(
'
TableList component was not properly initialized.
'
);
}
checkExperimentPlatform
=
()
=>
{
axios
(
`
${
MANAGER_IP
}
/experiment`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
const
trainingPlatform
=
res
.
data
.
params
.
trainingServicePlatform
!==
undefined
?
res
.
data
.
params
.
trainingServicePlatform
:
''
;
if
(
this
.
_isMounted
)
{
this
.
setState
({
experimentPlatform
:
trainingPlatform
});
}
}
});
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
...
...
@@ -377,6 +399,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
this
.
drawPointGraph
();
this
.
interTableList
=
window
.
setInterval
(
this
.
drawTableList
,
10000
);
this
.
interAccuracy
=
window
.
setInterval
(
this
.
drawPointGraph
,
10000
);
this
.
checkExperimentPlatform
();
}
componentWillUnmount
()
{
...
...
@@ -386,7 +409,10 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
render
()
{
const
{
accSource
,
accNodata
,
tableListSource
,
entriesTable
,
searchResultSource
,
isHasSearch
}
=
this
.
state
;
const
{
accSource
,
accNodata
,
tableListSource
,
entriesTable
,
searchResultSource
,
isHasSearch
,
experimentPlatform
}
=
this
.
state
;
const
titleOfacc
=
(
<
Title1
text
=
"Default Metric"
icon
=
"3.png"
/>
);
...
...
@@ -463,6 +489,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
updateList
=
{
this
.
drawTableList
}
searchResult
=
{
searchResultSource
}
isHasSearch
=
{
isHasSearch
}
platform
=
{
experimentPlatform
}
ref
=
{
(
tabList
)
=>
this
.
tableList
=
tabList
}
/>
</
div
>
...
...
src/webui/src/components/logPath/PaiTrialChild.tsx
0 → 100644
View file @
37843558
import
*
as
React
from
'
react
'
;
import
{
Row
,
Button
}
from
'
antd
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
interface
PaiTrialChildProps
{
logString
:
string
;
id
:
string
;
showLogModal
:
Function
;
isdisLogbtn
?:
boolean
;
}
class
PaiTrialChild
extends
React
.
Component
<
PaiTrialChildProps
,
{}
>
{
constructor
(
props
:
PaiTrialChildProps
)
{
super
(
props
);
}
render
()
{
const
{
logString
,
id
,
showLogModal
,
isdisLogbtn
}
=
this
.
props
;
return
(
<
div
>
{
logString
===
''
?
<
div
/>
:
<
Row
>
<
Row
>
<
a
target
=
"_blank"
href
=
{
`
${
DOWNLOAD_IP
}
/trial_
${
id
}
.log`
}
style
=
{
{
marginRight
:
10
}
}
>
trial stdout
</
a
>
</
Row
>
<
Row
>
<
Button
disabled
=
{
isdisLogbtn
}
type
=
"primary"
className
=
"tableButton"
onClick
=
{
showLogModal
.
bind
(
this
,
id
)
}
>
View
</
Button
>
</
Row
>
</
Row
>
}
</
div
>
);
}
}
export
default
PaiTrialChild
;
src/webui/src/components/logPath/PaiTrialLog.tsx
0 → 100644
View file @
37843558
import
*
as
React
from
'
react
'
;
import
{
Row
,
Button
}
from
'
antd
'
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
PaiTrialChild
from
'
./PaiTrialChild
'
;
interface
PaitrialLogProps
{
logStr
:
string
;
id
:
string
;
showLogModal
:
Function
;
trialStatus
?:
string
;
isdisLogbutton
?:
boolean
;
}
class
PaitrialLog
extends
React
.
Component
<
PaitrialLogProps
,
{}
>
{
constructor
(
props
:
PaitrialLogProps
)
{
super
(
props
);
}
render
()
{
const
{
logStr
,
id
,
showLogModal
,
isdisLogbutton
}
=
this
.
props
;
const
isTwopath
=
logStr
.
indexOf
(
'
,
'
)
!==
-
1
?
true
:
false
;
return
(
<
div
>
<
div
>
{
isTwopath
?
<
Row
>
<
Row
>
<
a
target
=
"_blank"
href
=
{
`
${
DOWNLOAD_IP
}
/trial_
${
id
}
.log`
}
style
=
{
{
marginRight
:
10
}
}
>
trial stdout
</
a
>
<
a
target
=
"_blank"
href
=
{
logStr
.
split
(
'
,
'
)[
1
]
}
>
hdfsLog
</
a
>
</
Row
>
<
Row
>
<
Button
disabled
=
{
isdisLogbutton
}
type
=
"primary"
className
=
"tableButton"
onClick
=
{
showLogModal
.
bind
(
this
,
id
)
}
>
View
</
Button
>
</
Row
>
</
Row
>
:
<
PaiTrialChild
logString
=
{
logStr
}
id
=
{
id
}
showLogModal
=
{
showLogModal
}
isdisLogbtn
=
{
isdisLogbutton
}
/>
}
</
div
>
</
div
>
);
}
}
export
default
PaitrialLog
;
src/webui/src/components/logPath/TrialLog.tsx
0 → 100644
View file @
37843558
import
*
as
React
from
'
react
'
;
import
LogPathChild
from
'
./LogPathChild
'
;
interface
TrialLogProps
{
logStr
:
string
;
id
:
string
;
}
class
TrialLog
extends
React
.
Component
<
TrialLogProps
,
{}
>
{
constructor
(
props
:
TrialLogProps
)
{
super
(
props
);
}
render
()
{
const
{
logStr
}
=
this
.
props
;
return
(
<
div
>
<
LogPathChild
eachLogpath
=
{
logStr
}
logName
=
"LogPath:"
/>
</
div
>
);
}
}
export
default
TrialLog
;
src/webui/src/components/overview/Progress.tsx
View file @
37843558
import
*
as
React
from
'
react
'
;
import
{
Row
,
Col
,
Popover
,
Button
,
message
Row
,
Col
,
Popover
,
Button
,
message
}
from
'
antd
'
;
import
axios
from
'
axios
'
;
import
{
MANAGER_IP
,
CONTROLTYPE
}
from
'
../../static/const
'
;
...
...
@@ -92,7 +88,8 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
if
(
error
.
response
.
data
.
error
)
{
message
.
error
(
error
.
response
.
data
.
error
);
}
else
{
message
.
error
(
`Update
${
CONTROLTYPE
[
1
].
toLocaleLowerCase
()}
failed`
);
message
.
error
(
`Update
${
CONTROLTYPE
[
1
].
toLocaleLowerCase
()}
failed`
);
}
}
});
...
...
@@ -179,7 +176,6 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
return
(
<
Row
className
=
"progress"
id
=
"barBack"
>
<
Row
className
=
"basic lineBasic"
>
<
Col
span
=
{
12
}
>
<
p
>
Status
</
p
>
<
div
className
=
"status"
>
<
span
className
=
{
status
}
>
{
status
}
</
span
>
...
...
@@ -198,10 +194,29 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
<
span
/>
}
</
div
>
</
Row
>
<
ProgressBar
who
=
"Duration"
percent
=
{
percent
}
description
=
{
runDuration
}
bgclass
=
{
status
}
maxString
=
{
`MaxDuration:
${
convertTime
(
trialProfile
.
maxDuration
)}
`
}
/>
<
ProgressBar
who
=
"TrialNum"
percent
=
{
bar2Percent
}
description
=
{
bar2
.
toString
()
}
bgclass
=
{
status
}
maxString
=
{
`MaxTrialNumber:
${
trialProfile
.
MaxTrialNum
}
`
}
/>
<
Row
className
=
"basic colorOfbasic mess"
>
<
Col
span
=
{
10
}
>
<
p
>
best metric
</
p
>
<
div
>
{
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
</
Col
>
<
Col
span
=
{
1
2
}
>
<
Col
span
=
{
1
4
}
>
{
/* modify concurrency */
}
<
p
>
C
oncurrency
</
p
>
<
p
>
c
oncurrency
</
p
>
<
Row
className
=
"inputBox"
>
<
input
type
=
"number"
...
...
@@ -227,24 +242,6 @@ class Progressed extends React.Component<ProgressProps, ProgressState> {
</
Row
>
</
Col
>
</
Row
>
<
ProgressBar
who
=
"Duration"
percent
=
{
percent
}
description
=
{
runDuration
}
bgclass
=
{
status
}
maxString
=
{
`MaxDuration:
${
convertTime
(
trialProfile
.
maxDuration
)}
`
}
/>
<
ProgressBar
who
=
"TrialNum"
percent
=
{
bar2Percent
}
description
=
{
bar2
.
toString
()
}
bgclass
=
{
status
}
maxString
=
{
`MaxTrialNumber:
${
trialProfile
.
MaxTrialNum
}
`
}
/>
<
Row
className
=
"basic colorOfbasic mess"
>
<
p
>
best metric
</
p
>
<
div
>
{
bestAccuracy
}
</
div
>
</
Row
>
<
Row
className
=
"mess"
>
<
Col
span
=
{
8
}
>
<
Row
className
=
"basic colorOfbasic"
>
...
...
src/webui/src/components/overview/SuccessTable.tsx
View file @
37843558
import
*
as
React
from
'
react
'
;
import
axios
from
'
axios
'
;
import
JSONTree
from
'
react-json-tree
'
;
import
{
Table
}
from
'
antd
'
;
import
{
Row
,
Modal
,
Input
,
Table
,
Tabs
}
from
'
antd
'
;
const
TabPane
=
Tabs
.
TabPane
;
const
{
TextArea
}
=
Input
;
import
{
DOWNLOAD_IP
}
from
'
../../static/const
'
;
import
{
TableObj
}
from
'
../../static/interface
'
;
import
{
convertDuration
}
from
'
../../static/function
'
;
import
PaiTrialLog
from
'
../logPath/PaiTrialLog
'
;
import
TrialLog
from
'
../logPath/TrialLog
'
;
import
'
../../static/style/tableStatus.css
'
;
import
LogPath
from
'
../logPath/LogPath
'
;
import
'
../../static/style/tableList.scss
'
;
interface
SuccessTableProps
{
tableSource
:
Array
<
TableObj
>
;
trainingPlatform
:
string
;
}
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
{}
>
{
interface
SuccessTableState
{
isShowLogModal
:
boolean
;
logContent
:
string
;
}
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
SuccessTableState
>
{
public
_isMounted
=
false
;
constructor
(
props
:
SuccessTableProps
)
{
super
(
props
);
this
.
state
=
{
isShowLogModal
:
false
,
logContent
:
''
};
}
showLogModalOverview
=
(
id
:
string
)
=>
{
axios
(
`
${
DOWNLOAD_IP
}
/trial_
${
id
}
.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
logContent
:
res
.
data
}));
}
}
})
.
catch
(
error
=>
{
if
(
error
.
response
.
status
===
500
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
logContent
:
'
failed to get log message
'
}));
}
}
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
isShowLogModal
:
true
});
}
}
hideLogModalOverview
=
()
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
({
isShowLogModal
:
false
,
logContent
:
''
// close modal, delete data
});
}
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
}
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
}
render
()
{
const
{
tableSource
}
=
this
.
props
;
const
{
tableSource
,
trainingPlatform
}
=
this
.
props
;
const
{
isShowLogModal
,
logContent
}
=
this
.
state
;
let
bgColor
=
''
;
const
columns
=
[{
...
...
@@ -114,6 +180,9 @@ class SuccessTable extends React.Component<SuccessTableProps, {}> {
'
This trial
\'
s logPath are not available.
'
;
return
(
<
pre
id
=
"description"
className
=
"hyperpar"
>
<
Row
className
=
"openRowContent"
>
<
Tabs
tabPosition
=
"left"
className
=
"card"
>
<
TabPane
tab
=
"Parameters"
key
=
"1"
>
{
isHasParameters
?
...
...
@@ -129,7 +198,22 @@ class SuccessTable extends React.Component<SuccessTableProps, {}> {
<
span
className
=
"error"
>
'This trial's parameters are not available.'
</
span
>
</
div
>
}
<
LogPath
logStr
=
{
logPathRow
}
/>
</
TabPane
>
<
TabPane
tab
=
"Log"
key
=
"2"
>
{
trainingPlatform
===
'
pai
'
||
trainingPlatform
===
'
kubeflow
'
?
<
PaiTrialLog
logStr
=
{
logPathRow
}
id
=
{
record
.
id
}
showLogModal
=
{
this
.
showLogModalOverview
}
/>
:
<
TrialLog
logStr
=
{
logPathRow
}
id
=
{
record
.
id
}
/>
}
</
TabPane
>
</
Tabs
>
</
Row
>
</
pre
>
);
};
...
...
@@ -142,6 +226,23 @@ class SuccessTable extends React.Component<SuccessTableProps, {}> {
className
=
"commonTableStyle"
pagination
=
{
false
}
/>
{
/* trial log modal */
}
<
Modal
title
=
"trial log"
visible
=
{
isShowLogModal
}
onCancel
=
{
this
.
hideLogModalOverview
}
footer
=
{
null
}
destroyOnClose
=
{
true
}
width
=
"80%"
>
<
div
id
=
"trialLogContent"
style
=
{
{
height
:
window
.
innerHeight
*
0.6
}
}
>
<
TextArea
value
=
{
logContent
}
disabled
=
{
true
}
className
=
"logcontent"
/>
</
div
>
</
Modal
>
</
div
>
);
}
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
37843558
...
...
@@ -2,18 +2,24 @@ import * as React from 'react';
import
axios
from
'
axios
'
;
import
JSONTree
from
'
react-json-tree
'
;
import
ReactEcharts
from
'
echarts-for-react
'
;
import
{
Row
,
Table
,
Button
,
Popconfirm
,
Modal
,
message
,
Checkbox
}
from
'
antd
'
;
import
{
Row
,
Input
,
Table
,
Tabs
,
Button
,
Popconfirm
,
Modal
,
message
,
Checkbox
}
from
'
antd
'
;
const
{
TextArea
}
=
Input
;
const
TabPane
=
Tabs
.
TabPane
;
const
CheckboxGroup
=
Checkbox
.
Group
;
import
{
MANAGER_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
MANAGER_IP
,
DOWNLOAD_IP
,
trialJobStatus
,
COLUMN
,
COLUMN_INDEX
}
from
'
../../static/const
'
;
import
{
convertDuration
}
from
'
../../static/function
'
;
import
{
TableObjFianl
,
TrialJob
}
from
'
../../static/interface
'
;
import
LogPath
from
'
../logPath/LogPath
'
;
import
PaiTrialLog
from
'
../logPath/PaiTrialLog
'
;
import
TrialLog
from
'
../logPath/TrialLog
'
;
import
'
../../static/style/search.scss
'
;
require
(
'
../../static/style/tableStatus.css
'
);
require
(
'
../../static/style/logPath.scss
'
);
require
(
'
../../static/style/search.scss
'
);
require
(
'
../../static/style/table.scss
'
);
require
(
'
../../static/style/button.scss
'
);
require
(
'
../../static/style/tableList.scss
'
);
const
echarts
=
require
(
'
echarts/lib/echarts
'
);
require
(
'
echarts/lib/chart/line
'
);
require
(
'
echarts/lib/component/tooltip
'
);
...
...
@@ -28,6 +34,7 @@ interface TableListProps {
searchResult
:
Array
<
TableObjFianl
>
;
updateList
:
Function
;
isHasSearch
:
boolean
;
platform
:
string
;
}
interface
TableListState
{
...
...
@@ -36,6 +43,8 @@ interface TableListState {
isObjFinal
:
boolean
;
isShowColumn
:
boolean
;
columnSelected
:
Array
<
string
>
;
// user select columnKeys
logModal
:
boolean
;
logMessage
:
string
;
}
interface
ColumnIndex
{
...
...
@@ -46,6 +55,9 @@ interface ColumnIndex {
class
TableList
extends
React
.
Component
<
TableListProps
,
TableListState
>
{
public
_isMounted
=
false
;
public
intervalTrialLog
=
10
;
public
_trialId
:
string
;
constructor
(
props
:
TableListProps
)
{
super
(
props
);
...
...
@@ -54,7 +66,9 @@ class TableList extends React.Component<TableListProps, TableListState> {
modalVisible
:
false
,
isObjFinal
:
false
,
isShowColumn
:
false
,
logModal
:
false
,
columnSelected
:
COLUMN
,
logMessage
:
''
};
}
...
...
@@ -92,6 +106,51 @@ class TableList extends React.Component<TableListProps, TableListState> {
}
}
updateTrialLogMessage
=
(
id
:
string
)
=>
{
this
.
_trialId
=
id
;
axios
(
`
${
DOWNLOAD_IP
}
/trial_
${
this
.
_trialId
}
.log`
,
{
method
:
'
GET
'
})
.
then
(
res
=>
{
if
(
res
.
status
===
200
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
logMessage
:
res
.
data
}));
}
}
})
.
catch
(
error
=>
{
if
(
error
.
response
.
status
===
500
)
{
if
(
this
.
_isMounted
)
{
this
.
setState
(()
=>
({
logMessage
:
'
failed to get log message
'
}));
}
}
});
}
showLogModal
=
(
id
:
string
)
=>
{
this
.
updateTrialLogMessage
(
id
);
this
.
intervalTrialLog
=
window
.
setInterval
(
this
.
updateTrialLogMessage
.
bind
(
this
,
this
.
_trialId
),
10000
);
if
(
this
.
_isMounted
)
{
this
.
setState
({
logModal
:
true
});
}
}
hideLogModal
=
()
=>
{
window
.
clearInterval
(
this
.
intervalTrialLog
);
if
(
this
.
_isMounted
)
{
this
.
setState
({
logModal
:
false
,
logMessage
:
''
});
}
}
hideShowColumnModal
=
()
=>
{
if
(
this
.
_isMounted
)
{
this
.
setState
({
...
...
@@ -235,11 +294,14 @@ class TableList extends React.Component<TableListProps, TableListState> {
render
()
{
const
{
entries
,
tableSource
,
searchResult
,
isHasSearch
}
=
this
.
props
;
const
{
entries
,
tableSource
,
searchResult
,
isHasSearch
,
platform
}
=
this
.
props
;
const
{
intermediateOption
,
modalVisible
,
isShowColumn
,
columnSelected
,
logMessage
,
logModal
}
=
this
.
state
;
let
showTitle
=
COLUMN
;
let
bgColor
=
''
;
const
trialJob
:
Array
<
TrialJob
>
=
[];
const
showColumn
:
Array
<
object
>
=
[];
if
(
tableSource
.
length
>=
1
)
{
const
temp
=
tableSource
[
0
].
acc
;
if
(
temp
!==
undefined
&&
typeof
temp
===
'
object
'
)
{
...
...
@@ -256,16 +318,12 @@ class TableList extends React.Component<TableListProps, TableListState> {
}
}
}
let
bgColor
=
''
;
const
trialJob
:
Array
<
TrialJob
>
=
[];
trialJobStatus
.
map
(
item
=>
{
trialJob
.
push
({
text
:
item
,
value
:
item
});
});
const
showColumn
:
Array
<
object
>
=
[];
Object
.
keys
(
columnSelected
).
map
(
key
=>
{
const
item
=
columnSelected
[
key
];
switch
(
item
)
{
...
...
@@ -473,12 +531,20 @@ class TableList extends React.Component<TableListProps, TableListState> {
record
.
description
.
logPath
:
'
This trial
\'
s logPath are not available.
'
;
const
isdisLogbutton
=
record
.
status
===
'
WAITING
'
?
true
:
false
;
return
(
<
pre
id
=
"allList"
className
=
"hyperpar"
>
<
Row
className
=
"openRowContent"
>
<
Tabs
tabPosition
=
"left"
className
=
"card"
>
<
TabPane
tab
=
"Parameters"
key
=
"1"
>
{
isHasParameters
?
<
JSONTree
<
JSONTree
hideRoot
=
{
true
}
shouldExpandNode
=
{
()
=>
true
}
// default expandNode
getItemString
=
{
()
=>
(<
span
/>)
}
// remove the {} items
...
...
@@ -490,7 +556,24 @@ class TableList extends React.Component<TableListProps, TableListState> {
<
span
className
=
"error"
>
'This trial's parameters are not available.'
</
span
>
</
div
>
}
<
LogPath
logStr
=
{
logPathRow
}
/>
</
TabPane
>
<
TabPane
tab
=
"Log"
key
=
"2"
>
{
platform
===
'
pai
'
||
platform
===
'
kubeflow
'
?
<
PaiTrialLog
logStr
=
{
logPathRow
}
id
=
{
record
.
id
}
showLogModal
=
{
this
.
showLogModal
}
trialStatus
=
{
record
.
status
}
isdisLogbutton
=
{
isdisLogbutton
}
/>
:
<
TrialLog
logStr
=
{
logPathRow
}
id
=
{
record
.
id
}
/>
}
</
TabPane
>
</
Tabs
>
</
Row
>
</
pre
>
);
};
...
...
@@ -523,6 +606,24 @@ 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
...
...
@@ -540,6 +641,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
className
=
"titleColumn"
/>
</
Modal
>
</
Row
>
);
}
...
...
src/webui/src/static/style/probar.scss
View file @
37843558
#barBack
{
/* status: 'INITIALIZED' | 'RUNNING' | 'ERROR' | 'STOPPING' | 'STOPPED' | 'DONE' */
.RUNNING
,
.STOPPING
,
.INITIALIZED
{
/* status: 'TUNER_NO_MORE_TRIAL' | 'NO_MORE_TRIAL' */
.RUNNING
,
.STOPPING
,
.INITIALIZED
,
.NO_MORE_TRIAL
,
.TUNER_NO_MORE_TRIAL
{
/* specific status color */
color
:
#0071bc
;
.ant-progress-bg
{
...
...
src/webui/src/static/style/progress.scss
View file @
37843558
...
...
@@ -73,6 +73,7 @@
*/
.inputBox
{
height
:
26px
;
margin-top
:
-3px
;
.concurrencyInput
{
width
:
25%
;
height
:
26px
;
...
...
src/webui/src/static/style/tableList.scss
0 → 100644
View file @
37843558
$color
:
#0071bc
;
.openRowContent
{
.ant-tabs-vertical.ant-tabs-left
.ant-tabs-bar
.ant-tabs-tab
{
text-align
:
left
!
important
;
}
}
.openRowContent
{
.ant-tabs-nav
.ant-tabs-tab
:hover
{
color
:
$color
;
}
}
.openRowContent
{
margin-top
:
15px
;
.card
{
.ant-tabs-vertical
.ant-tabs-bar
.ant-tabs-tab
{
margin
:
0
;
padding
:
8px
12px
;
}
.ant-tabs-nav
.ant-tabs-tab-active
{
color
:
$color
;
font-weight
:
500
;
background
:
#dedede
;
border-left
:
3px
solid
;
}
.ant-tabs-tabpane
{
background
:
#f2f2f2
;
padding
:
10px
20px
;
}
}
}
.trialLog
{
white-space
:
normal
;
color
:
#212121
;
}
#trialLogContent
{
.ant-input-disabled
{
color
:
#212121
;
background-color
:
#fff
;
cursor
:
pointer
;
border
:
none
;
}
.logcontent
{
height
:
100%
;
}
}
test/async_sharing_test/config.yml
0 → 100644
View file @
37843558
authorName
:
default
experimentName
:
example_weight_sharing
trialConcurrency
:
3
maxExecDuration
:
1h
maxTrialNum
:
10
#choice: local, remote, pai
trainingServicePlatform
:
remote
#choice: true, false
useAnnotation
:
false
multiThread
:
true
tuner
:
codeDir
:
.
classFileName
:
simple_tuner.py
className
:
SimpleTuner
trial
:
command
:
python3 main.py
codeDir
:
.
gpuNum
:
0
machineList
:
-
ip
:
10.10.10.10
username
:
bob
passwd
:
bob123
-
ip
:
10.10.10.11
username
:
bob
passwd
:
bob123
test/async_sharing_test/main.py
0 → 100644
View file @
37843558
"""
Test code for weight sharing
need NFS setup and mounted as `/mnt/nfs/nni`
"""
import
hashlib
import
os
import
random
import
time
import
nni
def
generate_rand_file
(
fl_name
):
"""
generate random file and write to `fl_name`
"""
fl_size
=
random
.
randint
(
1024
,
102400
)
fl_dir
=
os
.
path
.
split
(
fl_name
)[
0
]
if
not
os
.
path
.
exists
(
fl_dir
):
os
.
makedirs
(
fl_dir
)
with
open
(
fl_name
,
'wb'
)
as
fout
:
fout
.
write
(
os
.
urandom
(
fl_size
))
def
check_sum
(
fl_name
,
tid
=
None
):
"""
compute checksum for generated file of `fl_name`
"""
hasher
=
hashlib
.
md5
()
with
open
(
fl_name
,
'rb'
)
as
fin
:
for
chunk
in
iter
(
lambda
:
fin
.
read
(
4096
),
b
""
):
hasher
.
update
(
chunk
)
ret
=
hasher
.
hexdigest
()
if
tid
is
not
None
:
ret
=
ret
+
str
(
tid
)
return
ret
if
__name__
==
'__main__'
:
nfs_path
=
'/mnt/nfs/nni/test'
params
=
nni
.
get_next_parameter
()
print
(
params
)
if
params
[
'id'
]
==
0
:
model_file
=
os
.
path
.
join
(
nfs_path
,
str
(
params
[
'id'
]),
'model.dat'
)
generate_rand_file
(
model_file
)
time
.
sleep
(
10
)
nni
.
report_final_result
({
'checksum'
:
check_sum
(
model_file
,
tid
=
params
[
'id'
]),
'path'
:
model_file
})
else
:
model_file
=
params
[
'prev_path'
]
time
.
sleep
(
10
)
nni
.
report_final_result
({
'checksum'
:
check_sum
(
model_file
,
tid
=
params
[
'prev_id'
])
})
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