From 4b5feacdb11fad0056cdc6080aa1464831167b7e Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Tue, 10 May 2016 20:35:43 -0700 Subject: [PATCH 1/3] Move processes argument from Tournament.__init__ to tournament.play --- axelrod/tests/integration/test_tournament.py | 5 +-- axelrod/tests/unit/test_tournament.py | 40 ++++++++------------ axelrod/tournament.py | 23 +++++------ 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/axelrod/tests/integration/test_tournament.py b/axelrod/tests/integration/test_tournament.py index 7e1305eac..1580de852 100644 --- a/axelrod/tests/integration/test_tournament.py +++ b/axelrod/tests/integration/test_tournament.py @@ -50,8 +50,7 @@ def test_parallel_play(self): players=self.players, game=self.game, turns=20, - repetitions=self.test_repetitions, - processes=2) - scores = tournament.play(progress_bar=False).scores + repetitions=self.test_repetitions) + scores = tournament.play(processes=2, progress_bar=False).scores actual_outcome = sorted(zip(self.player_names, scores)) self.assertEqual(actual_outcome, self.expected_outcome) diff --git a/axelrod/tests/unit/test_tournament.py b/axelrod/tests/unit/test_tournament.py index 79c962f58..b1fa4bc4a 100644 --- a/axelrod/tests/unit/test_tournament.py +++ b/axelrod/tests/unit/test_tournament.py @@ -62,7 +62,6 @@ def test_init(self): players=self.players, game=self.game, turns=self.test_turns, - processes=4, noise=0.2) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertIsInstance( @@ -72,7 +71,6 @@ def test_init(self): self.assertEqual(tournament.turns, self.test_turns) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') - self.assertEqual(tournament._processes, 4) self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) @@ -182,10 +180,9 @@ def test_progress_bar_play_parallel(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) - results = tournament.play() + results = tournament.play(processes=2) self.assertIsInstance(results, axelrod.ResultSet) results = tournament.play(progress_bar=True) @@ -231,9 +228,8 @@ def test_parallel_play(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) - results = tournament.play(progress_bar=False) + repetitions=self.test_repetitions) + results = tournament.play(processes=2, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # The following relates to #516 @@ -245,9 +241,8 @@ def test_parallel_play(self): players=players, game=self.game, turns=20, - repetitions=self.test_repetitions, - processes=2) - scores = tournament.play(progress_bar=False).scores + repetitions=self.test_repetitions) + scores = tournament.play(processes=2, progress_bar=False).scores self.assertEqual(len(scores), len(players)) def test_run_serial(self): @@ -256,8 +251,7 @@ def test_run_serial(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) tournament._write_interactions = MagicMock( name='_write_interactions') self.assertTrue(tournament._run_serial()) @@ -272,8 +266,7 @@ def test_run_parallel(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) tournament._write_interactions = MagicMock( name='_write_interactions') self.assertTrue(tournament._run_parallel()) @@ -290,18 +283,17 @@ def test_n_workers(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=1) - self.assertEqual(tournament._n_workers(), max_processes) + repetitions=self.test_repetitions) + self.assertEqual(tournament._n_workers(processes=1), max_processes) tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=max_processes + 2) - self.assertEqual(tournament._n_workers(), max_processes) + repetitions=self.test_repetitions) + self.assertEqual(tournament._n_workers(processes=max_processes+2), + max_processes) @unittest.skipIf( cpu_count() < 2, @@ -315,9 +307,8 @@ def test_2_workers(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) - self.assertEqual(tournament._n_workers(), 2) + repetitions=self.test_repetitions,) + self.assertEqual(tournament._n_workers(processes=2), 2) def test_start_workers(self): workers = 2 @@ -523,7 +514,6 @@ def test_init(self): self.assertEqual(tournament.turns, float("inf")) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') - self.assertEqual(tournament._processes, None) self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 4a973d6ff..b463a94ef 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -20,7 +20,7 @@ class Tournament(object): def __init__(self, players, match_generator=RoundRobinMatches, name='axelrod', game=None, turns=200, repetitions=10, - processes=None, noise=0, with_morality=True): + noise=0, with_morality=True): """ Parameters ---------- @@ -53,7 +53,6 @@ def __init__(self, players, match_generator=RoundRobinMatches, self.match_generator = match_generator(players, turns, self.game, self.repetitions) self._with_morality = with_morality - self._processes = processes self._logger = logging.getLogger(__name__) def setup_output_file(self, filename=None): @@ -68,7 +67,7 @@ def setup_output_file(self, filename=None): # Save filename for loading ResultSet later self.filename = filename - def play(self, build_results=True, filename=None, progress_bar=True): + def play(self, build_results=True, filename=None, processes=None, progress_bar=True): """ Plays the tournament and passes the results to the ResultSet class @@ -92,10 +91,10 @@ def play(self, build_results=True, filename=None, progress_bar=True): if not build_results and not filename: warnings.warn("Tournament results will not be accessible since build_results=False and no filename was supplied.") - if self._processes is None: + if processes is None: self._run_serial(progress_bar=progress_bar) else: - self._run_parallel(progress_bar=progress_bar) + self._run_parallel(processes=processes, progress_bar=progress_bar) # Make sure that python has finished writing to disk self.outputfile.flush() @@ -151,7 +150,7 @@ def _write_interactions(self, results): row.append(history2) self.writer.writerow(row) - def _run_parallel(self, progress_bar=False): + def _run_parallel(self, processes=2, progress_bar=False): """ Run all matches in parallel @@ -166,7 +165,7 @@ def _run_parallel(self, progress_bar=False): # target functions which can be pickled and instance methods cannot. work_queue = Queue() done_queue = Queue() - workers = self._n_workers() + workers = self._n_workers(processes=processes) chunks = self.match_generator.build_match_chunks() for chunk in chunks: @@ -177,7 +176,7 @@ def _run_parallel(self, progress_bar=False): return True - def _n_workers(self): + def _n_workers(self, processes=2): """ Determines the number of parallel processes to use. @@ -185,8 +184,8 @@ def _n_workers(self): ------- integer """ - if (2 <= self._processes <= cpu_count()): - n_workers = self._processes + if (2 <= processes <= cpu_count()): + n_workers = processes else: n_workers = cpu_count() return n_workers @@ -297,7 +296,6 @@ class ProbEndTournament(Tournament): def __init__(self, players, match_generator=ProbEndRoundRobinMatches, name='axelrod', game=None, prob_end=.5, repetitions=10, - processes=None, noise=0, with_morality=True): """ @@ -324,8 +322,7 @@ def __init__(self, players, match_generator=ProbEndRoundRobinMatches, """ super(ProbEndTournament, self).__init__( players, name=name, game=game, turns=float("inf"), - repetitions=repetitions, processes=processes, - noise=noise, with_morality=with_morality) + repetitions=repetitions, noise=noise, with_morality=with_morality) self.prob_end = prob_end self.match_generator = ProbEndRoundRobinMatches( From 60f84993ba12f9b387049f1652428a7db27224fb Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Tue, 10 May 2016 20:35:43 -0700 Subject: [PATCH 2/3] Move processes argument from Tournament.__init__ to tournament.play --- axelrod/tests/integration/test_tournament.py | 5 +-- axelrod/tests/unit/test_tournament.py | 40 ++++++++------------ axelrod/tournament.py | 23 +++++------ 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/axelrod/tests/integration/test_tournament.py b/axelrod/tests/integration/test_tournament.py index 7e1305eac..1580de852 100644 --- a/axelrod/tests/integration/test_tournament.py +++ b/axelrod/tests/integration/test_tournament.py @@ -50,8 +50,7 @@ def test_parallel_play(self): players=self.players, game=self.game, turns=20, - repetitions=self.test_repetitions, - processes=2) - scores = tournament.play(progress_bar=False).scores + repetitions=self.test_repetitions) + scores = tournament.play(processes=2, progress_bar=False).scores actual_outcome = sorted(zip(self.player_names, scores)) self.assertEqual(actual_outcome, self.expected_outcome) diff --git a/axelrod/tests/unit/test_tournament.py b/axelrod/tests/unit/test_tournament.py index 11e105e74..c66b17e6a 100644 --- a/axelrod/tests/unit/test_tournament.py +++ b/axelrod/tests/unit/test_tournament.py @@ -63,7 +63,6 @@ def test_init(self): players=self.players, game=self.game, turns=self.test_turns, - processes=4, noise=0.2) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertIsInstance( @@ -73,7 +72,6 @@ def test_init(self): self.assertEqual(tournament.turns, self.test_turns) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') - self.assertEqual(tournament._processes, 4) self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) @@ -183,10 +181,9 @@ def test_progress_bar_play_parallel(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) - results = tournament.play() + results = tournament.play(processes=2) self.assertIsInstance(results, axelrod.ResultSet) results = tournament.play(progress_bar=True) @@ -229,9 +226,8 @@ def test_parallel_play(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) - results = tournament.play(progress_bar=False) + repetitions=self.test_repetitions) + results = tournament.play(processes=2, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # The following relates to #516 @@ -243,9 +239,8 @@ def test_parallel_play(self): players=players, game=self.game, turns=20, - repetitions=self.test_repetitions, - processes=2) - scores = tournament.play(progress_bar=False).scores + repetitions=self.test_repetitions) + scores = tournament.play(processes=2, progress_bar=False).scores self.assertEqual(len(scores), len(players)) def test_run_serial(self): @@ -254,8 +249,7 @@ def test_run_serial(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) tournament._write_interactions = MagicMock( name='_write_interactions') self.assertTrue(tournament._run_serial()) @@ -270,8 +264,7 @@ def test_run_parallel(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) + repetitions=self.test_repetitions) tournament._write_interactions = MagicMock( name='_write_interactions') self.assertTrue(tournament._run_parallel()) @@ -288,18 +281,17 @@ def test_n_workers(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=1) - self.assertEqual(tournament._n_workers(), max_processes) + repetitions=self.test_repetitions) + self.assertEqual(tournament._n_workers(processes=1), max_processes) tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=max_processes + 2) - self.assertEqual(tournament._n_workers(), max_processes) + repetitions=self.test_repetitions) + self.assertEqual(tournament._n_workers(processes=max_processes+2), + max_processes) @unittest.skipIf( cpu_count() < 2, @@ -313,9 +305,8 @@ def test_2_workers(self): players=self.players, game=self.game, turns=200, - repetitions=self.test_repetitions, - processes=2) - self.assertEqual(tournament._n_workers(), 2) + repetitions=self.test_repetitions,) + self.assertEqual(tournament._n_workers(processes=2), 2) def test_start_workers(self): workers = 2 @@ -521,7 +512,6 @@ def test_init(self): self.assertEqual(tournament.turns, float("inf")) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') - self.assertEqual(tournament._processes, None) self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) diff --git a/axelrod/tournament.py b/axelrod/tournament.py index 4a973d6ff..b463a94ef 100644 --- a/axelrod/tournament.py +++ b/axelrod/tournament.py @@ -20,7 +20,7 @@ class Tournament(object): def __init__(self, players, match_generator=RoundRobinMatches, name='axelrod', game=None, turns=200, repetitions=10, - processes=None, noise=0, with_morality=True): + noise=0, with_morality=True): """ Parameters ---------- @@ -53,7 +53,6 @@ def __init__(self, players, match_generator=RoundRobinMatches, self.match_generator = match_generator(players, turns, self.game, self.repetitions) self._with_morality = with_morality - self._processes = processes self._logger = logging.getLogger(__name__) def setup_output_file(self, filename=None): @@ -68,7 +67,7 @@ def setup_output_file(self, filename=None): # Save filename for loading ResultSet later self.filename = filename - def play(self, build_results=True, filename=None, progress_bar=True): + def play(self, build_results=True, filename=None, processes=None, progress_bar=True): """ Plays the tournament and passes the results to the ResultSet class @@ -92,10 +91,10 @@ def play(self, build_results=True, filename=None, progress_bar=True): if not build_results and not filename: warnings.warn("Tournament results will not be accessible since build_results=False and no filename was supplied.") - if self._processes is None: + if processes is None: self._run_serial(progress_bar=progress_bar) else: - self._run_parallel(progress_bar=progress_bar) + self._run_parallel(processes=processes, progress_bar=progress_bar) # Make sure that python has finished writing to disk self.outputfile.flush() @@ -151,7 +150,7 @@ def _write_interactions(self, results): row.append(history2) self.writer.writerow(row) - def _run_parallel(self, progress_bar=False): + def _run_parallel(self, processes=2, progress_bar=False): """ Run all matches in parallel @@ -166,7 +165,7 @@ def _run_parallel(self, progress_bar=False): # target functions which can be pickled and instance methods cannot. work_queue = Queue() done_queue = Queue() - workers = self._n_workers() + workers = self._n_workers(processes=processes) chunks = self.match_generator.build_match_chunks() for chunk in chunks: @@ -177,7 +176,7 @@ def _run_parallel(self, progress_bar=False): return True - def _n_workers(self): + def _n_workers(self, processes=2): """ Determines the number of parallel processes to use. @@ -185,8 +184,8 @@ def _n_workers(self): ------- integer """ - if (2 <= self._processes <= cpu_count()): - n_workers = self._processes + if (2 <= processes <= cpu_count()): + n_workers = processes else: n_workers = cpu_count() return n_workers @@ -297,7 +296,6 @@ class ProbEndTournament(Tournament): def __init__(self, players, match_generator=ProbEndRoundRobinMatches, name='axelrod', game=None, prob_end=.5, repetitions=10, - processes=None, noise=0, with_morality=True): """ @@ -324,8 +322,7 @@ def __init__(self, players, match_generator=ProbEndRoundRobinMatches, """ super(ProbEndTournament, self).__init__( players, name=name, game=game, turns=float("inf"), - repetitions=repetitions, processes=processes, - noise=noise, with_morality=with_morality) + repetitions=repetitions, noise=noise, with_morality=with_morality) self.prob_end = prob_end self.match_generator = ProbEndRoundRobinMatches( From b9178c9931ad9c63c39867f2c94cb8af5d460ff8 Mon Sep 17 00:00:00 2001 From: Vince Knight Date: Wed, 11 May 2016 11:50:57 +0100 Subject: [PATCH 3/3] Fixing hypothesis decorators. --- axelrod/tests/property.py | 26 ++++---------------------- axelrod/tests/unit/test_property.py | 14 -------------- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/axelrod/tests/property.py b/axelrod/tests/property.py index f40623270..b5154759d 100644 --- a/axelrod/tests/property.py +++ b/axelrod/tests/property.py @@ -60,8 +60,7 @@ def tournaments(draw, strategies=axelrod.strategies, min_size=1, max_size=10, min_turns=1, max_turns=200, min_noise=0, max_noise=1, - min_repetitions=1, max_repetitions=20, - max_processes=None): + min_repetitions=1, max_repetitions=20): """ A hypothesis decorator to return a tournament and a random seed (to ensure reproducibility for strategies that make use of the random module when @@ -85,8 +84,6 @@ def tournaments(draw, strategies=axelrod.strategies, The minimum number of repetitions max_repetitions : integer The maximum number of repetitions - max_processes : bool - Maximum number of processes to use """ seed = draw(random_module()) strategies = draw(strategy_lists(strategies=strategies, @@ -98,14 +95,8 @@ def tournaments(draw, strategies=axelrod.strategies, max_value=max_repetitions)) noise = draw(floats(min_value=min_noise, max_value=max_noise)) - if max_processes is not None: - processes = draw(integers(min_value=1, max_value=max_processes)) - else: - processes = None - tournament = axelrod.Tournament(players, turns=turns, - repetitions=repetitions, noise=noise, - processes=processes) + repetitions=repetitions, noise=noise) return tournament, seed @@ -114,8 +105,7 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies, min_size=1, max_size=10, min_prob_end=0, max_prob_end=1, min_noise=0, max_noise=1, - min_repetitions=1, max_repetitions=20, - max_processes=None): + min_repetitions=1, max_repetitions=20): """ A hypothesis decorator to return a tournament and a random seed (to ensure reproducibility for strategies that make use of the random module when @@ -139,8 +129,6 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies, The minimum number of repetitions max_repetitions : integer The maximum number of repetitions - max_processes : bool - Maximum number of processes to use """ seed = draw(random_module()) strategies = draw(strategy_lists(strategies=strategies, @@ -152,14 +140,8 @@ def prob_end_tournaments(draw, strategies=axelrod.strategies, max_value=max_repetitions)) noise = draw(floats(min_value=min_noise, max_value=max_noise)) - if max_processes is not None: - processes = draw(integers(min_value=1, max_value=max_processes)) - else: - processes = None - tournament = axelrod.ProbEndTournament(players, prob_end=prob_end, - repetitions=repetitions, noise=noise, - processes=processes) + repetitions=repetitions, noise=noise) return tournament, seed diff --git a/axelrod/tests/unit/test_property.py b/axelrod/tests/unit/test_property.py index e15b54418..79d36d5dc 100644 --- a/axelrod/tests/unit/test_property.py +++ b/axelrod/tests/unit/test_property.py @@ -105,7 +105,6 @@ def test_decorator(self, tournament_and_seed): self.assertGreaterEqual(tournament.noise, 0) self.assertLessEqual(tournament.repetitions, 50) self.assertGreaterEqual(tournament.repetitions, 2) - self.assertIsNone(tournament._processes) @given(tournament_and_seed=tournaments(strategies=axelrod.basic_strategies)) def test_decorator_with_given_strategies(self, tournament_and_seed): @@ -127,12 +126,6 @@ def test_decorator_with_stochastic_strategies(self, tournament_and_seed): for p in tournament.players: self.assertIn(str(p), stochastic_player_names) - @given(tournament_and_seed=tournaments(max_processes=2)) - def test_decorator_with_stochastic_strategies(self, tournament_and_seed): - tournament, seed = tournament_and_seed - self.assertGreaterEqual(tournament._processes, 1) - self.assertLessEqual(tournament._processes, 2) - class TestProbEndTournament(unittest.TestCase): @@ -157,7 +150,6 @@ def test_decorator(self, tournament_and_seed): self.assertGreaterEqual(tournament.noise, 0) self.assertLessEqual(tournament.repetitions, 50) self.assertGreaterEqual(tournament.repetitions, 2) - self.assertIsNone(tournament._processes) @given(tournament_and_seed=prob_end_tournaments(strategies=axelrod.basic_strategies)) def test_decorator_with_given_strategies(self, tournament_and_seed): @@ -179,12 +171,6 @@ def test_decorator_with_stochastic_strategies(self, tournament_and_seed): for p in tournament.players: self.assertIn(str(p), stochastic_player_names) - @given(tournament_and_seed=prob_end_tournaments(max_processes=2)) - def test_decorator_with_stochastic_strategies(self, tournament_and_seed): - tournament, seed = tournament_and_seed - self.assertGreaterEqual(tournament._processes, 1) - self.assertLessEqual(tournament._processes, 2) - class TestGame(unittest.TestCase): def test_call(self):