diff --git a/include/genn/genn/synapseGroup.h b/include/genn/genn/synapseGroup.h index 37559134cf..3129188702 100644 --- a/include/genn/genn/synapseGroup.h +++ b/include/genn/genn/synapseGroup.h @@ -142,8 +142,14 @@ class GENN_EXPORT SynapseGroup //! Is this synapse group a weight-sharing slave bool isWeightSharingSlave() const { return (getWeightSharingMaster() != nullptr); } + //! Has this synapse group's postsynaptic model been merged with others + /*! NOTE: this can only be called after model is finalized but needs to be public for PyGeNN */ bool isPSModelMerged() const{ return m_PSModelTargetName != getName(); } + //! Get the type to use for sparse connectivity indices for synapse group + //! /*! NOTE: this can only be called after model is finalized but needs to be public for PyGeNN */ + std::string getSparseIndType() const; + const WeightUpdateModels::Base *getWUModel() const{ return m_WUModel; } const std::vector &getWUParams() const{ return m_WUParams; } @@ -283,10 +289,7 @@ class GENN_EXPORT SynapseGroup /*! This is required when the pre-synaptic neuron population's outgoing synapse groups require different event threshold */ bool isEventThresholdReTestRequired() const{ return m_EventThresholdReTestRequired; } - const std::string &getPSModelTargetName() const{ return m_PSModelTargetName; } - - //! Get the type to use for sparse connectivity indices for synapse group - std::string getSparseIndType() const; + const std::string &getPSModelTargetName() const{ return m_PSModelTargetName; } //! Are any of this synapse group's weight update model variables referenced by a custom update bool areWUVarReferencedByCustomUpdate() const { return m_WUVarReferencedByCustomUpdate; } diff --git a/pygenn/genn_groups.py b/pygenn/genn_groups.py index 17491951fa..99f1659f65 100644 --- a/pygenn/genn_groups.py +++ b/pygenn/genn_groups.py @@ -1050,7 +1050,7 @@ def load(self): # Get pointers to ragged data structure members ind = self._assign_ext_ptr_array("ind", self.weight_update_var_size, - "unsigned int") + self.pop.get_sparse_ind_type()) row_length = self._assign_ext_ptr_array("rowLength", self.src.size, "unsigned int") diff --git a/src/genn/genn/code_generator/generateRunner.cc b/src/genn/genn/code_generator/generateRunner.cc index 0265fc9c6c..a96aab2db6 100644 --- a/src/genn/genn/code_generator/generateRunner.cc +++ b/src/genn/genn/code_generator/generateRunner.cc @@ -1228,7 +1228,7 @@ MemAlloc CodeGenerator::generateRunner(const filesystem::path &outputPath, const s.second.getSparseConnectivityLocation(), autoInitialized, s.second.getSrcNeuronGroup()->getNumNeurons()); // Target indices - backend.genVariablePushPull(runnerPushFunc, runnerPullFunc, "unsigned int", "ind" + s.second.getName(), + backend.genVariablePushPull(runnerPushFunc, runnerPullFunc, s.second.getSparseIndType(), "ind" + s.second.getName(), s.second.getSparseConnectivityLocation(), autoInitialized, size); }); } diff --git a/src/genn/genn/synapseGroup.cc b/src/genn/genn/synapseGroup.cc index c351b79a41..1001fd4870 100644 --- a/src/genn/genn/synapseGroup.cc +++ b/src/genn/genn/synapseGroup.cc @@ -238,6 +238,25 @@ bool SynapseGroup::isSpikeEventRequired() const return !getWUModel()->getEventCode().empty(); } //---------------------------------------------------------------------------- +std::string SynapseGroup::getSparseIndType() const +{ + // If narrow sparse inds are enabled + if(m_NarrowSparseIndEnabled) { + // If number of target neurons can be represented using a uint8, use this type + const unsigned int numTrgNeurons = getTrgNeuronGroup()->getNumNeurons(); + if(numTrgNeurons <= std::numeric_limits::max()) { + return "uint8_t"; + } + // Otherwise, if they can be represented as a uint16, use this type + else if(numTrgNeurons <= std::numeric_limits::max()) { + return "uint16_t"; + } + } + + // Otherwise, use 32-bit int + return "uint32_t"; +} +//---------------------------------------------------------------------------- const std::vector SynapseGroup::getWUConstInitVals() const { return getConstInitVals(m_WUVarInitialisers); @@ -590,26 +609,6 @@ void SynapseGroup::initDerivedParams(double dt) m_ConnectivityInitialiser.initDerivedParams(dt); } //---------------------------------------------------------------------------- -std::string SynapseGroup::getSparseIndType() const -{ - // If narrow sparse inds are enabled - if(m_NarrowSparseIndEnabled) { - // If number of target neurons can be represented using a uint8, use this type - const unsigned int numTrgNeurons = getTrgNeuronGroup()->getNumNeurons(); - if(numTrgNeurons <= std::numeric_limits::max()) { - return "uint8_t"; - } - // Otherwise, if they can be represented as a uint16, use this type - else if(numTrgNeurons <= std::numeric_limits::max()) { - return "uint16_t"; - } - } - - // Otherwise, use 32-bit int - return "uint32_t"; - -} -//---------------------------------------------------------------------------- bool SynapseGroup::canPSBeLinearlyCombined() const { // Return true if there are no variables or extra global parameters diff --git a/tests/features/connect_init/model.cc b/tests/features/connect_init/model.cc index 1d77065577..47f8d0efcd 100644 --- a/tests/features/connect_init/model.cc +++ b/tests/features/connect_init/model.cc @@ -23,6 +23,7 @@ void modelDefinition(ModelSpec &model) #endif model.setDT(0.1); model.setName("connect_init"); + model.setDefaultNarrowSparseIndEnabled(true); NeuronModels::LIF::ParamValues lifParams( 0.25, // 0 - C diff --git a/tests/features/connect_init/test.cc b/tests/features/connect_init/test.cc index 15193b31aa..91c4c78a59 100644 --- a/tests/features/connect_init/test.cc +++ b/tests/features/connect_init/test.cc @@ -32,8 +32,8 @@ class SimTest : public SimulationTest { }; -template -void calcHistogram(const unsigned int *rowLength, const uint32_t *ind, +template +void calcHistogram(const unsigned int *rowLength, const I *ind, unsigned int maxRowLength, std::array &histogram) { // Loop through rows