#!/usr/bin/env python3 """ DMLC submission script by mesos One need to make sure all slaves machines are ssh-able. """ from __future__ import absolute_import import os import sys import json import uuid import logging from threading import Thread from . import tracker try: import pymesos.subprocess logging.getLogger('pymesos').setLevel(logging.WARNING) def _run(prog, env, resources): cwd = os.getcwd() pymesos.subprocess.check_call( prog, shell=True, env=env, cwd=cwd, cpus=resources['cpus'], mem=resources['mem'] ) _USE_PYMESOS = True except ImportError: import subprocess DEVNULL = open(os.devnull, 'w') def _run(prog, env, resources): master = os.environ['MESOS_MASTER'] if ':' not in master: master += ':5050' name = str(uuid.uuid4()) cwd = os.getcwd() prog = "cd %s && %s" % (cwd, prog) resources = ';'.join('%s:%s' % (k, v) for k, v in resources.items()) prog = prog.replace('\'', '\\\'') env = json.dumps(env).replace('\'', '\\\'') resources = resources.replace('\'', '\\\'') cmd = ( 'mesos-execute --master=%s --name=\'%s\'' ' --command=\'%s\' --env=\'%s\' --resources=\'%s\'' % (master, name, prog, env, resources) ) subprocess.check_call( cmd, shell=True, stdout=DEVNULL, stderr=subprocess.STDOUT) _USE_PYMESOS = False def get_env(): # get system envs keys = set(['OMP_NUM_THREADS', 'KMP_AFFINITY', 'LD_LIBRARY_PATH']) return {k: v for k, v in os.environ.items() if k in keys} def submit(args): def mesos_submit(nworker, nserver, pass_envs): """ customized submit script """ # launch jobs for i in range(nworker + nserver): resources = {} pass_envs['DMLC_ROLE'] = 'server' if i < nserver else 'worker' if i < nserver: pass_envs['DMLC_SERVER_ID'] = i resources['cpus'] = args.server_cores resources['mem'] = args.server_memory_mb else: pass_envs['DMLC_WORKER_ID'] = i - nserver resources['cpus'] = args.worker_cores resources['mem'] = args.worker_memory_mb env = {str(k): str(v) for k, v in pass_envs.items()} env.update(get_env()) prog = ' '.join(args.command) thread = Thread(target=_run, args=(prog, env, resources)) thread.setDaemon(True) thread.start() return mesos_submit if not _USE_PYMESOS: logging.warning('No PyMesos found, use mesos-execute instead,' ' no task output available') if args.mesos_master: os.environ['MESOS_MASTER'] = args.mesos_master assert 'MESOS_MASTER' in os.environ, 'No mesos master configured!' tracker.submit(args.num_workers, args.num_servers, fun_submit=mesos_submit, pscmd=(' '.join(args.command)))