Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/genn/backends/cuda/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ class BACKEND_EXPORT Backend : public BackendSIMT
//! Get type of population RNG
virtual Type::ResolvedType getPopulationRNGType() const final;

//! Generate a fast uint32 divide
virtual std::string getFastU32Divide(const std::string &numerator, const std::string &divisorVar) const final;

//--------------------------------------------------------------------------
// CodeGenerator::BackendBase virtuals
//--------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions include/genn/genn/code_generator/backendSIMT.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ class GENN_EXPORT BackendSIMT : public BackendBase
//! Get type of population RNG
virtual Type::ResolvedType getPopulationRNGType() const = 0;

//! Generate a fast uint32 divide
virtual std::string getFastU32Divide(const std::string &numerator, const std::string &divisorVar) const = 0;

//------------------------------------------------------------------------
// BackendBase virtuals
//------------------------------------------------------------------------
Expand Down
32 changes: 32 additions & 0 deletions include/genn/genn/code_generator/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
#include <unordered_map>
#include <variant>

// Lib divide includes
extern "C"
{
#include "libdivide.h"
}

// GeNN includes
#include "gennExport.h"
#include "gennUtils.h"
Expand Down Expand Up @@ -409,6 +415,7 @@ class EnvironmentGroupMergedField : public EnvironmentExternalDynamicBase<Enviro
Runtime::MergedDynamicFieldDestinations&>>;
using GetFieldNonNumericValueFunc = std::function<NonNumericFieldValue(Runtime::Runtime&, const GroupInternal&, size_t)>;
using GetFieldNumericValueFunc = std::function<Type::NumericValue(const GroupInternal&, size_t)>;
using GetFieldUint32ValueFunc = std::function<uint32_t(const GroupInternal&, size_t)>;
using IsDynamicFn = bool (GroupInternal::*)(const std::string&) const;
using IsVarInitHeterogeneousFn = bool (G::*)(const std::string&, const std::string&) const;
using GetParamValuesFn = const std::map<std::string, Type::NumericValue> &(GroupInternal::*)(void) const;
Expand Down Expand Up @@ -500,6 +507,31 @@ class EnvironmentGroupMergedField : public EnvironmentExternalDynamicBase<Enviro
addField(type, name, type, fieldName, getFieldValue, indexSuffix, mergedFieldType, initialisers);
}

void addFastDivideField(const std::string &name, const std::string &fieldName,
GetFieldUint32ValueFunc getFieldValue)
{
// Add main field
addField(GeNN::Type::Uint32.addConst(), name,
GeNN::Type::Uint32, fieldName,
getFieldValue);

// Add "magic" field
addField(GeNN::Type::Uint32.addConst(), name + "_magic",
GeNN::Type::Uint32, fieldName + "Magic",
[getFieldValue](const GroupInternal &g, size_t i)
{
return libdivide_u32_branchfree_gen(getFieldValue(g, i)).magic;
});

// Add "more" field
addField(GeNN::Type::Uint8.addConst(), name + "_more",
GeNN::Type::Uint8, fieldName + "More",
[getFieldValue](const GroupInternal &g, size_t i)
{
return libdivide_u32_branchfree_gen(getFieldValue(g, i)).more;
});
}

void addParams(const Snippet::Base::ParamVec &params, const std::string &fieldSuffix,
GetParamValuesFn getParamValues, IsDynamicFn isDynamic)
{
Expand Down
Loading