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
3b27ac76
Unverified
Commit
3b27ac76
authored
Mar 21, 2022
by
liuzhe-lz
Committed by
GitHub
Mar 21, 2022
Browse files
Refactor NNI manager globals (step 1) - argparse (#4510)
parent
2499be70
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
242 additions
and
114 deletions
+242
-114
nni/experiment/experiment.py
nni/experiment/experiment.py
+4
-4
nni/experiment/launcher.py
nni/experiment/launcher.py
+20
-24
nni/tools/nnictl/legacy_launcher.py
nni/tools/nnictl/legacy_launcher.py
+6
-10
ts/nni_manager/common/globals/arguments.ts
ts/nni_manager/common/globals/arguments.ts
+96
-0
ts/nni_manager/main.ts
ts/nni_manager/main.ts
+18
-74
ts/nni_manager/package.json
ts/nni_manager/package.json
+3
-1
ts/nni_manager/test/common/globals/arguments.test.ts
ts/nni_manager/test/common/globals/arguments.test.ts
+69
-0
ts/nni_manager/yarn.lock
ts/nni_manager/yarn.lock
+26
-1
No files found.
nni/experiment/experiment.py
View file @
3b27ac76
...
@@ -91,7 +91,7 @@ class Experiment:
...
@@ -91,7 +91,7 @@ class Experiment:
self
.
id
:
str
=
management
.
generate_experiment_id
()
self
.
id
:
str
=
management
.
generate_experiment_id
()
self
.
port
:
Optional
[
int
]
=
None
self
.
port
:
Optional
[
int
]
=
None
self
.
_proc
:
Optional
[
Popen
]
=
None
self
.
_proc
:
Optional
[
Popen
]
=
None
self
.
mode
=
'new
'
self
.
action
=
'create
'
self
.
url_prefix
:
Optional
[
str
]
=
None
self
.
url_prefix
:
Optional
[
str
]
=
None
args
=
[
config
,
training_service
]
# deal with overloading
args
=
[
config
,
training_service
]
# deal with overloading
...
@@ -127,7 +127,7 @@ class Experiment:
...
@@ -127,7 +127,7 @@ class Experiment:
log_dir
=
Path
.
home
()
/
f
'nni-experiments/
{
self
.
id
}
/log'
log_dir
=
Path
.
home
()
/
f
'nni-experiments/
{
self
.
id
}
/log'
nni
.
runtime
.
log
.
start_experiment_log
(
self
.
id
,
log_dir
,
debug
)
nni
.
runtime
.
log
.
start_experiment_log
(
self
.
id
,
log_dir
,
debug
)
self
.
_proc
=
launcher
.
start_experiment
(
self
.
mode
,
self
.
id
,
config
,
port
,
debug
,
run_mode
,
self
.
url_prefix
)
self
.
_proc
=
launcher
.
start_experiment
(
self
.
action
,
self
.
id
,
config
,
port
,
debug
,
run_mode
,
self
.
url_prefix
)
assert
self
.
_proc
is
not
None
assert
self
.
_proc
is
not
None
self
.
port
=
port
# port will be None if start up failed
self
.
port
=
port
# port will be None if start up failed
...
@@ -261,7 +261,7 @@ class Experiment:
...
@@ -261,7 +261,7 @@ class Experiment:
def
_resume
(
exp_id
,
exp_dir
=
None
):
def
_resume
(
exp_id
,
exp_dir
=
None
):
exp
=
Experiment
()
exp
=
Experiment
()
exp
.
id
=
exp_id
exp
.
id
=
exp_id
exp
.
mode
=
'resume'
exp
.
action
=
'resume'
exp
.
config
=
launcher
.
get_stopped_experiment_config
(
exp_id
,
exp_dir
)
exp
.
config
=
launcher
.
get_stopped_experiment_config
(
exp_id
,
exp_dir
)
return
exp
return
exp
...
@@ -269,7 +269,7 @@ class Experiment:
...
@@ -269,7 +269,7 @@ class Experiment:
def
_view
(
exp_id
,
exp_dir
=
None
):
def
_view
(
exp_id
,
exp_dir
=
None
):
exp
=
Experiment
()
exp
=
Experiment
()
exp
.
id
=
exp_id
exp
.
id
=
exp_id
exp
.
mode
=
'view'
exp
.
action
=
'view'
exp
.
config
=
launcher
.
get_stopped_experiment_config
(
exp_id
,
exp_dir
)
exp
.
config
=
launcher
.
get_stopped_experiment_config
(
exp_id
,
exp_dir
)
return
exp
return
exp
...
...
nni/experiment/launcher.py
View file @
3b27ac76
...
@@ -27,23 +27,27 @@ _logger = logging.getLogger('nni.experiment')
...
@@ -27,23 +27,27 @@ _logger = logging.getLogger('nni.experiment')
@
dataclass
(
init
=
False
)
@
dataclass
(
init
=
False
)
class
NniManagerArgs
:
class
NniManagerArgs
:
# argv sent to "ts/nni_manager/main.js"
port
:
int
port
:
int
experiment_id
:
int
experiment_id
:
int
start_mode
:
str
# new
or
resume
action
:
str
#
'
new
', '
resume
', 'view'
mode
:
str
# training service platform
mode
:
str
# training service platform
, to be removed
log_dir
:
str
experiments_directory
:
str
# renamed "config.nni_experiments_directory", must be absolute
log_level
:
str
log_level
:
str
readonly
:
bool
=
False
foreground
:
bool
=
False
foreground
:
bool
=
False
url_prefix
:
Optional
[
str
]
=
None
url_prefix
:
Optional
[
str
]
=
None
# leading and trailing "/" must be stripped
dispatcher_pipe
:
Optional
[
str
]
=
None
dispatcher_pipe
:
Optional
[
str
]
=
None
def
__init__
(
self
,
action
,
exp_id
,
config
,
port
,
debug
,
foreground
,
url_prefix
):
def
__init__
(
self
,
action
,
exp_id
,
config
,
port
,
debug
,
foreground
,
url_prefix
):
self
.
port
=
port
self
.
port
=
port
self
.
experiment_id
=
exp_id
self
.
experiment_id
=
exp_id
self
.
action
=
action
self
.
foreground
=
foreground
self
.
foreground
=
foreground
self
.
url_prefix
=
url_prefix
self
.
url_prefix
=
url_prefix
self
.
log_dir
=
config
.
experiment_working_directory
# config field name "experiment_working_directory" is a mistake
# see "ts/nni_manager/common/globals/arguments.ts" for details
self
.
experiments_directory
=
config
.
experiment_working_directory
if
isinstance
(
config
.
training_service
,
list
):
if
isinstance
(
config
.
training_service
,
list
):
self
.
mode
=
'hybrid'
self
.
mode
=
'hybrid'
...
@@ -54,20 +58,14 @@ class NniManagerArgs:
...
@@ -54,20 +58,14 @@ class NniManagerArgs:
if
debug
and
self
.
log_level
not
in
[
'debug'
,
'trace'
]:
if
debug
and
self
.
log_level
not
in
[
'debug'
,
'trace'
]:
self
.
log_level
=
'debug'
self
.
log_level
=
'debug'
if
action
==
'resume'
:
self
.
start_mode
=
'resume'
elif
action
==
'view'
:
self
.
start_mode
=
'resume'
self
.
readonly
=
True
else
:
self
.
start_mode
=
'new'
def
to_command_line_args
(
self
):
def
to_command_line_args
(
self
):
# reformat fields to meet yargs library's format
# see "ts/nni_manager/common/globals/arguments.ts" for details
ret
=
[]
ret
=
[]
for
field
in
fields
(
self
):
for
field
in
fields
(
self
):
value
=
getattr
(
self
,
field
.
name
)
value
=
getattr
(
self
,
field
.
name
)
if
value
is
not
None
:
if
value
is
not
None
:
ret
.
append
(
'--'
+
field
.
name
)
ret
.
append
(
'--'
+
field
.
name
.
replace
(
'_'
,
'-'
)
)
if
isinstance
(
value
,
bool
):
if
isinstance
(
value
,
bool
):
ret
.
append
(
str
(
value
).
lower
())
ret
.
append
(
str
(
value
).
lower
())
else
:
else
:
...
@@ -76,6 +74,8 @@ class NniManagerArgs:
...
@@ -76,6 +74,8 @@ class NniManagerArgs:
def
start_experiment
(
action
,
exp_id
,
config
,
port
,
debug
,
run_mode
,
url_prefix
):
def
start_experiment
(
action
,
exp_id
,
config
,
port
,
debug
,
run_mode
,
url_prefix
):
foreground
=
run_mode
.
value
==
'foreground'
foreground
=
run_mode
.
value
==
'foreground'
if
url_prefix
is
not
None
:
url_prefix
=
url_prefix
.
strip
(
'/'
)
nni_manager_args
=
NniManagerArgs
(
action
,
exp_id
,
config
,
port
,
debug
,
foreground
,
url_prefix
)
nni_manager_args
=
NniManagerArgs
(
action
,
exp_id
,
config
,
port
,
debug
,
foreground
,
url_prefix
)
_ensure_port_idle
(
port
)
_ensure_port_idle
(
port
)
...
@@ -135,7 +135,7 @@ def _start_rest_server(nni_manager_args, run_mode) -> Tuple[int, Popen]:
...
@@ -135,7 +135,7 @@ def _start_rest_server(nni_manager_args, run_mode) -> Tuple[int, Popen]:
cmd
+=
nni_manager_args
.
to_command_line_args
()
cmd
+=
nni_manager_args
.
to_command_line_args
()
if
run_mode
.
value
==
'detach'
:
if
run_mode
.
value
==
'detach'
:
log
=
Path
(
nni_manager_args
.
log_dir
,
nni_manager_args
.
experiment_id
,
'log'
)
log
=
Path
(
nni_manager_args
.
experiments_directory
,
nni_manager_args
.
experiment_id
,
'log'
)
out
=
(
log
/
'nnictl_stdout.log'
).
open
(
'a'
)
out
=
(
log
/
'nnictl_stdout.log'
).
open
(
'a'
)
err
=
(
log
/
'nnictl_stderr.log'
).
open
(
'a'
)
err
=
(
log
/
'nnictl_stderr.log'
).
open
(
'a'
)
header
=
f
'Experiment
{
nni_manager_args
.
experiment_id
}
start:
{
datetime
.
now
()
}
'
header
=
f
'Experiment
{
nni_manager_args
.
experiment_id
}
start:
{
datetime
.
now
()
}
'
...
@@ -201,7 +201,7 @@ def _ensure_port_idle(port: int, message: Optional[str] = None) -> None:
...
@@ -201,7 +201,7 @@ def _ensure_port_idle(port: int, message: Optional[str] = None) -> None:
def
_start_rest_server_retiarii
(
config
:
ExperimentConfig
,
port
:
int
,
debug
:
bool
,
experiment_id
:
str
,
def
_start_rest_server_retiarii
(
config
:
ExperimentConfig
,
port
:
int
,
debug
:
bool
,
experiment_id
:
str
,
pipe_path
:
str
=
None
,
mode
:
str
=
'
new
'
)
->
Tuple
[
int
,
Popen
]:
pipe_path
:
str
,
mode
:
str
=
'
create
'
)
->
Tuple
[
int
,
Popen
]:
if
isinstance
(
config
.
training_service
,
list
):
if
isinstance
(
config
.
training_service
,
list
):
ts
=
'hybrid'
ts
=
'hybrid'
else
:
else
:
...
@@ -213,24 +213,20 @@ def _start_rest_server_retiarii(config: ExperimentConfig, port: int, debug: bool
...
@@ -213,24 +213,20 @@ def _start_rest_server_retiarii(config: ExperimentConfig, port: int, debug: bool
'port'
:
port
,
'port'
:
port
,
'mode'
:
ts
,
'mode'
:
ts
,
'experiment_id'
:
experiment_id
,
'experiment_id'
:
experiment_id
,
'
start_mode
'
:
mode
,
'
action
'
:
mode
,
'
log_dir
'
:
config
.
experiment_working_directory
,
'
experiments_directory
'
:
config
.
experiment_working_directory
,
'log_level'
:
'debug'
if
debug
else
'info'
'log_level'
:
'debug'
if
debug
else
'info'
}
}
if
pipe_path
is
not
None
:
if
pipe_path
is
not
None
:
args
[
'dispatcher_pipe'
]
=
pipe_path
args
[
'dispatcher_pipe'
]
=
pipe_path
if
mode
==
'view'
:
args
[
'start_mode'
]
=
'resume'
args
[
'readonly'
]
=
'true'
import
nni_node
import
nni_node
node_dir
=
Path
(
nni_node
.
__path__
[
0
])
node_dir
=
Path
(
nni_node
.
__path__
[
0
])
node
=
str
(
node_dir
/
(
'node.exe'
if
sys
.
platform
==
'win32'
else
'node'
))
node
=
str
(
node_dir
/
(
'node.exe'
if
sys
.
platform
==
'win32'
else
'node'
))
main_js
=
str
(
node_dir
/
'main.js'
)
main_js
=
str
(
node_dir
/
'main.js'
)
cmd
=
[
node
,
'--max-old-space-size=4096'
,
main_js
]
cmd
=
[
node
,
'--max-old-space-size=4096'
,
main_js
]
for
arg_key
,
arg_value
in
args
.
items
():
for
arg_key
,
arg_value
in
args
.
items
():
cmd
.
append
(
'--'
+
arg_key
)
cmd
.
append
(
'--'
+
arg_key
.
replace
(
'_'
,
'-'
)
)
cmd
.
append
(
str
(
arg_value
))
cmd
.
append
(
str
(
arg_value
))
if
sys
.
platform
==
'win32'
:
if
sys
.
platform
==
'win32'
:
...
...
nni/tools/nnictl/legacy_launcher.py
View file @
3b27ac76
...
@@ -70,21 +70,17 @@ def start_rest_server(port, platform, mode, experiment_id, foreground=False, log
...
@@ -70,21 +70,17 @@ def start_rest_server(port, platform, mode, experiment_id, foreground=False, log
node_command
=
os
.
path
.
join
(
entry_dir
,
'node'
)
node_command
=
os
.
path
.
join
(
entry_dir
,
'node'
)
cmds
=
[
node_command
,
'--max-old-space-size=4096'
,
entry_file
,
'--port'
,
str
(
port
),
'--mode'
,
platform
,
\
cmds
=
[
node_command
,
'--max-old-space-size=4096'
,
entry_file
,
'--port'
,
str
(
port
),
'--mode'
,
platform
,
\
'--experiment_id'
,
experiment_id
]
'--experiment_id'
,
experiment_id
]
if
mode
==
'view'
:
cmds
+=
[
'--action'
,
mode
]
cmds
+=
[
'--start_mode'
,
'resume'
]
cmds
+=
[
'--readonly'
,
'true'
]
else
:
cmds
+=
[
'--start_mode'
,
mode
]
if
log_dir
is
not
None
:
if
log_dir
is
not
None
:
cmds
+=
[
'--
log_dir
'
,
log_dir
]
cmds
+=
[
'--
experiments-directory
'
,
log_dir
]
if
log_level
is
not
None
:
if
log_level
is
not
None
:
cmds
+=
[
'--log
_
level'
,
log_level
]
cmds
+=
[
'--log
-
level'
,
log_level
]
if
foreground
:
if
foreground
:
cmds
+=
[
'--foreground'
,
'true'
]
cmds
+=
[
'--foreground'
,
'true'
]
if
url_prefix
:
if
url_prefix
:
_validate_prefix_path
(
url_prefix
)
_validate_prefix_path
(
url_prefix
)
set_prefix_url
(
url_prefix
)
set_prefix_url
(
url_prefix
)
cmds
+=
[
'--url
_
prefix'
,
url_prefix
]
cmds
+=
[
'--url
-
prefix'
,
url_prefix
.
strip
(
'/'
)
]
stdout_full_path
,
stderr_full_path
=
get_log_path
(
experiment_id
)
stdout_full_path
,
stderr_full_path
=
get_log_path
(
experiment_id
)
with
open
(
stdout_full_path
,
'a+'
)
as
stdout_file
,
open
(
stderr_full_path
,
'a+'
)
as
stderr_file
:
with
open
(
stdout_full_path
,
'a+'
)
as
stdout_file
,
open
(
stderr_full_path
,
'a+'
)
as
stderr_file
:
...
@@ -520,9 +516,9 @@ def create_experiment(args):
...
@@ -520,9 +516,9 @@ def create_experiment(args):
try
:
try
:
if
schema
==
1
:
if
schema
==
1
:
launch_experiment
(
args
,
config_v1
,
'
new
'
,
experiment_id
,
1
)
launch_experiment
(
args
,
config_v1
,
'
create
'
,
experiment_id
,
1
)
else
:
else
:
launch_experiment
(
args
,
config_v2
,
'
new
'
,
experiment_id
,
2
)
launch_experiment
(
args
,
config_v2
,
'
create
'
,
experiment_id
,
2
)
except
Exception
as
exception
:
except
Exception
as
exception
:
restServerPid
=
Experiments
().
get_all_experiments
().
get
(
experiment_id
,
{}).
get
(
'pid'
)
restServerPid
=
Experiments
().
get_all_experiments
().
get
(
experiment_id
,
{}).
get
(
'pid'
)
if
restServerPid
:
if
restServerPid
:
...
...
ts/nni_manager/common/globals/arguments.ts
0 → 100644
View file @
3b27ac76
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* Parse NNI manager's command line arguments.
**/
import
assert
from
'
assert/strict
'
;
import
yargs
from
'
yargs/yargs
'
;
/**
* Command line arguments provided by "nni/experiment/launcher.py".
*
* Hyphen-separated words are automatically converted to camelCases by yargs lib, but snake_cases are not.
* So it supports "--log-level" but does not support "--log_level".
*
* Unfortunately I misunderstood "experiment_working_directory" config field when deciding the name.
* It defaults to "~/nni-experiments" rather than "~/nni-experiments/<experiment-id>",
* and further more the working directory is "site-packages/nni_node", not either.
* For compatibility concern we cannot change the public API, so there is an inconsistency here.
**/
export
interface
NniManagerArgs
{
readonly
port
:
number
;
readonly
experimentId
:
string
;
readonly
action
:
'
create
'
|
'
resume
'
|
'
view
'
;
readonly
experimentsDirectory
:
string
;
// renamed "config.experiment_working_directory", must be absolute
readonly
logLevel
:
'
critical
'
|
'
error
'
|
'
warning
'
|
'
info
'
|
'
debug
'
;
readonly
foreground
:
boolean
;
readonly
urlPrefix
:
string
;
// leading and trailing "/" must be stripped
// these are planned to be removed
readonly
mode
:
string
;
readonly
dispatcherPipe
:
string
|
undefined
;
}
export
function
parseArgs
(
rawArgs
:
string
[]):
NniManagerArgs
{
const
parser
=
yargs
(
rawArgs
).
options
(
yargsOptions
).
strict
().
fail
((
_msg
,
err
,
_yargs
)
=>
{
throw
err
;
});
const
parsedArgs
:
NniManagerArgs
=
parser
.
parseSync
();
// strip yargs leftovers
const
argsAsAny
:
any
=
{};
for
(
const
key
in
yargsOptions
)
{
argsAsAny
[
key
]
=
(
parsedArgs
as
any
)[
key
];
assert
(
!
Number
.
isNaN
(
argsAsAny
[
key
]),
`Command line arg --
${
key
}
is not a number`
);
}
if
(
argsAsAny
.
dispatcherPipe
===
''
)
{
argsAsAny
.
dispatcherPipe
=
undefined
;
}
const
args
:
NniManagerArgs
=
argsAsAny
;
const
prefixErrMsg
=
`Command line arg --url-prefix "
${
args
.
urlPrefix
}
" is not stripped`
;
assert
(
!
args
.
urlPrefix
.
startsWith
(
'
/
'
)
&&
!
args
.
urlPrefix
.
endsWith
(
'
/
'
),
prefixErrMsg
);
return
args
;
}
const
yargsOptions
=
{
port
:
{
demandOption
:
true
,
type
:
'
number
'
},
experimentId
:
{
demandOption
:
true
,
type
:
'
string
'
},
action
:
{
choices
:
[
'
create
'
,
'
resume
'
,
'
view
'
]
as
const
,
demandOption
:
true
},
experimentsDirectory
:
{
demandOption
:
true
,
type
:
'
string
'
},
logLevel
:
{
choices
:
[
'
critical
'
,
'
error
'
,
'
warning
'
,
'
info
'
,
'
debug
'
]
as
const
,
demandOption
:
true
},
foreground
:
{
default
:
false
,
type
:
'
boolean
'
},
urlPrefix
:
{
default
:
''
,
type
:
'
string
'
},
mode
:
{
default
:
''
,
type
:
'
string
'
},
dispatcherPipe
:
{
default
:
''
,
type
:
'
string
'
}
}
as
const
;
ts/nni_manager/main.ts
View file @
3b27ac76
...
@@ -20,15 +20,11 @@ import { SqlDB } from './core/sqlDatabase';
...
@@ -20,15 +20,11 @@ import { SqlDB } from './core/sqlDatabase';
import
{
NNIExperimentsManager
}
from
'
./core/nniExperimentsManager
'
;
import
{
NNIExperimentsManager
}
from
'
./core/nniExperimentsManager
'
;
import
{
NNITensorboardManager
}
from
'
./core/nniTensorboardManager
'
;
import
{
NNITensorboardManager
}
from
'
./core/nniTensorboardManager
'
;
import
{
RestServer
}
from
'
./rest_server
'
;
import
{
RestServer
}
from
'
./rest_server
'
;
import
{
parseArgs
}
from
'
common/globals/arguments
'
;
function
initStartupInfo
(
const
args
=
parseArgs
(
process
.
argv
.
slice
(
2
));
startExpMode
:
string
,
experimentId
:
string
,
basePort
:
number
,
platform
:
string
,
logDirectory
:
string
,
experimentLogLevel
:
string
,
readonly
:
boolean
,
dispatcherPipe
:
string
,
urlprefix
:
string
):
void
{
const
createNew
:
boolean
=
(
startExpMode
===
ExperimentStartUpMode
.
NEW
);
setExperimentStartupInfo
(
createNew
,
experimentId
,
basePort
,
platform
,
logDirectory
,
experimentLogLevel
,
readonly
,
dispatcherPipe
,
urlprefix
);
}
async
function
initContainer
(
foreground
:
boolean
,
_platformMode
:
string
,
logFileName
?:
string
):
Promise
<
void
>
{
async
function
initContainer
():
Promise
<
void
>
{
Container
.
bind
(
Manager
)
Container
.
bind
(
Manager
)
.
to
(
NNIManager
)
.
to
(
NNIManager
)
.
scope
(
Scope
.
Singleton
);
.
scope
(
Scope
.
Singleton
);
...
@@ -45,84 +41,32 @@ async function initContainer(foreground: boolean, _platformMode: string, logFile
...
@@ -45,84 +41,32 @@ async function initContainer(foreground: boolean, _platformMode: string, logFile
.
to
(
NNITensorboardManager
)
.
to
(
NNITensorboardManager
)
.
scope
(
Scope
.
Singleton
);
.
scope
(
Scope
.
Singleton
);
const
DEFAULT_LOGFILE
:
string
=
path
.
join
(
getLogDir
(),
'
nnimanager.log
'
);
const
DEFAULT_LOGFILE
:
string
=
path
.
join
(
getLogDir
(),
'
nnimanager.log
'
);
if
(
!
foreground
)
{
if
(
!
args
.
foreground
)
{
if
(
logFileName
===
undefined
)
{
startLogging
(
DEFAULT_LOGFILE
);
startLogging
(
DEFAULT_LOGFILE
);
}
else
{
startLogging
(
logFileName
);
}
}
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
// eslint-disable-next-line @typescript-eslint/no-use-before-define
setLogLevel
(
logLevel
);
setLogLevel
(
args
.
logLevel
);
const
ds
:
DataStore
=
component
.
get
(
DataStore
);
const
ds
:
DataStore
=
component
.
get
(
DataStore
);
await
ds
.
init
();
await
ds
.
init
();
}
}
function
usage
():
void
{
setExperimentStartupInfo
(
console
.
info
(
'
usage: node main.js --port <port> --mode
\
args
.
action
===
'
create
'
,
<local/remote/pai/kubeflow/frameworkcontroller/aml/adl/hybrid/dlc> --start_mode <new/resume> --experiment_id <id> --foreground <true/false>
'
);
args
.
experimentId
,
}
args
.
port
,
args
.
mode
,
const
strPort
:
string
=
parseArg
([
'
--port
'
,
'
-p
'
]);
args
.
experimentsDirectory
,
if
(
!
strPort
||
strPort
.
length
===
0
)
{
args
.
logLevel
,
usage
();
args
.
action
===
'
view
'
,
process
.
exit
(
1
);
args
.
dispatcherPipe
??
''
,
}
args
.
urlPrefix
);
const
foregroundArg
:
string
=
parseArg
([
'
--foreground
'
,
'
-f
'
]);
if
(
foregroundArg
&&
!
[
'
true
'
,
'
false
'
].
includes
(
foregroundArg
.
toLowerCase
()))
{
console
.
log
(
`FATAL: foreground property should only be true or false`
);
usage
();
process
.
exit
(
1
);
}
const
foreground
:
boolean
=
(
foregroundArg
&&
foregroundArg
.
toLowerCase
()
===
'
true
'
)
?
true
:
false
;
const
port
:
number
=
parseInt
(
strPort
,
10
);
const
mode
:
string
=
parseArg
([
'
--mode
'
,
'
-m
'
]);
const
startMode
:
string
=
parseArg
([
'
--start_mode
'
,
'
-s
'
]);
if
(
!
[
ExperimentStartUpMode
.
NEW
,
ExperimentStartUpMode
.
RESUME
].
includes
(
startMode
))
{
console
.
log
(
`FATAL: unknown start_mode:
${
startMode
}
`
);
usage
();
process
.
exit
(
1
);
}
const
experimentId
:
string
=
parseArg
([
'
--experiment_id
'
,
'
-id
'
]);
if
(
experimentId
.
trim
().
length
<
1
)
{
console
.
log
(
`FATAL: cannot resume the experiment, invalid experiment_id:
${
experimentId
}
`
);
usage
();
process
.
exit
(
1
);
}
const
logDir
:
string
=
parseArg
([
'
--log_dir
'
,
'
-ld
'
]);
if
(
logDir
.
length
>
0
)
{
if
(
!
fs
.
existsSync
(
logDir
))
{
console
.
log
(
`FATAL: log_dir
${
logDir
}
does not exist`
);
}
}
const
logLevel
:
string
=
parseArg
([
'
--log_level
'
,
'
-ll
'
]);
const
readonlyArg
:
string
=
parseArg
([
'
--readonly
'
,
'
-r
'
]);
if
(
readonlyArg
&&
!
[
'
true
'
,
'
false
'
].
includes
(
readonlyArg
.
toLowerCase
()))
{
console
.
log
(
`FATAL: readonly property should only be true or false`
);
usage
();
process
.
exit
(
1
);
}
const
readonly
=
(
readonlyArg
&&
readonlyArg
.
toLowerCase
()
==
'
true
'
)
?
true
:
false
;
const
dispatcherPipe
:
string
=
parseArg
([
'
--dispatcher_pipe
'
]);
const
urlPrefix
:
string
=
parseArg
([
'
--url_prefix
'
]);
initStartupInfo
(
startMode
,
experimentId
,
port
,
mode
,
logDir
,
logLevel
,
readonly
,
dispatcherPipe
,
urlPrefix
);
mkDirP
(
getLogDir
())
mkDirP
(
getLogDir
())
.
then
(
async
()
=>
{
.
then
(
async
()
=>
{
try
{
try
{
await
initContainer
(
foreground
,
mode
);
await
initContainer
();
const
restServer
:
RestServer
=
component
.
get
(
RestServer
);
const
restServer
:
RestServer
=
component
.
get
(
RestServer
);
await
restServer
.
start
();
await
restServer
.
start
();
}
catch
(
err
)
{
}
catch
(
err
)
{
...
...
ts/nni_manager/package.json
View file @
3b27ac76
...
@@ -33,7 +33,8 @@
...
@@ -33,7 +33,8 @@
"ts-deferred"
:
"^1.0.4"
,
"ts-deferred"
:
"^1.0.4"
,
"typescript-ioc"
:
"^1.2.6"
,
"typescript-ioc"
:
"^1.2.6"
,
"typescript-string-operations"
:
"^1.4.1"
,
"typescript-string-operations"
:
"^1.4.1"
,
"ws"
:
"^7.4.6"
"ws"
:
"^7.4.6"
,
"yargs"
:
"^17.3.1"
},
},
"devDependencies"
:
{
"devDependencies"
:
{
"@types/chai"
:
"^4.2.18"
,
"@types/chai"
:
"^4.2.18"
,
...
@@ -55,6 +56,7 @@
...
@@ -55,6 +56,7 @@
"@types/tar"
:
"^4.0.4"
,
"@types/tar"
:
"^4.0.4"
,
"@types/tmp"
:
"^0.2.0"
,
"@types/tmp"
:
"^0.2.0"
,
"@types/ws"
:
"^7.4.4"
,
"@types/ws"
:
"^7.4.4"
,
"@types/yargs"
:
"^17.0.8"
,
"@typescript-eslint/eslint-plugin"
:
"^2.10.0"
,
"@typescript-eslint/eslint-plugin"
:
"^2.10.0"
,
"@typescript-eslint/parser"
:
"^4.26.0"
,
"@typescript-eslint/parser"
:
"^4.26.0"
,
"chai"
:
"^4.3.4"
,
"chai"
:
"^4.3.4"
,
...
...
ts/nni_manager/test/common/globals/arguments.test.ts
0 → 100644
View file @
3b27ac76
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import
assert
from
'
assert/strict
'
;
import
{
parseArgs
}
from
'
common/globals/arguments
'
;
const
command
=
'
--port 80 --experiment-id ID --action resume --experiments-directory DIR --log-level error
'
;
const
expected
=
{
port
:
80
,
experimentId
:
'
ID
'
,
action
:
'
resume
'
,
experimentsDirectory
:
'
DIR
'
,
logLevel
:
'
error
'
,
foreground
:
false
,
urlPrefix
:
''
,
mode
:
''
,
dispatcherPipe
:
undefined
,
};
function
testGoodShort
():
void
{
const
args
=
parseArgs
(
command
.
split
(
'
'
));
assert
.
deepEqual
(
args
,
expected
);
}
function
testGoodLong
():
void
{
const
cmd
=
command
+
'
--url-prefix URL/prefix --foreground true
'
;
const
args
=
parseArgs
(
cmd
.
split
(
'
'
));
const
expectedLong
=
Object
.
assign
({},
expected
);
expectedLong
.
urlPrefix
=
'
URL/prefix
'
;
expectedLong
.
foreground
=
true
;
assert
.
deepEqual
(
args
,
expectedLong
);
}
function
testBadKey
():
void
{
const
cmd
=
command
+
'
--bad 1
'
;
assert
.
throws
(()
=>
parseArgs
(
cmd
.
split
(
'
'
)));
}
function
testBadPos
():
void
{
const
cmd
=
command
.
replace
(
'
--port
'
,
'
port
'
);
assert
.
throws
(()
=>
parseArgs
(
cmd
.
split
(
'
'
)));
}
function
testBadNum
():
void
{
const
cmd
=
command
.
replace
(
'
80
'
,
'
8o
'
);
assert
.
throws
(()
=>
parseArgs
(
cmd
.
split
(
'
'
)));
}
function
testBadBool
():
void
{
const
cmd
=
command
+
'
--foreground 1
'
;
assert
.
throws
(()
=>
parseArgs
(
cmd
.
split
(
'
'
)));
}
function
testBadChoice
():
void
{
const
cmd
=
command
.
replace
(
'
resume
'
,
'
new
'
);
assert
.
throws
(()
=>
parseArgs
(
cmd
.
split
(
'
'
)));
}
describe
(
'
## globals.arguments ##
'
,
()
=>
{
it
(
'
good short
'
,
()
=>
testGoodShort
());
it
(
'
good long
'
,
()
=>
testGoodLong
());
it
(
'
bad key arg
'
,
()
=>
testBadKey
());
it
(
'
bad positional arg
'
,
()
=>
testBadPos
());
it
(
'
bad number
'
,
()
=>
testBadNum
());
it
(
'
bad boolean
'
,
()
=>
testBadBool
());
it
(
'
bad choice
'
,
()
=>
testBadChoice
());
});
ts/nni_manager/yarn.lock
View file @
3b27ac76
...
@@ -820,6 +820,18 @@
...
@@ -820,6 +820,18 @@
dependencies:
dependencies:
"@types/node" "*"
"@types/node" "*"
"@types/yargs-parser@*":
version "20.2.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==
"@types/yargs@^17.0.8":
version "17.0.8"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.8.tgz#d23a3476fd3da8a0ea44b5494ca7fa677b9dad4c"
integrity sha512-wDeUwiUmem9FzsyysEwRukaEdDNcwbROvQ9QGRKaLI6t+IltNzbn4/i4asmB10auvZGQCzSQ6t0GSczEThlUXw==
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^2.10.0":
"@typescript-eslint/eslint-plugin@^2.10.0":
version "2.34.0"
version "2.34.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9"
...
@@ -5752,7 +5764,7 @@ yallist@^4.0.0:
...
@@ -5752,7 +5764,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@20.2.4, yargs-parser@>=20.2.7, yargs-parser@^18.1.2, yargs-parser@^20.2.2:
yargs-parser@20.2.4, yargs-parser@>=20.2.7, yargs-parser@^18.1.2, yargs-parser@^20.2.2
, yargs-parser@^21.0.0
:
version "20.2.7"
version "20.2.7"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
...
@@ -5797,6 +5809,19 @@ yargs@^15.0.2:
...
@@ -5797,6 +5809,19 @@ yargs@^15.0.2:
y18n "^4.0.0"
y18n "^4.0.0"
yargs-parser "^18.1.2"
yargs-parser "^18.1.2"
yargs@^17.3.1:
version "17.3.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9"
integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.0.0"
yn@3.1.1:
yn@3.1.1:
version "3.1.1"
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
...
...
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