# Buggy code
def _exec_command_fn(settings):
    """
    executes the jobs defined by run command on hosts.
    :param hosts_alloc: list of dict indicating the allocating info.
    For example,
        [{'Hostname':'worker-0', 'Rank': 0, 'Local_rank': 0, 'Cross_rank':0,
            'Size':2, 'Local_size':1, 'Cross_size':2},
        {'Hostname':'worker-1', 'Rank': 1, 'Local_rank': 0, 'Cross_rank':1,
            'Size':2, 'Local_size':1, 'Cross_size':2}
        ]
    :type hosts_alloc: list(dict)
    :param remote_host_names: names that are resolved to one of the addresses
    of remote hosts interfaces.
    :type remote_host_names: set
    :param _run_command: command to execute
    :type _run_command: string
    :return:
    :rtype:
    """
    ssh_port_arg = (
        "-p {ssh_port}".format(ssh_port=settings.ssh_port) if settings.ssh_port else ""
    )

    def _exec_command(command, slot_info, events):
        index = slot_info.rank
        host_name = slot_info.hostname

        host_address = network.resolve_host_address(host_name)
        local_addresses = network.get_local_host_addresses()
        if host_address not in local_addresses:
            command = (
                "ssh -o StrictHostKeyChecking=no {host} {ssh_port_arg} "
                "{local_command}".format(
                    host=host_name,
                    ssh_port_arg=ssh_port_arg,
                    local_command=quote(
                        "cd {pwd} > /dev/null 2>&1 ; {local_command}".format(
                            pwd=os.getcwd(), local_command=command
                        )
                    ),
                )
            )

        if settings.verbose:
            print(command)

        # Redirect output if requested
        stdout = stderr = None
        stdout_file = stderr_file = None
        if settings.output_filename:
            padded_rank = _pad_rank(index, settings.num_proc)
            output_dir_rank = os.path.join(
                settings.output_filename, "rank.{rank}".format(rank=padded_rank)
            )
            if not os.path.exists(output_dir_rank):
                os.mkdir(output_dir_rank)

            stdout_file = open(os.path.join(output_dir_rank, "stdout"), "w")
            stderr_file = open(os.path.join(output_dir_rank, "stderr"), "w")

            stdout = MultiFile([sys.stdout, stdout_file])
            stderr = MultiFile([sys.stderr, stderr_file])

        try:
            exit_code = safe_shell_exec.execute(
                command, index=index, stdout=stdout, stderr=stderr, events=events
            )
            if exit_code != 0:
                print(
                    "Process {idx} exit with status code {ec}.".format(
                        idx=index, ec=exit_code
                    )
                )
        except Exception as e:
            print(
                "Exception happened during safe_shell_exec, exception "
                "message: {message}".format(message=e)
            )
            exit_code = 1
        finally:
            if stdout_file:
                stdout_file.close()
            if stderr_file:
                stderr_file.close()
        return exit_code, time.time()

    return _exec_command


# Traceback (struct.error)
root@ip-172-31-37-52:/# horovodrun -np 2 -H localhost:1,172.31.35.37:1 -p 12345 --verbose ls
Filtering local host names.
Remote host found: 172.31.35.37
Checking ssh on all remote hosts.
SSH was successful into all the remote hosts.
Testing interfaces on all the hosts.
Launched horovod server.
Attempted to launch horovod task servers.
Waiting for the hosts to acknowledge.
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 37436)
Exception happened during processing of request from ('172.31.37.52', 52632)
----------------------------------------
Exception happened during processing of request from ('172.31.37.52', 52636)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
Traceback (most recent call last):
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('172.31.37.52', 55358)
----------------------------------------
Exception happened during processing of request from ('172.31.37.52', 52642)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
Exception happened during processing of request from ('127.0.0.1', 37442)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
struct.error: unpack requires a buffer of 4 bytes
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
----------------------------------------
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
Exception happened during processing of request from ('172.31.37.52', 55364)
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 37448)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
----------------------------------------
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('172.31.37.52', 55368)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('172.31.35.37', 39790)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
----------------------------------------
Exception happened during processing of request from ('172.31.35.37', 39796)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
----------------------------------------
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
Exception happened during processing of request from ('172.31.35.37', 39798)
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/socketserver.py", line 654, in process_request_thread
self.finish_request(request, client_address)
File "/opt/conda/lib/python3.6/socketserver.py", line 364, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/opt/conda/lib/python3.6/socketserver.py", line 724, in __init__
self.handle()
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 105, in handle
req = server._wire.read(self.rfile)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 79, in read
message_len = struct.unpack('i', rfile.read(4))[0]
struct.error: unpack requires a buffer of 4 bytes
----------------------------------------
Launching horovod task function was not successful:
Traceback (most recent call last):
File "/opt/conda/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/opt/conda/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/task_fn.py", line 67, in <module>
_task_fn(index, driver_addresses, settings)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/task_fn.py", line 27, in _task_fn
driver_addresses, settings.key, settings.verbose)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/driver/driver_service.py", line 44, in __init__
match_intf=match_intf)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/service/driver_service.py", line 159, in __init__
match_intf=match_intf)
File "/opt/conda/lib/python3.6/site-packages/horovod/run/common/util/network.py", line 172, in __init__
'Linux.'.format(service_name=service_name, addresses=addresses))
horovod.run.common.util.network.NoValidAddressesFound: Horovod was unable to connect to horovod driver service on any of the following addresses: {'lo': [('127.0.0.1', 4548)], 'ens3': [('172.31.37.52', 4548)], 'docker0': [('172.17.0.1', 4548)]}.

One possible cause of this problem is that horovod currently requires every host to have at least one routable network interface with the same name across all of the hosts. You can run "ifconfig -a" on every host and check for the common routable interface. To fix the problem, you can rename interfaces on Linux.

# Fixed code
def _exec_command_fn(settings):
    """
    executes the jobs defined by run command on hosts.
    :param hosts_alloc: list of dict indicating the allocating info.
    For example,
        [{'Hostname':'worker-0', 'Rank': 0, 'Local_rank': 0, 'Cross_rank':0,
            'Size':2, 'Local_size':1, 'Cross_size':2},
        {'Hostname':'worker-1', 'Rank': 1, 'Local_rank': 0, 'Cross_rank':1,
            'Size':2, 'Local_size':1, 'Cross_size':2}
        ]
    :type hosts_alloc: list(dict)
    :param remote_host_names: names that are resolved to one of the addresses
    of remote hosts interfaces.
    :type remote_host_names: set
    :param _run_command: command to execute
    :type _run_command: string
    :return:
    :rtype:
    """
    ssh_port_arg = (
        "-p {ssh_port}".format(ssh_port=settings.ssh_port) if settings.ssh_port else ""
    )

    def _exec_command(command, slot_info, events):
        index = slot_info.rank
        host_name = slot_info.hostname

        host_address = network.resolve_host_address(host_name)
        local_addresses = network.get_local_host_addresses()
        if host_address not in local_addresses:
            command = (
                "ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no "
                "{host} {ssh_port_arg} "
                "{local_command}".format(
                    host=host_name,
                    ssh_port_arg=ssh_port_arg,
                    local_command=quote(
                        "cd {pwd} > /dev/null 2>&1 ; {local_command}".format(
                            pwd=os.getcwd(), local_command=command
                        )
                    ),
                )
            )

        if settings.verbose:
            print(command)

        # Redirect output if requested
        stdout = stderr = None
        stdout_file = stderr_file = None
        if settings.output_filename:
            padded_rank = _pad_rank(index, settings.num_proc)
            output_dir_rank = os.path.join(
                settings.output_filename, "rank.{rank}".format(rank=padded_rank)
            )
            if not os.path.exists(output_dir_rank):
                os.mkdir(output_dir_rank)

            stdout_file = open(os.path.join(output_dir_rank, "stdout"), "w")
            stderr_file = open(os.path.join(output_dir_rank, "stderr"), "w")

            stdout = MultiFile([sys.stdout, stdout_file])
            stderr = MultiFile([sys.stderr, stderr_file])

        try:
            exit_code = safe_shell_exec.execute(
                command, index=index, stdout=stdout, stderr=stderr, events=events
            )
            if exit_code != 0:
                print(
                    "Process {idx} exit with status code {ec}.".format(
                        idx=index, ec=exit_code
                    )
                )
        except Exception as e:
            print(
                "Exception happened during safe_shell_exec, exception "
                "message: {message}".format(message=e)
            )
            exit_code = 1
        finally:
            if stdout_file:
                stdout_file.close()
            if stderr_file:
                stderr_file.close()
        return exit_code, time.time()

    return _exec_command