neuropercolation/cellular_automaton/automaton.py

63 lines
2.1 KiB
Python
Raw Normal View History

2019-01-31 12:38:48 +00:00
import multiprocessing
2019-02-16 17:05:26 +00:00
from multiprocessing import freeze_support
from ctypes import c_int
2018-12-01 14:14:22 +00:00
class CellularAutomatonProcessor:
def __init__(self, cellular_automaton):
self._ca = cellular_automaton
def evolve_x_times(self, x):
for x in range(x):
self.evolve()
def evolve(self):
2019-02-16 17:05:26 +00:00
self._ca.current_evolution_step += 1
i = self._ca.current_evolution_step
r = self._ca.evolution_rule.evolve_cell
2019-02-16 17:05:26 +00:00
list(map(lambda c: c.evolve_if_ready(r, i), tuple(self._ca.cells.values())))
class CellularAutomatonMultiProcessor(CellularAutomatonProcessor):
def __init__(self, cellular_automaton, process_count: int = 2):
2019-02-16 17:05:26 +00:00
freeze_support()
if process_count < 1:
raise ValueError
super().__init__(cellular_automaton)
self.evolve_range = range(len(self._ca.cells))
2019-02-16 17:05:26 +00:00
self.shared_evolution_step = multiprocessing.RawValue(c_int, self._ca.current_evolution_step)
2019-02-16 17:05:26 +00:00
self.__init_processes_and_clean_cell_instances(process_count)
def __init_processes_and_clean_cell_instances(self, process_count):
self.pool = multiprocessing.Pool(processes=process_count,
initializer=_init_process,
initargs=(tuple(self._ca.cells.values()),
self._ca.evolution_rule,
2019-02-16 17:05:26 +00:00
self.shared_evolution_step))
for cell in self._ca.cells.values():
2019-02-16 17:05:26 +00:00
del cell.neighbor_states
def evolve(self):
2019-02-16 17:05:26 +00:00
self._ca.current_evolution_step += 1
self.shared_evolution_step.value = self._ca.current_evolution_step
self.pool.map(_process_routine, self.evolve_range)
global_cells = None
global_rule = None
2019-02-16 17:05:26 +00:00
global_evolution_step = None
def _init_process(cells, rule, index):
2019-02-16 17:05:26 +00:00
global global_rule, global_cells, global_evolution_step
global_cells = cells
global_rule = rule
2019-02-16 17:05:26 +00:00
global_evolution_step = index
def _process_routine(i):
2019-02-16 17:05:26 +00:00
global_cells[i].evolve_if_ready(global_rule.evolve_cell, global_evolution_step.value)