From fc517e4a75ec9263d217b356c08d10c2d520695f Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Fri, 20 Feb 2026 10:19:59 +0000 Subject: [PATCH 1/7] Typed semantic sugar for an additional_parameter --- .../pyNN/models/populations/population.py | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index 31bc036c540..b403dc983ec 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -35,6 +35,8 @@ from spinn_utilities.logger_utils import warn_once from spinn_utilities.overrides import overrides +from pacman.model.partitioner_splitters import AbstractSplitterCommon + from spinn_front_end_common.utilities.exceptions import ConfigurationException from spynnaker.pyNN.data import SpynnakerDataView @@ -84,6 +86,15 @@ def __init__( structure: Optional[BaseStructure] = None, initial_values: Optional[Dict[str, float]] = None, label: Optional[str] = None, + *, + max_rate: Optional[float] = None, + n_colour_bits: Optional[int] = None, + neurons_per_core: Optional[Union[int, Tuple[int, ...]]] = None, + port: Optional[int] = None, + reserve_reverse_ip_tag: Optional[bool] = None, + seed: Optional[int] = None, + splitter: Optional[AbstractSplitterCommon] = None, + virtual_key: Optional[int] = None, additional_parameters: Optional[_ParamDict] = None, **additional_kwargs: _ParamDict): """ @@ -95,10 +106,26 @@ def __init__( :param structure: :param initial_values: Initial values of state variables :param label: A label for the population + :param max_rate: Typed semantic sugar for an additional_parameter + :param n_colour_bits: Typed semantic sugar for an additional_parameter + :param neurons_per_core: Typed semantic sugar for an additional_parameter + :param port: Typed semantic sugar for an additional_parameter + :param reserve_reverse_ip_tag: + Typed semantic sugar for an additional_parameter + :param seed: Typed semantic sugar for an additional_parameter + :param splitter: Typed semantic sugar for an additional_parameter + :param virtual_key: Typed semantic sugar for an additional_parameter :param additional_parameters: Additional parameters to pass to the vertex creation function. + See the Moodel's create_vertex for more details. + These will be ignored if the Model does not accept this parameter. + These will raise an Exception if a Vertex is passed in + There may be additional parameters not listed in this init. + Values passed in as key=value take precedent over any + in an additional_parameter= dict :param additional_kwargs: - A nicer way of allowing additional things + A nicer way of passing in any other additional_parameters + not specifically declared here. """ # Deal with the kwargs! additional: _ParamDict = dict() @@ -106,6 +133,22 @@ def __init__( additional.update(additional_parameters) if additional_kwargs: additional.update(additional_kwargs) + if max_rate is not None: + additional['max_rate'] = max_rate + if n_colour_bits is not None: + additional['n_colour_bits'] = n_colour_bits + if neurons_per_core is not None: + additional['neurons_per_core'] = neurons_per_core + if port is not None: + additional['port'] = port + if reserve_reverse_ip_tag is not None: + additional['reserve_reverse_ip_tag'] = reserve_reverse_ip_tag + if seed is not None: + additional['seed'] = seed + if splitter is not None: + additional['splitter'] = splitter + if virtual_key is not None: + additional['virtual_key'] = virtual_key # build our initial objects self.__celltype: AbstractPyNNModel From 0693edd66653226f6ef3194ac5fb8261e3582dd6 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Fri, 20 Feb 2026 12:35:05 +0000 Subject: [PATCH 2/7] remove star in params --- spynnaker/pyNN/models/populations/population.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index b403dc983ec..2cb297827d3 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -86,7 +86,6 @@ def __init__( structure: Optional[BaseStructure] = None, initial_values: Optional[Dict[str, float]] = None, label: Optional[str] = None, - *, max_rate: Optional[float] = None, n_colour_bits: Optional[int] = None, neurons_per_core: Optional[Union[int, Tuple[int, ...]]] = None, @@ -108,7 +107,8 @@ def __init__( :param label: A label for the population :param max_rate: Typed semantic sugar for an additional_parameter :param n_colour_bits: Typed semantic sugar for an additional_parameter - :param neurons_per_core: Typed semantic sugar for an additional_parameter + :param neurons_per_core: + Typed semantic sugar for an additional_parameter :param port: Typed semantic sugar for an additional_parameter :param reserve_reverse_ip_tag: Typed semantic sugar for an additional_parameter @@ -117,7 +117,7 @@ def __init__( :param virtual_key: Typed semantic sugar for an additional_parameter :param additional_parameters: Additional parameters to pass to the vertex creation function. - See the Moodel's create_vertex for more details. + See the Model's create_vertex method for more details. These will be ignored if the Model does not accept this parameter. These will raise an Exception if a Vertex is passed in There may be additional parameters not listed in this init. From b376025c82a744b5ca662aa57ba50fb2b793e9ae Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Fri, 20 Feb 2026 14:14:01 +0000 Subject: [PATCH 3/7] changes to please mypy --- spynnaker/pyNN/external_devices/__init__.py | 23 ++++++++++++++----- .../pyNN/models/populations/population.py | 6 ++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/spynnaker/pyNN/external_devices/__init__.py b/spynnaker/pyNN/external_devices/__init__.py index a7542d41c3e..a883cb54fd5 100644 --- a/spynnaker/pyNN/external_devices/__init__.py +++ b/spynnaker/pyNN/external_devices/__init__.py @@ -207,6 +207,7 @@ def EthernetControlPopulation( local_host: Optional[str] = None, local_port: Optional[int] = None, database_notify_port_num: Optional[int] = None, database_ack_port_num: Optional[int] = None, + n_synapse_cores: Optional[int] = None, **additional_kwargs: Dict[str, Any]) -> Population: # pylint: disable=invalid-name """ @@ -227,8 +228,13 @@ def EthernetControlPopulation( :param database_notify_port_num: The optional port to which notifications from the database notification protocol are to be sent + :param n_synapse_cores: Typed semantic sugar for an additional_kwargs :param additional_kwargs: - A nicer way of allowing additional things to the Population + Additional parameters to pass to the vertex creation function. + See the Model's create_vertex method for more details. + These will be ignored if the Model does not accept this parameter. + These will raise an Exception if a Vertex is passed in + There may be additional parameters not listed in this init. :return: A pyNN Population which can be used as the target of a Projection. @@ -237,9 +243,14 @@ def EthernetControlPopulation( Projection, but it might not send spikes. :raises TypeError: If an invalid model class is used. """ + additional: Dict[str, Any] = dict() + if additional_kwargs: + additional.update(additional_kwargs) + if n_synapse_cores is not None: + additional['n_synapse_cores'] = n_synapse_cores # pylint: disable=global-statement population = Population(n_neurons, model, label=label, - **additional_kwargs) + additional_parameters=additional) vertex, aec, vertex_label = __vtx(population) translator = aec.get_message_translator() live_packet_gather_label = "EthernetControlReceiver" @@ -306,13 +317,13 @@ def EthernetSensorPopulation( if not isinstance(device, AbstractEthernetSensor): raise TypeError( "Device must be an instance of AbstractEthernetSensor") - injector_params = dict(device.get_injector_parameters()) - + additional_parameters = dict(device.get_injector_parameters()) + if additional_kwargs: + additional_parameters.update(additional_kwargs) population = Population( device.get_n_neurons(), SpikeInjector(notify=False), label=device.get_injector_label(), - additional_parameters=injector_params, - **additional_kwargs) + additional_parameters=additional_parameters) if isinstance(device, AbstractSendMeMulticastCommandsVertex): cmd_conn = EthernetCommandConnection( device.get_translator(), [device], local_host, diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index 2cb297827d3..584566bc00a 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -86,8 +86,9 @@ def __init__( structure: Optional[BaseStructure] = None, initial_values: Optional[Dict[str, float]] = None, label: Optional[str] = None, - max_rate: Optional[float] = None, + *, max_rate: Optional[float] = None, n_colour_bits: Optional[int] = None, + n_synapse_cores: Optional[int] = None, neurons_per_core: Optional[Union[int, Tuple[int, ...]]] = None, port: Optional[int] = None, reserve_reverse_ip_tag: Optional[bool] = None, @@ -107,6 +108,7 @@ def __init__( :param label: A label for the population :param max_rate: Typed semantic sugar for an additional_parameter :param n_colour_bits: Typed semantic sugar for an additional_parameter + :param n_synapse_cores: Typed semantic sugar for an additional_parameter :param neurons_per_core: Typed semantic sugar for an additional_parameter :param port: Typed semantic sugar for an additional_parameter @@ -137,6 +139,8 @@ def __init__( additional['max_rate'] = max_rate if n_colour_bits is not None: additional['n_colour_bits'] = n_colour_bits + if n_synapse_cores is not None: + additional['n_synapse_cores'] = n_synapse_cores if neurons_per_core is not None: additional['neurons_per_core'] = neurons_per_core if port is not None: From dcf4ba69b99a468c55c7a6d4ca84033c9ce8ac43 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Fri, 20 Feb 2026 14:27:12 +0000 Subject: [PATCH 4/7] flake8 --- spynnaker/pyNN/models/populations/population.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index 584566bc00a..c9ea04d25d0 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -108,7 +108,8 @@ def __init__( :param label: A label for the population :param max_rate: Typed semantic sugar for an additional_parameter :param n_colour_bits: Typed semantic sugar for an additional_parameter - :param n_synapse_cores: Typed semantic sugar for an additional_parameter + :param n_synapse_cores: + Typed semantic sugar for an additional_parameter :param neurons_per_core: Typed semantic sugar for an additional_parameter :param port: Typed semantic sugar for an additional_parameter From d6aa796eb18ccfaa52f1976754975cf3e2bf1989 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Mon, 23 Feb 2026 07:20:00 +0000 Subject: [PATCH 5/7] Document likely meaning --- .../pyNN/models/populations/population.py | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index c9ea04d25d0..732986941c1 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -106,29 +106,47 @@ def __init__( :param structure: :param initial_values: Initial values of state variables :param label: A label for the population - :param max_rate: Typed semantic sugar for an additional_parameter - :param n_colour_bits: Typed semantic sugar for an additional_parameter + :param max_rate: + Model.create_vertex parameter. + Likely: + The maximum number of spikes for any neuron at any timestamp + :param n_colour_bits: + Model.create_vertex parameter. + Likely: The number of bits to use for colour :param n_synapse_cores: - Typed semantic sugar for an additional_parameter + Model.create_vertex parameter. + Likely: The number of synapse cores; 0 to force combined cores, + or None to allow the system to choose :param neurons_per_core: - Typed semantic sugar for an additional_parameter - :param port: Typed semantic sugar for an additional_parameter + Model.create_vertex parameter. + Likely: A ceiling on + the number of neurons that can be placed on a single core. + :param port: + Model.create_vertex parameter. + Likely: The live input portthe vertex receives spikes on :param reserve_reverse_ip_tag: - Typed semantic sugar for an additional_parameter - :param seed: Typed semantic sugar for an additional_parameter - :param splitter: Typed semantic sugar for an additional_parameter - :param virtual_key: Typed semantic sugar for an additional_parameter + Model.create_vertex parameter. + Likely: Extra flag for input without a reserved port + :param seed: + Model.create_vertex parameter. + Likely: The Population seed, + used to ensure the same random generation on each run. + :param splitter: + Model.create_vertex parameter. + Likely: splitter from application vertices to machine vertices + :param virtual_key: + Model.create_vertex parameter. + Likely: + The virtual_key of the population to identify the population. :param additional_parameters: - Additional parameters to pass to the vertex creation function. - See the Model's create_vertex method for more details. - These will be ignored if the Model does not accept this parameter. - These will raise an Exception if a Vertex is passed in - There may be additional parameters not listed in this init. - Values passed in as key=value take precedent over any - in an additional_parameter= dict + Alternative way of entering Model.create_vertex parameter. + Ignored if also provided as a named parameter. :param additional_kwargs: - A nicer way of passing in any other additional_parameters - not specifically declared here. + Additional Model.create_vertex parameters. + See the Model's create_vertex method for more details. + create_vertex parameters will be ignored if + the Model does not accept this parameter, + or raise an Exception if a Vertex is passed in """ # Deal with the kwargs! additional: _ParamDict = dict() From 27e99637eb5d147bc396c1aeba9db6582709ffc6 Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Mon, 23 Feb 2026 07:30:14 +0000 Subject: [PATCH 6/7] spelling --- spynnaker/pyNN/models/populations/population.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spynnaker/pyNN/models/populations/population.py b/spynnaker/pyNN/models/populations/population.py index 732986941c1..e5e9350a602 100644 --- a/spynnaker/pyNN/models/populations/population.py +++ b/spynnaker/pyNN/models/populations/population.py @@ -123,7 +123,7 @@ def __init__( the number of neurons that can be placed on a single core. :param port: Model.create_vertex parameter. - Likely: The live input portthe vertex receives spikes on + Likely: The live input port the vertex receives spikes on :param reserve_reverse_ip_tag: Model.create_vertex parameter. Likely: Extra flag for input without a reserved port From fb556ccaab11df44a485c307a67e614bdb7553db Mon Sep 17 00:00:00 2001 From: "Christian Y. Brenninkmeijer" Date: Mon, 23 Feb 2026 07:43:03 +0000 Subject: [PATCH 7/7] improve docs --- spynnaker/pyNN/external_devices/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spynnaker/pyNN/external_devices/__init__.py b/spynnaker/pyNN/external_devices/__init__.py index a883cb54fd5..c7b92bf137b 100644 --- a/spynnaker/pyNN/external_devices/__init__.py +++ b/spynnaker/pyNN/external_devices/__init__.py @@ -228,9 +228,12 @@ def EthernetControlPopulation( :param database_notify_port_num: The optional port to which notifications from the database notification protocol are to be sent - :param n_synapse_cores: Typed semantic sugar for an additional_kwargs + :param n_synapse_cores: + Model.create_vertex parameter. + Likely: The number of synapse cores; 0 to force combined cores, + or None to allow the system to choose :param additional_kwargs: - Additional parameters to pass to the vertex creation function. + Additional parameters to pass to the Model.create_vertex function. See the Model's create_vertex method for more details. These will be ignored if the Model does not accept this parameter. These will raise an Exception if a Vertex is passed in