<s> """<STR_LIT>""" <EOL> import os . path <EOL> import uuid <EOL> import time <EOL> import shutil <EOL> import signal <EOL> import select <EOL> import random <EOL> import tempfile <EOL> import datetime <EOL> import multiprocessing <EOL> import numpy <EOL> import borg <EOL> logger = borg . get_logger ( __name__ , default_level = "<STR_LIT>" ) <EOL> def random_seed ( ) : <EOL> """<STR_LIT>""" <EOL> return numpy . random . randint ( <NUM_LIT:0> , <NUM_LIT:2> ** <NUM_LIT> ) <EOL> def timed_read ( fds , timeout = - <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> polling = select . poll ( ) <EOL> for fd in fds : <EOL> polling . register ( fd , select . POLLIN ) <EOL> changed = dict ( polling . poll ( timeout * <NUM_LIT:1000> ) ) <EOL> def make_read ( fd ) : <EOL> revents = changed . get ( fd , <NUM_LIT:0> ) <EOL> if revents & select . POLLIN : <EOL> return os . read ( fd , <NUM_LIT> ) <EOL> elif revents & select . POLLHUP : <EOL> return "<STR_LIT>" <EOL> else : <EOL> return None <EOL> return map ( make_read , fds ) <EOL> class SolverProcess ( multiprocessing . Process ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , parse_output , arguments , stm_queue , mts_queue , solver_id , tmpdir , cwd ) : <EOL> self . _parse_output = parse_output <EOL> self . _arguments = arguments <EOL> self . _stm_queue = stm_queue <EOL> self . _mts_queue = mts_queue <EOL> self . _solver_id = solver_id <EOL> self . _tmpdir = tmpdir <EOL> self . _seed = random_seed ( ) <EOL> self . _popened = None <EOL> self . _cwd = cwd <EOL> if self . _cwd is None : <EOL> logger . info ( "<STR_LIT>" , arguments ) <EOL> else : <EOL> logger . info ( "<STR_LIT>" , arguments , cwd ) <EOL> multiprocessing . Process . __init__ ( self ) <EOL> def run ( self ) : <EOL> numpy . random . seed ( self . _seed ) <EOL> random . seed ( numpy . random . randint ( <NUM_LIT:2> ** <NUM_LIT> ) ) <EOL> try : <EOL> class DeathRequestedError ( Exception ) : <EOL> pass <EOL> try : <EOL> def handle_sigusr1 ( number , frame ) : <EOL> raise DeathRequestedError ( ) <EOL> try : <EOL> signal . signal ( signal . SIGUSR1 , handle_sigusr1 ) <EOL> self . handle_subsolver ( ) <EOL> finally : <EOL> signal . signal ( signal . SIGUSR1 , signal . SIG_IGN ) <EOL> except DeathRequestedError : <EOL> pass <EOL> except Exception , error : <EOL> self . _stm_queue . put ( error ) <EOL> except KeyboardInterrupt : <EOL> pass <EOL> finally : <EOL> if self . _popened is not None : <EOL> self . _popened . kill ( ) <EOL> os . kill ( self . _popened . pid , signal . SIGCONT ) <EOL> self . _popened . wait ( ) <EOL> shutil . rmtree ( self . _tmpdir , ignore_errors = True ) <EOL> def handle_subsolver ( self ) : <EOL> limit = <NUM_LIT:0.0> <EOL> stdout = "<STR_LIT>" <EOL> expenditure = datetime . timedelta ( seconds = limit ) <EOL> last_expenditure = expenditure <EOL> last_audit = time . time ( ) - <NUM_LIT:1.0> <EOL> while limit == <NUM_LIT:0.0> or self . _popened is not None : <EOL> if expenditure >= datetime . timedelta ( seconds = limit ) : <EOL> if self . _popened is not None : <EOL> os . kill ( popened . pid , signal . SIGSTOP ) <EOL> run_cost = borg . util . seconds ( expenditure - last_expenditure ) <EOL> self . _stm_queue . put ( ( self . _solver_id , run_cost , None , False ) ) <EOL> additional = self . _mts_queue . get ( ) <EOL> limit += additional <EOL> last_expenditure = expenditure <EOL> if self . _popened is None : <EOL> popened = borg . unix . sessions . spawn_pipe_session ( self . _arguments , cwd = self . _cwd ) <EOL> self . _popened = popened <EOL> descriptors = [ popened . stdout . fileno ( ) , popened . stderr . fileno ( ) ] <EOL> accountant = borg . unix . accounting . SessionTimeAccountant ( popened . pid ) <EOL> else : <EOL> os . kill ( popened . pid , signal . SIGCONT ) <EOL> ( chunk , _ ) = timed_read ( descriptors , <NUM_LIT:1.0> ) <EOL> if time . time ( ) - last_audit > borg . defaults . proc_poll_period : <EOL> accountant . audit ( ) <EOL> expenditure = accountant . total <EOL> last_audit = time . time ( ) <EOL> if chunk == "<STR_LIT>" : <EOL> self . _popened = None <EOL> elif chunk is not None : <EOL> stdout += chunk <EOL> answer = self . _parse_output ( stdout ) <EOL> run_cost = borg . util . seconds ( expenditure - last_expenditure ) <EOL> self . _stm_queue . put ( ( self . _solver_id , run_cost , answer , True ) ) <EOL> def prepare ( command , root , cnf_path , tmpdir ) : <EOL> """<STR_LIT>""" <EOL> keywords = { <EOL> "<STR_LIT:root>" : root , <EOL> "<STR_LIT>" : cnf_path , <EOL> "<STR_LIT>" : random_seed ( ) , <EOL> "<STR_LIT>" : tmpdir , <EOL> } <EOL> return [ s . format ( ** keywords ) for s in command ] <EOL> class RunningSolver ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( <EOL> self , <EOL> parse , <EOL> command , <EOL> root , <EOL> task_path , <EOL> stm_queue = None , <EOL> solver_id = None , <EOL> cwd = None , <EOL> ) : <EOL> """<STR_LIT>""" <EOL> if stm_queue is None : <EOL> self . _stm_queue = multiprocessing . Queue ( ) <EOL> else : <EOL> self . _stm_queue = stm_queue <EOL> if solver_id is None : <EOL> self . _solver_id = uuid . uuid4 ( ) <EOL> else : <EOL> self . _solver_id = solver_id <EOL> self . _mts_queue = multiprocessing . Queue ( ) <EOL> self . _tmpdir = tempfile . mkdtemp ( prefix = "<STR_LIT>" ) <EOL> self . _process = SolverProcess ( <EOL> parse , <EOL> prepare ( command , root , task_path , self . _tmpdir ) , <EOL> self . _stm_queue , <EOL> self . _mts_queue , <EOL> self . _solver_id , <EOL> self . _tmpdir , <EOL> cwd , <EOL> ) <EOL> def __call__ ( self , budget ) : <EOL> """<STR_LIT>""" <EOL> self . unpause_for ( budget ) <EOL> response = self . _stm_queue . get ( ) <EOL> if isinstance ( response , Exception ) : <EOL> raise response <EOL> else : <EOL> ( solver_id , run_cpu_cost , answer , terminated ) = response <EOL> assert solver_id == self . _solver_id <EOL> self . stop ( ) <EOL> borg . get_accountant ( ) . charge_cpu ( run_cpu_cost ) <EOL> return answer <EOL> def unpause_for ( self , budget ) : <EOL> """<STR_LIT>""" <EOL> if not self . _process . is_alive ( ) : <EOL> self . _process . start ( ) <EOL> self . _mts_queue . put ( budget ) <EOL> def stop ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _process . is_alive ( ) : <EOL> os . kill ( self . _process . pid , signal . SIGUSR1 ) <EOL> self . _process . join ( ) <EOL> shutil . rmtree ( self . _tmpdir , ignore_errors = True ) <EOL> class RunningPortfolio ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , portfolio , suite , task ) : <EOL> """<STR_LIT>""" <EOL> self . portfolio = portfolio <EOL> self . suite = suite <EOL> self . task = task <EOL> def run_then_stop ( self , budget ) : <EOL> """<STR_LIT>""" <EOL> return self . portfolio ( self . task , self . suite , borg . Cost ( cpu_seconds = budget ) ) <EOL> class RunningPortfolioFactory ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , portfolio , suite ) : <EOL> """<STR_LIT>""" <EOL> self . portfolio = portfolio <EOL> self . suite = suite <EOL> def start ( self , task ) : <EOL> """<STR_LIT>""" <EOL> return RunningPortfolio ( self . portfolio , self . suite , task ) <EOL> class EmptySolver ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , answer ) : <EOL> self . _answer = answer <EOL> def __call__ ( self , budget ) : <EOL> return self . _answer <EOL> def unpause_for ( self , budget ) : <EOL> pass <EOL> def stop ( self ) : <EOL> pass </s>
