class SynapsesIndex(object): """ Создает индекс для поиска всех синапсов в self.value[j] для каждого нейрона в self.key[i]. self.key - вектор ключей self.value - вектор значений j = self.key[i] next_j = self.value[j] Если next_j == data_types.null, то value[j] - последний элемент в цепочке. """ def __init__(self, length, data): self.key = Vector() self.value = Vector() meta_key = Metadata((length, 1), types.address) meta_value = Metadata((len(data), 1), types.address) self.key.add(meta_key) self.key.fill(null) self.value.add(meta_value) self.value.fill(null) for value_address, key_address in enumerate(data): prev_value_address = self.key.data[key_address] self.key.data[key_address] = value_address self.value.data[value_address] = prev_value_address def __getitem__(self, key): value_address = self.key[key] ret = [] # possible infinite loop in malformed indexes while value_address != null: ret.append(value_address) value_address = self.value[value_address] if value_address == null: return ret return ret def create_device_data_pointer(self, device): """ Создание указателей на данные на устройстве """ self.key.create_device_data_pointer(device) self.value.create_device_data_pointer(device) def to_device(self, device): """ Загрузка на устройство """ self.key.to_device(device) self.value.to_device(device) def from_device(self, device): """ Выгрузка с устройства """ self.key.from_device(device) self.value.from_device(device)
class OutputIndex(object): """ Индекс всех output нейронов. С помощью этого индекса генерится numpy массив в котором спайки переводятся в числа. Чем выше частота спайков у нейрона, тем больше будет число. i = 0..количество output нейронов address[i] - адрес output нейрона data[i] - результат перевода спайков в число. Если спайка небыло - число уменьшается на 1 пока не станет равным нулю. Если спайк был, смотрим разницу между текущим тиком домена и предыдущим в tick[i] и переводим разницу в число tick[i] - тик при котором был предыдущий спайк нейрона. """ def __init__(self): self.address = Vector() self.meta_address = ExtendableMetadata((0, 1), types.address) self.address.add(self.meta_address) self.data = Vector() self.meta_data = ExtendableMetadata((0, 1), types.output) self.data.add(self.meta_data) self.tick = Vector() self.meta_tick = ExtendableMetadata((0, 1), types.tick) self.tick.add(self.meta_tick) self.pos = -1 self.cache = [] def add(self, layer): """ Добавляет все нейроны из layer в индекс """ if not layer.config.get('output'): return neurons_metadata = layer.neurons_metadata neurons_metadata_address = neurons_metadata.address self.cache.append([ self.pos + 1, len(layer), layer.config['output'] ]) for i in xrange(len(layer)): self.pos += 1 index = self.pos self.meta_address[index] = neurons_metadata_address + i self.meta_data[index] = 0 self.meta_tick[index] = 0 def data_to_send(self): ret = [] for pos, length, source_id in self.cache: ret.append([source_id, self.data.data[pos:pos + length]]) return ret def clear(self): self.pos = -1 for meta in [self.meta_address, self.meta_data, self.meta_tick]: meta.resize(length=0) def shrink(self): for vector in [self.address, self.data, self.tick]: vector.shrink() def create_device_data_pointer(self, device): """ Создание указателей на данные на устройстве """ self.address.create_device_data_pointer(device) self.data.create_device_data_pointer(device) self.tick.create_device_data_pointer(device) def to_device(self, device): """ Загрузка на устройство """ self.address.to_device(device) self.data.to_device(device) self.tick.to_device(device) def from_device(self, device): """ Выгрузка с устройства """ self.address.from_device(device) self.data.from_device(device) self.tick.from_device(device)
class TransmitterIndex(object): """ Индекс передающих нейронов i = 0..количество IS_TRANSMITTER нейронов j = 0..количество IS_RECEIVER нейронов local_address[i] - адрес IS_TRANSMITTER нейрона в domain.neurons is_spiked[i] - признак того, что нужно передать спайк, то же самое что и neuron.flags & IS_SPIKED && !(neuron.flags & IS_DEAD) key[i] - адрес первого элемента в цепочке value[j] value[j] - следующий адрес IS_RECEIVER нейрона в удаленном домене или null если адрес последний remote_domain[j] - домен IS_RECEIVER нейрона remote_address[j] - адрес IS_RECEIVER нейрона в удаленнном домене remote_receiver_index[j] - адрес IS_RECEIVER нейрона в post_domain.receive_index """ def __init__(self, data=None): self.local_address = Vector() self.meta_local_address = ExtendableMetadata((0, 1), types.address) self.local_address.add(self.meta_local_address) self.is_spiked = Vector() self.meta_is_spiked = ExtendableMetadata((0, 1), types.neuron_flags) self.is_spiked.add(self.meta_is_spiked) self.key = Vector() self.meta_key = ExtendableMetadata((0, 1), types.address) self.key.add(self.meta_key) self.value = Vector() self.meta_value = ExtendableMetadata((0, 1), types.address) self.value.add(self.meta_value) self.remote_domain = Vector() self.meta_remote_domain \ = ExtendableMetadata((0, 1), types.medium_address) self.remote_domain.add(self.meta_remote_domain) self.remote_address = Vector() self.meta_remote_address = ExtendableMetadata((0, 1), types.address) self.remote_address.add(self.meta_remote_address) self.remote_receiver_index = Vector() self.meta_remote_receiver_index \ = ExtendableMetadata((0, 1), types.address) self.remote_receiver_index.add(self.meta_remote_receiver_index) self.data = {} self.address_to_key_index = {} self.key_pos = -1 self.value_pos = -1 if data: self.rebuild(data) def add(self, local_address, remote_domain_index, remote_address, remote_receiver_index): """ Добавляет один элемент в индекс """ if local_address in self.data \ and remote_domain_index in self.data[local_address]: return False key_index = self.address_to_key_index.get(local_address) if key_index is None: self.key_pos += 1 self.data[local_address] = {} self.address_to_key_index[local_address] = self.key_pos key_index = self.key_pos self.meta_key[key_index] = null self.meta_is_spiked[key_index] = 0 self.meta_local_address[key_index] = local_address self.value_pos += 1 value_index = self.value_pos prev_value_index = self.meta_key[key_index] self.meta_key[key_index] = value_index self.meta_value[value_index] = prev_value_index self.meta_remote_domain[value_index] = remote_domain_index self.meta_remote_address[value_index] = remote_address self.meta_remote_receiver_index[value_index] = remote_receiver_index self.data[local_address][remote_domain_index] = (remote_address, remote_receiver_index) return True def clear(self): self.data = {} self.key_pos = -1 self.value_pos = -1 self.address_to_key_index = {} for meta in [self.meta_local_address, self.meta_is_spiked, self.meta_key, self.meta_value, self.meta_remote_domain, self.meta_remote_address]: meta.resize(length=0) def rebuild(self, data): """ Перестраивает весь индекс """ # TODO: do not loose order in self.data self.clear() for local_address in data.keys(): for domain_index in data[local_address]: remote_address, remote_receiver_index \ = data[local_address][domain_index] self.add(local_address, domain_index, remote_address, remote_receiver_index) self.shrink() def shrink(self): for vector in [self.local_address, self.is_spiked, self.key, self.value, self.remote_domain, self.remote_address, self.remote_receiver_index]: vector.shrink() def create_device_data_pointer(self, device): """ Создание указателей на данные на устройстве """ self.local_address.create_device_data_pointer(device) self.is_spiked.create_device_data_pointer(device) def to_device(self, device): """ Загрузка на устройство """ self.local_address.to_device(device) self.is_spiked.to_device(device) def from_device(self, device): """ Выгрузка с устройства """ self.local_address.from_device(device) self.is_spiked.from_device(device)
class ReceiverIndex(object): """ Индекс принимающих нейронов i = 0..количество IS_RECEIVER нейронов i - адрес IS_RECEIVER нейрона в индексе (этот адрес приходит из других доменов) local_address[i] - адрес IS_RECEIVER нейрона в domain.neurons is_spiked[i] - информация о спайке IS_RECEIVER нейрона (ее мы будем полчать из IS_TRANSMITTER нейрона в другом домене) remote_domain[i] - домен IS_TRANSMITTER нейрона remote_address[i] - адрес IS_TRANSMITTER нейрона в удаленнном домене """ def __init__(self, data=None): self.local_address = Vector() self.meta_local_address = ExtendableMetadata((0, 1), types.address) self.local_address.add(self.meta_local_address) self.is_spiked = Vector() self.meta_is_spiked = ExtendableMetadata((0, 1), types.neuron_flags) self.is_spiked.add(self.meta_is_spiked) self.meta_remote_domain \ = ExtendableMetadata((0, 1), types.medium_address) self.remote_domain = Vector() self.remote_domain.add(self.meta_remote_domain) self.remote_address = Vector() self.meta_remote_address = ExtendableMetadata((0, 1), types.address) self.remote_address.add(self.meta_remote_address) self.data = {} self.address_to_index = {} self.pos = -1 if data: self.rebuild(data) def add(self, local_address, remote_domain_index, remote_address): """ Добавляет один элемент в индекс """ # self.data[remote_domain_index][remote_address] = local_address if remote_domain_index in self.data \ and remote_address in self.data[remote_domain_index]: return False index = self.address_to_index.get(local_address) if index: return False self.pos += 1 if remote_domain_index not in self.data: self.data[remote_domain_index] = {} self.data[remote_domain_index][remote_address] = local_address self.address_to_index[local_address] = self.pos index = self.pos self.meta_is_spiked[index] = 0 self.meta_local_address[index] = local_address self.meta_remote_domain[index] = remote_domain_index self.meta_remote_address[index] = remote_address return True def clear(self): self.data = {} self.pos = -1 self.address_to_index = {} for meta in [self.meta_local_address, self.meta_is_spiked, self.meta_remote_domain, self.meta_remote_address]: meta.resize(length=0) def rebuild(self, data): """ Перестраивает весь индекс """ # TODO: do not loose order in self.data self.clear() for remote_domain_index in data.keys(): for remote_address in data[remote_domain_index]: self.add(data[remote_domain_index][remote_address], remote_domain_index, remote_address) self.shrink() def shrink(self): for vector in [self.local_address, self.is_spiked, self.remote_domain, self.remote_address]: vector.shrink() def get_local_address(self, remote_domain_index, remote_address): """ Получаем локальный адрес IS_RECEIVER нейрона по адресу IS_TRANSMITTER нейрона другого домена """ if remote_domain_index not in self.data: return return self.data[remote_domain_index].get(remote_address) def create_device_data_pointer(self, device): """ Создание указателей на данные на устройстве """ self.local_address.create_device_data_pointer(device) self.is_spiked.create_device_data_pointer(device) def to_device(self, device): """ Загрузка на устройство """ self.local_address.to_device(device) self.is_spiked.to_device(device) def from_device(self, device): """ Выгрузка с устройства """ self.local_address.from_device(device) self.is_spiked.from_device(device)