Ejemplo n.º 1
0
    def step(self):
        epoch_end_message = ActorSystem().ask(
            self.node_supervisor, HgsMessage(HgsOperation.NEW_METAEPOCH))
        self.cost = epoch_end_message.data

        ActorSystem().ask(self.node_supervisor,
                          HgsMessage(HgsOperation.TRIM_NOT_PROGRESSING))
        ActorSystem().ask(self.node_supervisor,
                          HgsMessage(HgsOperation.TRIM_REDUNDANT))
        ActorSystem().ask(self.node_supervisor,
                          HgsMessage(HgsOperation.RELEASE_SPROUTS))

        ActorSystem().ask(self.node_supervisor,
                          HgsMessage(HgsOperation.REVIVE))
        logger.info(f"step finished, current cost = {self.cost}")
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
 def send_merged_population(self):
     self.log_hgs_state()
     self.hgs.send(
         self.sender,
         HgsMessage(HgsOperation.POPULATION, self.sender_task_id,
                    self.merged_population),
     )
Ejemplo n.º 4
0
 def receive_trim_confirmation(self, msg: NodeMessage, sender: Actor):
     self.nodes_finished += 1
     if self.nodes_finished == self.requests_count:
         self.hgs.send(
             self.sender,
             HgsMessage(HgsOperation.TRIM_NOT_PROGRESSING_END,
                        self.sender_task_id),
         )
Ejemplo n.º 5
0
 def finish_metaepoch(self, msg: NodeMessage, sender: Actor):
     self.nodes_finished += 1
     if msg.data:
         self.metaepoch_costs.append(
             self.hgs.config.cost_modifiers[msg.data.level] *
             msg.data.epoch_cost)
     if self.nodes_finished == self.requests_count:
         self.log("All nodes have ended their metaepochs")
         self.hgs.cost += max(self.metaepoch_costs)
         self.hgs.send(
             self.sender,
             HgsMessage(HgsOperation.METAEPOCH_END, self.sender_task_id,
                        self.hgs.cost),
         )
Ejemplo n.º 6
0
 def receive_trim_confirmation(self, msg: NodeMessage, sender: Actor):
     trim_info = msg.data
     trim_info.node = sender
     self.trim_infos.append(trim_info)
     if len(self.trim_infos) == self.requests_count:
         self.trim_infos.sort(reverse=True, key=lambda info: info.level)
         for level, lvl_infos in itertools.groupby(
                 self.trim_infos, key=lambda info: info.level):
             self.log(f"trim lvl infos: {list(lvl_infos)} for lvl={level}")
             self.trim_redundant(list(lvl_infos))
         self.hgs.send(
             self.sender,
             HgsMessage(HgsOperation.TRIM_REDUNDANT_END,
                        self.sender_task_id, True),
         )
Ejemplo n.º 7
0
    def release_next_sprout(self):
        if (self.released_sprouts >= self.node.sproutiveness
                or self.alive_sprouts_count >= self.node.max_hgs_sprouts_no):
            self.log("finishing because max sprouts reached")
            self.finish()
            return

        delegate = self.node.delegates[self.current_delegate_index]
        self.log(
            f"checking next delegate: {delegate}, index: {self.current_delegate_index}"
        )
        self.current_delegate_index += 1

        if not any([
                tools.redundant(
                    [delegate],
                    [sprout.center],
                    self.node.min_dists[self.node.level + 1],
                ) for sprout in self.next_lvl_sprouts_states
                if sprout.population_len > 0
        ]):
            candidate_population = tools.population_from_delegate(
                delegate,
                self.node.hgs_population_sizes[self.node.level + 1],
                self.node.hgs_dims,
                self.node.hgs_mutation_rates[self.node.level + 1],
                self.node.hgs_mutation_etas[self.node.level + 1],
            )

            self.log("releasing new sprout!")
            new_sprout_state = create_node_state(self.node.myAddress,
                                                 self.node.level + 1, True,
                                                 False, candidate_population)
            self.created_sprouts_states.append(new_sprout_state)
            self.next_lvl_sprouts_states.append(new_sprout_state)
            self.node.send(
                self.node.supervisor,
                HgsMessage(
                    HgsOperation.REGISTER_NODE,
                    self.id,
                    (self.node.level + 1, candidate_population),
                ),
            )
        else:
            # TODO: logging redundant candidates
            # self.log("   CANDIDATE REDUNDANT")
            self.try_relase_next_sprout()
Ejemplo n.º 8
0
    def receiveMessage(self, msg, sender):
        self.log(f"SUPERVISOR RECEIVED: {msg} from: {sender}")
        if isinstance(msg, HgsMessage):
            if msg.operation == HgsOperation.START:
                self.start(msg.data)
                self.parent_actor = sender
                self.send(sender, "done")
            elif msg.operation == HgsOperation.REGISTER_NODE:
                level, population = msg.data
                node = self.create_node(level, population)
                self.nodes.append(node)
                self.level_nodes[level].append(node)
                self.send(
                    sender, HgsMessage(HgsOperation.REGISTER_NODE_END, msg.id, node)
                )
            else:
                self.execute_new_task(msg, sender)

        elif isinstance(msg, NodeMessage):
            operation = self.tasks[msg.id]
            operation.execute(msg, sender)
Ejemplo n.º 9
0
    def receive_release_confirmation(self, msg: NodeMessage, sender: Actor):
        self.current_lvl_states.append(msg.data[0])
        self.next_lvl_states.extend(msg.data[1])

        self.hgs.node_states.append(msg.data[0])
        self.hgs.node_states.extend(msg.data[1])

        self.lvl_index += 1
        if self.lvl_index >= len(self.hgs.level_nodes[self.current_lvl]):
            self.current_lvl -= 1
            self.lvl_index = 0
            self.next_lvl_states = self.current_lvl_states
            self.current_lvl_states = []
            if self.current_lvl < 0:
                self.hgs.send(
                    self.sender,
                    HgsMessage(HgsOperation.RELEASE_SPROUTS_END,
                               self.sender_task_id),
                )
                return

        self.send_next_request()
Ejemplo n.º 10
0
    def __init__(
            self,
            population,
            dims,
            fitnesses,
            fitness_errors,
            cost_modifiers,
            driver,
            mutation_etas,
            crossover_etas,
            mutation_rates,
            crossover_rates,
            reference_point,
            mantissa_bits,
            min_progress_ratio,
            metaepoch_len=5,
            max_level=2,
            max_sprouts_no=20,
            sproutiveness=1,
            comparison_multipliers=(1.0, 0.1, 0.01),
            population_sizes=(64, 16, 4),
            *args,
            **kwargs,
    ):
        super().__init__(*args, **kwargs)

        self.hgs_config = HgsConfig()

        self.hgs_config.driver = driver
        self.hgs_config.population = population

        self.hgs_config.dims = dims
        self.hgs_config.reference_point = reference_point
        self.hgs_config.fitnesses = fitnesses

        self.hgs_config.fitness_errors = fitness_errors
        self.hgs_config.cost_modifiers = cost_modifiers

        corner_a = np.array([x for x, _ in dims])
        corner_b = np.array([x for _, x in dims])
        corner_dist = np.linalg.norm(corner_a - corner_b)
        self.hgs_config.min_dists = [
            x * corner_dist for x in comparison_multipliers
        ]
        logger.info(
            f'multipliers: {comparison_multipliers}, min dists: {self.hgs_config.min_dists}'
        )

        self.hgs_config.metaepoch_len = metaepoch_len
        self.hgs_config.max_level = max_level
        self.hgs_config.max_sprouts_no = max_sprouts_no
        self.hgs_config.sproutiveness = sproutiveness
        self.hgs_config.min_progress_ratio = min_progress_ratio

        self.hgs_config.mutation_etas = mutation_etas
        self.hgs_config.mutation_rates = mutation_rates
        self.hgs_config.crossover_etas = crossover_etas
        self.hgs_config.crossover_rates = crossover_rates
        self.hgs_config.population_sizes = population_sizes

        self.hgs_config.mantissa_bits = mantissa_bits
        self.hgs_config.driver_message_adapter_factory = (
            self.driver_message_adapter_factory)

        # TODO this is shared variable which is a problem in actor model
        self.hgs_config.global_fitness_archive = [
            tools.ResultArchive() for _ in range(3)
        ]

        # TODO add preconditions checking if message adapter is HGS message adapter

        logger.info("HGS CREATED")
        self.hgs_system = ActorSystem()
        self.node_supervisor = self.hgs_system.createActor(HgsNodeSupervisor)

        self.hgs_system.ask(
            self.node_supervisor,
            HgsMessage(HgsOperation.START, data=self.hgs_config))
        self.hgs_system.ask(self.node_supervisor,
                            HgsMessage(HgsOperation.CHECK_STATUS))
        self.cost = 0
Ejemplo n.º 11
0
 def finalized_population(self):
     return (ActorSystem().ask(self.node_supervisor,
                               HgsMessage(HgsOperation.POPULATION)).data)
Ejemplo n.º 12
0
 def finish(self):
     self.hgs.send(self.sender,
                   HgsMessage(HgsOperation.REVIVE_END, self.sender_task_id))
Ejemplo n.º 13
0
 def send_status(self):
     self.hgs.send(
         self.sender,
         HgsMessage(HgsOperation.CHECK_STATUS, self.sender_task_id,
                    self.nodes_states),
     )