52 typedef std::tuple<std::string, std::string, GetFieldValueFunc, FieldType>
Field;
55 GroupMerged(
size_t index,
const std::string &precision,
const std::vector<std::reference_wrapper<const GroupInternal>> groups)
56 : m_Index(index), m_LiteralSuffix((precision ==
"float") ?
"f" :
""), m_Groups(
std::move(groups))
65 const GroupInternal &
getArchetype()
const {
return m_Groups.front().get(); }
71 const std::vector<std::reference_wrapper<const GroupInternal>> &
getGroups()
const{
return m_Groups; }
74 const std::vector<Field> &
getFields()
const{
return m_Fields; }
81 auto sortedFields = m_Fields;
82 std::sort(sortedFields.begin(), sortedFields.end(),
83 [&backend](
const Field &a,
const Field &b)
85 return (backend.
getSize(std::get<0>(a)) > backend.
getSize(std::get<0>(b)));
93 bool host =
false)
const 95 os <<
"struct Merged" << name <<
"Group" <<
getIndex() << std::endl;
100 for(
const auto &f : sortedFields) {
103 const std::string &type = std::get<0>(f);
118 os <<
" " << std::get<1>(f) <<
";" << std::endl;
123 os <<
";" << std::endl;
130 for(
size_t fieldIndex = 0; fieldIndex < sortedFields.size(); fieldIndex++) {
131 const auto &f = sortedFields[fieldIndex];
133 if(fieldIndex != (sortedFields.size() - 1)) {
142 size_t structSize = 0;
143 size_t largestFieldSize = 0;
145 for(
const auto &f : sortedFields) {
147 const size_t fieldSize = backend.
getSize(std::get<0>(f));
148 structSize += fieldSize;
151 largestFieldSize = std::max(fieldSize, largestFieldSize);
164 if(!memorySpaces.empty()) {
169 for(
auto &
m : memorySpaces) {
171 if(
m.second > groupBytes) {
173 m_MemorySpace =
m.first;
176 m.second -= groupBytes;
190 bool isParamReferenced(
const std::vector<std::string> &codeStrings,
const std::string ¶mName)
const 192 return std::any_of(codeStrings.begin(), codeStrings.end(),
193 [¶mName](
const std::string &c)
195 return (c.find(
"$(" + paramName +
")") != std::string::npos);
204 const double archetypeValue = getParamValuesFn(
getArchetype()).at(index);
208 [archetypeValue, index, getParamValuesFn](
const GroupInternal &g)
210 return (getParamValuesFn(g).at(index) != archetypeValue);
217 m_Fields.emplace_back(type, name, getFieldValue, fieldType);
223 [getFieldValue,
this](
const G &g,
size_t i)
225 return getFieldValue(g, i) + m_LiteralSuffix;
230 void addPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix)
233 addField(type +
"*", name, [prefix](
const G &g,
size_t) {
return prefix + g.getName(); });
240 for(
const auto &v : vars) {
249 for(
size_t v = 0; v < varReferences.size(); v++) {
250 addField(varReferences[v].type +
"*", varReferences[v].name,
251 [getVarRefFn, arrayPrefix, v](
const G &g,
size_t)
253 const auto varRef = getVarRefFn(g).at(v);
254 return arrayPrefix + varRef.getVar().name + varRef.getTargetName();
261 for(
const auto &e : egps) {
263 const std::string prefix = isPointer ? arrayPrefix :
"";
265 [e, prefix, varName](
const G &g,
size_t) { return prefix + e.name + varName + g.getName(); },
273 for(
size_t i = 0; i < egpRefs.size(); i++) {
274 const auto &e = egpRefs.at(i);
276 [arrayPrefix, e, getEGPRefFn, i](
const G &g,
size_t)
278 const auto egpRef = getEGPRefFn(g).at(i);
279 return arrayPrefix + egpRef.getEGP().name + egpRef.getTargetName();
285 template<
typename T,
typename P,
typename H>
287 P getParamValues, H isHeterogeneous)
290 for(
size_t p = 0; p < paramNames.size(); p++) {
292 if((static_cast<const T*>(
this)->*isHeterogeneous)(p)) {
295 [p, getParamValues](
const G &g,
size_t)
297 const auto &values = getParamValues(g);
304 template<
typename T,
typename D,
typename H>
306 D getDerivedParamValues, H isHeterogeneous)
309 for(
size_t p = 0; p < derivedParams.size(); p++) {
311 if((static_cast<const T*>(
this)->*isHeterogeneous)(p)) {
314 [p, getDerivedParamValues](
const G &g,
size_t)
316 const auto &values = getDerivedParamValues(g);
323 template<
typename T,
typename V,
typename H>
327 const std::vector<Models::VarInit> &archetypeVarInitialisers = (
getArchetype().*getVarInitialisers)();
328 for(
size_t v = 0; v < archetypeVarInitialisers.size(); v++) {
331 for(
size_t p = 0; p < varInit.
getParams().size(); p++) {
332 if((static_cast<const T*>(
this)->*isHeterogeneous)(v, p)) {
334 [p, v, getVarInitialisers](
const G &g, size_t)
336 const auto &values = (g.*getVarInitialisers)()[v].getParams();
344 template<
typename T,
typename V,
typename H>
348 const std::vector<Models::VarInit> &archetypeVarInitialisers = (
getArchetype().*getVarInitialisers)();
349 for(
size_t v = 0; v < archetypeVarInitialisers.size(); v++) {
353 if((static_cast<const T*>(
this)->*isHeterogeneous)(v, d)) {
355 [d, v, getVarInitialisers](
const G &g, size_t)
357 const auto &values = (g.*getVarInitialisers)()[v].getDerivedParams();
367 void updateHash(H getHashableFn, boost::uuids::detail::sha1 &hash)
const 374 template<
typename T,
typename V,
typename R>
375 void updateParamHash(R isParamReferencedFn, V getValueFn, boost::uuids::detail::sha1 &hash)
const 378 const auto &archetypeParams = getValueFn(
getArchetype());
379 for(
size_t p = 0; p < archetypeParams.size(); p++) {
381 if((static_cast<const T*>(
this)->*isParamReferencedFn)(p)) {
391 template<
typename T,
typename V,
typename R>
395 const std::vector<Models::VarInit> &archetypeVarInitialisers = (
getArchetype().*getVarInitialisers)();
396 for(
size_t v = 0; v < archetypeVarInitialisers.size(); v++) {
399 for(
size_t p = 0; p < varInit.
getParams().size(); p++) {
401 if((static_cast<const T *>(
this)->*isParamReferencedFn)(v, p)) {
404 const auto &values = (g.get().*getVarInitialisers)()[v].getParams();
414 template<
typename T,
typename V,
typename R>
418 const std::vector<Models::VarInit> &archetypeVarInitialisers = (
getArchetype().*getVarInitialisers)();
419 for(
size_t v = 0; v < archetypeVarInitialisers.size(); v++) {
424 if((static_cast<const T *>(
this)->*isDerivedParamReferencedFn)(v, d)) {
427 const auto &values = (g.get().*getVarInitialisers)()[v].getDerivedParams();
440 const std::string &name,
bool host =
false)
const 448 definitionsInternalFunc <<
"EXPORT_FUNC void pushMerged" << name <<
"Group" <<
getIndex() <<
"ToDevice(unsigned int idx, ";
450 definitionsInternalFunc <<
");" << std::endl;
454 for(
const auto &f : sortedFields) {
457 definitionsInternalFunc <<
"EXPORT_FUNC void pushMerged" << name << getIndex() << std::get<1>(f) <<
"ToDevice(unsigned int idx, ";
472 runnerVarDecl <<
"Merged" << name <<
"Group" <<
getIndex() <<
" merged" << name <<
"Group" <<
getIndex() <<
"[" <<
getGroups().size() <<
"];" << std::endl;
475 definitionsInternalVar <<
"EXPORT_VAR Merged" << name <<
"Group" <<
getIndex() <<
" merged" << name <<
"Group" <<
getIndex() <<
"[" <<
getGroups().size() <<
"]; " << std::endl;
479 for(
size_t groupIndex = 0; groupIndex <
getGroups().size(); groupIndex++) {
482 runnerMergedStructAlloc <<
"merged" << name <<
"Group" <<
getIndex() <<
"[" << groupIndex <<
"] = {";
483 generateStructFieldArguments(runnerMergedStructAlloc, groupIndex, sortedFields);
484 runnerMergedStructAlloc <<
"};" << std::endl;
488 runnerMergedStructAlloc <<
"pushMerged" << name <<
"Group" <<
getIndex() <<
"ToDevice(" << groupIndex <<
", ";
489 generateStructFieldArguments(runnerMergedStructAlloc, groupIndex, sortedFields);
490 runnerMergedStructAlloc <<
");" << std::endl;
499 void generateStructFieldArguments(
CodeStream &os,
size_t groupIndex,
500 const std::vector<Field> &sortedFields)
const 506 for(
size_t fieldIndex = 0; fieldIndex < sortedFields.size(); fieldIndex++) {
507 const auto &f = sortedFields[fieldIndex];
508 const std::string fieldInitVal = std::get<2>(f)(g, groupIndex);
510 if(fieldIndex != (sortedFields.size() - 1)) {
519 const size_t m_Index;
520 const std::string m_LiteralSuffix;
521 std::string m_MemorySpace;
522 std::vector<Field> m_Fields;
523 std::vector<std::reference_wrapper<const GroupInternal>> m_Groups;
533 const std::vector<std::reference_wrapper<const NeuronGroupInternal>> &groups);
542 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
543 runnerVarDecl, runnerMergedStructAlloc, name);
546 void genMergedGroupSpikeCountReset(
CodeStream &os,
unsigned int batchSize)
const;
561 const std::vector<std::reference_wrapper<const NeuronGroupInternal>> &groups);
570 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
571 runnerVarDecl, runnerMergedStructAlloc, name);
590 bool isParamHeterogeneous(
size_t index)
const;
593 bool isDerivedParamHeterogeneous(
size_t index)
const;
596 bool isVarInitParamHeterogeneous(
size_t varIndex,
size_t paramIndex)
const;
599 bool isVarInitDerivedParamHeterogeneous(
size_t varIndex,
size_t paramIndex)
const;
602 bool isCurrentSourceParamHeterogeneous(
size_t childIndex,
size_t paramIndex)
const;
605 bool isCurrentSourceDerivedParamHeterogeneous(
size_t childIndex,
size_t paramIndex)
const;
608 bool isCurrentSourceVarInitParamHeterogeneous(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
611 bool isCurrentSourceVarInitDerivedParamHeterogeneous(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
614 bool isPSMParamHeterogeneous(
size_t childIndex,
size_t paramIndex)
const;
617 bool isPSMDerivedParamHeterogeneous(
size_t childIndex,
size_t varIndex)
const;
620 bool isPSMGlobalVarHeterogeneous(
size_t childIndex,
size_t paramIndex)
const;
623 bool isPSMVarInitParamHeterogeneous(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
626 bool isPSMVarInitDerivedParamHeterogeneous(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
642 bool init,
const std::vector<std::reference_wrapper<const NeuronGroupInternal>> &groups);
644 void updateBaseHash(
bool init, boost::uuids::detail::sha1 &hash)
const;
646 template<
typename T,
typename G,
typename H>
648 G getVectorFunc, H getHashDigestFunc)
const 650 const std::vector<T*> &archetypeChildren = (
getArchetype().*getVectorFunc)();
653 sortedGroupChildren.reserve(
getGroups().size());
656 std::vector<std::pair<boost::uuids::detail::sha1::digest_type, T*>> childDigests;
657 childDigests.reserve(archetypeChildren.size());
662 const std::vector<T*> &groupChildren = (g.get().*getVectorFunc)();
663 assert(groupChildren.size() == archetypeChildren.size());
666 childDigests.clear();
667 for(
auto *c : groupChildren) {
668 childDigests.emplace_back((c->*getHashDigestFunc)(), c);
672 std::sort(childDigests.begin(), childDigests.end(),
673 [](
const std::pair<boost::uuids::detail::sha1::digest_type, T*> &a,
674 const std::pair<boost::uuids::detail::sha1::digest_type, T*> &b)
676 return (a.first < b.first);
681 sortedGroupChildren.emplace_back();
682 sortedGroupChildren.back().reserve(groupChildren.size());
685 std::transform(childDigests.cbegin(), childDigests.cend(), std::back_inserter(sortedGroupChildren.back()),
686 [](
const std::pair<boost::uuids::detail::sha1::digest_type, T*> &a){
return a.second; });
691 bool isVarInitParamReferenced(
size_t varIndex,
size_t paramIndex)
const;
694 bool isVarInitDerivedParamReferenced(
size_t varIndex,
size_t paramIndex)
const;
697 bool isCurrentSourceParamReferenced(
size_t childIndex,
size_t paramIndex)
const;
700 bool isCurrentSourceDerivedParamReferenced(
size_t childIndex,
size_t paramIndex)
const;
703 bool isCurrentSourceVarInitParamReferenced(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
706 bool isCurrentSourceVarInitDerivedParamReferenced(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
709 bool isPSMParamReferenced(
size_t childIndex,
size_t paramIndex)
const;
712 bool isPSMDerivedParamReferenced(
size_t childIndex,
size_t varIndex)
const;
715 bool isPSMGlobalVarReferenced(
size_t childIndex,
size_t varIndex)
const;
718 bool isPSMVarInitParamReferenced(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
721 bool isPSMVarInitDerivedParamReferenced(
size_t childIndex,
size_t varIndex,
size_t paramIndex)
const;
723 template<
typename T,
typename G>
725 const std::vector<std::vector<T>> &sortedGroupChildren, G getParamValuesFn)
const 728 const double firstValue = getParamValuesFn(sortedGroupChildren[0][childIndex]).at(paramIndex);
731 for(
size_t i = 0; i < sortedGroupChildren.size(); i++) {
732 const auto group = sortedGroupChildren[i][childIndex];
733 if(getParamValuesFn(group).at(paramIndex) != firstValue) {
741 template<
typename T = NeuronGroupMergedBase,
typename C,
typename H,
typename V>
743 const std::vector<std::vector<C>> &sortedGroupChildren,
744 size_t childIndex,
const std::string &prefix,
745 H isChildParamHeterogeneousFn, V getValueFn)
748 for(
size_t p = 0; p < paramNames.size(); p++) {
750 if((static_cast<const T*>(
this)->*isChildParamHeterogeneousFn)(childIndex, p)) {
751 addScalarField(paramNames[p] + prefix + std::to_string(childIndex),
752 [&sortedGroupChildren, childIndex, p, getValueFn](
const NeuronGroupInternal &,
size_t groupIndex)
754 const auto *child = sortedGroupChildren.at(groupIndex).at(childIndex);
761 template<
typename T = NeuronGroupMergedBase,
typename C,
typename H,
typename V>
763 const std::vector<std::vector<C>> &sortedGroupChildren,
764 size_t childIndex,
const std::string &prefix,
765 H isChildDerivedParamHeterogeneousFn, V getValueFn)
768 for(
size_t p = 0; p < derivedParams.size(); p++) {
770 if((static_cast<const T*>(
this)->*isChildDerivedParamHeterogeneousFn)(childIndex, p)) {
771 addScalarField(derivedParams[p].name + prefix + std::to_string(childIndex),
772 [&sortedGroupChildren, childIndex, p, getValueFn](
const NeuronGroupInternal &,
size_t groupIndex)
774 const auto *child = sortedGroupChildren.at(groupIndex).at(childIndex);
781 template<
typename T = NeuronGroupMergedBase,
typename C,
typename H,
typename V>
783 const std::vector<std::vector<C>> &sortedGroupChildren,
784 size_t childIndex,
size_t varIndex,
const std::string &prefix,
785 H isChildParamHeterogeneousFn, V getVarInitialiserFn)
788 for(
size_t p = 0; p < paramNames.size(); p++) {
790 if((static_cast<const T*>(
this)->*isChildParamHeterogeneousFn)(childIndex, varIndex, p)) {
791 addScalarField(paramNames[p] + prefix + std::to_string(childIndex),
792 [&sortedGroupChildren, childIndex, varIndex, p, getVarInitialiserFn](
const NeuronGroupInternal &,
size_t groupIndex)
794 const auto *child = sortedGroupChildren.at(groupIndex).at(childIndex);
795 const std::vector<Models::VarInit> &varInit = (child->*getVarInitialiserFn)();
802 template<
typename T = NeuronGroupMergedBase,
typename C,
typename H,
typename V>
804 const std::vector<std::vector<C>> &sortedGroupChildren,
805 size_t childIndex,
size_t varIndex,
const std::string &prefix,
806 H isChildDerivedParamHeterogeneousFn, V getVarInitialiserFn)
809 for(
size_t p = 0; p < derivedParams.size(); p++) {
811 if((static_cast<const T*>(
this)->*isChildDerivedParamHeterogeneousFn)(childIndex, varIndex, p)) {
812 addScalarField(derivedParams[p].name + prefix + std::to_string(childIndex),
813 [&sortedGroupChildren, childIndex, varIndex, p, getVarInitialiserFn](
const NeuronGroupInternal &,
size_t groupIndex)
815 const auto *child = sortedGroupChildren.at(groupIndex).at(childIndex);
816 const std::vector<Models::VarInit> &varInit = (child->*getVarInitialiserFn)();
824 void addChildEGPs(
const std::vector<Snippet::Base::EGP> &egps,
size_t childIndex,
825 const std::string &arrayPrefix,
const std::string &prefix,
828 for(
const auto &e : egps) {
830 const std::string varPrefix = isPointer ? arrayPrefix :
"";
831 addField(e.type, e.name + prefix + std::to_string(childIndex),
834 return varPrefix + e.name + getEGPSuffixFn(groupIndex, childIndex);
840 template<
typename T = NeuronGroupMergedBase,
typename C,
typename V,
typename R>
842 size_t childIndex, R isChildParamReferencedFn, V getValueFn,
843 boost::uuids::detail::sha1 &hash)
const 846 const auto &archetypeParamNames = (sortedGroupChildren.front().at(childIndex)->*getValueFn)();
847 for(
size_t p = 0; p < archetypeParamNames.size(); p++) {
849 if((static_cast<const T*>(
this)->*isChildParamReferencedFn)(childIndex, p)) {
851 for(
size_t g = 0; g <
getGroups().size(); g++) {
853 const auto *child = sortedGroupChildren.at(g).at(childIndex);
862 template<
typename T = NeuronGroupMergedBase,
typename C,
typename V,
typename R>
864 size_t childIndex, R isChildDerivedParamReferencedFn, V getValueFn,
865 boost::uuids::detail::sha1 &hash)
const 868 const auto &archetypeDerivedParams = (sortedGroupChildren.front().at(childIndex)->*getValueFn)();
869 for(
size_t p = 0; p < archetypeDerivedParams.size(); p++) {
871 if((static_cast<const T*>(
this)->*isChildDerivedParamReferencedFn)(childIndex, p)) {
873 for(
size_t g = 0; g <
getGroups().size(); g++) {
875 const auto *child = sortedGroupChildren.at(g).at(childIndex);
884 template<
typename T = NeuronGroupMergedBase,
typename C,
typename R,
typename V>
886 size_t childIndex,
size_t varIndex, R isChildParamReferencedFn, V getVarInitialiserFn,
887 boost::uuids::detail::sha1 &hash)
const 890 const auto &archetypeVarInit = (sortedGroupChildren.front().at(childIndex)->*getVarInitialiserFn)();
891 const auto &archetypeParams = archetypeVarInit.at(varIndex).getParams();
892 for(
size_t p = 0; p < archetypeParams.size(); p++) {
894 if((static_cast<const T*>(
this)->*isChildParamReferencedFn)(childIndex, varIndex, p)) {
896 for(
size_t g = 0; g <
getGroups().size(); g++) {
898 const auto *child = sortedGroupChildren.at(g).at(childIndex);
899 const std::vector<Models::VarInit> &varInit = (child->*getVarInitialiserFn)();
908 template<
typename T = NeuronGroupMergedBase,
typename C,
typename R,
typename V>
910 size_t childIndex,
size_t varIndex, R isChildDerivedParamReferencedFn, V getVarInitialiserFn,
911 boost::uuids::detail::sha1 &hash)
const 914 const auto &archetypeVarInit = (sortedGroupChildren.front().at(childIndex)->*getVarInitialiserFn)();
915 const auto &archetypeDerivedParams = archetypeVarInit.at(varIndex).getDerivedParams();
916 for(
size_t p = 0; p < archetypeDerivedParams.size(); p++) {
918 if((static_cast<const T*>(
this)->*isChildDerivedParamReferencedFn)(childIndex, varIndex, p)) {
920 for(
size_t g = 0; g <
getGroups().size(); g++) {
922 const auto *child = sortedGroupChildren.at(g).at(childIndex);
923 const auto &varInit = (child->*getVarInitialiserFn)();
932 void addMergedInSynPointerField(
const std::string &type,
const std::string &name,
933 size_t archetypeIndex,
const std::string &prefix);
935 void addMergedPreOutputOutSynPointerField(
const std::string &type,
const std::string &name,
936 size_t archetypeIndex,
const std::string &prefix);
943 std::vector<std::vector<SynapseGroupInternal*>> m_SortedMergedInSyns;
944 std::vector<std::vector<SynapseGroupInternal*>> m_SortedMergedPreOutputOutSyns;
945 std::vector<std::vector<CurrentSourceInternal*>> m_SortedCurrentSources;
957 const std::vector<std::reference_wrapper<const SynapseGroupInternal>> &group);
966 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
967 runnerVarDecl, runnerMergedStructAlloc, name);
983 const std::vector<std::reference_wrapper<const SynapseGroupInternal>> &groups);
992 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
993 runnerVarDecl, runnerMergedStructAlloc, name,
true);
997 bool isConnectivityInitParamHeterogeneous(
size_t paramIndex)
const;
1000 bool isConnectivityInitDerivedParamHeterogeneous(
size_t paramIndex)
const;
1012 bool isSparseConnectivityInitParamReferenced(
size_t paramIndex)
const;
1015 bool isSparseConnectivityInitDerivedParamReferenced(
size_t paramIndex)
const;
1028 bool isWUParamHeterogeneous(
size_t paramIndex)
const;
1031 bool isWUDerivedParamHeterogeneous(
size_t paramIndex)
const;
1034 bool isWUGlobalVarHeterogeneous(
size_t varIndex)
const;
1037 bool isWUVarInitParamHeterogeneous(
size_t varIndex,
size_t paramIndex)
const;
1040 bool isWUVarInitDerivedParamHeterogeneous(
size_t varIndex,
size_t paramIndex)
const;
1043 bool isSparseConnectivityInitParamHeterogeneous(
size_t paramIndex)
const;
1046 bool isSparseConnectivityInitDerivedParamHeterogeneous(
size_t paramIndex)
const;
1049 bool isToeplitzConnectivityInitParamHeterogeneous(
size_t paramIndex)
const;
1052 bool isToeplitzConnectivityInitDerivedParamHeterogeneous(
size_t paramIndex)
const;
1055 bool isSrcNeuronParamHeterogeneous(
size_t paramIndex)
const;
1058 bool isSrcNeuronDerivedParamHeterogeneous(
size_t paramIndex)
const;
1061 bool isTrgNeuronParamHeterogeneous(
size_t paramIndex)
const;
1064 bool isTrgNeuronDerivedParamHeterogeneous(
size_t paramIndex)
const;
1084 std::string getPreSlot(
unsigned int batchSize)
const;
1085 std::string getPostSlot(
unsigned int batchSize)
const;
1089 return getPreVarIndex(
getArchetype().getSrcNeuronGroup()->isDelayRequired(), batchSize, varDuplication, index);
1094 return getPostVarIndex(
getArchetype().getTrgNeuronGroup()->isDelayRequired(), batchSize, varDuplication, index);
1099 return getPreVarIndex(
getArchetype().getDelaySteps() != 0, batchSize, varDuplication, index);
1104 return getPostVarIndex(
getArchetype().getBackPropDelaySteps() != 0, batchSize, varDuplication, index);
1107 std::string getPostDenDelayIndex(
unsigned int batchSize,
const std::string &index,
const std::string &offset)
const;
1109 std::string getPreVarIndex(
bool delay,
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1110 std::string getPostVarIndex(
bool delay,
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1112 std::string getPrePrevSpikeTimeIndex(
bool delay,
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1113 std::string getPostPrevSpikeTimeIndex(
bool delay,
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1117 return ((batchSize == 1) ?
"" :
"postBatchOffset + ") + index;
1122 return ((batchSize == 1) ?
"" :
"preBatchOffset + ") + index;
1125 std::string getSynVarIndex(
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1126 std::string getKernelVarIndex(
unsigned int batchSize,
VarAccessDuplication varDuplication,
const std::string &index)
const;
1143 Role role,
const std::string &archetypeCode,
const std::vector<std::reference_wrapper<const SynapseGroupInternal>> &groups);
1148 boost::uuids::detail::sha1::digest_type getHashDigest(
Role role)
const;
1156 void addPSPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix);
1157 void addPreOutputPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix);
1158 void addSrcPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix);
1159 void addTrgPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix);
1160 void addWeightSharingPointerField(
const std::string &type,
const std::string &name,
const std::string &prefix);
1162 std::string getVarIndex(
bool delay,
unsigned int batchSize,
VarAccessDuplication varDuplication,
1163 const std::string &index,
const std::string &prefix)
const;
1166 bool isWUParamReferenced(
size_t paramIndex)
const;
1169 bool isWUDerivedParamReferenced(
size_t paramIndex)
const;
1172 bool isWUGlobalVarReferenced(
size_t varIndex)
const;
1175 bool isWUVarInitParamReferenced(
size_t varIndex,
size_t paramIndex)
const;
1178 bool isWUVarInitDerivedParamReferenced(
size_t varIndex,
size_t paramIndex)
const;
1181 bool isSparseConnectivityInitParamReferenced(
size_t paramIndex)
const;
1184 bool isSparseConnectivityInitDerivedParamReferenced(
size_t paramIndex)
const;
1187 bool isToeplitzConnectivityInitParamReferenced(
size_t paramIndex)
const;
1190 bool isToeplitzConnectivityInitDerivedParamReferenced(
size_t paramIndex)
const;
1193 bool isSrcNeuronParamReferenced(
size_t paramIndex)
const;
1196 bool isSrcNeuronDerivedParamReferenced(
size_t paramIndex)
const;
1199 bool isTrgNeuronParamReferenced(
size_t paramIndex)
const;
1202 bool isTrgNeuronDerivedParamReferenced(
size_t paramIndex)
const;
1212 const std::string m_ArchetypeCode;
1218 template<
typename G>
1223 const std::vector<std::reference_wrapper<const G>> &groups)
1228 for(
const auto &v : cm->
getVars()) {
1250 const std::vector<std::reference_wrapper<const CustomUpdateInternal>> &groups);
1259 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
1260 runnerVarDecl, runnerMergedStructAlloc, name,
true);
1276 const std::vector<std::reference_wrapper<const CustomUpdateWUInternal>> &groups);
1285 generateRunnerBase(backend, definitionsInternal, definitionsInternalFunc, definitionsInternalVar,
1286 runnerVarDecl, runnerMergedStructAlloc, name,
true);
const std::vector< SynapseGroupInternal * > & getSortedArchetypeMergedPreOutputOutSyns() const
Get sorted vectors of merged outgoing synapse groups with presynaptic output belonging to archetype g...
Definition: groupMerged.h:632
void updateChildParamHash(const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, R isChildParamReferencedFn, V getValueFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:841
Definition: neuronGroupInternal.h:9
void genKernelIndex(std::ostream &os, const CodeGenerator::Substitutions &subs) const
Generate an index into a kernel based on the id_kernel_XXX variables in subs.
Definition: groupMerged.h:1079
static const std::string name
Definition: groupMerged.h:973
static const std::string name
Definition: groupMerged.h:1266
Definition: groupMerged.h:557
std::vector< EGPRef > EGPRefVec
Definition: models.h:117
Definition: groupMerged.h:1246
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:1255
std::vector< Var > VarVec
Definition: models.h:115
Definition: groupMerged.h:1021
const std::vector< CurrentSourceInternal * > & getSortedArchetypeCurrentSources() const
Get sorted vectors of current sources belonging to archetype group.
Definition: groupMerged.h:635
Definition: groupMerged.h:1272
Definition: groupMerged.h:1219
void addHeterogeneousChildDerivedParams(const Snippet::Base::DerivedParamVec &derivedParams, const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, const std::string &prefix, H isChildDerivedParamHeterogeneousFn, V getValueFn)
Definition: groupMerged.h:762
const std::vector< Field > & getFields() const
Get group fields.
Definition: groupMerged.h:74
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:538
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:962
void genKernelIndex(const G *group, std::ostream &os, const CodeGenerator::Substitutions &subs, K getKernelSizeFn)
Definition: codeGenUtils.h:180
void addHeterogeneousChildParams(const Snippet::Base::StringVec ¶mNames, const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, const std::string &prefix, H isChildParamHeterogeneousFn, V getValueFn)
Definition: groupMerged.h:742
#define GENN_EXPORT
Definition: gennExport.h:13
void addHeterogeneousChildVarInitDerivedParams(const Snippet::Base::DerivedParamVec &derivedParams, const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, size_t varIndex, const std::string &prefix, H isChildDerivedParamHeterogeneousFn, V getVarInitialiserFn)
Definition: groupMerged.h:803
void addPointerField(const std::string &type, const std::string &name, const std::string &prefix)
Definition: groupMerged.h:230
void addHeterogeneousVarInitParams(const Models::Base::VarVec &vars, V getVarInitialisers, H isHeterogeneous)
Definition: groupMerged.h:324
void addHeterogeneousVarInitDerivedParams(const Models::Base::VarVec &vars, V getVarInitialisers, H isHeterogeneous)
Definition: groupMerged.h:345
void generateStruct(CodeStream &os, const BackendBase &backend, const std::string &name, bool host=false) const
Generate declaration of struct to hold this merged group.
Definition: groupMerged.h:92
void addChildEGPs(const std::vector< Snippet::Base::EGP > &egps, size_t childIndex, const std::string &arrayPrefix, const std::string &prefix, S getEGPSuffixFn)
Definition: groupMerged.h:824
static const std::string name
Definition: groupMerged.h:1005
GENN_EXPORT void init(plog::Severity gennLevel, plog::Severity codeGeneratorLevel, plog::IAppender *gennAppender, plog::IAppender *codeGeneratorAppender)
Definition: logging.cc:6
void addField(const std::string &type, const std::string &name, GetFieldValueFunc getFieldValue, FieldType fieldType=FieldType::Standard)
Definition: groupMerged.h:214
void writePreciseString(std::ostream &os, T value)
This function writes a floating point value to a stream -setting the precision so no digits are lost...
Definition: gennUtils.h:92
Helper class for generating code - automatically inserts brackets, indents etc.
Definition: backendBase.h:30
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:566
std::string getPreISynIndex(unsigned int batchSize, const std::string &index) const
Definition: groupMerged.h:1120
void assignMemorySpaces(const BackendBase &backend, BackendBase::MemorySpaces &memorySpaces)
Assign memory spaces to group.
Definition: groupMerged.h:161
Base class for all current source models.
Definition: customUpdateModels.h:31
bool isParamReferenced(const std::vector< std::string > &codeStrings, const std::string ¶mName) const
Helper to test whether parameter is referenced in vector of codestrings.
Definition: groupMerged.h:190
void updateChildVarInitParamsHash(const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, size_t varIndex, R isChildParamReferencedFn, V getVarInitialiserFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:885
const std::vector< std::reference_wrapper< const GroupInternal > > & getGroups() const
Gets access to underlying vector of neuron groups which have been merged.
Definition: groupMerged.h:71
Definition: groupMerged.h:33
std::vector< std::pair< std::string, size_t > > MemorySpaces
Vector of prefixes required to allocate in memory space and size of memory space. ...
Definition: backendBase.h:190
Definition: synapseGroupInternal.h:9
Definition: codeStream.h:21
const std::string & getArchetypeCode() const
Definition: groupMerged.h:1150
std::function< std::string(const G &, size_t)> GetFieldValueFunc
Definition: groupMerged.h:51
Definition: substitutions.h:21
void addHeterogeneousDerivedParams(const Snippet::Base::DerivedParamVec &derivedParams, const std::string &suffix, D getDerivedParamValues, H isHeterogeneous)
Definition: groupMerged.h:305
const std::string & getMemorySpace() const
Get name of memory space assigned to group.
Definition: groupMerged.h:68
void updateVarInitParamHash(V getVarInitialisers, R isParamReferencedFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:392
void addHeterogeneousParams(const Snippet::Base::StringVec ¶mNames, const std::string &suffix, P getParamValues, H isHeterogeneous)
Definition: groupMerged.h:286
const std::vector< unsigned int > & getKernelSize() const
Definition: synapseGroup.h:130
void updateHash(const T &value, boost::uuids::detail::sha1 &hash)
Hash arithmetic types and enums.
Definition: gennUtils.h:128
size_t getIndex() const
Definition: groupMerged.h:62
bool isChildParamValueHeterogeneous(size_t childIndex, size_t paramIndex, const std::vector< std::vector< T >> &sortedGroupChildren, G getParamValuesFn) const
Definition: groupMerged.h:724
Definition: backendBase.h:176
FieldType
Definition: groupMerged.h:39
size_t padSize(size_t size, size_t blockSize)
Pad an integer to a multiple of another.
Definition: codeGenUtils.h:64
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:1281
GENN_EXPORT bool isTypePointer(const std::string &type)
Function to determine whether a string containing a type is a pointer.
Definition: gennUtils.cc:75
std::vector< Field > getSortedFields(const BackendBase &backend) const
Get group fields, sorted into order they will appear in struct.
Definition: groupMerged.h:77
void addEGPReferences(const Models::Base::EGPRefVec &egpRefs, const std::string &arrayPrefix, E getEGPRefFn)
Definition: groupMerged.h:271
bool isKernelSizeHeterogeneous(const G *group, size_t dimensionIndex, K getKernelSizeFn)
Definition: codeGenUtils.h:152
void updateChildDerivedParamHash(const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, R isChildDerivedParamReferencedFn, V getValueFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:863
Definition: groupMerged.h:583
virtual StringVec getParamNames() const
Gets names of of (independent) model parameters.
Definition: snippet.h:187
const GroupInternal & getArchetype() const
Get 'archetype' neuron group - it's properties represent those of all other merged neuron groups...
Definition: groupMerged.h:65
static const std::string name
Definition: groupMerged.h:551
static const std::string name
Definition: groupMerged.h:577
virtual VarVec getVars() const
Gets names and types (as strings) of model variables.
Definition: models.h:123
const SnippetBase * getSnippet() const
Definition: snippet.h:263
void updateVarInitDerivedParamHash(V getVarInitialisers, R isDerivedParamReferencedFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:415
GroupMerged(size_t index, const std::string &precision, const std::vector< std::reference_wrapper< const GroupInternal >> groups)
Definition: groupMerged.h:55
const std::vector< double > & getParams() const
Definition: snippet.h:264
void generateRunner(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc) const
Definition: groupMerged.h:988
Role
Definition: groupMerged.h:1132
void addEGPs(const Snippet::Base::EGPVec &egps, const std::string &arrayPrefix, const std::string &varName="")
Definition: groupMerged.h:259
std::vector< DerivedParam > DerivedParamVec
Definition: snippet.h:181
CustomUpdateHostReductionGroupMergedBase(size_t index, const std::string &precision, const BackendBase &backend, const std::vector< std::reference_wrapper< const G >> &groups)
Definition: groupMerged.h:1222
void addScalarField(const std::string &name, GetFieldValueFunc getFieldValue, FieldType fieldType=FieldType::Standard)
Definition: groupMerged.h:220
std::string getKernelSize(const G *group, size_t dimensionIndex, K getKernelSizeFn)
Definition: codeGenUtils.h:167
std::vector< std::string > StringVec
Definition: snippet.h:178
size_t getSize(const std::string &type) const
Get the size of the type.
Definition: backendBase.cc:44
const std::vector< SynapseGroupInternal * > & getSortedArchetypeMergedInSyns() const
Get sorted vectors of merged incoming synapse groups belonging to archetype group.
Definition: groupMerged.h:629
virtual std::string getMergedGroupFieldHostType(const std::string &type) const =0
When generating function calls to push to merged groups, backend without equivalent of Unified Virtua...
VarAccessDuplication
Flags defining how variables should be duplicated across multiple batches.
Definition: varAccess.h:28
void orderNeuronGroupChildren(std::vector< std::vector< T *>> &sortedGroupChildren, G getVectorFunc, H getHashDigestFunc) const
Definition: groupMerged.h:647
Definition: groupMerged.h:529
void addVars(const Models::Base::VarVec &vars, const std::string &arrayPrefix)
Definition: groupMerged.h:237
size_t getStructArraySize(const BackendBase &backend) const
Definition: groupMerged.h:139
std::string getPostVarIndex(unsigned int batchSize, VarAccessDuplication varDuplication, const std::string &index) const
Definition: groupMerged.h:1092
void addHeterogeneousChildVarInitParams(const Snippet::Base::StringVec ¶mNames, const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, size_t varIndex, const std::string &prefix, H isChildParamHeterogeneousFn, V getVarInitialiserFn)
Definition: groupMerged.h:782
std::vector< VarRef > VarRefVec
Definition: models.h:116
void updateHash(H getHashableFn, boost::uuids::detail::sha1 &hash) const
Helper to update hash with the hash of calling getHashableFn on each group.
Definition: groupMerged.h:367
virtual std::string getPointerPrefix() const
Different backends may have different or no pointer prefix (e.g. __global for OpenCL) ...
Definition: backendBase.h:369
std::string getPreWUVarIndex(unsigned int batchSize, VarAccessDuplication varDuplication, const std::string &index) const
Definition: groupMerged.h:1097
bool isParamValueHeterogeneous(size_t index, P getParamValuesFn) const
Helper to test whether parameter values are heterogeneous within merged group.
Definition: groupMerged.h:201
void addVarReferences(const Models::Base::VarRefVec &varReferences, const std::string &arrayPrefix, V getVarRefFn)
Definition: groupMerged.h:246
std::tuple< std::string, std::string, GetFieldValueFunc, FieldType > Field
Definition: groupMerged.h:52
This variable is read-write.
std::string getKernelSize(size_t dimensionIndex) const
Get expression for kernel size in dimension (may be literal or group->kernelSizeXXX) ...
Definition: groupMerged.h:1073
virtual VarRefVec getVarRefs() const
Gets names and types (as strings) of model variable references.
Definition: customUpdateModels.h:38
static const std::string name
Definition: groupMerged.h:1292
void generateRunnerBase(const BackendBase &backend, CodeStream &definitionsInternal, CodeStream &definitionsInternalFunc, CodeStream &definitionsInternalVar, CodeStream &runnerVarDecl, CodeStream &runnerMergedStructAlloc, const std::string &name, bool host=false) const
Definition: groupMerged.h:437
void updateParamHash(R isParamReferencedFn, V getValueFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:375
virtual DerivedParamVec getDerivedParams() const
Definition: snippet.h:191
std::string getPreVarIndex(unsigned int batchSize, VarAccessDuplication varDuplication, const std::string &index) const
Definition: groupMerged.h:1087
G GroupInternal
Definition: groupMerged.h:50
virtual std::string getDeviceVarPrefix() const
Definition: backendBase.h:362
bool isKernelSizeHeterogeneous(size_t dimensionIndex) const
Is kernel size heterogeneous in this dimension?
Definition: groupMerged.h:1067
std::string getPostWUVarIndex(unsigned int batchSize, VarAccessDuplication varDuplication, const std::string &index) const
Definition: groupMerged.h:1102
Definition: groupMerged.h:979
void generateStructFieldArgumentDefinitions(CodeStream &os, const BackendBase &backend) const
Definition: groupMerged.h:126
const std::vector< double > & getDerivedParams() const
Definition: snippet.h:265
std::string getPostISynIndex(unsigned int batchSize, const std::string &index) const
Definition: groupMerged.h:1115
Definition: groupMerged.h:953
m
Definition: genn_model.py:117
void updateChildVarInitDerivedParamsHash(const std::vector< std::vector< C >> &sortedGroupChildren, size_t childIndex, size_t varIndex, R isChildDerivedParamReferencedFn, V getVarInitialiserFn, boost::uuids::detail::sha1 &hash) const
Definition: groupMerged.h:909
Definition: codeStream.h:94
std::vector< EGP > EGPVec
Definition: snippet.h:179