Example #1
0
def run_sp(func, *args, **kwargs):
    """
    Run a function in a subprocess and return its value.  This is for achieving subprocess
    isolation, not parallelism.  The subprocess is configured so things like logging work
    correctly, and is initialized with a derived random seed.
    """
    ctx = LKContext.INSTANCE
    rq = ctx.SimpleQueue()
    seed = derive_seed(none_on_old_numpy=True)
    worker_args = (log_queue(), seed, rq, func, args, kwargs)
    _log.debug('spawning subprocess to run %s', func)
    proc = ctx.Process(target=_sp_worker, args=worker_args)
    proc.start()
    _log.debug('waiting for process %s to return', proc)
    success, payload = rq.get()
    _log.debug('received success=%s', success)
    _log.debug('waiting for process %s to exit', proc)
    proc.join()
    if proc.exitcode:
        _log.error('subprocess failed with code %d', proc.exitcode)
        raise RuntimeError('subprocess failed with code ' + str(proc.exitcode))
    if success:
        return payload
    else:
        _log.error('subprocess raised exception: %s', payload)
        raise ChildProcessError('error in child process', payload)
Example #2
0
def _initialize_mp_worker(mkey, func, threads, log_queue, seed):
    seed = derive_seed(mp.current_process().name,
                       base=seed,
                       none_on_old_numpy=True)
    _initialize_worker(log_queue, seed)
    global __work_model, __work_func

    nnt_env = os.environ.get('NUMBA_NUM_THREADS', None)
    if nnt_env is None or int(nnt_env) > threads:
        _log.debug('configuring Numba thread count')
        import numba
        numba.config.NUMBA_NUM_THREADS = threads
    try:
        import mkl
        _log.debug('configuring MKL thread count')
        mkl.set_num_threads(threads)
    except ImportError:
        pass

    __work_model = mkey
    # deferred function unpickling to minimize imports before initialization
    __work_func = pickle.loads(func)

    _log.debug('worker %d ready (process %s)', os.getpid(),
               mp.current_process())
Example #3
0
def test_derive_seed_str():
    random.init_rng(42, propagate=False)
    s2 = random.derive_seed(b'wombat')
    assert s2.entropy == 42
    assert s2.spawn_key == (zlib.crc32(b'wombat'), )
Example #4
0
def test_derive_seed_intkey():
    random.init_rng(42, propagate=False)
    s2 = random.derive_seed(10, 7)
    assert s2.entropy == 42
    assert s2.spawn_key == (10, 7)
Example #5
0
def main(opts: STANOptions):
    stan.init()
    if opts.init_only:
        return  # we're done

    keys = ['stan', opts.model]

    if opts.joint:
        inf_dir = data_dir / 'joint-inference'
        mfile = mod_dir / f'joint-{opts.model}.stan'
    else:
        if opts.data:
            inf_dir = data_dir / opts.data / 'inference'
        mfile = mod_dir / f'{opts.model}.stan'
        keys.append(opts.data)

    model = stan.compile(mfile)
    if opts.compile_only:
        return  # we're done

    _log.info('sampling %s on %s (variant %s)', opts.model, opts.data,
              opts.variant)

    seed = derive_seed(*keys)
    sample_args = stan.sample_options(seed, opts)

    if opts.input:
        input = inf_dir / opts.input
    else:
        input = inf_dir / (opts.basename + '-inputs.json')
    output = inf_dir / opts.basename
    sum_file = inf_dir / (opts.basename + '-summary.csv')
    dia_file = inf_dir / (opts.basename + '-diag.txt')
    draw_file = output / 'samples.zarr'

    _log.info('running %d chains with %d warmup and %d sampling iterations',
              sample_args['chains'], sample_args['iter_warmup'],
              sample_args['iter_sampling'])
    output.mkdir(exist_ok=True)

    mcmc = model.sample(os.fspath(input),
                        output_dir=os.fspath(output),
                        **sample_args)

    _log.info('starting sample compression')
    comp = stan.start_compression(output)

    with ThreadPoolExecutor() as pool:
        _log.info('spawning summarization process')
        summary = pool.submit(lambda m: m.summary(), mcmc)
        _log.info('spawning diagnostic process')
        diag = pool.submit(lambda m: m.diagnose(), mcmc)

        _log.info('saving model samples')
        stan.save_samples(draw_file, mcmc)

        _log.info('waiting for summary results')
        summary = summary.result()
        _log.info('saving model summary')
        summary.to_csv(sum_file, index=True)

        _log.info('waiting for diagnostic results')
        diag = diag.result()
        _log.info('saving diagnostics')
        dia_file.write_text(diag)

    _log.info('finalizing sample compression')
    stan.finish_compression(output, comp)
def stan_seed(*keys):
    seed = derive_seed(*keys)
    stan_seed = seed.generate_state(1)[0] & 0x80000000  # put in range of int
    _log.info('using random seed %s (from %s)', stan_seed, seed)
Example #7
0
def test_derive_seed_str():
    random.init_rng(42, propagate=False)
    s2 = random.derive_seed(b'wombat')
    assert s2.entropy == 42