Пример #1
0
def config(agent):
    logging.debug('Prepare config')
    config = agent.net_config
    if not config:
        raise ValueError('No net config')
    config = Config(config)
    config.make_unique()
    if agent.config['out']:
        agent.config['out'].write(to_json(config))
    return config
Пример #2
0
 def __init__(self, config):
     self.config = Config(config)
     self.domains = []
     self._find = None
     self.is_pause = False
     self.is_stop = False
Пример #3
0
class OpenRE(object):
    """
    Основной класс.
        config - настройки сети
        local_domains - один или несколько domain.name которые нужно создать
            локально
    Пример работы:
        from openre import OpenRE
        ore = OpenRE(config)
        ore.run()
    config - содержит в себе настройки для сети включая оборудование, на
             котором будут проходить вычисления.
    Пример config:
        {
            'domain': {
                'name'        : 1,
                'device'    : '0',
                'layers'    : [
                    {
                        'threshold': 30000,
                        'relaxation': 1000,
                    },
                    {
                        'threshold': 30000,
                    }
                ],
            },
        }
    """
    def __init__(self, config):
        self.config = Config(config)
        self.domains = []
        self._find = None
        self.is_pause = False
        self.is_stop = False

    def __repr__(self):
        return 'OpenRE(%s)' % repr(self.config)

    def deploy(self, domain_factory=None):
        """
        Создание сети.
        """
        self.deploy_domains(domain_factory)
        self.deploy_layers()
        self.deploy_neurons()
        self.pre_deploy_synapses()
        # here wait for all domains is synced
        res = self.deploy_synapses()
        if isinstance(res, GeneratorType):
            list(res)
        # here wait for all domains is synced
        self.post_deploy_synapses()
        self.post_deploy()

    def deploy_domains(self, domain_factory=None):
        """
        Создание пустых доменов
        """
        if domain_factory is None:
            domain_factory = create_domain_factory()
        layer_by_name = {}
        for layer in self.config['layers']:
            layer_by_name[layer['name']] = layer

        # TODO: - выдавать предупреждение если не весь слой моделируется
        #       - выдавать предупреждение или падать если один и тот же слoй
        #           частично или полностью моделируется дважды
        domain_index = -1
        for domain_config in self.config['domains']:
            domain_index += 1
            # No layers in source devices like cams, mics, etc.
            if 'layers' not in domain_config:
                domain_config['layers'] = []
            domain_config = deepcopy(domain_config)
            for domain_layer in domain_config['layers']:
                domain_layer.update(
                    deepcopy(layer_by_name[domain_layer['name']]))
            domain_class = domain_factory(domain_config['name'])
            domain = domain_class(domain_config, self, domain_index)
            self.domains.append(domain)

        if self.config.get('rate_limit'):
            self.tick = rate_limited(self.config['rate_limit'])(self.tick)

    def deploy_layers(self):
        for domain in self.domains:
            domain.deploy_layers()

    def deploy_neurons(self):
        for domain in self.domains:
            domain.deploy_neurons()

    def pre_deploy_synapses(self):
        for domain in self.domains:
            domain.pre_deploy_synapses()

    def deploy_synapses_async(self):
        for domain in self.domains:
            ret = domain.deploy_synapses_async()
            if isinstance(ret, GeneratorType):
                for res in ret:
                    yield res
        # send the rest
        for domain in self.domains:
            domain.send_synapse_pack()
            domain.send_receiver_index_pack()

    def deploy_synapses(self):
        ret = self.deploy_synapses_async()
        for _ in ret:
            pass

    def post_deploy_synapses(self):
        for domain in self.domains:
            domain.post_deploy_synapses()

    def post_deploy(self):
        for domain in self.domains:
            domain.deploy_indexes()
            domain.deploy_device()

    def tick(self):
        """
        Один шаг моделирования.
        """
        if self.is_pause or self.is_stop:
            return
        for domain in self.domains:
            domain.tick()

    def run(self):
        """
        Основной цикл.
        """
        logging.debug('Run')
        last_sec = int(time())
        tick_per_sec = 0
        logger_level = logging.getLogger().getEffectiveLevel()
        try:
            while True:
                if logger_level <= logging.DEBUG:
                    now = int(time())
                    if last_sec != now:
                        last_sec = now
                        logging.debug('Ticks/sec: %s', tick_per_sec)
                        tick_per_sec = 0
                    tick_per_sec += 1
                if self.is_stop:
                    self.is_stop = False
                    break
                self.tick()
        except:
            self.clean()
            raise

    def find(self, layer_name, x, y):
        """
        Ищет домен и слой для заданных координат x и y в слое layer_name
        """
        # precache
        if self._find is None:
            self._find = {}
            layer_by_name = {}
            for layer in self.config['layers']:
                layer_by_name[layer['name']] = layer

            for domain in self.config['domains']:
                domain_name = domain['name']
                layer_index = -1
                for layer in domain['layers']:
                    layer = deepcopy(layer)
                    layer_index += 1
                    domain_layer_name = layer['name']
                    if domain_layer_name not in self._find:
                        self._find[domain_layer_name] = []
                    layer['domain_name'] = domain_name
                    layer['layer_index'] = layer_index
                    layer['width'] = layer_by_name[domain_layer_name]['width']
                    layer['height'] = layer_by_name[domain_layer_name]['height']
                    self._find[domain_layer_name].append(layer)
        if layer_name not in self._find:
            return None
        for row in self._find[layer_name]:
            if 'shape' not in row:
                if x < 0 or y < 0 \
                   or x >= row['width'] or y >= row['height']:
                    continue
            else:
                shape = row['shape']
                # coordinate is out of domains layer bounds
                if x < shape[0] \
                   or x >= shape[0] + shape[2] \
                   or y < shape[1] \
                   or y >= shape[1] + shape[3] \
                   or x < 0 or y < 0 \
                   or x >= row['width'] or y >= row['height']:
                    continue
            return {
                'domain_name': row['domain_name'],
                'layer_index': row['layer_index'],
            }
        return None

    def start(self):
        """
        Снимаем с паузы.
        Ставим флаг self.is_pause = False
        """
        self.is_pause = False

    def stop(self):
        """
        Ставим флаг self.is_stop = True
        """
        self.is_stop = True

    def pause(self):
        """
        Ставим флаг self.is_pause = True
        """
        self.is_pause = True

    def clean(self):
        """
        Завершаем работу сети
        """
        for domain in self.domains:
            domain.clean()