def add_state(self, state, info=None, host=socket.gethostname(), login=get_login()): 'Устанавливает статус расчета, НЕ вызывает commit()' if not state in ('waited', 'activated', 'started', 'finished', 'stopped', 'suspended'): raise Exception( 'unknown status "%s" for "%s"' % (state, self.path if hasattr(self, 'path') else '???')) if info == None and state == 'started': info = os.getpid() if info == None and state == 'stopped': info = '' #.join(mixt.except_report(None)) if not hasattr(self, 'statelist'): self.statelist = [] if self.statelist: self.__dict__['runtime'] = chrono.Date() - self.statelist[-1][3] if state == 'finished': self.__dict__['progress'] = 1. self.statelist.append((state, login, host, chrono.Date()) + ((info, ) if info != None else ()))
def set_progress(self, progress, prompt='', runtime=-1): '''Устанавливает progress и runtime, выводит при необходимости mixt.ProgressBar. prompt=@clean очищает ProgressBar, @close prompt result закрывает ProgressBar''' if not hasattr(self, 'statelist'): self.statelist = [] runtime = (chrono.Date() - self.statelist[-1][3] if self.statelist else 0.) if runtime < 0 else chrono.Time(runtime) self.__dict__['progress'], self.__dict__['runtime'] = progress, runtime if os.path.exists(self.path + '.RACS'): self.commit() #self.md5sources = self.commit() ??? if prompt: if not '_progressbar' in self.__dict__: self.__dict__['_progressbar'] = mixt.ProgressBar() if prompt == '@clean': self._progressbar.clean() elif prompt.startswith('@close '): self._progressbar.close(*prompt[7:].rsplit(' ', 1)) else: self._progressbar.out(progress, prompt)
def set_progress(self, progress): #, prompt='', runtime=-1): #runtime = (chrono.Date()-self.statelist[-1][3] if self.statelist else 0.) if runtime<0 else chrono.Time(runtime) self.__dict__['progress'], self.__dict__[ 'runtime'] = progress, chrono.Date() - self.statelist[-1][3] self.commit()
def __init__(self, **D): #self.runtime, self.progress, self.statelist, self.args, self._wraps = chrono.Time(0.), 0., [], list(_cl_args), [] self.runtime, self.progress, self.statelist, self.args, self._wraps, self.tags = chrono.Time( 0.), 0., [], list(sys.argv), [], set(_cl_tags) for k, v in D.items(): # обработка аргументов конструктора if k in _racs_params and not k in _racs_cl_params: _racs_params[k] = v elif not k in _racs_params: self.__dict__[k] = v #----------------------------------------------------------------------- # серийный запуск и демонизация расчета #----------------------------------------------------------------------- global _args_from_racs if _racs_params.get('_mpi', 0) == 3: if mpi_proc_number() == 0: # головной процесс for q in reduce( lambda L, a: [l + [(a, x)] for x in _arg_seqs[a] for l in L], _arg_order, [[]]): data, proc = mpi_recv(-1) # получаем запрос на задание path = mixt.make_path(_racs_params['_repo'] % self, _racs_params['_calc_num']) mpi_send(_args_from_racs + q + [('path', path)], proc) else: for p in range(1, mpi_proc_count()): mpi_send(None, p) mpi_finalize() sys.exit() else: while 1: mpi_send( (socket.gethostname(), mixt.get_login(), os.getpid()), 0) _args_from_racs = mpi_recv(0)[0] if not _args_from_racs: mpi_finalize() sys.exit() pid = os.fork() if not pid: break os.waitpid(-1, 0) elif _arg_seqs: _base_args_from_racs, t_start, n_start, n_finish = list( _args_from_racs), time.time(), 0, 0 queue = reduce( lambda L, a: [l + [(a, x)] for x in _arg_seqs[a] for l in L], _arg_order, [[('racs_master', os.getpid())]]) if _racs_params['_daemonize']: mixt.mk_daemon() if not os.path.exists('.racs'): os.mkdir('.racs') if not os.path.exists('/tmp/racs'): os.system('mkdir /tmp/racs; chmod a+rwx /tmp/racs') stitle = _racs_params['_title'] if _racs_params.get( '_title') else str(os.getpid()) copies, pids, logfile, smode, lenQ = _racs_params[ '_copies'], [], '.racs/started-%s' % stitle, 'Running the queue', len( queue) if '_continue' in _racs_params: old_log, runs, irun, finishes = _racs_params[ '_continue'], {}, 0, [] old_tasks = [ l[:-1] for l in open(old_log) if not l.startswith('# ') ] for i, p in [(j, l.split()[1]) for j, l in enumerate(old_tasks) if l[0] != '#']: if p[0] == '+': runs[int(p[1:])] = (irun, i) irun += 1 # номер открытой задачи отвечает номеру задачи в очереди else: finishes.append( runs.pop(int(p[1:]))[0] ) # добавляем этот номер в список закрытых задач n_start = n_finish = len(finishes) for p in reversed(sorted(finishes)): del queue[p] #print finishes, runs, queue for p in runs.values(): old_tasks[p[1]] = '#>>>' + old_tasks[p[1]] old_tasks += [ '#>>>%s -%s сlosed on continuation of the queue %r' % (chrono.Date(), p, stitle) for p in runs.keys() ] if old_log.startswith('.racs/started-'): os.rename(old_log, '.racs/stopped-' + old_log.split('-', 1)[1]) if os.path.exists(old_log + '.log'): os.rename( old_log + '.log', '.racs/stopped-' + old_log.split('-', 1)[1] + '.log') for l in os.listdir('/tmp/racs/'): if not os.path.exists('/tmp/racs/' + l): os.remove('/tmp/racs/' + l) smode = 'Continued the queue (original %i tasks)' % lenQ #del p, old_log, runs, irun, finishes print smode, 'of %i tasks in %i threads, master PID=%i, logfile="%s"' % ( len(queue), copies, os.getpid(), logfile) streams, OUT = [sys.stdout, open(logfile, 'w') ], lambda msg: [(s.write(msg + '\n'), s.flush()) for s in streams] symlink = '/tmp/racs/started-%s.%i' % ( stitle, int(([0] + [ s.rsplit('.', 1)[1] for s in os.listdir('/tmp/racs/') if s.startswith('started-%s.' % stitle) and s[len('started-%s.' % stitle):].isdigit() ])[-1]) + 1) os.symlink(os.path.abspath(logfile), symlink) if _racs_params['_daemonize']: mixt.set_output(logfile + '.log') OUT('# %s@%s:%s repo=%r tasks=%i threads=%i PID=%i\n# ' % (mixt.get_login(), socket.gethostname(), os.getcwd(), _racs_params['_repo'], lenQ, copies, os.getpid()) + ' '.join(sys.argv)) for a in _arg_order: OUT('# %s: %s' % (a, _arg_seqs[a])) finish_msg = lambda: OUT('%s -%i %g%% %s %s' % ( chrono.Date(), p, 100. * n_finish / lenQ, mixt.time2string(time.time() - t_start), mixt.time2string((time.time() - t_start) * lenQ / n_finish))) if '_continue' in _racs_params: map(OUT, old_tasks) for q in queue: if len(pids) == copies: p = os.waitpid(-1, 0)[0] pids.remove(p) n_finish += 1 time.sleep(1) finish_msg() #<<< for lock append finish_msg on clusters? _args_from_racs = _base_args_from_racs + q #+[('master', os.getpid())] pid = os.fork() if not pid: break pids.append(pid) n_start += 1 OUT('%s +%i %g%% %s' % (chrono.Date(), pid, 100. * n_start / lenQ, ' '.join( '%s=%r' % i for i in q[1:]))) else: while (pids): p = os.waitpid(-1, 0)[0] pids.remove(p) n_finish += 1 time.sleep(1) finish_msg() #<<< for lock append finish_msg on clusters? if _racs_params['_daemonize']: streams[0].close() os.rename(logfile + '.log', '.racs/finished-%s.log' % stitle) streams[1].close() os.rename(logfile, '.racs/finished-%s' % stitle) os.system('rm -f ' + symlink) sys.exit() elif _racs_params.get('_daemonize', False): mixt.mk_daemon() #----------------------------------------------------------------------- if 'path' in dict(_args_from_racs): self.__dict__['path'] = dict(_args_from_racs)['path'] if 'path' in self.__dict__: # подготовка пути self.path = mixt.normpath(self.path) if self.path[-1] != '/': self.path += '/' if os.path.exists(self.path + '.RACS'): self.__dict__.update(cPickle.load(open(self.path + '.RACS'))) for k, v in _args_from_racs: # накат сторонних параметров if k in self.__dict__: v = mixt.string2bool(v) if type( self.__dict__[k]) is bool else self.__dict__[k].__class__( v) self.__dict__[k] = v _init_hook(self)