コード例 #1
0
    def __init__(
            self, n_neurons, machine_time_step, timescale_factor, label, port,
            virtual_key=None):

        ReverseIpTagMultiCastSource.__init__(
            self, n_keys=n_neurons, machine_time_step=machine_time_step,
            timescale_factor=timescale_factor, label=label, receive_port=port,
            virtual_key=virtual_key)
コード例 #2
0
    def __init__(
            self, n_neurons, machine_time_step, timescale_factor, label, port,
            virtual_key=None):

        ReverseIpTagMultiCastSource.__init__(
            self, n_keys=n_neurons, machine_time_step=machine_time_step,
            timescale_factor=timescale_factor, label=label, receive_port=port,
            virtual_key=virtual_key)
        AbstractProvidesOutgoingPartitionConstraints.__init__(self)
コード例 #3
0
 def get_number_of_mallocs_used_by_dsg(self, vertex_slice, in_edges):
     mallocs = \
         ReverseIpTagMultiCastSource.get_number_of_mallocs_used_by_dsg(
             self, vertex_slice, in_edges)
     if config.getboolean("SpecExecution", "specExecOnHost"):
         return 1
     else:
         return mallocs
コード例 #4
0
 def get_number_of_mallocs_used_by_dsg(self, vertex_slice, in_edges):
     mallocs = \
         ReverseIpTagMultiCastSource.get_number_of_mallocs_used_by_dsg(
             self, vertex_slice, in_edges)
     if config.getboolean("SpecExecution", "specExecOnHost"):
         return 1
     else:
         return mallocs
コード例 #5
0
    def __init__(
            self, n_neurons, spike_times, machine_time_step, timescale_factor,
            port=None, tag=None, ip_address=None, board_address=None,
            max_on_chip_memory_usage_for_spikes_in_bytes=(
                constants.SPIKE_BUFFER_SIZE_BUFFERING_IN),
            space_before_notification=640,
            constraints=None, label="SpikeSourceArray",
            spike_recorder_buffer_size=(
                constants.EIEIO_SPIKE_BUFFER_SIZE_BUFFERING_OUT),
            buffer_size_before_receive=(
                constants.EIEIO_BUFFER_SIZE_BEFORE_RECEIVE)):
        self._ip_address = ip_address
        if ip_address is None:
            self._ip_address = config.get("Buffers", "receive_buffer_host")
        self._port = port
        if port is None:
            self._port = config.getint("Buffers", "receive_buffer_port")

        ReverseIpTagMultiCastSource.__init__(
            self, n_keys=n_neurons, machine_time_step=machine_time_step,
            timescale_factor=timescale_factor, label=label,
            constraints=constraints,
            max_atoms_per_core=(SpikeSourceArray.
                                _model_based_max_atoms_per_core),
            board_address=board_address,
            receive_port=None, receive_sdp_port=None, receive_tag=None,
            virtual_key=None, prefix=None, prefix_type=None, check_keys=False,
            send_buffer_times=spike_times,
            send_buffer_max_space=max_on_chip_memory_usage_for_spikes_in_bytes,
            send_buffer_space_before_notify=space_before_notification,
            send_buffer_notification_ip_address=self._ip_address,
            send_buffer_notification_port=self._port,
            send_buffer_notification_tag=tag)
        AbstractSpikeRecordable.__init__(self)

        # handle recording
        self._spike_recorder = EIEIOSpikeRecorder(machine_time_step)
        self._spike_recorder_buffer_size = spike_recorder_buffer_size
        self._buffer_size_before_receive = buffer_size_before_receive
コード例 #6
0
    def __init__(self, n_neurons, machine_time_step, timescale_factor,
                 label, images=None, 
                 port=12345, virtual_key=None,
                 spikes_per_second=0, ring_buffer_sigma=None, 
                 database_socket=None, 
                 behaviour="SACCADE", max_saccade_distance=1,
                 frames_per_microsaccade = 1, frames_per_saccade = 29, #~30
                 total_on_time_ms = 1000, inter_off_time_ms = 100,
                 background_gray = 0,
                 fps=90, mode="128", scale_img=True, polarity="MERGED",
                 inhibition = False, inh_area_width = 2,
                 threshold=12, adaptive_threshold = False,
                 min_threshold=6, max_threshold=168,
                 threshold_delta_down = 2, threshold_delta_up = 12,
                 output_type="TIME", num_bits_per_spike=5, 
                 history_weight=0.99, save_spikes=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population
        
        """
        
        
        self._loaded_idx = 0
        self._total_images = 0
        self._image_list = self.get_images_paths(images)
        
        fixed_n_neurons = n_neurons

        if mode == ExternalImageDvsEmulatorDevice.MODE_128 or \
           mode == ExternalImageDvsEmulatorDevice.MODE_64  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_32  or \
           mode == ExternalImageDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalImageDvsEmulatorDevice.UP_POLARITY or
            polarity == ExternalImageDvsEmulatorDevice.DOWN_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2*(self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn("The specified number of neurons for the DVS emulator"
                        " device has been ignored {} will be used instead"
                        .format(fixed_n_neurons))

        self._center_x = 0
        self._center_y = 0
        
        self._max_saccade_distance = max_saccade_distance
        self._frames_per_microsaccade = frames_per_microsaccade
        self._frames_per_saccade = frames_per_saccade
        self._traverse_speed = (self._out_res*2.)/((total_on_time_ms/1000.)*fps)
        
        self._behaviour = behaviour
        self._total_on_time_ms = total_on_time_ms
        self._inter_off_time_ms = inter_off_time_ms
        self._background_gray = background_gray
        
        self._polarity = polarity
        self._polarity_n = ExternalImageDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type
        
        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None
        
        self._ref_frame = 128*numpy.ones((self._out_res, self._out_res), dtype=int16) 
        
        self._curr_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._moved_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        self._silence_frame = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes_frame = numpy.zeros((self._out_res, self._out_res, 3), dtype=uint8)
        
        self._diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._abs_diff = numpy.zeros((self._out_res, self._out_res), dtype=int16)
        
        self._spikes = numpy.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        
        self._thresh_matrix = None
        if adaptive_threshold:
          self._thresh_matrix = numpy.zeros((self._out_res, self._out_res), 
                                             dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)
        
        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None
        
        self._threshold = int16(threshold)
        
        self._data_shift = uint8(numpy.log2(self._out_res))
        self._up_down_shift = uint8(2*self._data_shift)
        self._data_mask = uint8(self._out_res - 1)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8 #8-bit images don't need more
        elif self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6 #should be enough?
        else:
            self._num_bins = int(1000./fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)
        
        if self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalImageDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, self._num_bins)
        else:
            self._log2_table = generate_log2_table(self._num_bits_per_spike, 8) #stupid hack, compatibility issues
            
        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._half_frame = fps/2
        self._max_time_ms = int16((1./fps)*1000)
        
        self._time_per_spike_pack_ms = self.calculate_time_per_pack()
        
        self._get_sizes = True
        self._scale_changed = False
        
        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port
        
        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        
        self._history_weight = history_weight
        
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(self, 
                n_neurons=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(self, 
                n_keys=self._n_neurons, 
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor, 
                label=self._label, 
                receive_port=self._local_port,
                virtual_key=virtual_key)
        
        AbstractProvidesOutgoingConstraints.__init__(self)

        print "number of neurons for webcam = %d"%self._n_neurons
        
        self._live_conn = SpynnakerLiveSpikesConnection(send_labels = [self._label, ],
                                                        local_port = self._local_port)
        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s"%(n_neurons, label))
        
        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes
        self._spike_list = []
コード例 #7
0
    def __init__(self,
                 n_neurons,
                 machine_time_step,
                 timescale_factor,
                 database_socket,
                 label,
                 port=12345,
                 virtual_key=None,
                 spikes_per_second=0,
                 ring_buffer_sigma=None,
                 device_id=0,
                 fps=60,
                 mode="128",
                 scale_img=True,
                 polarity="MERGED",
                 inhibition=False,
                 inh_area_width=2,
                 threshold=12,
                 adaptive_threshold=False,
                 min_threshold=6,
                 max_threshold=168,
                 threshold_delta_down=2,
                 threshold_delta_up=12,
                 output_type="TIME",
                 num_bits_per_spike=4,
                 history_weight=0.99,
                 save_spikes=None,
                 run_time_ms=None,
                 local_port=19876):
        """
        :param device_id: int for webcam modes, or string for video file
        :param mode: The retina "mode"
        :param retina_key: The value of the top 16-bits of the key
        :param polarity: The "polarity" of the retina data
        :param machine_time_step: The time step of the simulation
        :param timescale_factor: The timescale factor of the simulation
        :param label: The label for the population
        :param n_neurons: The number of neurons in the population

        """
        fixed_n_neurons = n_neurons

        if mode == ExternalDvsEmulatorDevice.MODE_128 or \
           mode == ExternalDvsEmulatorDevice.MODE_64  or \
           mode == ExternalDvsEmulatorDevice.MODE_32  or \
           mode == ExternalDvsEmulatorDevice.MODE_16:
            self._out_res = int(mode)
            self._res_2x = self._out_res * 2

        else:
            raise exceptions.SpynnakerException("the model does not "
                                                "recongise this mode")

        if (polarity == ExternalDvsEmulatorDevice.UP_POLARITY
                or polarity == ExternalDvsEmulatorDevice.DOWN_POLARITY
                or polarity == ExternalDvsEmulatorDevice.RECTIFIED_POLARITY):
            fixed_n_neurons = self._out_res**2
        else:
            fixed_n_neurons = 2 * (self._out_res**2)

        if fixed_n_neurons != n_neurons and n_neurons is not None:
            logger.warn(
                "The specified number of neurons for the DVS emulator"
                " device has been ignored {} will be used instead".format(
                    fixed_n_neurons))

        self._video_source = None
        self._device_id = device_id
        self._is_virtual_cam = False
        self._polarity = polarity
        self._polarity_n = ExternalDvsEmulatorDevice.POLARITY_DICT[polarity]
        self._global_max = int16(0)
        self._output_type = output_type

        self._raw_frame = None
        self._gray_frame = None
        self._tmp_frame = None

        self._ref_frame = 128 * np.ones(
            (self._out_res, self._out_res), dtype=int16)

        self._curr_frame = np.zeros((self._out_res, self._out_res),
                                    dtype=int16)

        self._spikes_frame = np.zeros((self._out_res, self._out_res, 3),
                                      dtype=uint8)

        self._diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._abs_diff = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._spikes = np.zeros((self._out_res, self._out_res), dtype=int16)

        self._adaptive_threshold = adaptive_threshold
        self._thresh_matrix = None
        if adaptive_threshold:
            self._thresh_matrix = np.zeros((self._out_res, self._out_res),
                                           dtype=int16)

        self._threshold_delta_down = int16(threshold_delta_down)
        self._threshold_delta_up = int16(threshold_delta_up)
        self._max_threshold = int16(max_threshold)
        self._min_threshold = int16(min_threshold)

        self._up_spikes = None
        self._down_spikes = None
        self._spikes_lists = None

        self._threshold = int16(threshold)

        self._data_shift = uint8(np.log2(self._out_res))
        self._up_down_shift = uint8(2 * self._data_shift)
        self._data_mask = uint8(self._out_res - 1)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN:
            self._num_bins = 8  #8-bit images don't need more
        elif self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._num_bins = 6  #should be enough?
        else:
            self._num_bins = int(1000. / fps)

        self._num_bits_per_spike = min(num_bits_per_spike, self._num_bins)

        if self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN or \
           self._output_type == ExternalDvsEmulatorDevice.OUTPUT_TIME_BIN_THR:
            self._log2_table = gs.generate_log2_table(self._num_bits_per_spike,
                                                      self._num_bins)
        else:
            self._log2_table = gs.generate_log2_table(
                self._num_bits_per_spike,
                8)  #stupid hack, compatibility issues

        self._scale_img = scale_img
        self._img_height = 0
        self._img_height_crop_u = 0
        self._img_height_crop_b = 0
        self._img_width = 0
        self._img_width_crop_l = 0
        self._img_width_crop_r = 0
        self._img_ratio = 0.
        self._img_scaled_width = 0
        self._scaled_width = 0
        self._fps = fps
        self._max_time_ms = 0
        self._time_per_frame = 0.

        self._time_per_spike_pack_ms = 0

        self._get_sizes = True
        self._scale_changed = False

        self._running = True

        self._label = label
        self._n_neurons = fixed_n_neurons
        self._local_port = local_port

        self._inh_area_width = inh_area_width
        self._inhibition = inhibition
        self._inh_coords = gs.generate_inh_coords(self._out_res, self._out_res,
                                                  inh_area_width)

        self._history_weight = history_weight

        self._run_time_ms = run_time_ms
        ################################################################

        if spinn_version == "2015.005":
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_neurons=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                port=self._local_port,
                label=self._label,
                virtual_key=virtual_key)
        else:
            ReverseIpTagMultiCastSource.__init__(
                self,
                n_keys=self._n_neurons,
                machine_time_step=machine_time_step,
                timescale_factor=timescale_factor,
                label=self._label,
                receive_port=self._local_port,
                virtual_key=virtual_key)

        AbstractProvidesOutgoingConstraints.__init__(self)

        print("number of neurons for webcam = %d" % self._n_neurons)

        self._live_conn = SpynnakerLiveSpikesConnection(
            send_labels=[
                self._label,
            ], local_port=self._local_port)

        def init(label, n_neurons, run_time_ms, machine_timestep_ms):
            print("Sending %d neuron sources from %s" % (n_neurons, label))

        self._live_conn.add_init_callback(self._label, init)
        self._live_conn.add_start_callback(self._label, self.run)
        self._sender = None

        self._save_spikes = save_spikes
コード例 #8
0
    def __init__(
        self,
        n_neurons,
        machine_time_step,
        timescale_factor,
        spike_times=None,
        port=None,
        tag=None,
        ip_address=None,
        board_address=None,
        max_on_chip_memory_usage_for_spikes_in_bytes=(constants.SPIKE_BUFFER_SIZE_BUFFERING_IN),
        space_before_notification=640,
        constraints=None,
        label="SpikeSourceArray",
        spike_recorder_buffer_size=(constants.EIEIO_SPIKE_BUFFER_SIZE_BUFFERING_OUT),
        buffer_size_before_receive=(constants.EIEIO_BUFFER_SIZE_BEFORE_RECEIVE),
    ):
        self._ip_address = ip_address
        if ip_address is None:
            self._ip_address = config.get("Buffers", "receive_buffer_host")
        self._port = port
        if port is None:
            self._port = config.getint("Buffers", "receive_buffer_port")
        if spike_times is None:
            spike_times = []

        ReverseIpTagMultiCastSource.__init__(
            self,
            n_keys=n_neurons,
            machine_time_step=machine_time_step,
            timescale_factor=timescale_factor,
            label=label,
            constraints=constraints,
            max_atoms_per_core=(SpikeSourceArray._model_based_max_atoms_per_core),
            board_address=board_address,
            receive_port=None,
            receive_sdp_port=None,
            receive_tag=None,
            virtual_key=None,
            prefix=None,
            prefix_type=None,
            check_keys=False,
            send_buffer_times=spike_times,
            send_buffer_max_space=max_on_chip_memory_usage_for_spikes_in_bytes,
            send_buffer_space_before_notify=space_before_notification,
            send_buffer_notification_ip_address=self._ip_address,
            send_buffer_notification_port=self._port,
            send_buffer_notification_tag=tag,
        )
        AbstractSpikeRecordable.__init__(self)
        AbstractProvidesOutgoingEdgeConstraints.__init__(self)
        SimplePopulationSettable.__init__(self)
        AbstractMappable.__init__(self)
        AbstractHasFirstMachineTimeStep.__init__(self)

        # handle recording
        self._spike_recorder = EIEIOSpikeRecorder(machine_time_step)
        self._spike_recorder_buffer_size = spike_recorder_buffer_size
        self._buffer_size_before_receive = buffer_size_before_receive

        # Keep track of any previously generated buffers
        self._send_buffers = dict()
        self._spike_recording_region_size = None
        self._partitioned_vertices = list()
        self._partitioned_vertices_current_max_buffer_size = dict()

        # used for reset and rerun
        self._requires_mapping = True
        self._last_runtime_position = 0

        self._max_on_chip_memory_usage_for_spikes = max_on_chip_memory_usage_for_spikes_in_bytes
        self._space_before_notification = space_before_notification
        if self._max_on_chip_memory_usage_for_spikes is None:
            self._max_on_chip_memory_usage_for_spikes = front_end_common_constants.MAX_SIZE_OF_BUFFERED_REGION_ON_CHIP

        # check the values do not conflict with chip memory limit
        if self._max_on_chip_memory_usage_for_spikes < 0:
            raise exceptions.ConfigurationException(
                "The memory usage on chip is either beyond what is supportable"
                " on the spinnaker board being supported or you have requested"
                " a negative value for a memory usage. Please correct and"
                " try again"
            )

        if self._max_on_chip_memory_usage_for_spikes < self._space_before_notification:
            self._space_before_notification = self._max_on_chip_memory_usage_for_spikes
コード例 #9
0
    def __init__(self,
                 n_neurons,
                 spike_times=default_parameters['spike_times'],
                 port=none_pynn_default_parameters['port'],
                 tag=none_pynn_default_parameters['tag'],
                 ip_address=none_pynn_default_parameters['ip_address'],
                 board_address=none_pynn_default_parameters['board_address'],
                 max_on_chip_memory_usage_for_spikes_in_bytes=DEFAULT1,
                 space_before_notification=none_pynn_default_parameters[
                     'space_before_notification'],
                 constraints=none_pynn_default_parameters['constraints'],
                 label=none_pynn_default_parameters['label'],
                 spike_recorder_buffer_size=none_pynn_default_parameters[
                     'spike_recorder_buffer_size'],
                 buffer_size_before_receive=none_pynn_default_parameters[
                     'buffer_size_before_receive']):

        config = globals_variables.get_simulator().config
        self._ip_address = ip_address
        if ip_address is None:
            self._ip_address = config.get("Buffers", "receive_buffer_host")
        self._port = port
        if port is None:
            self._port = helpful_functions.read_config_int(
                config, "Buffers", "receive_buffer_port")
        if spike_times is None:
            spike_times = []

        ReverseIpTagMultiCastSource.__init__(
            self,
            n_keys=n_neurons,
            label=label,
            constraints=constraints,
            max_atoms_per_core=(
                SpikeSourceArray._model_based_max_atoms_per_core),
            board_address=board_address,
            receive_port=None,
            receive_tag=None,
            virtual_key=None,
            prefix=None,
            prefix_type=None,
            check_keys=False,
            send_buffer_times=spike_times,
            send_buffer_partition_id=constants.SPIKE_PARTITION_ID,
            send_buffer_max_space=max_on_chip_memory_usage_for_spikes_in_bytes,
            send_buffer_space_before_notify=space_before_notification,
            buffer_notification_ip_address=self._ip_address,
            buffer_notification_port=self._port,
            buffer_notification_tag=tag)

        AbstractSpikeRecordable.__init__(self)
        AbstractProvidesOutgoingPartitionConstraints.__init__(self)
        SimplePopulationSettable.__init__(self)
        AbstractChangableAfterRun.__init__(self)
        ProvidesKeyToAtomMappingImpl.__init__(self)

        # handle recording
        self._spike_recorder = EIEIOSpikeRecorder()
        self._spike_recorder_buffer_size = spike_recorder_buffer_size
        self._buffer_size_before_receive = buffer_size_before_receive

        # Keep track of any previously generated buffers
        self._send_buffers = dict()
        self._spike_recording_region_size = None
        self._machine_vertices = list()

        # used for reset and rerun
        self._requires_mapping = True
        self._last_runtime_position = 0

        self._max_on_chip_memory_usage_for_spikes = \
            max_on_chip_memory_usage_for_spikes_in_bytes
        self._space_before_notification = space_before_notification
        if self._max_on_chip_memory_usage_for_spikes is None:
            self._max_on_chip_memory_usage_for_spikes = \
                front_end_common_constants.MAX_SIZE_OF_BUFFERED_REGION_ON_CHIP

        # check the values do not conflict with chip memory limit
        if self._max_on_chip_memory_usage_for_spikes < 0:
            raise exceptions.ConfigurationException(
                "The memory usage on chip is either beyond what is supportable"
                " on the spinnaker board being supported or you have requested"
                " a negative value for a memory usage. Please correct and"
                " try again")

        if (self._max_on_chip_memory_usage_for_spikes <
                self._space_before_notification):
            self._space_before_notification =\
                self._max_on_chip_memory_usage_for_spikes
コード例 #10
0
    def __init__(
            self, n_neurons, machine_time_step, timescale_factor,
            spike_times=None, port=None, tag=None, ip_address=None,
            board_address=None, max_on_chip_memory_usage_for_spikes_in_bytes=(
                constants.SPIKE_BUFFER_SIZE_BUFFERING_IN),
            space_before_notification=640,
            constraints=None, label="SpikeSourceArray",
            spike_recorder_buffer_size=(
                constants.EIEIO_SPIKE_BUFFER_SIZE_BUFFERING_OUT),
            buffer_size_before_receive=(
                constants.EIEIO_BUFFER_SIZE_BEFORE_RECEIVE)):
        self._ip_address = ip_address
        if ip_address is None:
            self._ip_address = config.get("Buffers", "receive_buffer_host")
        self._port = port
        if port is None:
            self._port = config.getint("Buffers", "receive_buffer_port")
        if spike_times is None:
            spike_times = []
        self._minimum_sdram_for_buffering = config.getint(
            "Buffers", "minimum_buffer_sdram")
        self._using_auto_pause_and_resume = config.getboolean(
            "Buffers", "use_auto_pause_and_resume")

        ReverseIpTagMultiCastSource.__init__(
            self, n_keys=n_neurons, machine_time_step=machine_time_step,
            timescale_factor=timescale_factor, label=label,
            constraints=constraints,
            max_atoms_per_core=(SpikeSourceArray.
                                _model_based_max_atoms_per_core),
            board_address=board_address,
            receive_port=None, receive_sdp_port=None, receive_tag=None,
            virtual_key=None, prefix=None, prefix_type=None, check_keys=False,
            send_buffer_times=spike_times,
            send_buffer_max_space=max_on_chip_memory_usage_for_spikes_in_bytes,
            send_buffer_space_before_notify=space_before_notification,
            send_buffer_notification_ip_address=self._ip_address,
            send_buffer_notification_port=self._port,
            send_buffer_notification_tag=tag)

        AbstractSpikeRecordable.__init__(self)
        AbstractProvidesOutgoingPartitionConstraints.__init__(self)
        SimplePopulationSettable.__init__(self)
        AbstractChangableAfterRun.__init__(self)
        AbstractHasFirstMachineTimeStep.__init__(self)

        # handle recording
        self._spike_recorder = EIEIOSpikeRecorder(machine_time_step)
        self._spike_recorder_buffer_size = spike_recorder_buffer_size
        self._buffer_size_before_receive = buffer_size_before_receive

        # Keep track of any previously generated buffers
        self._send_buffers = dict()
        self._spike_recording_region_size = None
        self._partitioned_vertices = list()
        self._partitioned_vertices_current_max_buffer_size = dict()

        # used for reset and rerun
        self._requires_mapping = True
        self._last_runtime_position = 0

        self._max_on_chip_memory_usage_for_spikes = \
            max_on_chip_memory_usage_for_spikes_in_bytes
        self._space_before_notification = space_before_notification
        if self._max_on_chip_memory_usage_for_spikes is None:
            self._max_on_chip_memory_usage_for_spikes = \
                front_end_common_constants.MAX_SIZE_OF_BUFFERED_REGION_ON_CHIP

        # check the values do not conflict with chip memory limit
        if self._max_on_chip_memory_usage_for_spikes < 0:
            raise exceptions.ConfigurationException(
                "The memory usage on chip is either beyond what is supportable"
                " on the spinnaker board being supported or you have requested"
                " a negative value for a memory usage. Please correct and"
                " try again")

        if (self._max_on_chip_memory_usage_for_spikes <
                self._space_before_notification):
            self._space_before_notification =\
                self._max_on_chip_memory_usage_for_spikes