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
d7920fd2
"git@developer.sourcefind.cn:modelzoo/fastfold_pytorch.git" did not exist on "75d561f206fe298bd2420a99fc1f858e9300fc81"
Unverified
Commit
d7920fd2
authored
Feb 07, 2020
by
SparkSnail
Committed by
GitHub
Feb 07, 2020
Browse files
Add foreground mode in nnictl (#1956)
parent
26aa1136
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
80 additions
and
41 deletions
+80
-41
docs/en_US/Tutorial/Nnictl.md
docs/en_US/Tutorial/Nnictl.md
+2
-2
src/nni_manager/common/log.ts
src/nni_manager/common/log.ts
+22
-21
src/nni_manager/main.ts
src/nni_manager/main.ts
+27
-3
tools/nni_cmd/launcher.py
tools/nni_cmd/launcher.py
+27
-13
tools/nni_cmd/nnictl.py
tools/nni_cmd/nnictl.py
+2
-2
No files found.
docs/en_US/Tutorial/Nnictl.md
View file @
d7920fd2
...
...
@@ -49,7 +49,7 @@ nnictl support commands:
|--config, -c| True| |YAML configure file of the experiment|
|--port, -p|False| |the port of restful server|
|--debug, -d|False||set debug mode|
|--
watch
, -
w
|False||set
watch mode
|
|--
foreground
, -
f
|False||set
foreground mode, print log content to terminal
|
*
Examples
...
...
@@ -98,7 +98,7 @@ Debug mode will disable version check function in Trialkeeper.
|id| True| |The id of the experiment you want to resume|
|--port, -p| False| |Rest port of the experiment you want to resume|
|--debug, -d|False||set debug mode|
|--
watch
, -
w
|False||set
watch mode
|
|--
foreground
, -
f
|False||set
foreground mode, print log content to terminal
|
*
Example
...
...
src/nni_manager/common/log.ts
View file @
d7920fd2
...
...
@@ -4,13 +4,11 @@
'
use strict
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
{
Writable
}
from
'
stream
'
;
import
{
WritableStreamBuffer
}
from
'
stream-buffers
'
;
import
{
format
}
from
'
util
'
;
import
*
as
component
from
'
../common/component
'
;
import
{
getExperimentStartupInfo
,
isReadonly
}
from
'
./experimentStartupInfo
'
;
import
{
getLogDir
}
from
'
./utils
'
;
const
FATAL
:
number
=
1
;
const
ERROR
:
number
=
2
;
...
...
@@ -55,23 +53,21 @@ class BufferSerialEmitter {
@
component
.
Singleton
class
Logger
{
private
DEFAULT_LOGFILE
:
string
=
path
.
join
(
getLogDir
(),
'
nnimanager.log
'
);
private
level
:
number
=
INFO
;
private
bufferSerialEmitter
:
BufferSerialEmitter
;
private
writable
:
Writable
;
private
bufferSerialEmitter
?
:
BufferSerialEmitter
;
private
writable
?
:
Writable
;
private
readonly
:
boolean
=
false
;
constructor
(
fileName
?:
string
)
{
let
logFile
:
string
|
undefined
=
fileName
;
if
(
logFile
===
undefined
)
{
logFile
=
this
.
DEFAULT_LOGFILE
;
const
logFile
:
string
|
undefined
=
fileName
;
if
(
logFile
)
{
this
.
writable
=
fs
.
createWriteStream
(
logFile
,
{
flags
:
'
a+
'
,
encoding
:
'
utf8
'
,
autoClose
:
true
});
this
.
bufferSerialEmitter
=
new
BufferSerialEmitter
(
this
.
writable
);
}
this
.
writable
=
fs
.
createWriteStream
(
logFile
,
{
flags
:
'
a+
'
,
encoding
:
'
utf8
'
,
autoClose
:
true
});
this
.
bufferSerialEmitter
=
new
BufferSerialEmitter
(
this
.
writable
);
const
logLevelName
:
string
=
getExperimentStartupInfo
()
.
getLogLevel
();
...
...
@@ -84,7 +80,9 @@ class Logger {
}
public
close
():
void
{
this
.
writable
.
destroy
();
if
(
this
.
writable
)
{
this
.
writable
.
destroy
();
}
}
public
trace
(...
param
:
any
[]):
void
{
...
...
@@ -128,12 +126,15 @@ class Logger {
*/
private
log
(
level
:
string
,
param
:
any
[]):
void
{
if
(
!
this
.
readonly
)
{
const
buffer
:
WritableStreamBuffer
=
new
WritableStreamBuffer
();
buffer
.
write
(
`[
${(
new
Date
()).
toLocaleString
()}
]
${
level
}
`
);
buffer
.
write
(
format
(
param
));
buffer
.
write
(
'
\n
'
);
buffer
.
end
();
this
.
bufferSerialEmitter
.
feed
(
buffer
.
getContents
());
const
logContent
=
`[
${(
new
Date
()).
toLocaleString
()}
]
${
level
}
${
format
(
param
)}
\n`
;
if
(
this
.
writable
&&
this
.
bufferSerialEmitter
)
{
const
buffer
:
WritableStreamBuffer
=
new
WritableStreamBuffer
();
buffer
.
write
(
logContent
);
buffer
.
end
();
this
.
bufferSerialEmitter
.
feed
(
buffer
.
getContents
());
}
else
{
console
.
log
(
logContent
);
}
}
}
}
...
...
src/nni_manager/main.ts
View file @
d7920fd2
...
...
@@ -6,6 +6,7 @@
import
{
Container
,
Scope
}
from
'
typescript-ioc
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
component
from
'
./common/component
'
;
import
{
Database
,
DataStore
}
from
'
./common/datastore
'
;
import
{
setExperimentStartupInfo
}
from
'
./common/experimentStartupInfo
'
;
...
...
@@ -34,7 +35,7 @@ function initStartupInfo(
setExperimentStartupInfo
(
createNew
,
expId
,
basePort
,
logDirectory
,
experimentLogLevel
,
readonly
);
}
async
function
initContainer
(
platformMode
:
string
,
logFileName
?:
string
):
Promise
<
void
>
{
async
function
initContainer
(
foreground
:
boolean
,
platformMode
:
string
,
logFileName
?:
string
):
Promise
<
void
>
{
if
(
platformMode
===
'
local
'
)
{
Container
.
bind
(
TrainingService
)
.
to
(
LocalTrainingService
)
...
...
@@ -71,6 +72,12 @@ async function initContainer(platformMode: string, logFileName?: string): Promis
Container
.
bind
(
DataStore
)
.
to
(
NNIDataStore
)
.
scope
(
Scope
.
Singleton
);
const
DEFAULT_LOGFILE
:
string
=
path
.
join
(
getLogDir
(),
'
nnimanager.log
'
);
if
(
foreground
)
{
logFileName
=
undefined
;
}
else
if
(
logFileName
===
undefined
)
{
logFileName
=
DEFAULT_LOGFILE
;
}
Container
.
bind
(
Logger
).
provider
({
get
:
():
Logger
=>
new
Logger
(
logFileName
)
});
...
...
@@ -81,7 +88,7 @@ async function initContainer(platformMode: string, logFileName?: string): Promis
function
usage
():
void
{
console
.
info
(
'
usage: node main.js --port <port> --mode
\
<local/remote/pai/kubeflow/frameworkcontroller/paiYarn> --start_mode <new/resume> --experiment_id <id>
'
);
<local/remote/pai/kubeflow/frameworkcontroller/paiYarn> --start_mode <new/resume> --experiment_id <id>
--foreground <true/false>
'
);
}
const
strPort
:
string
=
parseArg
([
'
--port
'
,
'
-p
'
]);
...
...
@@ -90,6 +97,14 @@ if (!strPort || strPort.length === 0) {
process
.
exit
(
1
);
}
const
foregroundArg
:
string
=
parseArg
([
'
--foreground
'
,
'
-f
'
]);
if
(
!
(
'
true
'
||
'
false
'
).
includes
(
foregroundArg
.
toLowerCase
()))
{
console
.
log
(
`FATAL: foreground property should only be true or false`
);
usage
();
process
.
exit
(
1
);
}
const
foreground
:
boolean
=
foregroundArg
.
toLowerCase
()
===
'
true
'
?
true
:
false
;
const
port
:
number
=
parseInt
(
strPort
,
10
);
const
mode
:
string
=
parseArg
([
'
--mode
'
,
'
-m
'
]);
...
...
@@ -138,7 +153,7 @@ initStartupInfo(startMode, experimentId, port, logDir, logLevel, readonly);
mkDirP
(
getLogDir
())
.
then
(
async
()
=>
{
try
{
await
initContainer
(
mode
);
await
initContainer
(
foreground
,
mode
);
const
restServer
:
NNIRestServer
=
component
.
get
(
NNIRestServer
);
await
restServer
.
start
();
const
log
:
Logger
=
getLogger
();
...
...
@@ -162,6 +177,15 @@ function getStopSignal(): any {
}
}
function
getCtrlCSignal
():
any
{
return
'
SIGINT
'
;
}
process
.
on
(
getCtrlCSignal
(),
async
()
=>
{
const
log
:
Logger
=
getLogger
();
log
.
info
(
`Get SIGINT signal!`
);
});
process
.
on
(
getStopSignal
(),
async
()
=>
{
const
log
:
Logger
=
getLogger
();
let
hasError
:
boolean
=
false
;
...
...
tools/nni_cmd/launcher.py
View file @
d7920fd2
...
...
@@ -9,7 +9,7 @@ import random
import
site
import
time
import
tempfile
from
subprocess
import
Popen
,
check_call
,
CalledProcessError
from
subprocess
import
Popen
,
check_call
,
CalledProcessError
,
PIPE
,
STDOUT
from
nni_annotation
import
expand_annotations
,
generate_search_space
from
nni.constants
import
ModuleName
,
AdvisorModuleName
from
.launcher_utils
import
validate_all_content
...
...
@@ -20,7 +20,7 @@ from .common_utils import get_yml_content, get_json_content, print_error, print_
detect_port
,
get_user
,
get_python_dir
from
.constants
import
NNICTL_HOME_DIR
,
ERROR_INFO
,
REST_TIME_OUT
,
EXPERIMENT_SUCCESS_INFO
,
LOG_HEADER
,
PACKAGE_REQUIREMENTS
from
.command_utils
import
check_output_command
,
kill_command
from
.nnictl_utils
import
update_experiment
,
set_monitor
from
.nnictl_utils
import
update_experiment
def
get_log_path
(
config_file_name
):
'''generate stdout and stderr log path'''
...
...
@@ -78,17 +78,17 @@ def get_nni_installation_path():
print_error
(
'Fail to find nni under python library'
)
exit
(
1
)
def
start_rest_server
(
port
,
platform
,
mode
,
config_file_name
,
experiment_id
=
None
,
log_dir
=
None
,
log_level
=
None
):
def
start_rest_server
(
args
,
platform
,
mode
,
config_file_name
,
experiment_id
=
None
,
log_dir
=
None
,
log_level
=
None
):
'''Run nni manager process'''
if
detect_port
(
port
):
if
detect_port
(
args
.
port
):
print_error
(
'Port %s is used by another process, please reset the port!
\n
'
\
'You could use
\'
nnictl create --help
\'
to get help information'
%
port
)
'You could use
\'
nnictl create --help
\'
to get help information'
%
args
.
port
)
exit
(
1
)
if
(
platform
!=
'local'
)
and
detect_port
(
int
(
port
)
+
1
):
if
(
platform
!=
'local'
)
and
detect_port
(
int
(
args
.
port
)
+
1
):
print_error
(
'PAI mode need an additional adjacent port %d, and the port %d is used by another process!
\n
'
\
'You could set another port to start experiment!
\n
'
\
'You could use
\'
nnictl create --help
\'
to get help information'
%
((
int
(
port
)
+
1
),
(
int
(
port
)
+
1
)))
'You could use
\'
nnictl create --help
\'
to get help information'
%
((
int
(
args
.
port
)
+
1
),
(
int
(
args
.
port
)
+
1
)))
exit
(
1
)
print_normal
(
'Starting restful server...'
)
...
...
@@ -99,7 +99,7 @@ def start_rest_server(port, platform, mode, config_file_name, experiment_id=None
node_command
=
'node'
if
sys
.
platform
==
'win32'
:
node_command
=
os
.
path
.
join
(
entry_dir
[:
-
3
],
'Scripts'
,
'node.exe'
)
cmds
=
[
node_command
,
entry_file
,
'--port'
,
str
(
port
),
'--mode'
,
platform
]
cmds
=
[
node_command
,
entry_file
,
'--port'
,
str
(
args
.
port
),
'--mode'
,
platform
]
if
mode
==
'view'
:
cmds
+=
[
'--start_mode'
,
'resume'
]
cmds
+=
[
'--readonly'
,
'true'
]
...
...
@@ -111,6 +111,8 @@ def start_rest_server(port, platform, mode, config_file_name, experiment_id=None
cmds
+=
[
'--log_level'
,
log_level
]
if
mode
in
[
'resume'
,
'view'
]:
cmds
+=
[
'--experiment_id'
,
experiment_id
]
if
args
.
foreground
:
cmds
+=
[
'--foreground'
,
'true'
]
stdout_full_path
,
stderr_full_path
=
get_log_path
(
config_file_name
)
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
()))
...
...
@@ -120,9 +122,15 @@ def start_rest_server(port, platform, mode, config_file_name, experiment_id=None
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
)
if
args
.
foreground
:
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
PIPE
,
stderr
=
STDOUT
,
creationflags
=
CREATE_NEW_PROCESS_GROUP
)
else
:
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
)
if
args
.
foreground
:
process
=
Popen
(
cmds
,
cwd
=
entry_dir
,
stdout
=
PIPE
,
stderr
=
PIPE
)
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
):
...
...
@@ -424,7 +432,7 @@ def launch_experiment(args, experiment_config, mode, config_file_name, experimen
if
log_level
not
in
[
'trace'
,
'debug'
]
and
(
args
.
debug
or
experiment_config
.
get
(
'debug'
)
is
True
):
log_level
=
'debug'
# start rest server
rest_process
,
start_time
=
start_rest_server
(
args
.
port
,
experiment_config
[
'trainingServicePlatform'
],
\
rest_process
,
start_time
=
start_rest_server
(
args
,
experiment_config
[
'trainingServicePlatform'
],
\
mode
,
config_file_name
,
experiment_id
,
log_dir
,
log_level
)
nni_config
.
set_config
(
'restServerPid'
,
rest_process
.
pid
)
# Deal with annotation
...
...
@@ -493,8 +501,14 @@ def launch_experiment(args, experiment_config, mode, config_file_name, experimen
experiment_config
[
'experimentName'
])
print_normal
(
EXPERIMENT_SUCCESS_INFO
%
(
experiment_id
,
' '
.
join
(
web_ui_url_list
)))
if
args
.
watch
:
set_monitor
(
True
,
3
,
args
.
port
,
rest_process
.
pid
)
if
args
.
foreground
:
try
:
while
True
:
log_content
=
rest_process
.
stdout
.
readline
().
strip
().
decode
(
'utf-8'
)
print
(
log_content
)
except
KeyboardInterrupt
:
kill_command
(
rest_process
.
pid
)
print_normal
(
'Stopping experiment...'
)
def
create_experiment
(
args
):
'''start a new experiment'''
...
...
tools/nni_cmd/nnictl.py
View file @
d7920fd2
...
...
@@ -51,7 +51,7 @@ def parse_args():
parser_start
.
add_argument
(
'--config'
,
'-c'
,
required
=
True
,
dest
=
'config'
,
help
=
'the path of yaml config file'
)
parser_start
.
add_argument
(
'--port'
,
'-p'
,
default
=
DEFAULT_REST_PORT
,
dest
=
'port'
,
help
=
'the port of restful server'
)
parser_start
.
add_argument
(
'--debug'
,
'-d'
,
action
=
'store_true'
,
help
=
' set debug mode'
)
parser_start
.
add_argument
(
'--
watch
'
,
'-
w
'
,
action
=
'store_true'
,
help
=
' set
watch mode
'
)
parser_start
.
add_argument
(
'--
foreground
'
,
'-
f
'
,
action
=
'store_true'
,
help
=
' set
foreground mode, print log content to terminal
'
)
parser_start
.
set_defaults
(
func
=
create_experiment
)
# parse resume command
...
...
@@ -59,7 +59,7 @@ def parse_args():
parser_resume
.
add_argument
(
'id'
,
nargs
=
'?'
,
help
=
'The id of the experiment you want to resume'
)
parser_resume
.
add_argument
(
'--port'
,
'-p'
,
default
=
DEFAULT_REST_PORT
,
dest
=
'port'
,
help
=
'the port of restful server'
)
parser_resume
.
add_argument
(
'--debug'
,
'-d'
,
action
=
'store_true'
,
help
=
' set debug mode'
)
parser_resume
.
add_argument
(
'--
watch
'
,
'-
w
'
,
action
=
'store_true'
,
help
=
' set
watch mode
'
)
parser_resume
.
add_argument
(
'--
foreground
'
,
'-
f
'
,
action
=
'store_true'
,
help
=
' set
foreground mode, print log content to terminal
'
)
parser_resume
.
set_defaults
(
func
=
resume_experiment
)
# parse view command
...
...
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