コード例 #1
0
ファイル: test_trace.py プロジェクト: tfeng90/quiesce
async def test_sparse_trace():
    """Test that tracing sparsely samples profiles"""
    base = rsgame.empty(4, 3)
    game1 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [1, 0, 0])
    game2 = paygame.game_replace(base, base.all_profiles(),
                                 (base.all_profiles() > 0) * [-0.5, 1.5, 0])
    save1 = savesched.savesched(gamesched.gamesched(game1))
    save2 = savesched.savesched(gamesched.gamesched(game2))

    sgame1 = schedgame.schedgame(save1)
    sgame2 = schedgame.schedgame(save2)

    await asyncio.gather(innerloop.inner_loop(sgame1),
                         innerloop.inner_loop(sgame2))

    # Assert that innerloop doesn't scheduler all profiles
    assert save1.get_game().num_profiles == 11
    assert save2.get_game().num_profiles == 11

    ((st1, *_, en1), _), ((st2, *_, en2), _) = (  # pylint: disable=too-many-star-expressions
        await trace.trace_all_equilibria(sgame1, sgame2))

    # Assert that trace found the expected equilibria
    assert np.isclose(st1, 0)
    assert np.isclose(en1, 1 / 3, atol=1e-3)
    assert np.isclose(st2, 1 / 3, atol=1e-3)
    assert np.isclose(en2, 1)

    # Assert that trace didn't need many extra profiles
    assert save1.get_game().num_profiles == 12
    assert save2.get_game().num_profiles == 12
コード例 #2
0
ファイル: test_trace.py プロジェクト: qiji00626/quiesce
async def test_random_trace_sched(base):
    """Test tracing for random schedulers"""
    sched1 = gamesched.gamesched(gamegen.game_replace(base))
    sched2 = gamesched.gamesched(gamegen.game_replace(base))
    traces = await trace.trace_all_equilibria(
        schedgame.schedgame(sched1), schedgame.schedgame(sched2), style="one"
    )
    verify_complete_traces(traces)
コード例 #3
0
async def run(args): # pylint: disable=too-many-locals
    """Command line entry point for tracing"""
    sched0 = CanonWrapper(await schedspec.parse_scheduler(args.sched0))
    sched1 = CanonWrapper(await schedspec.parse_scheduler(args.sched1))
    red, red_players = utils.parse_reduction(sched0, args)
    agame0 = schedgame.schedgame(sched0, red, red_players)
    agame1 = schedgame.schedgame(sched1, red, red_players)

    async def get_point(prob, eqm):
        """Get the point in a trace for an equilibrium"""
        supp = eqm > 0
        game0 = await agame0.get_deviation_game(supp)
        game1 = await agame1.get_deviation_game(supp)
        reg = regret.mixture_regret(
            rsgame.mix(game0, game1, prob), eqm)
        return {
            't': float(prob),
            'equilibrium': sched0.mixture_to_json(eqm),
            'regret': float(reg)}

    async def get_trace(probs, peqa):
        """Get the trace for probabilities and equilibria"""
        return await asyncio.gather(*[
            get_point(p, eqm) for p, eqm in zip(probs, peqa)])

    async with sched0, sched1:
        with futures.ProcessPoolExecutor(args.procs) as executor:
            traces = await trace.trace_all_equilibria(
                agame0, agame1, regret_thresh=args.regret_thresh,
                dist_thresh=args.dist_thresh,
                restricted_game_size=args.max_restrict_size,
                num_equilibria=args.num_equilibria,
                num_backups=args.num_backups, devs_by_role=args.dev_by_role,
                style=args.style, executor=executor)
        jtraces = await asyncio.gather(*[
            get_trace(ts, teqa) for ts, teqa in traces])

    max_reg = 0.0
    spans = [[-1, -1]]
    for jtrace in jtraces:
        max_reg = max(max_reg, max(p['regret'] for p in jtrace))
        span = spans[-1]
        start, *_, end = jtrace
        if start['t'] <= span[1]:
            span[1] = max(span[1], end['t'])
        else:
            spans.append([start['t'], end['t']])

    logging.error(
        'tracing finished finding %d traces covering %s, with maximum regret '
        '%g', len(jtraces),
        ' U '.join('[{:g}, {:g}]'.format(s, e) for s, e in spans[1:]), max_reg)

    json.dump(jtraces, args.output)
    args.output.write('\n')
コード例 #4
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_nash_failure():
    """With regret thresh of zero, nash will fail"""
    game = gamegen.sym_2p2s_known_eq(1 / 3)
    sched = gamesched.gamesched(game)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     regret_thresh=0)
    assert not eqa.size
コード例 #5
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_by_role_simple(base):
    """Test that inner loop works by role"""
    sgame = gamegen.samplegame_replace(base)
    sched = gamesched.samplegamesched(sgame)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     devs_by_role=True)
    verify_dist_thresh(eqa)
コード例 #6
0
ファイル: test_schedgame.py プロジェクト: qiji00626/quiesce
async def test_random_redgame(players, strats, _):
    """Test properties of games returned from scheduler"""
    game = gamegen.samplegame(players, strats)
    rest = game.random_restriction()
    sched = gamesched.samplegamesched(game)
    sgame = schedgame.schedgame(sched)

    devgame1 = await sgame.get_deviation_game(rest)
    prof = devgame1.profiles()[
        np.all((devgame1.profiles() == 0) | ~np.isnan(devgame1.payoffs()), 1).nonzero()[
            0
        ][0]
    ]
    assert prof in devgame1
    assert (
        devgame1.num_complete_profiles
        <= devgame1.num_profiles
        <= devgame1.num_all_profiles
    )

    devgame2 = await sgame.get_deviation_game(rest)
    assert hash(devgame1) == hash(devgame2)
    assert devgame1 == devgame2
    assert devgame1 + devgame2 == devgame2 + devgame1
    assert np.allclose(devgame1.get_payoffs(prof), devgame2.get_payoffs(prof))

    rrest = devgame1.random_restriction()
    assert devgame1.restrict(rrest) == devgame2.restrict(rrest)
コード例 #7
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_num_eqa(base, num):
    """Test that inner loop returns alternate number of equilibria"""
    sgame = gamegen.samplegame_replace(base)
    sched = gamesched.samplegamesched(sgame)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     num_equilibria=num,
                                     devs_by_role=True)
    verify_dist_thresh(eqa)
コード例 #8
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_failures(players, strats, count, when):
    """Test that inner loop handles exceptions during scheduling"""
    game = gamegen.game(players, strats)
    sched = gamesched.gamesched(game)
    esched = tu.ExceptionScheduler(sched, count, when)
    sgame = schedgame.schedgame(esched)
    with pytest.raises(tu.SchedulerException):
        await innerloop.inner_loop(sgame, restricted_game_size=5)
コード例 #9
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_game(base):
    """Test that inner loop works for a game"""
    game = gamegen.samplegame_replace(base)
    sched = gamesched.gamesched(game)
    eqas = await innerloop.inner_loop(schedgame.schedgame(sched))
    verify_dist_thresh(eqas)
    eqag = await innerloop.inner_loop(asyncgame.wrap(game))
    assert utils.allclose_perm(eqas, eqag, atol=1e-3, rtol=1e3)
コード例 #10
0
ファイル: test_schedgame.py プロジェクト: tfeng90/quiesce
async def test_random_normalize(players, strats, _):
    """Test normalizing random games"""
    game = gamegen.samplegame(players, strats)
    sched = gamesched.samplegamesched(game)
    sgame = schedgame.schedgame(sched)
    rgame = await sgame.get_restricted_game(np.ones(game.num_strats, bool))
    ngame = rgame.normalize()
    assert np.all(ngame.payoffs() >= -1e-7)
    assert np.all(ngame.payoffs() <= 1 + 1e-7)
コード例 #11
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_known_eq(eq_prob):
    """Test that inner loop finds known equilibria"""
    game = gamegen.sym_2p2s_known_eq(eq_prob)
    sched = gamesched.gamesched(game)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     devs_by_role=True)
    assert eqa.size, "didn't find equilibrium"
    expected = [eq_prob, 1 - eq_prob]
    assert np.isclose(eqa, expected, atol=1e-3, rtol=1e-3).all(-1).any()
    verify_dist_thresh(eqa)
コード例 #12
0
ファイル: test_schedgame.py プロジェクト: qiji00626/quiesce
async def test_exception(players, strats, when, _):
    """Test that exceptions are raised appropriately"""
    game = gamegen.samplegame(players, strats)
    sched = gamesched.samplegamesched(game)
    esched = utils.ExceptionScheduler(sched, 10, when)
    sgame = schedgame.schedgame(esched)
    rests = np.concatenate(
        [game.random_restrictions(3), np.ones((1, game.num_strats), bool)]
    )
    with pytest.raises(utils.SchedulerException):
        await asyncio.gather(*[sgame.get_restricted_game(rest) for rest in rests])
コード例 #13
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_dpr(redgame):
    """Test that inner loop handles dpr"""
    fullgame = rsgame.empty(redgame.num_role_players**2,
                            redgame.num_role_strats)
    profs = dpr.expand_profiles(fullgame, redgame.all_profiles())
    pays = np.random.random(profs.shape)
    pays[profs == 0] = 0
    sgame = paygame.samplegame_replace(fullgame, profs, [pays[:, None]])
    sched = gamesched.samplegamesched(sgame)
    game = schedgame.schedgame(sched, dpr, redgame.num_role_players)
    eqa = await innerloop.inner_loop(game)
    verify_dist_thresh(eqa)
コード例 #14
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_backups_used():
    """Test that outerloop uses backups

    Since restricted game size is 1, but the only equilibria has support two,
    this must use backups to find an equilibrium."""
    sgame = gamegen.sym_2p2s_known_eq(0.5)
    sched = gamesched.gamesched(sgame)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched),
                                     restricted_game_size=1)
    assert eqa.size, "didn't find equilibrium"
    expected = [0.5, 0.5]
    assert np.isclose(eqa, expected, atol=1e-3, rtol=1e-3).all(-1).any()
    verify_dist_thresh(eqa)
コード例 #15
0
ファイル: test_schedgame.py プロジェクト: tfeng90/quiesce
async def test_random_complete_dev(players, strats, _):
    """Test the deviations are complete in random games"""
    game = gamegen.samplegame(players, strats)
    sched = gamesched.samplegamesched(game)
    sgame = schedgame.schedgame(sched)
    mix = sgame.random_sparse_mixture()
    supp = mix > 0
    dev_game = await sgame.get_deviation_game(supp)
    devs, jac = dev_game.deviation_payoffs(mix, jacobian=True)
    assert not np.isnan(devs).any()
    assert not np.isnan(jac[supp]).any()
    assert np.isnan(jac[~supp]).all()
    for role in range(sgame.num_roles):
        mask = (role == sgame.role_indices)
        dev_game = await sgame.get_deviation_game(supp, role_index=role)
        rdevs = dev_game.deviation_payoffs(mix)
        assert np.allclose(rdevs[supp], devs[supp])
        assert np.allclose(rdevs[mask], devs[mask])
        assert supp[~mask].all() or np.isnan(rdevs[~mask]).any()
コード例 #16
0
async def run(args):
    """Entry point for cli"""
    sched = await schedspec.parse_scheduler(args.scheduler)
    red, red_players = utils.parse_reduction(sched, args)
    agame = schedgame.schedgame(sched, red, red_players)

    async def get_regret(eqm):
        """Gets the regret of an equilibrium"""
        game = await agame.get_deviation_game(eqm > 0)
        return float(regret.mixture_regret(game, eqm))

    async with sched:
        with futures.ProcessPoolExecutor(args.procs) as executor:
            eqa = await innerloop.inner_loop(
                agame,
                regret_thresh=args.regret_thresh,
                dist_thresh=args.dist_thresh,
                restricted_game_size=args.max_restrict_size,
                num_equilibria=args.num_equilibria,
                num_backups=args.num_backups,
                devs_by_role=args.dev_by_role,
                style=args.style,
                executor=executor,
            )
        regrets = await asyncio.gather(*[get_regret(eqm) for eqm in eqa])

    logging.error(
        "quiesce finished finding %d equilibria:\n%s",
        eqa.shape[0],
        "\n".join("{:d}) {} with regret {:g}".format(
            i, sched.mixture_to_repr(eqm), reg)
                  for i, (eqm, reg) in enumerate(zip(eqa, regrets), 1)),
    )

    json.dump(
        [{
            "equilibrium": sched.mixture_to_json(eqm),
            "regret": reg
        } for eqm, reg in zip(eqa, regrets)],
        args.output,
    )
    args.output.write("\n")
コード例 #17
0
ファイル: test_schedgame.py プロジェクト: tfeng90/quiesce
async def test_random_caching(players, strats, _):
    """Test that profiles are cached (identical)"""
    game = gamegen.samplegame(players, strats)
    rest1, rest2 = game.random_restrictions(2)
    sched = gamesched.samplegamesched(game)
    sgame = schedgame.schedgame(sched)
    assert str(sgame) == str(sched)

    rgame11 = await sgame.get_restricted_game(rest1)
    rgame21 = await sgame.get_restricted_game(rest2)
    devs11 = await sgame.get_deviation_game(rest1)
    devs21 = await sgame.get_deviation_game(rest2)

    rgame12 = await sgame.get_restricted_game(rest1)
    rgame22 = await sgame.get_restricted_game(rest2)
    assert rgame11 == rgame12
    assert rgame21 == rgame22

    devs12 = await sgame.get_deviation_game(rest1)
    devs22 = await sgame.get_deviation_game(rest2)
    assert devs11 == devs12
    assert devs21 == devs22
コード例 #18
0
ファイル: test_innerloop.py プロジェクト: tfeng90/quiesce
async def test_innerloop_simple(base):
    """Test that inner loop works for a simple setup"""
    sgame = gamegen.samplegame_replace(base)
    sched = gamesched.samplegamesched(sgame)
    eqa = await innerloop.inner_loop(schedgame.schedgame(sched))
    verify_dist_thresh(eqa)