def get_spikes(self): """ How to get spikes (of a population's neurons) from the recorder. :return: the spikes (event times) from the underlying vertex :rtype: ~numpy.ndarray """ # check we're in a state where we can get spikes if not isinstance(self.__vertex, AbstractSpikeRecordable): raise ConfigurationException( "This population has not got the capability to record spikes") if not self.__vertex.is_recording_spikes(): raise ConfigurationException( "This population has not been set to record spikes") sim = get_simulator() if not sim.has_ran: logger.warning( "The simulation has not yet run, therefore spikes cannot " "be retrieved, hence the list will be empty") return numpy.zeros((0, 2)) if sim.use_virtual_board: logger.warning( "The simulation is using a virtual machine and so has not " "truly ran, hence the spike list will be empty") return numpy.zeros((0, 2)) # assuming we got here, everything is OK, so we should go get the # spikes return self.__vertex.get_spikes(sim.placements, sim.buffer_manager)
def __init__( self, hostname, port, board_address=None, tag=None, strip_sdp=True, use_prefix=False, key_prefix=None, prefix_type=None, message_type=EIEIOType.KEY_32_BIT, right_shift=0, payload_as_time_stamps=True, use_payload_prefix=True, payload_prefix=None, payload_right_shift=0, number_of_packets_sent_per_time_step=0, constraints=None, label=None): """ """ if ((message_type == EIEIOType.KEY_PAYLOAD_32_BIT or message_type == EIEIOType.KEY_PAYLOAD_16_BIT) and use_payload_prefix and payload_as_time_stamps): raise ConfigurationException( "Timestamp can either be included as payload prefix or as " "payload to each key, not both") if ((message_type == EIEIOType.KEY_32_BIT or message_type == EIEIOType.KEY_16_BIT) and not use_payload_prefix and payload_as_time_stamps): raise ConfigurationException( "Timestamp can either be included as payload prefix or as" " payload to each key, but current configuration does not " "specify either of these") if (not isinstance(prefix_type, EIEIOPrefix) and prefix_type is not None): raise ConfigurationException( "the type of a prefix type should be of a EIEIOPrefix, " "which can be located in :" "SpinnMan.messages.eieio.eieio_prefix_type") if label is None: label = "Live Packet Gatherer" ApplicationVertex.__init__(self, label, constraints, 1) # Try to place this near the Ethernet self.add_constraint(RadialPlacementFromChipConstraint(0, 0)) # storage objects self._iptags = None # tag info self._ip_address = hostname self._port = port self._board_address = board_address self._tag = tag self._strip_sdp = strip_sdp # eieio info self._prefix_type = prefix_type self._use_prefix = use_prefix self._key_prefix = key_prefix self._message_type = message_type self._right_shift = right_shift self._payload_as_time_stamps = payload_as_time_stamps self._use_payload_prefix = use_payload_prefix self._payload_prefix = payload_prefix self._payload_right_shift = payload_right_shift self._number_of_packets_sent_per_time_step = \ number_of_packets_sent_per_time_step
def get_events(self, variable): """ How to get rewiring events (of a post-population) from recorder :return: the rewires (event times, values) from the underlying vertex :rtype: ~numpy.ndarray """ # check we're in a state where we can get rewires if not isinstance(self.__vertex, AbstractEventRecordable): raise ConfigurationException( "This population has not got the capability to record rewires") if not self.__vertex.is_recording(REWIRING): raise ConfigurationException( "This population has not been set to record rewires") sim = get_simulator() if not sim.has_ran: logger.warning( "The simulation has not yet run, therefore rewires cannot " "be retrieved, hence the list will be empty") return numpy.zeros((0, 4)) if sim.use_virtual_board: logger.warning( "The simulation is using a virtual machine and so has not " "truly ran, hence the rewires list will be empty") return numpy.zeros((0, 4)) return self.__vertex.get_events(variable, sim.placements, sim.buffer_manager)
def _install_virtual_key(self, n_keys): # check that virtual key is valid if self._virtual_key < 0: raise ConfigurationException("Virtual keys must be positive") # Get a mask and maximum number of keys for the number of keys # requested self._mask, max_key = self._calculate_mask(n_keys) # Check that the number of keys and the virtual key don't interfere if n_keys > max_key: raise ConfigurationException( "The mask calculated from the number of keys will not work " "with the virtual key specified") if self._prefix is not None: # Check that the prefix doesn't change the virtual key in the # masked area masked_key = (self._virtual_key | self._prefix) & self._mask if self._virtual_key != masked_key: raise ConfigurationException( "The number of keys, virtual key and key prefix settings " "don't work together") else: # If no prefix was generated, generate one self._prefix_type = EIEIOPrefix.UPPER_HALF_WORD self._prefix = self._virtual_key
def check_indexes(self, indexes): """ :param list(int) indexes: """ if indexes is None: return if len(indexes) == 0: raise ConfigurationException("Empty indexes list") found = False warning = None for index in indexes: if index < 0: raise ConfigurationException( "Negative indexes are not supported") elif index >= self.__n_neurons: warning = "Ignoring indexes greater than population size." else: found = True if warning is not None: logger.warning(warning) if not found: raise ConfigurationException( "All indexes larger than population size")
def __call__(self, machine_graph=None, application_graph=None, graph_mapper=None): # Generate an n_keys map for the graph and add constraints n_keys_map = DictBasedMachinePartitionNKeysMap() if machine_graph is None: raise ConfigurationException( "A machine graph is required for this mapper. " "Please choose and try again") if (application_graph is None) != (graph_mapper is None): raise ConfigurationException( "Can only do one graph. semantically doing 2 graphs makes no " "sense. Please choose and try again") if application_graph is not None: # generate progress bar progress = ProgressBar( machine_graph.n_vertices, "Getting number of keys required by each edge using " "application graph") # iterate over each partition in the graph for vertex in progress.over(machine_graph.vertices): partitions = machine_graph.\ get_outgoing_edge_partitions_starting_at_vertex( vertex) for partition in partitions: added_constraints = False constraints = self._process_application_partition( partition, n_keys_map, graph_mapper) if not added_constraints: partition.add_constraints(constraints) else: self._check_constraints_equal( constraints, partition.constraints) else: # generate progress bar progress = ProgressBar( machine_graph.n_vertices, "Getting number of keys required by each edge using " "machine graph") for vertex in progress.over(machine_graph.vertices): partitions = machine_graph.\ get_outgoing_edge_partitions_starting_at_vertex( vertex) for partition in partitions: added_constraints = False constraints = self._process_machine_partition( partition, n_keys_map) if not added_constraints: partition.add_constraints(constraints) else: self._check_constraints_equal( constraints, partition.constraints) return n_keys_map
def _get_recorded_matrix(self, variable): """ Perform safety checks and get the recorded data from the vertex\ in matrix format. :param variable: the variable name to read. supported variable names are :'gsyn_exc', 'gsyn_inh', 'v' :return: the data """ timer = Timer() timer.start_timing() data = None sim = get_simulator() get_simulator().verify_not_running() # check that we're in a state to get voltages if not isinstance( self._population._vertex, AbstractNeuronRecordable): raise ConfigurationException( "This population has not got the capability to record {}" .format(variable)) if not self._population._vertex.is_recording(variable): raise ConfigurationException( "This population has not been set to record {}" .format(variable)) if not sim.has_ran: logger.warning( "The simulation has not yet run, therefore {} cannot" " be retrieved, hence the list will be empty".format( variable)) data = numpy.zeros((0, 3)) indexes = [] sampling_interval = self._population._vertex.\ get_neuron_sampling_interval(variable) elif sim.use_virtual_board: logger.warning( "The simulation is using a virtual machine and so has not" " truly ran, hence the list will be empty") data = numpy.zeros((0, 3)) indexes = [] sampling_interval = self._population._vertex.\ get_neuron_sampling_interval(variable) else: # assuming we got here, everything is ok, so we should go get the # data results = self._population._vertex.get_data( variable, sim.no_machine_time_steps, sim.placements, sim.graph_mapper, sim.buffer_manager, sim.machine_time_step) (data, indexes, sampling_interval) = results get_simulator().add_extraction_timing( timer.take_sample()) return (data, indexes, sampling_interval)
def get_recorded_matrix(self, variable): """ Perform safety checks and get the recorded data from the vertex\ in matrix format. :param str variable: The variable name to read. Supported variable names are: ``gsyn_exc``, ``gsyn_inh``, ``v`` :return: data, indexes, sampling_interval :rtype: tuple(~numpy.ndarray, list(int), float) """ data = None sim = get_simulator() sim.verify_not_running() # check that we're in a state to get voltages if not isinstance(self.__vertex, AbstractNeuronRecordable): raise ConfigurationException( "This population has not got the capability to record {}". format(variable)) if not self.__vertex.is_recording(variable): raise ConfigurationException( "This population has not been set to record {}".format( variable)) if not sim.has_ran: logger.warning( "The simulation has not yet run, therefore {} cannot be " "retrieved, hence the list will be empty".format(variable)) data = numpy.zeros((0, 3)) indexes = [] sampling_interval = self.__vertex.get_neuron_sampling_interval( variable) elif sim.use_virtual_board: logger.warning( "The simulation is using a virtual machine and so has not " "truly ran, hence the list will be empty") data = numpy.zeros((0, 3)) indexes = [] sampling_interval = self.__vertex.get_neuron_sampling_interval( variable) else: # assuming we got here, everything is ok, so we should go get the # data results = self.__vertex.get_data(variable, sim.no_machine_time_steps, sim.placements, sim.buffer_manager) (data, indexes, sampling_interval) = results return (data, indexes, sampling_interval)
def check_sampling_interval(sampling_interval): step = globals_variables.get_simulator().machine_time_step / 1000 if sampling_interval is None: return step rate = int(sampling_interval / step) if sampling_interval != rate * step: msg = "sampling_interval {} is not an an integer " \ "multiple of the simulation timestep {}" \ "".format(sampling_interval, step) raise ConfigurationException(msg) if rate > MAX_RATE: msg = "sampling_interval {} higher than max allowed which is {}" \ "".format(sampling_interval, step * MAX_RATE) raise ConfigurationException(msg) return sampling_interval
def _turn_off_recording(self, variable, sampling_interval, remove_indexes): if self._sampling_rates[variable] == 0: # Already off so ignore other parameters return if remove_indexes is None: # turning all off so ignoring sampling interval self._sampling_rates[variable] = 0 self._indexes[variable] = None return # No good reason to specify_interval when turning off if sampling_interval is not None: rate = self._compute_rate(sampling_interval) # But if they do make sure it is the same as before if rate != self._sampling_rates[variable]: raise ConfigurationException( "Illegal sampling_interval parameter while turning " "off recording") if self._indexes[variable] is None: # start with all indexes self._indexes[variable] = range(self._n_neurons) # remove the indexes not recording self._indexes[variable] = \ [index for index in self._indexes[variable] if index not in remove_indexes] # Check is at least one index still recording if len(self._indexes[variable]) == 0: self._sampling_rates[variable] = 0 self._indexes[variable] = None
def __call__(self, transceiver, placements, has_ran, provenance_data_objects=None): """ :param transceiver: the SpiNNMan interface object :param placements: The placements of the vertices :param has_ran: token that states that the simulation has ran """ if not has_ran: raise ConfigurationException( "This function has been called before the simulation has ran." " This is deemed an error, please rectify and try again") if provenance_data_objects is not None: prov_items = provenance_data_objects else: prov_items = list() progress = ProgressBar(placements.n_placements, "Getting provenance data") # retrieve provenance data from any cores that provide data for placement in progress.over(placements.placements): if isinstance(placement.vertex, AbstractProvidesProvenanceDataFromMachine): # get data prov_items.extend( placement.vertex.get_provenance_data_from_machine( transceiver, placement)) return prov_items
def __call__(self, executable_targets, app_id, transceiver, loaded_application_data_token, generated_connectors_on_machine_token): """ Go through the executable targets and load each binary to \ everywhere and then send a start request to the cores that \ actually use it """ if not loaded_application_data_token: raise ConfigurationException( "The token for having loaded the application data token is set" " to false and therefore I cannot run. Please fix and try " "again") if not generated_connectors_on_machine_token: raise exceptions.ConfigurationException( "The token for generating connectors on machine token is set" " to false and therefore I cannot run. Please fix and try " "again") progress = ProgressBar(executable_targets.total_processors + 1, "Loading executables onto the machine") for binary in executable_targets.binaries: progress.update( self._launch_binary(executable_targets, binary, transceiver, app_id)) self._start_simulation(executable_targets, transceiver, app_id) progress.update() progress.end() return True
def is_recording(self, variable): try: return self._sampling_rates[variable] > 0 except KeyError as e: msg = "Variable {} is not supported. Supported variables are {}" \ "".format(variable, self.get_recordable_variables()) raise_from(ConfigurationException(msg), e)
def convert_param_to_numpy(param, no_atoms): """ Convert parameters into numpy arrays :param param: the param to convert :param no_atoms: the number of atoms available for conversion of param :return numpy.array: the converted param in whatever format it was given """ # Deal with random distributions by generating values if globals_variables.get_simulator().is_a_pynn_random(param): # numpy reduces a single valued array to a single value, so enforce # that it is an array param_value = param.next(n=no_atoms) if hasattr(param_value, '__iter__'): return numpy.array(param_value, dtype="float") return numpy.array([param_value], dtype="float") # Deal with a single value by exploding to multiple values if not hasattr(param, '__iter__'): return numpy.array([param] * no_atoms, dtype="float") # Deal with multiple values, but not the correct number of them if len(param) != no_atoms: raise ConfigurationException( "The number of params does not equal with the number of atoms in" " the vertex") # Deal with the correct number of multiple values return numpy.array(param, dtype="float")
def _calculate_power_down_energy(cls, time, machine, job, version, n_frames): """ Calculate power down costs :param float time: time powered down, in milliseconds :param ~.Machine machine: :param AbstractMachineAllocationController job: the spalloc job object :param int version: :param int n_frames: number of frames used by this machine :return: energy in joules :rtype: float """ # pylint: disable=too-many-arguments # if spalloc or hbp if job is not None: return time * n_frames * cls.MILLIWATTS_FOR_FRAME_IDLE_COST # if 48 chip elif version == 5 or version == 4: return time * cls.MILLIWATTS_FOR_BOXED_48_CHIP_FRAME_IDLE_COST # if 4 chip elif version == 3 or version == 2: return machine.n_chips * time * cls.MILLIWATTS_PER_IDLE_CHIP # boom else: raise ConfigurationException("don't know what to do here")
def set_retina_transmission(self, retina_key=RetinaKey.NATIVE_128_X_128, retina_payload=None, time=None): """ Set the retina transmission key :param retina_key: the new key for the retina :param retina_payload: \ the new payload for the set retina key command packet :type retina_payload: enum or None :param time: when to transmit this packet :return: the command to send :rtype: \ :py:class:`spinn_front_end_common.utility_models.multi_cast_command.MultiCastCommand` """ if retina_key == RetinaKey.FIXED_KEY and retina_payload is None: retina_payload = RetinaPayload.EVENTS_IN_PAYLOAD if retina_payload is None: retina_payload = RetinaPayload.NO_PAYLOAD if (retina_key == RetinaKey.FIXED_KEY and retina_payload != RetinaPayload.EVENTS_IN_PAYLOAD): raise ConfigurationException( "If the Retina Key is FIXED_KEY, the payload must be" " EVENTS_IN_PAYLOAD") return MultiCastCommand(key=self.set_retina_transmission_key, payload=retina_key.value | retina_payload.value, time=time)
def get_data(self, variable, run_time, placements, graph_mapper, buffer_manager, local_time_period_map): if variable == DRNLMachineVertex.MOC: return self._drnl_neuron_recorder.get_matrix_data( self._label, buffer_manager, DRNLMachineVertex.MOC_RECORDABLE_REGION_ID, placements, graph_mapper, self, variable, run_time, local_time_period_map) elif variable == IHCANMachineVertex.SPIKE_PROB: matrix_data = self._ihcan_neuron_recorder.get_matrix_data( self._label, buffer_manager, IHCANMachineVertex. RECORDING_REGIONS.SPIKE_PROBABILITY_REGION_ID.value, placements, graph_mapper, self, variable, run_time, local_time_period_map) # convert to n fibers per time step. new_matrix_data = list() for element in matrix_data[0]: seq_elements = list() for seq_index in range(0, self._model.seq_size): seq_elements.append( element[0 + seq_index::self._model.seq_size]) for time_step in seq_elements: new_matrix_data.append(time_step) return new_matrix_data, matrix_data[1][0:10], matrix_data[2] elif variable == IHCANMachineVertex.SPIKES: return self._ihcan_neuron_recorder.get_spikes( self._label, buffer_manager, IHCANMachineVertex. RECORDING_REGIONS.SPIKE_RECORDING_REGION_ID.value, placements, graph_mapper, self, run_time) else: raise ConfigurationException(self.RECORDING_ERROR.format(variable))
def _send_read_notification(self, database_path): """ sends notifications to a list of socket addresses that the\ database has been written. Message also includes the path to the\ database :param database_path: the path to the database :rtype: None """ # noinspection PyBroadException if database_path is not None: try: self._sent_visualisation_confirmation = True # add file path to database into command message. number_of_chars = len(database_path) if number_of_chars > MAX_DATABASE_PATH_LENGTH: raise ConfigurationException( "The file path to the database is too large to be " "transmitted via the command packet, " "please set the file path manually and " "set the .cfg parameter [Database] send_file_path " "to False") eieio_command_message = DatabaseConfirmation(database_path) # Send command and wait for response logger.info( "*** Notifying external sources that the database is " "ready for reading ***") # noinspection PyBroadException for connection in self._data_base_message_connections: try: connection.send_eieio_message(eieio_command_message) except Exception: logger.warning( "*** Failed to notify external application on" " {}:{} about the database ***".format( connection.remote_ip_address, connection.remote_port)) # if the system needs to wait, try receiving a packet back if self._wait_for_read_confirmation: for connection in self._data_base_message_connections: try: connection.receive_eieio_message() logger.info("*** Confirmation from {}:{} received," " continuing ***".format( connection.remote_ip_address, connection.remote_port)) except Exception: logger.warning( "*** Failed to receive notification from" " external application on" " {}:{} about the database ***".format( connection.remote_ip_address, connection.remote_port)) except Exception: traceback.print_exc()
def _find_closest_live_packet_gatherer(machine_vertex, machine_lpgs, machine, placements): """ Locates the LPG on the nearest Ethernet-connected chip to the\ machine vertex in question, or the LPG on 0, 0 if a closer one\ can't be found. :param machine_vertex: the machine vertex to locate the nearest LPG to :param machine_lpgs: dict of gatherers by chip placed on :param machine: the SpiNNaker machine object :param placements: the placements object :return: the local LPG :raise ConfigurationException: if a local gatherer cannot be found """ # locate location of vertex in machine placement = placements.get_placement_of_vertex(machine_vertex) chip = machine.get_chip_at(placement.x, placement.y) # locate closest LPG if (chip.nearest_ethernet_x, chip.nearest_ethernet_y) in machine_lpgs: return machine_lpgs[chip.nearest_ethernet_x, chip.nearest_ethernet_y] if (0, 0) in machine_lpgs: return machine_lpgs[0, 0] # if got through all LPG vertices and not found the right one. go BOOM raise ConfigurationException( "Cannot find a Live Packet Gatherer from {} for the vertex {}" " located {}:{}".format(machine_lpgs, machine_vertex, chip.x, chip.y))
def __init__(self, p_connect, allow_self_connections=True, safe=True, verbose=False): """ :param p_connect: a float between zero and one. Each potential connection is created\ with this probability. :type p_connect: float :param allow_self_connections: if the connector is used to connect a Population to itself, this\ flag determines whether a neuron is allowed to connect to itself,\ or only to other neurons in the Population. :type allow_self_connections: bool :param `pyNN.Space` space: a Space object, needed if you wish to specify distance-dependent\ weights or delays - not implemented """ super(FixedProbabilityConnector, self).__init__(safe, verbose) self._p_connect = p_connect self._allow_self_connections = allow_self_connections if not 0 <= self._p_connect <= 1: raise ConfigurationException( "The probability must be between 0 and 1 (inclusive)")
def get_data(self): txrx = self.front_end.transceiver() placement = self.placement n_steps = self.front_end.no_machine_time_steps() # Get the data region base address where results are stored for the # core record_region_base_address = locate_memory_region_for_placement( placement, DataRegions.RESULTS, txrx) # find how many bytes are needed to be read number_of_bytes_to_read = txrx.read_word(placement.x, placement.y, record_region_base_address) expected_bytes = n_steps * self.RECORDING_ELEMENT_SIZE if number_of_bytes_to_read != expected_bytes: raise ConfigurationException( "number of bytes seems wrong; have {} but expected {}".format( number_of_bytes_to_read, expected_bytes)) # read the bytes raw_data = txrx.read_memory( placement.x, placement.y, record_region_base_address + self.RECORDING_HEADER_SIZE, number_of_bytes_to_read) # convert to booleans return [ bool(element) for element in n_word_struct(n_steps).unpack(raw_data) ]
def get_message_translator(self): if self.__message_translator is None: raise ConfigurationException( "This population was not given a translator, and so cannot be" "used for Ethernet communication. Please provide a " "translator for the population.") return self.__message_translator
def __init__( self, size, cellclass, cellparams=None, structure=None, initial_values=None, label=None, constraints=None, additional_parameters=None): # pylint: disable=too-many-arguments # hard code initial values as required if initial_values is None: initial_values = {} model = cellclass if inspect.isclass(cellclass): if cellparams is None: model = cellclass() else: model = cellclass(**cellparams) elif cellparams: raise ConfigurationException( "cellclass is an instance which includes params so " "cellparams must be None") self._celltype = model # build our initial objects super(Population, self).__init__( spinnaker_control=globals_variables.get_simulator(), size=size, label=label, constraints=constraints, model=model, structure=structure, initial_values=initial_values, additional_parameters=additional_parameters) Recorder.__init__(self, population=self) # annotations used by neo objects self._annotations = dict()
def __init__(self, p_connect, allow_self_connections=True, safe=True, callback=None, verbose=False, rng=None): """ :param float p_connect: a float between zero and one. Each potential connection is created\ with this probability. :param bool allow_self_connections: if the connector is used to connect a Population to itself, this\ flag determines whether a neuron is allowed to connect to itself,\ or only to other neurons in the Population. :param bool safe: :param callable callback: Ignored :param bool verbose: :param rng: Seeded random number generator, or None to make one when needed :type rng: ~pyNN.random.NumpyRNG or None """ super(FixedProbabilityConnector, self).__init__(safe, callback, verbose) self._p_connect = p_connect self.__allow_self_connections = allow_self_connections self._rng = rng if not 0 <= self._p_connect <= 1: raise ConfigurationException( "The probability must be between 0 and 1 (inclusive)")
def _determine_simulation_sync_signals(executable_types, no_sync_changes): """ Determines the start states, and creates core subsets of the\ states for further checks. :param no_sync_changes: sync counter :param executable_types: the types of executables :return: the sync signal and updated no_sync_changes """ sync_signal = None if ExecutableType.USES_SIMULATION_INTERFACE in executable_types: if no_sync_changes % 2 == 0: sync_signal = Signal.SYNC0 else: sync_signal = Signal.SYNC1 # when it falls out of the running, it'll be in a next sync \ # state, thus update needed no_sync_changes += 1 # handle the sync states, but only send once if they work with \ # the simulation interface requirement if ExecutableType.SYNC in executable_types: if sync_signal == Signal.SYNC1: raise ConfigurationException( "There can only be one SYNC signal per run. This is " "because we cannot ensure the cores have not reached the " "next SYNC state before we send the next SYNC. Resulting " "in uncontrolled behaviour") sync_signal = Signal.SYNC0 no_sync_changes += 1 return sync_signal, no_sync_changes
def convert_param_to_numpy(param, no_atoms): """ Convert parameters into numpy arrays. :param param: the param to convert :type param: ~pyNN.random.NumpyRNG or int or float or list(int) or list(float) or ~numpy.ndarray :param int no_atoms: the number of atoms available for conversion of param :return: the converted param as an array of floats :rtype: ~numpy.ndarray(float) """ # Deal with random distributions by generating values if isinstance(param, RandomDistribution): # numpy reduces a single valued array to a single value, so enforce # that it is an array param_value = param.next(n=no_atoms) if hasattr(param_value, '__iter__'): return numpy.array(param_value, dtype="float") return numpy.array([param_value], dtype="float") # Deal with a single value by exploding to multiple values if not hasattr(param, '__iter__'): return numpy.array([param] * no_atoms, dtype="float") # Deal with multiple values, but not the correct number of them if len(param) != no_atoms: raise ConfigurationException( "The number of params does not equal with the number of atoms in" " the vertex") # Deal with the correct number of multiple values return numpy.array(param, dtype="float")
def is_recording(self, variable): if variable == DRNLMachineVertex.MOC: return self._drnl_neuron_recorder.is_recording(variable) elif variable in IHCANMachineVertex.RECORDABLES: return self._ihcan_neuron_recorder.is_recording(variable) else: raise ConfigurationException(self.RECORDING_ERROR.format(variable))
def __init__(self, speaker, protocol, start_active_time=0, start_total_period=0, start_frequency=0, start_melody=None, timesteps_between_send=None): """ :param speaker: The PushBotSpeaker value to control :param protocol: The protocol instance to get commands from :param start_active_time: The "active time" to set at the start :param start_total_period: The "total period" to set at the start :param start_frequency: The "frequency" to set at the start :param start_melody: The "melody" to set at the start :param timesteps_between_send:\ The number of timesteps between sending commands to the device,\ or None to use the default """ # pylint: disable=too-many-arguments if not isinstance(speaker, PushBotSpeaker): raise ConfigurationException( "speaker parameter must be a PushBotSpeaker value") super(PushBotEthernetSpeakerDevice, self).__init__(protocol, speaker, True, timesteps_between_send) # protocol specific data items self._command_protocol = protocol self._start_active_time = start_active_time self._start_total_period = start_total_period self._start_frequency = start_frequency self._start_melody = start_melody
def _find_closest_live_packet_gatherer(self, m_vertex, lpg_params): """ Locates the LPG on the nearest Ethernet-connected chip to the\ machine vertex in question, or the LPG on 0, 0 if a closer one\ can't be found. :param ~.MachineVertex m_vertex: the machine vertex to locate the nearest LPG to :param LivePacketGatherParameters lpg_params: parameters to decide what LPG is to be used :return: the local LPG :rtype: LivePacketGatherMachineVertex :raise ConfigurationException: if a local gatherer cannot be found """ # locate location of vertex in machine placement = self._placements.get_placement_of_vertex(m_vertex) chip = self._machine.get_chip_at(placement.x, placement.y) # locate closest LPG machine_lpgs = self._lpg_to_vertex[lpg_params] chip_key = (chip.nearest_ethernet_x, chip.nearest_ethernet_y) if chip_key in machine_lpgs: return machine_lpgs[chip_key] # Fallback to the root (better than total failure) if (0, 0) in machine_lpgs: return machine_lpgs[0, 0] # if got through all LPG vertices and not found the right one. go BOOM raise ConfigurationException( "Cannot find a Live Packet Gatherer from {} for the vertex {}" " located on {}:{}".format(machine_lpgs, m_vertex, chip.x, chip.y))
def __call__(self, txrx, app_id, all_core_subsets): # check that the right number of processors are in sync processors_completed = txrx.get_core_state_count( app_id, CPUState.FINISHED) total_processors = len(all_core_subsets) left_to_do_cores = total_processors - processors_completed progress = ProgressBar( left_to_do_cores, "Forcing error cores to generate provenance data") error_cores = txrx.get_cores_in_state(all_core_subsets, CPUState.RUN_TIME_EXCEPTION) watchdog_cores = txrx.get_cores_in_state(all_core_subsets, CPUState.WATCHDOG) idle_cores = txrx.get_cores_in_state(all_core_subsets, CPUState.IDLE) if error_cores or watchdog_cores or idle_cores: raise ConfigurationException( "Some cores have crashed. RTE cores {}, watch-dogged cores {}," " idle cores {}".format(error_cores.values(), watchdog_cores.values(), idle_cores.values())) # check that all cores are in the state FINISHED which shows that # the core has received the message and done provenance updating self._update_provenance(txrx, total_processors, processors_completed, all_core_subsets, app_id, progress) progress.end()