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
611a45fc
Unverified
Commit
611a45fc
authored
May 31, 2019
by
chicm-ms
Committed by
GitHub
May 31, 2019
Browse files
Merge pull request #19 from microsoft/master
pull code
parents
841d4677
e267a737
Changes
155
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
308 additions
and
80 deletions
+308
-80
test/config_test/examples/mnist-nested-search-space.test.yml
test/config_test/examples/mnist-nested-search-space.test.yml
+2
-2
test/pipelines-it-remote-windows.yml
test/pipelines-it-remote-windows.yml
+49
-0
test/remote_docker.py
test/remote_docker.py
+20
-4
tools/README_zh_CN.md
tools/README_zh_CN.md
+1
-1
tools/nni_annotation/code_generator.py
tools/nni_annotation/code_generator.py
+91
-0
tools/nni_annotation/search_space_generator.py
tools/nni_annotation/search_space_generator.py
+18
-1
tools/nni_annotation/testcase/mutable_layer_usercode/simple.py
.../nni_annotation/testcase/mutable_layer_usercode/simple.py
+53
-0
tools/nni_cmd/config_schema.py
tools/nni_cmd/config_schema.py
+11
-5
tools/nni_cmd/config_utils.py
tools/nni_cmd/config_utils.py
+1
-1
tools/nni_cmd/constants.py
tools/nni_cmd/constants.py
+3
-2
tools/nni_cmd/launcher.py
tools/nni_cmd/launcher.py
+25
-15
tools/nni_cmd/nnictl_utils.py
tools/nni_cmd/nnictl_utils.py
+22
-41
tools/nni_cmd/tensorboard_utils.py
tools/nni_cmd/tensorboard_utils.py
+3
-5
tools/nni_cmd/url_utils.py
tools/nni_cmd/url_utils.py
+7
-0
uninstall.ps1
uninstall.ps1
+2
-3
No files found.
test/config_test/examples/mnist-
cascading
-search-space.test.yml
→
test/config_test/examples/mnist-
nested
-search-space.test.yml
View file @
611a45fc
...
...
@@ -3,7 +3,7 @@ experimentName: default_test
maxExecDuration
:
5m
maxTrialNum
:
4
trialConcurrency
:
2
searchSpacePath
:
../../../examples/trials/mnist-
cascading
-search-space/search_space.json
searchSpacePath
:
../../../examples/trials/mnist-
nested
-search-space/search_space.json
tuner
:
#choice: TPE, Random, Anneal, Evolution
...
...
@@ -13,7 +13,7 @@ assessor:
classArgs
:
optimize_mode
:
maximize
trial
:
codeDir
:
../../../examples/trials/mnist-
cascading
-search-space
codeDir
:
../../../examples/trials/mnist-
nested
-search-space
command
:
python3 mnist.py --batch_num
100
gpuNum
:
0
...
...
test/pipelines-it-remote-windows.yml
0 → 100644
View file @
611a45fc
jobs
:
-
job
:
'
integration_test_remote_windows'
steps
:
-
script
:
python -m pip install --upgrade pip setuptools
displayName
:
'
Install
python
tools'
-
task
:
CopyFilesOverSSH@0
inputs
:
sshEndpoint
:
$(end_point)
targetFolder
:
/tmp/nnitest/$(Build.BuildId)/nni-remote
overwrite
:
true
displayName
:
'
Copy
all
files
to
remote
machine'
-
script
:
|
powershell.exe -file install.ps1
displayName
:
'
Install
nni
toolkit
via
source
code'
-
script
:
|
python -m pip install scikit-learn==0.20.1 --user
displayName
:
'
Install
dependencies
for
integration
tests'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
inline
inline
:
cd /tmp/nnitest/$(Build.BuildId)/nni-remote/deployment/pypi;make build
continueOnError
:
true
displayName
:
'
build
nni
bdsit_wheel'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
commands
commands
:
python3 /tmp/nnitest/$(Build.BuildId)/nni-remote/test/remote_docker.py --mode start --name $(Build.BuildId) --image nni/nni --os windows
displayName
:
'
Start
docker'
-
powershell
:
|
Write-Host "Downloading Putty..."
(New-Object Net.WebClient).DownloadFile("https://the.earth.li/~sgtatham/putty/latest/w64/pscp.exe", "$(Agent.TempDirectory)\pscp.exe")
$(Agent.TempDirectory)\pscp.exe -hostkey $(hostkey) -pw $(pscp_pwd) $(remote_user)@$(remote_host):/tmp/nnitest/$(Build.BuildId)/port test\port
Get-Content test\port
displayName
:
'
Get
docker
port'
-
powershell
:
|
cd test
python generate_ts_config.py --ts remote --remote_user $(docker_user) --remote_host $(remote_host) --remote_port $(Get-Content port) --remote_pwd $(docker_pwd) --nni_manager_ip $(nni_manager_ip)
Get-Content training_service.yml
python config_test.py --ts remote --exclude cifar10,smac,bohb
displayName
:
'
integration
test'
-
task
:
SSH@0
inputs
:
sshEndpoint
:
$(end_point)
runOptions
:
commands
commands
:
python3 /tmp/nnitest/$(Build.BuildId)/nni-remote/test/remote_docker.py --mode stop --name $(Build.BuildId) --os windows
displayName
:
'
Stop
docker'
test/remote_docker.py
View file @
611a45fc
...
...
@@ -30,18 +30,33 @@ def find_wheel_package(dir):
return
file_name
return
None
def
start_container
(
image
,
name
):
def
start_container
(
image
,
name
,
nnimanager_os
):
'''Start docker container, generate a port in /tmp/nnitest/{name}/port file'''
port
=
find_port
()
source_dir
=
'/tmp/nnitest/'
+
name
run_cmds
=
[
'docker'
,
'run'
,
'-d'
,
'-p'
,
str
(
port
)
+
':22'
,
'--name'
,
name
,
'--mount'
,
'type=bind,source='
+
source_dir
+
',target=/tmp/nni'
,
image
]
output
=
check_output
(
run_cmds
)
commit_id
=
output
.
decode
(
'utf-8'
)
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'dist'
))
if
nnimanager_os
==
'windows'
:
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'nni-remote/deployment/pypi/dist'
))
else
:
wheel_name
=
find_wheel_package
(
os
.
path
.
join
(
source_dir
,
'dist'
))
if
not
wheel_name
:
print
(
'Error: could not find wheel package in {0}'
.
format
(
source_dir
))
exit
(
1
)
sdk_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
'/tmp/nni/dist/{0}'
.
format
(
wheel_name
)]
def
get_dist
(
wheel_name
):
'''get the wheel package path'''
if
nnimanager_os
==
'windows'
:
return
'/tmp/nni/nni-remote/deployment/pypi/dist/{0}'
.
format
(
wheel_name
)
else
:
return
'/tmp/nni/dist/{0}'
.
format
(
wheel_name
)
pip_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
'--upgrade'
,
'pip'
]
check_call
(
pip_cmds
)
sdk_cmds
=
[
'docker'
,
'exec'
,
name
,
'python3'
,
'-m'
,
'pip'
,
'install'
,
get_dist
(
wheel_name
)]
check_call
(
sdk_cmds
)
with
open
(
source_dir
+
'/port'
,
'w'
)
as
file
:
file
.
write
(
str
(
port
))
...
...
@@ -58,8 +73,9 @@ if __name__ == '__main__':
parser
.
add_argument
(
'--mode'
,
required
=
True
,
choices
=
[
'start'
,
'stop'
],
dest
=
'mode'
,
help
=
'start or stop a container'
)
parser
.
add_argument
(
'--name'
,
required
=
True
,
dest
=
'name'
,
help
=
'the name of container to be used'
)
parser
.
add_argument
(
'--image'
,
dest
=
'image'
,
help
=
'the image to be used'
)
parser
.
add_argument
(
'--os'
,
dest
=
'os'
,
default
=
'unix'
,
choices
=
[
'unix'
,
'windows'
],
help
=
'nniManager os version'
)
args
=
parser
.
parse_args
()
if
args
.
mode
==
'start'
:
start_container
(
args
.
image
,
args
.
name
)
start_container
(
args
.
image
,
args
.
name
,
args
.
os
)
else
:
stop_container
(
args
.
name
)
tools/README_zh_CN.md
View file @
611a45fc
...
...
@@ -54,4 +54,4 @@ NNI CTL 模块用来控制 Neural Network Intelligence,包括开始新 Experim
## 开始使用 NNI CTL
参考
[
NNI CTL 文档
](
../docs/zh_CN/NNICTLDOC.md
)
。
\ No newline at end of file
参考
[
NNI CTL 文档
](
../docs/zh_CN/Nnictl.md
)
。
\ No newline at end of file
tools/nni_annotation/code_generator.py
View file @
611a45fc
...
...
@@ -25,6 +25,94 @@ from nni_cmd.common_utils import print_warning
# pylint: disable=unidiomatic-typecheck
def
parse_annotation_mutable_layers
(
code
,
lineno
):
"""Parse the string of mutable layers in annotation.
Return a list of AST Expr nodes
code: annotation string (excluding '@')
"""
module
=
ast
.
parse
(
code
)
assert
type
(
module
)
is
ast
.
Module
,
'internal error #1'
assert
len
(
module
.
body
)
==
1
,
'Annotation mutable_layers contains more than one expression'
assert
type
(
module
.
body
[
0
])
is
ast
.
Expr
,
'Annotation is not expression'
call
=
module
.
body
[
0
].
value
nodes
=
[]
mutable_id
=
'mutable_block_'
+
str
(
lineno
)
mutable_layer_cnt
=
0
for
arg
in
call
.
args
:
fields
=
{
'layer_choice'
:
False
,
'fixed_inputs'
:
False
,
'optional_inputs'
:
False
,
'optional_input_size'
:
False
,
'layer_output'
:
False
}
for
k
,
value
in
zip
(
arg
.
keys
,
arg
.
values
):
if
k
.
id
==
'layer_choice'
:
assert
not
fields
[
'layer_choice'
],
'Duplicated field: layer_choice'
assert
type
(
value
)
is
ast
.
List
,
'Value of layer_choice should be a list'
call_funcs_keys
=
[]
call_funcs_values
=
[]
call_kwargs_values
=
[]
for
call
in
value
.
elts
:
assert
type
(
call
)
is
ast
.
Call
,
'Element in layer_choice should be function call'
call_name
=
astor
.
to_source
(
call
).
strip
()
call_funcs_keys
.
append
(
ast
.
Str
(
s
=
call_name
))
call_funcs_values
.
append
(
call
.
func
)
assert
not
call
.
args
,
'Number of args without keyword should be zero'
kw_args
=
[]
kw_values
=
[]
for
kw
in
call
.
keywords
:
kw_args
.
append
(
kw
.
arg
)
kw_values
.
append
(
kw
.
value
)
call_kwargs_values
.
append
(
ast
.
Dict
(
keys
=
kw_args
,
values
=
kw_values
))
call_funcs
=
ast
.
Dict
(
keys
=
call_funcs_keys
,
values
=
call_funcs_values
)
call_kwargs
=
ast
.
Dict
(
keys
=
call_funcs_keys
,
values
=
call_kwargs_values
)
fields
[
'layer_choice'
]
=
True
elif
k
.
id
==
'fixed_inputs'
:
assert
not
fields
[
'fixed_inputs'
],
'Duplicated field: fixed_inputs'
assert
type
(
value
)
is
ast
.
List
,
'Value of fixed_inputs should be a list'
fixed_inputs
=
value
fields
[
'fixed_inputs'
]
=
True
elif
k
.
id
==
'optional_inputs'
:
assert
not
fields
[
'optional_inputs'
],
'Duplicated field: optional_inputs'
assert
type
(
value
)
is
ast
.
List
,
'Value of optional_inputs should be a list'
var_names
=
[
ast
.
Str
(
s
=
astor
.
to_source
(
var
).
strip
())
for
var
in
value
.
elts
]
optional_inputs
=
ast
.
Dict
(
keys
=
var_names
,
values
=
value
.
elts
)
fields
[
'optional_inputs'
]
=
True
elif
k
.
id
==
'optional_input_size'
:
assert
not
fields
[
'optional_input_size'
],
'Duplicated field: optional_input_size'
assert
type
(
value
)
is
ast
.
Num
,
'Value of optional_input_size should be a number'
optional_input_size
=
value
fields
[
'optional_input_size'
]
=
True
elif
k
.
id
==
'layer_output'
:
assert
not
fields
[
'layer_output'
],
'Duplicated field: layer_output'
assert
type
(
value
)
is
ast
.
Name
,
'Value of layer_output should be ast.Name type'
layer_output
=
value
fields
[
'layer_output'
]
=
True
else
:
raise
AssertionError
(
'Unexpected field in mutable layer'
)
# make call for this mutable layer
assert
fields
[
'layer_choice'
],
'layer_choice must exist'
assert
fields
[
'layer_output'
],
'layer_output must exist'
mutable_layer_id
=
'mutable_layer_'
+
str
(
mutable_layer_cnt
)
mutable_layer_cnt
+=
1
target_call_attr
=
ast
.
Attribute
(
value
=
ast
.
Name
(
id
=
'nni'
,
ctx
=
ast
.
Load
()),
attr
=
'mutable_layer'
,
ctx
=
ast
.
Load
())
target_call_args
=
[
ast
.
Str
(
s
=
mutable_id
),
ast
.
Str
(
s
=
mutable_layer_id
),
call_funcs
,
call_kwargs
]
if
fields
[
'fixed_inputs'
]:
target_call_args
.
append
(
fixed_inputs
)
else
:
target_call_args
.
append
(
ast
.
NameConstant
(
value
=
None
))
if
fields
[
'optional_inputs'
]:
target_call_args
.
append
(
optional_inputs
)
assert
fields
[
'optional_input_size'
],
'optional_input_size must exist when optional_inputs exists'
target_call_args
.
append
(
optional_input_size
)
else
:
target_call_args
.
append
(
ast
.
NameConstant
(
value
=
None
))
target_call
=
ast
.
Call
(
func
=
target_call_attr
,
args
=
target_call_args
,
keywords
=
[])
node
=
ast
.
Assign
(
targets
=
[
layer_output
],
value
=
target_call
)
nodes
.
append
(
node
)
return
nodes
def
parse_annotation
(
code
):
"""Parse an annotation string.
...
...
@@ -235,6 +323,9 @@ class Transformer(ast.NodeTransformer):
or
string
.
startswith
(
'@nni.get_next_parameter('
):
return
parse_annotation
(
string
[
1
:])
# expand annotation string to code
if
string
.
startswith
(
'@nni.mutable_layers('
):
return
parse_annotation_mutable_layers
(
string
[
1
:],
node
.
lineno
)
if
string
.
startswith
(
'@nni.variable('
)
\
or
string
.
startswith
(
'@nni.function_choice('
):
self
.
stack
[
-
1
]
=
string
[
1
:]
# mark that the next expression is annotated
...
...
tools/nni_annotation/search_space_generator.py
View file @
611a45fc
...
...
@@ -38,7 +38,8 @@ _ss_funcs = [
'qnormal'
,
'lognormal'
,
'qlognormal'
,
'function_choice'
'function_choice'
,
'mutable_layer'
]
...
...
@@ -50,6 +51,18 @@ class SearchSpaceGenerator(ast.NodeTransformer):
self
.
search_space
=
{}
self
.
last_line
=
0
# last parsed line, useful for error reporting
def
generate_mutable_layer_search_space
(
self
,
args
):
mutable_block
=
args
[
0
].
s
mutable_layer
=
args
[
1
].
s
if
mutable_block
not
in
self
.
search_space
:
self
.
search_space
[
mutable_block
]
=
dict
()
self
.
search_space
[
mutable_block
][
mutable_layer
]
=
{
'layer_choice'
:
[
key
.
s
for
key
in
args
[
2
].
keys
],
'optional_inputs'
:
[
key
.
s
for
key
in
args
[
5
].
keys
],
'optional_input_size'
:
args
[
6
].
n
}
def
visit_Call
(
self
,
node
):
# pylint: disable=invalid-name
self
.
generic_visit
(
node
)
...
...
@@ -68,6 +81,10 @@ class SearchSpaceGenerator(ast.NodeTransformer):
self
.
last_line
=
node
.
lineno
if
func
==
'mutable_layer'
:
self
.
generate_mutable_layer_search_space
(
node
.
args
)
return
node
if
node
.
keywords
:
# there is a `name` argument
assert
len
(
node
.
keywords
)
==
1
,
'Smart parameter has keyword argument other than "name"'
...
...
tools/nni_annotation/testcase/mutable_layer_usercode/simple.py
0 → 100644
View file @
611a45fc
import
time
def
add_one
(
inputs
):
return
inputs
+
1
def
add_two
(
inputs
):
return
inputs
+
2
def
add_three
(
inputs
):
return
inputs
+
3
def
add_four
(
inputs
):
return
inputs
+
4
def
main
():
images
=
5
"""@nni.mutable_layers(
{
layer_choice: [add_one(), add_two(), add_three(), add_four()],
optional_inputs: [images],
optional_input_size: 1,
layer_output: layer_1_out
},
{
layer_choice: [add_one(), add_two(), add_three(), add_four()],
optional_inputs: [layer_1_out],
optional_input_size: 1,
layer_output: layer_2_out
},
{
layer_choice: [add_one(), add_two(), add_three(), add_four()],
optional_inputs: [layer_1_out, layer_2_out],
optional_input_size: 1,
layer_output: layer_3_out
}
)"""
"""@nni.report_intermediate_result(layer_1_out)"""
time
.
sleep
(
2
)
"""@nni.report_intermediate_result(layer_2_out)"""
time
.
sleep
(
2
)
"""@nni.report_intermediate_result(layer_3_out)"""
time
.
sleep
(
2
)
layer_3_out
=
layer_3_out
+
10
"""@nni.report_final_result(layer_3_out)"""
if
__name__
==
'__main__'
:
main
()
tools/nni_cmd/config_schema.py
View file @
611a45fc
...
...
@@ -63,7 +63,9 @@ common_schema = {
Optional
(
'advisor'
):
dict
,
Optional
(
'assessor'
):
dict
,
Optional
(
'localConfig'
):
{
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
)
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
),
Optional
(
'maxTrialNumPerGpu'
):
setType
(
'maxTrialNumPerGpu'
,
int
),
Optional
(
'useActiveGpu'
):
setType
(
'useActiveGpu'
,
bool
)
}
}
tuner_schema_dict
=
{
...
...
@@ -310,26 +312,30 @@ frameworkcontroller_config_schema = {
})
}
machine_list_sch
i
ma
=
{
machine_list_sch
e
ma
=
{
Optional
(
'machineList'
):[
Or
({
'ip'
:
setType
(
'ip'
,
str
),
Optional
(
'port'
):
setNumberRange
(
'port'
,
int
,
1
,
65535
),
'username'
:
setType
(
'username'
,
str
),
'passwd'
:
setType
(
'passwd'
,
str
),
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
)
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
),
Optional
(
'maxTrialNumPerGpu'
):
setType
(
'maxTrialNumPerGpu'
,
int
),
Optional
(
'useActiveGpu'
):
setType
(
'useActiveGpu'
,
bool
)
},{
'ip'
:
setType
(
'ip'
,
str
),
Optional
(
'port'
):
setNumberRange
(
'port'
,
int
,
1
,
65535
),
'username'
:
setType
(
'username'
,
str
),
'sshKeyPath'
:
setPathCheck
(
'sshKeyPath'
),
Optional
(
'passphrase'
):
setType
(
'passphrase'
,
str
),
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
)
Optional
(
'gpuIndices'
):
Or
(
int
,
And
(
str
,
lambda
x
:
len
([
int
(
i
)
for
i
in
x
.
split
(
','
)])
>
0
),
error
=
'gpuIndex format error!'
),
Optional
(
'maxTrialNumPerGpu'
):
setType
(
'maxTrialNumPerGpu'
,
int
),
Optional
(
'useActiveGpu'
):
setType
(
'useActiveGpu'
,
bool
)
})]
}
LOCAL_CONFIG_SCHEMA
=
Schema
({
**
common_schema
,
**
common_trial_schema
})
REMOTE_CONFIG_SCHEMA
=
Schema
({
**
common_schema
,
**
common_trial_schema
,
**
machine_list_sch
i
ma
})
REMOTE_CONFIG_SCHEMA
=
Schema
({
**
common_schema
,
**
common_trial_schema
,
**
machine_list_sch
e
ma
})
PAI_CONFIG_SCHEMA
=
Schema
({
**
common_schema
,
**
pai_trial_schema
,
**
pai_config_schema
})
...
...
tools/nni_cmd/config_utils.py
View file @
611a45fc
...
...
@@ -119,4 +119,4 @@ class Experiments:
return
json
.
load
(
file
)
except
ValueError
:
return
{}
return
{}
\ No newline at end of file
return
{}
tools/nni_cmd/constants.py
View file @
611a45fc
...
...
@@ -86,12 +86,13 @@ TUNERS_SUPPORTING_IMPORT_DATA = {
'Anneal'
,
'GridSearch'
,
'MetisTuner'
,
'BOHB'
'BOHB'
,
'SMAC'
,
'BatchTuner'
}
TUNERS_NO_NEED_TO_IMPORT_DATA
=
{
'Random'
,
'Batch_tuner'
,
'Hyperband'
}
...
...
tools/nni_cmd/launcher.py
View file @
611a45fc
...
...
@@ -125,18 +125,17 @@ def start_rest_server(port, platform, mode, config_file_name, experiment_id=None
if
mode
==
'resume'
:
cmds
+=
[
'--experiment_id'
,
experiment_id
]
stdout_full_path
,
stderr_full_path
=
get_log_path
(
config_file_name
)
stdout_file
=
open
(
stdout_full_path
,
'a+'
)
stderr_file
=
open
(
stderr_full_path
,
'a+'
)
time_now
=
time
.
strftime
(
'%Y-%m-%d %H:%M:%S'
,
time
.
localtime
(
time
.
time
()))
#add time information in the header of log files
log_header
=
LOG_HEADER
%
str
(
time_now
)
stdout_file
.
write
(
log_header
)
stderr_file
.
write
(
log_header
)
if
sys
.
platform
==
'win32'
:
from
subprocess
import
CREATE_NEW_PROCESS_GROUP
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
stdout_file
,
stderr
=
stderr_file
,
creationflags
=
CREATE_NEW_PROCESS_GROUP
)
else
:
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
stdout_file
,
stderr
=
stderr_file
)
with
open
(
stdout_full_path
,
'a+'
)
as
stdout_file
,
open
(
stderr_full_path
,
'a+'
)
as
stderr_file
:
time_now
=
time
.
strftime
(
'%Y-%m-%d %H:%M:%S'
,
time
.
localtime
(
time
.
time
()))
#add time information in the header of log files
log_header
=
LOG_HEADER
%
str
(
time_now
)
stdout_file
.
write
(
log_header
)
stderr_file
.
write
(
log_header
)
if
sys
.
platform
==
'win32'
:
from
subprocess
import
CREATE_NEW_PROCESS_GROUP
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
stdout_file
,
stderr
=
stderr_file
,
creationflags
=
CREATE_NEW_PROCESS_GROUP
)
else
:
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
stdout_file
,
stderr
=
stderr_file
)
return
process
,
str
(
time_now
)
def
set_trial_config
(
experiment_config
,
port
,
config_file_name
):
...
...
@@ -160,9 +159,13 @@ def set_local_config(experiment_config, port, config_file_name):
request_data
=
dict
()
if
experiment_config
.
get
(
'localConfig'
):
request_data
[
'local_config'
]
=
experiment_config
[
'localConfig'
]
if
request_data
[
'local_config'
]
and
request_data
[
'local_config'
].
get
(
'gpuIndices'
)
\
and
isinstance
(
request_data
[
'local_config'
].
get
(
'gpuIndices'
),
int
):
request_data
[
'local_config'
][
'gpuIndices'
]
=
str
(
request_data
[
'local_config'
].
get
(
'gpuIndices'
))
if
request_data
[
'local_config'
]:
if
request_data
[
'local_config'
].
get
(
'gpuIndices'
)
and
isinstance
(
request_data
[
'local_config'
].
get
(
'gpuIndices'
),
int
):
request_data
[
'local_config'
][
'gpuIndices'
]
=
str
(
request_data
[
'local_config'
].
get
(
'gpuIndices'
))
if
request_data
[
'local_config'
].
get
(
'maxTrialNumOnEachGpu'
):
request_data
[
'local_config'
][
'maxTrialNumOnEachGpu'
]
=
request_data
[
'local_config'
].
get
(
'maxTrialNumOnEachGpu'
)
if
request_data
[
'local_config'
].
get
(
'useActiveGpu'
):
request_data
[
'local_config'
][
'useActiveGpu'
]
=
request_data
[
'local_config'
].
get
(
'useActiveGpu'
)
response
=
rest_put
(
cluster_metadata_url
(
port
),
json
.
dumps
(
request_data
),
REST_TIME_OUT
)
err_message
=
''
if
not
response
or
not
check_response
(
response
):
...
...
@@ -343,6 +346,13 @@ def set_experiment(experiment_config, mode, port, config_file_name):
def
launch_experiment
(
args
,
experiment_config
,
mode
,
config_file_name
,
experiment_id
=
None
):
'''follow steps to start rest server and start experiment'''
nni_config
=
Config
(
config_file_name
)
# check execution policy in powershell
if
sys
.
platform
==
'win32'
:
execution_policy
=
check_output
([
'powershell.exe'
,
'Get-ExecutionPolicy'
]).
decode
(
'ascii'
).
strip
()
if
execution_policy
==
'Restricted'
:
print_error
(
'PowerShell execution policy error, please run PowerShell as administrator with this command first:
\r\n
'
\
+
'
\'
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
\'
'
)
exit
(
1
)
# check packages for tuner
package_name
,
module_name
=
None
,
None
if
experiment_config
.
get
(
'tuner'
)
and
experiment_config
[
'tuner'
].
get
(
'builtinTunerName'
):
...
...
tools/nni_cmd/nnictl_utils.py
View file @
611a45fc
...
...
@@ -26,8 +26,8 @@ import datetime
import
time
from
subprocess
import
call
,
check_output
from
.rest_utils
import
rest_get
,
rest_delete
,
check_rest_server_quick
,
check_response
from
.url_utils
import
trial_jobs_url
,
experiment_url
,
trial_job_id_url
,
export_data_url
from
.config_utils
import
Config
,
Experiments
from
.url_utils
import
trial_jobs_url
,
experiment_url
,
trial_job_id_url
from
.constants
import
NNICTL_HOME_DIR
,
EXPERIMENT_INFORMATION_FORMAT
,
EXPERIMENT_DETAIL_FORMAT
,
\
EXPERIMENT_MONITOR_INFO
,
TRIAL_MONITOR_HEAD
,
TRIAL_MONITOR_CONTENT
,
TRIAL_MONITOR_TAIL
,
REST_TIME_OUT
from
.common_utils
import
print_normal
,
print_error
,
print_warning
,
detect_process
...
...
@@ -450,30 +450,9 @@ def monitor_experiment(args):
print_error
(
exception
)
exit
(
1
)
def
parse_trial_data
(
content
):
"""output: List[Dict]"""
trial_records
=
[]
for
trial_data
in
content
:
for
phase_i
in
range
(
len
(
trial_data
[
'hyperParameters'
])):
hparam
=
json
.
loads
(
trial_data
[
'hyperParameters'
][
phase_i
])[
'parameters'
]
hparam
[
'id'
]
=
trial_data
[
'id'
]
if
'finalMetricData'
in
trial_data
.
keys
()
and
phase_i
<
len
(
trial_data
[
'finalMetricData'
]):
reward
=
json
.
loads
(
trial_data
[
'finalMetricData'
][
phase_i
][
'data'
])
if
isinstance
(
reward
,
(
float
,
int
)):
dict_tmp
=
{
**
hparam
,
**
{
'reward'
:
reward
}}
elif
isinstance
(
reward
,
dict
):
dict_tmp
=
{
**
hparam
,
**
reward
}
else
:
raise
ValueError
(
"Invalid finalMetricsData format: {}/{}"
.
format
(
type
(
reward
),
reward
))
else
:
dict_tmp
=
hparam
trial_records
.
append
(
dict_tmp
)
return
trial_records
def
export_trials_data
(
args
):
"""
export experiment metadata to csv
"""
'''
export experiment metadata to csv
'''
nni_config
=
Config
(
get_config_filename
(
args
))
rest_port
=
nni_config
.
get_config
(
'restServerPort'
)
rest_pid
=
nni_config
.
get_config
(
'restServerPid'
)
...
...
@@ -482,26 +461,28 @@ def export_trials_data(args):
return
running
,
response
=
check_rest_server_quick
(
rest_port
)
if
running
:
response
=
rest_get
(
trial_jobs
_url
(
rest_port
),
20
)
response
=
rest_get
(
export_data
_url
(
rest_port
),
20
)
if
response
is
not
None
and
check_response
(
response
):
content
=
json
.
loads
(
response
.
text
)
# dframe = pd.DataFrame.from_records([parse_trial_data(t_data) for t_data in content])
# dframe.to_csv(args.csv_path, sep='\t')
records
=
parse_trial_data
(
content
)
if
args
.
type
==
'json'
:
json_records
=
[]
for
trial
in
records
:
value
=
trial
.
pop
(
'reward'
,
None
)
trial_id
=
trial
.
pop
(
'id'
,
None
)
json_records
.
append
({
'parameter'
:
trial
,
'value'
:
value
,
'id'
:
trial_id
})
with
open
(
args
.
path
,
'w'
)
as
file
:
if
args
.
type
==
'csv'
:
writer
=
csv
.
DictWriter
(
file
,
set
.
union
(
*
[
set
(
r
.
keys
())
for
r
in
records
]))
with
open
(
args
.
path
,
'w'
)
as
file
:
file
.
write
(
response
.
text
)
elif
args
.
type
==
'csv'
:
content
=
json
.
loads
(
response
.
text
)
trial_records
=
[]
for
record
in
content
:
if
not
isinstance
(
record
[
'value'
],
(
float
,
int
)):
formated_record
=
{
**
record
[
'parameter'
],
**
record
[
'value'
],
**
{
'id'
:
record
[
'id'
]}}
else
:
formated_record
=
{
**
record
[
'parameter'
],
**
{
'reward'
:
record
[
'value'
],
'id'
:
record
[
'id'
]}}
trial_records
.
append
(
formated_record
)
with
open
(
args
.
path
,
'w'
)
as
file
:
writer
=
csv
.
DictWriter
(
file
,
set
.
union
(
*
[
set
(
r
.
keys
())
for
r
in
trial_records
]))
writer
.
writeheader
()
writer
.
writerows
(
records
)
else
:
json
.
dump
(
json_records
,
file
)
writer
.
writerows
(
trial_records
)
else
:
print_error
(
'Unknown type: %s'
%
args
.
type
)
exit
(
1
)
else
:
print_error
(
'Export failed...'
)
else
:
print_error
(
'Restful server is not Running'
)
print_error
(
'Restful server is not Running'
)
\ No newline at end of file
tools/nni_cmd/tensorboard_utils.py
View file @
611a45fc
...
...
@@ -94,11 +94,9 @@ def start_tensorboard_process(args, nni_config, path_list, temp_nni_path):
if
detect_port
(
args
.
port
):
print_error
(
'Port %s is used by another process, please reset port!'
%
str
(
args
.
port
))
exit
(
1
)
stdout_file
=
open
(
os
.
path
.
join
(
temp_nni_path
,
'tensorboard_stdout'
),
'a+'
)
stderr_file
=
open
(
os
.
path
.
join
(
temp_nni_path
,
'tensorboard_stderr'
),
'a+'
)
cmds
=
[
'tensorboard'
,
'--logdir'
,
format_tensorboard_log_path
(
path_list
),
'--port'
,
str
(
args
.
port
)]
tensorboard_process
=
Popen
(
cmds
,
stdout
=
stdout_file
,
stderr
=
stderr_file
)
with
open
(
os
.
path
.
join
(
temp_nni_path
,
'tensorboard_stdout'
),
'a+'
)
as
stdout_file
,
open
(
os
.
path
.
join
(
temp_nni_path
,
'tensorboard_stderr'
),
'a+'
)
as
stderr_file
:
cmds
=
[
'tensorboard'
,
'--logdir'
,
format_tensorboard_log_path
(
path_list
),
'--port'
,
str
(
args
.
port
)]
tensorboard_process
=
Popen
(
cmds
,
stdout
=
stdout_file
,
stderr
=
stderr_file
)
url_list
=
get_local_urls
(
args
.
port
)
print_normal
(
COLOR_GREEN_FORMAT
%
'Start tensorboard success!
\n
'
+
'Tensorboard urls: '
+
' '
.
join
(
url_list
))
tensorboard_process_pid_list
=
nni_config
.
get_config
(
'tensorboardPidList'
)
...
...
tools/nni_cmd/url_utils.py
View file @
611a45fc
...
...
@@ -35,6 +35,8 @@ CHECK_STATUS_API = '/check-status'
TRIAL_JOBS_API
=
'/trial-jobs'
EXPORT_DATA_API
=
'/export-data'
TENSORBOARD_API
=
'/tensorboard'
...
...
@@ -68,6 +70,11 @@ def trial_job_id_url(port, job_id):
return
'{0}:{1}{2}{3}/:{4}'
.
format
(
BASE_URL
,
port
,
API_ROOT_URL
,
TRIAL_JOBS_API
,
job_id
)
def
export_data_url
(
port
):
'''get export_data url'''
return
'{0}:{1}{2}{3}'
.
format
(
BASE_URL
,
port
,
API_ROOT_URL
,
EXPORT_DATA_API
)
def
tensorboard_url
(
port
):
'''get tensorboard url'''
return
'{0}:{1}{2}{3}'
.
format
(
BASE_URL
,
port
,
API_ROOT_URL
,
TENSORBOARD_API
)
...
...
uninstall.ps1
View file @
611a45fc
$NNI_DEPENDENCY_FOLDER
=
"C:\tmp\
$
env
:
USERNAME
"
$NNI_DEPENDENCY_FOLDER
=
[
System.IO.Path
]::
GetTempPath
()
+
$
env
:
USERNAME
$
env
:
PYTHONIOENCODING
=
"UTF-8"
if
(
$
env
:
VIRTUAL_ENV
){
...
...
@@ -27,4 +26,4 @@ Remove-Item "src/nni_manager/node_modules" -Recurse -Force
Remove-Item
"src/webui/build"
-Recurse
-Force
Remove-Item
"src/webui/node_modules"
-Recurse
-Force
Remove-Item
$NNI_YARN_FOLDER
-Recurse
-Force
Remove-Item
$NNI_NODE_FOLDER
-Recurse
-Force
\ No newline at end of file
Remove-Item
$NNI_NODE_FOLDER
-Recurse
-Force
Prev
1
…
4
5
6
7
8
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