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
403195f0
Unverified
Commit
403195f0
authored
Jul 15, 2021
by
Yuge Zhang
Committed by
GitHub
Jul 15, 2021
Browse files
Merge branch 'master' into nn-meter
parents
99aa8226
a7278d2d
Changes
207
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
176 additions
and
69 deletions
+176
-69
ts/nni_manager/training_service/test/localTrainingService.test.ts
...anager/training_service/test/localTrainingService.test.ts
+2
-2
ts/nni_manager/yarn.lock
ts/nni_manager/yarn.lock
+31
-0
ts/webui/src/components/public-child/OpenRow.tsx
ts/webui/src/components/public-child/OpenRow.tsx
+22
-5
ts/webui/src/components/trial-detail/search/Search.tsx
ts/webui/src/components/trial-detail/search/Search.tsx
+71
-57
ts/webui/src/static/interface.ts
ts/webui/src/static/interface.ts
+16
-0
ts/webui/src/static/model/experiment.ts
ts/webui/src/static/model/experiment.ts
+29
-5
ts/webui/src/static/style/openRow.scss
ts/webui/src/static/style/openRow.scss
+5
-0
No files found.
ts/nni_manager/training_service/test/localTrainingService.test.ts
View file @
403195f0
...
...
@@ -100,8 +100,8 @@ describe('Unit Test for LocalTrainingService', () => {
fs
.
mkdirSync
(
jobDetail
.
workingDirectory
)
fs
.
writeFileSync
(
path
.
join
(
jobDetail
.
workingDirectory
,
'
trial.log
'
),
'
trial log
'
)
fs
.
writeFileSync
(
path
.
join
(
jobDetail
.
workingDirectory
,
'
stderr
'
),
'
trial stderr
'
)
chai
.
expect
(
await
localTrainingService
.
getTrial
Log
(
jobDetail
.
id
,
'
TRIAL_LOG
'
)).
to
.
be
.
equals
(
'
trial log
'
);
chai
.
expect
(
await
localTrainingService
.
getTrial
Log
(
jobDetail
.
id
,
'
TRIAL_ERROR
'
)).
to
.
be
.
equals
(
'
trial stderr
'
);
chai
.
expect
(
await
localTrainingService
.
getTrial
File
(
jobDetail
.
id
,
'
trial.log
'
)).
to
.
be
.
equals
(
'
trial log
'
);
chai
.
expect
(
await
localTrainingService
.
getTrial
File
(
jobDetail
.
id
,
'
stderr
'
)).
to
.
be
.
equals
(
'
trial stderr
'
);
fs
.
unlinkSync
(
path
.
join
(
jobDetail
.
workingDirectory
,
'
trial.log
'
))
fs
.
unlinkSync
(
path
.
join
(
jobDetail
.
workingDirectory
,
'
stderr
'
))
fs
.
rmdirSync
(
jobDetail
.
workingDirectory
)
...
...
ts/nni_manager/yarn.lock
View file @
403195f0
...
...
@@ -503,6 +503,13 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/http-proxy@^1.17.7":
version "1.17.7"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f"
integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==
dependencies:
"@types/node" "*"
"@types/js-base64@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/js-base64/-/js-base64-3.3.1.tgz#36c2d6dc126277ea28a4d0599d0cafbf547b51e6"
...
...
@@ -2071,6 +2078,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
execa@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
...
...
@@ -2273,6 +2285,11 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
follow-redirects@^1.0.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
...
...
@@ -2715,6 +2732,15 @@ http-proxy-agent@^4.0.1:
agent-base "6"
debug "4"
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
dependencies:
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
...
...
@@ -5010,6 +5036,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
...
...
ts/webui/src/components/public-child/OpenRow.tsx
View file @
403195f0
...
...
@@ -56,8 +56,13 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
}
};
openTrialLog
=
(
type
:
string
):
void
=>
{
window
.
open
(
`
${
MANAGER_IP
}
/trial-log/
${
this
.
props
.
trialId
}
/
${
type
}
`
);
openTrialLog
=
(
filename
:
string
):
void
=>
{
window
.
open
(
`
${
MANAGER_IP
}
/trial-file/
${
this
.
props
.
trialId
}
/
${
filename
}
`
);
};
openModelOnnx
=
():
void
=>
{
// TODO: netron might need prefix.
window
.
open
(
`/netron/index.html?url=
${
MANAGER_IP
}
/trial-file/
${
this
.
props
.
trialId
}
/model.onnx`
);
};
render
():
React
.
ReactNode
{
...
...
@@ -113,16 +118,16 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
<
div
id
=
'trialog'
>
<
div
className
=
'copy'
style
=
{
{
marginTop
:
15
}
}
>
<
PrimaryButton
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
TRIAL_LOG
'
)
}
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
trial.log
'
)
}
text
=
'View trial log'
/>
<
PrimaryButton
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
TRIAL_ERROR
'
)
}
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
stderr
'
)
}
text
=
'View trial error'
styles
=
{
{
root
:
{
marginLeft
:
15
}
}
}
/>
<
PrimaryButton
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
TRIAL_STDOUT
'
)
}
onClick
=
{
this
.
openTrialLog
.
bind
(
this
,
'
stdout
'
)
}
text
=
'View trial stdout'
styles
=
{
{
root
:
{
marginLeft
:
15
}
}
}
/>
...
...
@@ -132,6 +137,18 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
)
}
</
PivotItem
>
{
EXPERIMENT
.
metadata
.
tag
.
includes
(
'
retiarii
'
)
?
(
<
PivotItem
headerText
=
'Visualization'
key
=
'3'
itemIcon
=
'FlowChart'
>
<
div
id
=
'visualization'
>
<
div
id
=
'visualizationText'
>
Visualize models with 3rd-party tools.
</
div
>
<
PrimaryButton
onClick
=
{
this
.
openModelOnnx
.
bind
(
this
)
}
text
=
'Netron'
styles
=
{
{
root
:
{
marginLeft
:
15
}
}
}
/>
</
div
>
</
PivotItem
>
)
:
null
}
</
Pivot
>
</
Stack
>
</
Stack
>
...
...
ts/webui/src/components/trial-detail/search/Search.tsx
View file @
403195f0
...
...
@@ -154,75 +154,89 @@ function Search(props): any {
}
allFilterConditions
.
forEach
(
eachFilterConditionStr
=>
{
let
eachFilterConditionArr
:
string
[]
=
[];
// EXPERIMENT.searchSpace[parameter]._type === 'choice'
if
(
eachFilterConditionStr
.
includes
(
'
>
'
||
'
<
'
))
{
const
operator
=
eachFilterConditionStr
.
includes
(
'
>
'
)
===
true
?
'
>
'
:
'
<
'
;
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
operator
);
newSearchFilter
.
push
({
name
:
eachFilterConditionArr
[
0
],
operator
:
operator
,
value1
:
eachFilterConditionArr
[
1
],
value2
:
''
,
choice
:
[],
isChoice
:
false
});
}
else
if
(
eachFilterConditionStr
.
includes
(
'
≠
'
))
{
// drop_rate≠6; status≠[x,xx,xxx]; conv_size≠[3,7]
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
'
≠
'
);
const
filterName
=
eachFilterConditionArr
[
0
]
===
'
Status
'
?
'
StatusNNI
'
:
eachFilterConditionArr
[
0
];
const
isChoicesType
=
isChoiceType
(
filterName
);
newSearchFilter
.
push
({
name
:
filterName
,
operator
:
'
≠
'
,
value1
:
isChoicesType
?
''
:
JSON
.
parse
(
eachFilterConditionArr
[
1
]),
value2
:
''
,
choice
:
isChoicesType
?
convertStringArrToList
(
eachFilterConditionArr
[
1
])
:
[],
isChoice
:
isChoicesType
?
true
:
false
});
// input content looks like that: `Trial id:`
if
(
eachFilterConditionStr
.
endsWith
(
'
:
'
)
||
eachFilterConditionStr
.
endsWith
(
'
<
'
)
||
eachFilterConditionStr
.
endsWith
(
'
>
'
)
||
eachFilterConditionStr
.
endsWith
(
'
≠
'
)
)
{
return
;
}
else
{
// = : conv_size:[1,2,3,4]; Trial id:3; hidden_size:[1,2], status:[val1,val2,val3]
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
'
:
'
);
const
filterName
=
eachFilterConditionArr
[
0
]
===
'
Status
'
?
'
StatusNNI
'
:
eachFilterConditionArr
[
0
];
const
isChoicesType
=
isChoiceType
(
filterName
);
const
isArray
=
eachFilterConditionArr
.
length
>
1
&&
eachFilterConditionArr
[
1
].
includes
(
'
[
'
||
'
]
'
)
?
true
:
false
;
if
(
isArray
===
true
)
{
if
(
isChoicesType
===
true
)
{
// status:[SUCCEEDED]
newSearchFilter
.
push
({
name
:
filterName
,
operator
:
'
=
'
,
value1
:
''
,
value2
:
''
,
choice
:
convertStringArrToList
(
eachFilterConditionArr
[
1
]),
isChoice
:
true
});
let
eachFilterConditionArr
:
string
[]
=
[];
// EXPERIMENT.searchSpace[parameter]._type === 'choice'
if
(
eachFilterConditionStr
.
includes
(
'
>
'
||
'
<
'
))
{
const
operator
=
eachFilterConditionStr
.
includes
(
'
>
'
)
===
true
?
'
>
'
:
'
<
'
;
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
operator
);
newSearchFilter
.
push
({
name
:
eachFilterConditionArr
[
0
],
operator
:
operator
,
value1
:
eachFilterConditionArr
[
1
],
value2
:
''
,
choice
:
[],
isChoice
:
false
});
}
else
if
(
eachFilterConditionStr
.
includes
(
'
≠
'
))
{
// drop_rate≠6; status≠[x,xx,xxx]; conv_size≠[3,7]
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
'
≠
'
);
const
filterName
=
eachFilterConditionArr
[
0
]
===
'
Status
'
?
'
StatusNNI
'
:
eachFilterConditionArr
[
0
];
const
isChoicesType
=
isChoiceType
(
filterName
);
newSearchFilter
.
push
({
name
:
filterName
,
operator
:
'
≠
'
,
value1
:
isChoicesType
?
''
:
JSON
.
parse
(
eachFilterConditionArr
[
1
]),
value2
:
''
,
choice
:
isChoicesType
?
convertStringArrToList
(
eachFilterConditionArr
[
1
])
:
[],
isChoice
:
isChoicesType
?
true
:
false
});
}
else
if
(
eachFilterConditionStr
.
includes
(
'
:
'
))
{
// = : conv_size:[1,2,3,4]; Trial id:3; hidden_size:[1,2], status:[val1,val2,val3]
eachFilterConditionArr
=
eachFilterConditionStr
.
trim
().
split
(
'
:
'
);
const
filterName
=
eachFilterConditionArr
[
0
]
===
'
Status
'
?
'
StatusNNI
'
:
eachFilterConditionArr
[
0
];
const
isChoicesType
=
isChoiceType
(
filterName
);
const
isArray
=
eachFilterConditionArr
.
length
>
1
&&
eachFilterConditionArr
[
1
].
includes
(
'
[
'
||
'
]
'
)
?
true
:
false
;
if
(
isArray
===
true
)
{
if
(
isChoicesType
===
true
)
{
// status:[SUCCEEDED]
newSearchFilter
.
push
({
name
:
filterName
,
operator
:
'
=
'
,
value1
:
''
,
value2
:
''
,
choice
:
convertStringArrToList
(
eachFilterConditionArr
[
1
]),
isChoice
:
true
});
}
else
{
// drop_rate:[1,10]
newSearchFilter
.
push
({
name
:
eachFilterConditionArr
[
0
],
operator
:
'
between
'
,
value1
:
JSON
.
parse
(
eachFilterConditionArr
[
1
])[
0
],
value2
:
JSON
.
parse
(
eachFilterConditionArr
[
1
])[
1
],
choice
:
[],
isChoice
:
false
});
}
}
else
{
// drop_rate:[1,10]
newSearchFilter
.
push
({
name
:
eachFilterConditionArr
[
0
],
operator
:
'
between
'
,
value1
:
JSON
.
parse
(
eachFilterConditionArr
[
1
]
)[
0
]
,
value2
:
JSON
.
parse
(
eachFilterConditionArr
[
1
])[
1
]
,
operator
:
'
=
'
,
value1
:
eachFilterConditionArr
[
1
],
value2
:
''
,
choice
:
[],
isChoice
:
false
});
}
}
else
{
newSearchFilter
.
push
({
name
:
eachFilterConditionArr
[
0
],
operator
:
'
=
'
,
value1
:
eachFilterConditionArr
[
1
],
value2
:
''
,
choice
:
[],
isChoice
:
false
});
// user input: Trial id
return
;
}
}
});
changeTableListPage
(
newSearchFilter
);
}
...
...
ts/webui/src/static/interface.ts
View file @
403195f0
...
...
@@ -165,6 +165,21 @@ interface ExperimentProfile {
revision
:
number
;
}
interface
ExperimentMetadata
{
id
:
string
;
port
:
number
;
startTime
:
number
|
string
;
endTime
:
number
|
string
;
status
:
string
;
platform
:
string
;
experimentName
:
string
;
tag
:
any
[];
pid
:
number
;
webuiUrl
:
any
[];
logDir
:
string
;
prefixUrl
:
string
|
null
;
}
interface
NNIManagerStatus
{
status
:
string
;
errors
:
string
[];
...
...
@@ -230,6 +245,7 @@ export {
MetricDataRecord
,
TrialJobInfo
,
ExperimentProfile
,
ExperimentMetadata
,
NNIManagerStatus
,
EventMap
,
SingleAxis
,
...
...
ts/webui/src/static/model/experiment.ts
View file @
403195f0
import
{
MANAGER_IP
}
from
'
../const
'
;
import
{
ExperimentConfig
,
toSeconds
}
from
'
../experimentConfig
'
;
import
{
ExperimentProfile
,
NNIManagerStatus
}
from
'
../interface
'
;
import
{
ExperimentProfile
,
ExperimentMetadata
,
NNIManagerStatus
}
from
'
../interface
'
;
import
{
requestAxios
}
from
'
../function
'
;
import
{
SearchSpace
}
from
'
./searchspace
'
;
...
...
@@ -32,8 +32,24 @@ const emptyProfile: ExperimentProfile = {
revision
:
0
};
const
emptyMetadata
:
ExperimentMetadata
=
{
id
:
''
,
port
:
0
,
startTime
:
''
,
endTime
:
''
,
status
:
''
,
platform
:
''
,
experimentName
:
''
,
tag
:
[],
pid
:
0
,
webuiUrl
:
[],
logDir
:
''
,
prefixUrl
:
null
};
class
Experiment
{
private
profileField
?:
ExperimentProfile
;
private
metadataField
?:
ExperimentMetadata
=
undefined
;
private
statusField
?:
NNIManagerStatus
=
undefined
;
private
isNestedExperiment
:
boolean
=
false
;
private
isexperimentError
:
boolean
=
false
;
...
...
@@ -82,10 +98,14 @@ class Experiment {
public
async
update
():
Promise
<
boolean
>
{
let
updated
=
false
;
await
requestAxios
(
`
${
MANAGER_IP
}
/experiment`
)
.
then
(
data
=>
{
updated
=
updated
||
!
compareProfiles
(
this
.
profileField
,
data
);
this
.
profileField
=
data
;
await
Promise
.
all
([
requestAxios
(
`
${
MANAGER_IP
}
/experiment`
),
requestAxios
(
`
${
MANAGER_IP
}
/experiment-metadata`
)])
.
then
(([
profile
,
metadata
])
=>
{
updated
||=
!
compareProfiles
(
this
.
profileField
,
profile
);
this
.
profileField
=
profile
;
if
(
JSON
.
stringify
(
this
.
metadataField
)
!==
JSON
.
stringify
(
metadata
))
{
this
.
metadataField
=
metadata
;
}
})
.
catch
(
error
=>
{
this
.
isexperimentError
=
true
;
...
...
@@ -111,6 +131,10 @@ class Experiment {
return
this
.
profileField
===
undefined
?
emptyProfile
:
this
.
profileField
;
}
get
metadata
():
ExperimentMetadata
{
return
this
.
metadataField
===
undefined
?
emptyMetadata
:
this
.
metadataField
;
}
get
config
():
ExperimentConfig
{
return
this
.
profile
.
params
;
}
...
...
ts/webui/src/static/style/openRow.scss
View file @
403195f0
...
...
@@ -55,3 +55,8 @@ $bgColor: #f2f2f2;
}
}
}
#visualizationText
{
margin
:
5px
0
10px
15px
;
font-size
:
14px
;
}
Prev
1
…
7
8
9
10
11
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