Skip to content

Commit e988cb1

Browse files
icywang86ruiPiali Das
authored and
Piali Das
committed
Remove usage of fcntl (aws#347)
fcntl is only available on linux systems. Importing sagemaker on Windows fails cause of this. This change removes usage of fcntl. _stream_out exists because jupyter swallows stderr and stdout from a child process. We have to capture it from the main process and pipe to stdout here. This change redirects the child process's stderr to stdout so we only need to read from stdout which is already non-blocking.
1 parent 3ecf26a commit e988cb1

File tree

1 file changed

+4
-19
lines changed

1 file changed

+4
-19
lines changed

src/sagemaker/local/image.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import sys
2727
import tarfile
2828
import tempfile
29-
from fcntl import fcntl, F_GETFL, F_SETFL
3029
from six.moves.urllib.parse import urlparse
3130
from threading import Thread
3231

@@ -105,7 +104,7 @@ def train(self, input_data_config, hyperparameters):
105104
compose_command = self._compose()
106105

107106
_ecr_login_if_needed(self.sagemaker_session.boto_session, self.image)
108-
process = subprocess.Popen(compose_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
107+
process = subprocess.Popen(compose_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
109108

110109
try:
111110
_stream_output(process)
@@ -555,34 +554,20 @@ def __init__(self, host_dir, container_dir=None, channel=None):
555554
def _stream_output(process):
556555
"""Stream the output of a process to stdout
557556
558-
This function takes an existing process that will be polled for output. Both stdout and
559-
stderr will be polled and both will be sent to sys.stdout.
557+
This function takes an existing process that will be polled for output. Only stdout
558+
will be polled and sent to sys.stdout.
560559
561560
Args:
562561
process(subprocess.Popen): a process that has been started with
563-
stdout=PIPE and stderr=PIPE
562+
stdout=PIPE and stderr=STDOUT
564563
565564
Returns (int): process exit code
566565
"""
567566
exit_code = None
568567

569-
# Get the current flags for the stderr file descriptor
570-
# And add the NONBLOCK flag to allow us to read even if there is no data.
571-
# Since usually stderr will be empty unless there is an error.
572-
flags = fcntl(process.stderr, F_GETFL) # get current process.stderr flags
573-
fcntl(process.stderr, F_SETFL, flags | os.O_NONBLOCK)
574-
575568
while exit_code is None:
576569
stdout = process.stdout.readline().decode("utf-8")
577570
sys.stdout.write(stdout)
578-
try:
579-
stderr = process.stderr.readline().decode("utf-8")
580-
sys.stdout.write(stderr)
581-
except IOError:
582-
# If there is nothing to read on stderr we will get an IOError
583-
# this is fine.
584-
pass
585-
586571
exit_code = process.poll()
587572

588573
if exit_code != 0:

0 commit comments

Comments
 (0)