def create_node(self, level, population): node = self.actors_cache.pop() if self.actors_cache else self.createActor(Node) # time.sleep(10) node_config = NodeConfig(self.config, level, population) self.send(node, HgsMessage(HgsOperation.HELLO)) self.send(node, NodeMessage(NodeOperation.RESET, data=node_config)) return node
def send_trim_request(self, msg: HgsMessage, sender: Actor): self.sender = sender self.sender_task_id = msg.id self.requests_count = len(self.hgs.nodes) for node in self.hgs.nodes: self.hgs.send(node, NodeMessage(NodeOperation.CHECK_STATUS, self.id))
def send_next_request(self): current_node = self.hgs.level_nodes[self.current_lvl][self.lvl_index] self.hgs.send( current_node, NodeMessage(NodeOperation.RELEASE_SPROUTS, self.id, data=self.next_lvl_states), )
def start_metaepoch(self, msg: HgsMessage, sender: Actor): self.log("New metaepoch, nodes: ") for lvl, nodes in self.hgs.level_nodes.items(): self.log(f"{lvl} : {nodes}") self.hgs.node_states.clear() self.sender = sender self.sender_task_id = msg.id self.requests_count = len(self.hgs.nodes) for node in self.hgs.nodes: self.hgs.send(node, NodeMessage(NodeOperation.NEW_METAEPOCH, self.id))
def send_check(self, msg: HgsMessage, sender: Actor): self.nodes_lvl = msg.data self.sender = sender self.sender_task_id = msg.id self.nodes_to_check = self.get_nodes_to_check() self.log(f"nodes to check: {self.nodes_to_check}") if self.nodes_to_check: for node in self.nodes_to_check: self.hgs.send(node, NodeMessage(NodeOperation.CHECK_STATUS, self.id)) else: self.send_status()
def finish(self): my_state = create_node_state(self.node.myAddress, self.node.level, self.node.alive, self.node.ripe, self.node.population) self.node.send( self.sender, NodeMessage( NodeOperation.RELEASE_SPROUTS_END, self.sender_task_id, (my_state, self.created_sprouts_states), ), )
def stream_metaepoch_results(self, msg: NodeMessage, sender: Actor): self.run_metaepoch().pipe( ops.do_action(on_completed=lambda: self.node.send( sender, NodeMessage(NodeOperation.METAEPOCH_END, msg.id, self. last_result_data), )) ).subscribe( lambda result: self.update_cost(result) # lambda result: self.node.send( # sender, NodeMessage(NodeOperation.NEW_RESULT, msg.id, result) # ) )
def send_trim_request(self, msg: HgsMessage, sender: Actor): self.sender = sender self.sender_task_id = msg.id self.requests_count = len(self.hgs.nodes) for lvl, nodes in self.hgs.level_nodes.items(): for node in nodes: self.hgs.send( node, NodeMessage( NodeOperation.TRIM_NOT_PROGRESSING, self.id, data=self.hgs.config.min_progress_ratio[lvl], ), )
def receive_sprouting_request(self, msg: NodeMessage, sender: Actor): self.log("receiving next level states") self.sender = sender self.sender_task_id = msg.id self.next_lvl_sprouts_states = msg.data if self.node.ripe: if self.node.sprouts: for sprout in self.node.sprouts: self.node.send( sprout, NodeMessage(NodeOperation.CHECK_STATUS, self.id)) else: self.start_sprouting() else: self.log("finishing because not ripe") self.finish()
def send_revive_request(self, msg: HgsMessage, sender: Actor): self.sender = sender self.sender_task_id = msg.id if len([state for state in self.hgs.node_states if state.alive]) == 0: ripe_nodes = [ state.address for state in self.hgs.node_states if state.ripe ] self.ripe_nodes_count = len(ripe_nodes) for ripe_node in ripe_nodes: self.hgs.send(ripe_node, NodeMessage(NodeOperation.REVIVE, self.id)) for i in range(self.hgs.config.max_level + 1): self.hgs.config.min_progress_ratio[i] /= 2 # TODO: logging root revival self.log("!!! RESURRECTION", lvl=logging.INFO) else: self.finish()
def trim_redundant(self, lvl_infos): alive = [x for x in lvl_infos if x.alive] processed = [] dead = [x for x in lvl_infos if not x.alive] for sprout in alive: to_compare = [x for x in dead] to_compare.extend(processed) for another_sprout in to_compare: if not sprout.alive: break if (another_sprout.ripe or another_sprout in processed) and tools.redundant( [another_sprout.center], [sprout.center], self.hgs.min_dists[sprout.level], ): self.hgs.send(sprout.node, NodeMessage(NodeOperation.KILL, self.id)) sprout.alive = False # TODO: logging killing redundant sprouts self.log(" KILL REDUNDANT") processed.append(sprout)
def trim_not_progressing(self, msg: NodeMessage, sender: Actor): min_progress_ratio = msg.data if self.node.old_hypervolume and self.node.old_hypervolume > 0.0: self.log( f"progress: {(self.node.hypervolume / (self.node.old_hypervolume + EPSILON)) - 1.0}, min ratio: {min_progress_ratio}", logging.INFO, ) if (self.node.alive and self.node.old_hypervolume is not None and self.node.old_hypervolume > 0.0 and ((self.node.hypervolume / (self.node.old_hypervolume + EPSILON)) - 1.0) < (min_progress_ratio / 2**self.node.level)): # TODO: kij wie, czy współczynnik kurczący wymagany progress jest potrzebny (to / X**sprout.level) self.node.alive = False self.node.center = np.mean(self.node.population, axis=0) self.node.ripe = True # TODO: logging killing not progressing sprouts self.log(" KILL NOT PROGRESSING") self.node.send( sender, NodeMessage(NodeOperation.TRIM_NOT_PROGRESSING_END, msg.id))
def get_nodes_populations(self, msg: HgsMessage, sender: Actor): self.sender = sender self.sender_task_id = msg.id self.requests_count = len(self.hgs.nodes) for node in self.hgs.nodes: self.hgs.send(node, NodeMessage(NodeOperation.POPULATION, self.id))
def send_population(self, msg: NodeMessage, sender: Actor): self.node.send( sender, NodeMessage(NodeOperation.POPULATION, msg.id, self.node.population))
def revive(self, msg: NodeMessage, sender: Actor): self.node.ripe = False self.node.alive = True self.node.send(sender, NodeMessage(NodeOperation.REVIVE, msg.id))
def send_status(self, msg: NodeMessage, sender: Actor): state = create_node_state(sender, self.node.level, self.node.alive, self.node.ripe, self.node.population) self.node.send(sender, NodeMessage(NodeOperation.CHECK_STATUS, msg.id, state))