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
"vscode:/vscode.git/clone" did not exist on "9f14634befca7fc0bead363cab4a427abc96b683"
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