diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000..c40becf81
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,124 @@
+Language: Cpp
+AccessModifierOffset: -2
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveMacros: false
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Left
+AlignOperands: false
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: AllDefinitions
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterCaseLabel: true
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: false
+ AfterExternBlock: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Allman
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 2
+ContinuationIndentWidth: 2
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+InsertBraces: true
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: true
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: true
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: true
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: true
+SpacesInParentheses: true
+SpacesInSquareBrackets: true
+Standard: Cpp03
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 8
+UseTab: Never
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 000000000..e02b1c455
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1 @@
+Checks: '-*,modernize-use-nullptr,modernize-use-override,bugprone,modernize-redundant-void-arg'
diff --git a/.gitignore b/.gitignore
index 3b24d7e6d..888cfaf75 100755
--- a/.gitignore
+++ b/.gitignore
@@ -39,4 +39,9 @@ doxygen
python/test/log.txt
python/Potjans_2014/data/
python/Potjans_2014_tmp/data/
+python/mpi_mem_check/test_*.dat
+python/mpi_mem_check/req_mem_*.dat
+python/mpi_mem_check/full_*.dat
+python/mpi_mem_check/log*.txt
+python/mpi_mem_check/report.nsys-rep
.vscode/
diff --git a/Makefile.am b/Makefile.am
index f45167727..5cf0608c6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,17 +12,54 @@ CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
HCUSRC=\
+connect.h \
+conn12b.h \
+conn16b.h \
remote_connect.h \
+connect_rules.h \
+connect_spec.h \
+nestgpu.h \
+get_spike.h \
+send_spike.h \
+rev_spike.h \
+spike_buffer.h \
+remote_spike.h \
+mpi_comm.h \
+base_neuron.h \
+node_group.h \
+neuron_models.h \
+poiss_gen.h \
+poiss_gen_variables.h \
+cuda_error.h \
+ngpu_exception.h \
+getRealTime.h \
+random.h \
utilities.h \
distribution.h \
+scan.h \
+prefix_scan.h \
+nested_loop.h \
copass_kernels.h \
copass_sort.h \
-connect.h \
-iaf_psc_exp_g.h \
-iaf_psc_exp_hc_params.h \
-iaf_psc_exp_hc.h \
-iaf_psc_exp.h \
+rk5_const.h \
+rk5.h \
+rk5_interface.h \
+propagate_error.h \
+propagator_stability.h \
+stdp.h \
+syn_model.h \
+test_syn_model.h \
+spike_detector.h \
+spike_generator.h \
+parrot_neuron.h \
+multimeter.h \
ext_neuron.h \
+user_m1.h \
+user_m1_kernel.h \
+user_m1_rk5.h \
+user_m2.h \
+user_m2_kernel.h \
+user_m2_rk5.h \
aeif_cond_alpha.h \
aeif_cond_alpha_kernel.h \
aeif_cond_alpha_multisynapse.h \
@@ -46,17 +83,6 @@ aeif_psc_exp_kernel.h \
aeif_psc_exp_multisynapse.h \
aeif_psc_exp_multisynapse_kernel.h \
aeif_psc_exp_multisynapse_rk5.h \
-base_neuron.h \
-connect.h \
-connect_rules.h \
-connect_spec.h \
-copass_kernels.h \
-copass_sort.h \
-cuda_error.h \
-distribution.h \
-ext_neuron.h \
-getRealTime.h \
-get_spike.h \
iaf_psc_exp_g.h \
iaf_psc_exp.h \
iaf_psc_exp_hc.h \
@@ -68,53 +94,46 @@ izhikevich_cond_beta_rk5.h \
izhikevich.h \
izhikevich_psc_exp_2s.h \
izhikevich_psc_exp_5s.h \
-izhikevich_psc_exp.h \
-multimeter.h \
-nested_loop.h \
-nestgpu.h \
-neuron_models.h \
-ngpu_exception.h \
-node_group.h \
-parrot_neuron.h \
-poiss_gen.h \
-poiss_gen_variables.h \
-prefix_scan.h \
-propagate_error.h \
-propagator_stability.h \
-random.h \
-rev_spike.h \
-rk5_const.h \
-rk5.h \
-rk5_interface.h \
-scan.h \
-send_spike.h \
-spike_buffer.h \
-spike_detector.h \
-spike_generator.h \
-remote_spike.h \
-mpi_comm.h \
-stdp.h \
-syn_model.h \
-test_syn_model.h \
-user_m1.h \
-user_m1_kernel.h \
-user_m1_rk5.h \
-user_m2.h \
-user_m2_kernel.h \
-user_m2_rk5.h \
-utilities.h
+izhikevich_psc_exp.h
CUSRC=\
+connect.cu \
+conn12b.cu \
+conn16b.cu \
remote_connect.cu \
+connect_rules.cu \
+nestgpu.cu \
+get_spike.cu \
+send_spike.cu \
+rev_spike.cu \
+spike_buffer.cu \
+remote_spike.cu \
+mpi_comm.cu \
+base_neuron.cu \
+node_group.cu \
+neuron_models.cu \
+poiss_gen.cu \
+getRealTime.cu \
+random.cu \
utilities.cu \
distribution.cu \
+scan.cu \
+prefix_scan.cu \
+nested_loop.cu \
copass_kernels.cu \
copass_sort.cu \
-connect.cu \
-iaf_psc_exp_g.cu \
-iaf_psc_exp_hc.cu \
-iaf_psc_exp.cu \
+rk5.cu \
+propagator_stability.cu \
+stdp.cu \
+syn_model.cu \
+test_syn_model.cu \
+spike_detector.cu \
+spike_generator.cu \
+parrot_neuron.cu \
+multimeter.cu \
ext_neuron.cu \
+user_m1.cu \
+user_m2.cu \
aeif_cond_alpha.cu \
aeif_cond_alpha_multisynapse.cu \
aeif_cond_beta.cu \
@@ -124,15 +143,6 @@ aeif_psc_alpha_multisynapse.cu \
aeif_psc_delta.cu \
aeif_psc_exp.cu \
aeif_psc_exp_multisynapse.cu \
-base_neuron.cu \
-connect.cu \
-connect_rules.cu \
-copass_kernels.cu \
-copass_sort.cu \
-distribution.cu \
-ext_neuron.cu \
-getRealTime.cu \
-get_spike.cu \
iaf_psc_exp.cu \
iaf_psc_exp_g.cu \
iaf_psc_exp_hc.cu \
@@ -141,32 +151,8 @@ izhikevich_cond_beta.cu \
izhikevich.cu \
izhikevich_psc_exp_2s.cu \
izhikevich_psc_exp_5s.cu \
-izhikevich_psc_exp.cu \
-multimeter.cu \
-nested_loop.cu \
-nestgpu.cu \
-neuron_models.cu \
-node_group.cu \
-parrot_neuron.cu \
-poiss_gen.cu \
-prefix_scan.cu \
-propagator_stability.cu \
-random.cu \
-rev_spike.cu \
-rk5.cu \
-scan.cu \
-send_spike.cu \
-spike_buffer.cu \
-spike_detector.cu \
-spike_generator.cu \
-remote_spike.cu \
-mpi_comm.cu \
-stdp.cu \
-syn_model.cu \
-test_syn_model.cu \
-user_m1.cu \
-user_m2.cu \
-utilities.cu
+izhikevich_psc_exp.cu
+
HCPPSRC=\
nestgpu_C.h
diff --git a/build_support/.clang-tidy-ignore b/build_support/.clang-tidy-ignore
new file mode 100644
index 000000000..fbb2a9235
--- /dev/null
+++ b/build_support/.clang-tidy-ignore
@@ -0,0 +1 @@
+*.cuh
diff --git a/build_support/check_all_c_c++_cu_files.sh b/build_support/check_all_c_c++_cu_files.sh
new file mode 100755
index 000000000..bc99fb34a
--- /dev/null
+++ b/build_support/check_all_c_c++_cu_files.sh
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+#
+# This file is part of NEST GPU.
+#
+# Copyright (C) 2021 The NEST Initiative
+#
+# NEST GPU is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# NEST GPU is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NEST GPU. If not, see .
+#
+
+# With this script you can easily check all C/C++/CU files contained in
+# the src directory of NEST GPU. Internally it uses clang-tidy to do
+# the actual check.
+#
+
+function make_temp_dir {
+ # Create a temporary directory and store its name in a variable.
+ TEMPD=$(mktemp -d)
+
+ # Exit if the temp directory wasn't created successfully.
+ if [ ! -e "$TEMPD" ]; then
+ >&2 echo "Error: failed to create temp directory"
+ exit 1
+ fi
+
+
+ # Make sure the temp directory gets removed on script exit.
+ trap "exit 1" HUP INT PIPE QUIT TERM
+ trap 'rm -rf "$TEMPD"' EXIT
+}
+
+if [ "$#" -ne 1 ]; then
+ echo "Usage: $0 "
+ exit 1
+fi
+
+CMD_DIR=$(dirname $(echo $0))
+CLANG_TIDY=${CMD_DIR}/clang-tidy-cuda.sh
+
+if [ ! -f $CLANG_TIDY ]; then
+ echo "Error: $CLANG_TIDY file not found in $CMD_DIR folder"
+ exit 1
+fi
+
+SRC_DIR=$1
+if [ -d "$SRC_DIR" ]; then
+ if [ -L "$SRC_DIR" ]; then
+ # It is a symlink
+ echo "Error: cannot pass a symboloc link as source path"
+ exit 1
+ fi
+else
+ echo "Error: source path $SRC_DIR not found"
+ exit 1
+fi
+
+make_temp_dir
+CONF_DIR=${TEMPD}/config
+mkdir $CONF_DIR
+if [ ! -e "$CONF_DIR" ]; then
+ >&2 echo "Error: failed to create $CONF_DIR directory"
+ exit 1
+fi
+CONF_H=${CONF_DIR}/config.h
+:>$CONF_H
+if [ ! -f $CONF_H ]; then
+ echo "Error: cannot create temporary file $CONF_H"
+ exit 1
+fi
+
+
+cp $CLANG_TIDY $TEMPD
+CLANG_TIDY=$(basename $CLANG_TIDY)
+if [ ! -f $TEMPD/$CLANG_TIDY ]; then
+ echo "Error: cannot create temporary executable $CLANG_TIDY in folder $TEMPD"
+ exit 1
+fi
+
+pushd .
+cd $SRC_DIR
+
+for fn in $(ls *.cu *.cpp *.cc *.c *.cuh *.hpp *.h); do
+ cat $fn | sed 's:////:#if 0:;s:////:#endif:' > $TEMPD/$fn
+ if [ ! -f $TEMPD/$fn ]; then
+ echo "Error: cannot create file $TEMPD/$fn"
+ popd
+ exit 1
+ fi
+done
+
+
+cd $TEMPD
+
+PASSED_NUM=0
+for fn in $(ls *.cu *.cpp *.cc *.c | grep -v user_m); do
+ echo " - Check with $CLANG_TIDY C/C++/CUDA file: $fn"
+ #$TEMPD/$CLANG_TIDY --include-path=../../build_cmake/libnestutil/ $fn
+ echo "$TEMPD/$CLANG_TIDY --include-path=$CONF_DIR $fn"
+ $TEMPD/$CLANG_TIDY --include-path=$CONF_DIR $fn
+ if [ $? -eq 0 ]; then
+ echo PASSED
+ PASSED_NUM=$(($PASSED_NUM + 1))
+ else
+ popd
+ exit 1
+ fi
+
+done
+
+popd
+echo "Checked $PASSED_NUM files with clang-tidy-cuda.sh"
+echo "All tests PASSED"
+
+exit 0
diff --git a/build_support/clang-format-cuda.sh b/build_support/clang-format-cuda.sh
new file mode 100755
index 000000000..e31fef014
--- /dev/null
+++ b/build_support/clang-format-cuda.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]; then
+ echo "Usage: $0 input-file"
+ return
+fi
+
+if [ ! -f .clang-format ]; then
+ echo "Error: .clang-format file not found in current directory"
+ return
+fi
+
+if [ ! -f $1 ]; then
+ echo "Error: input file $1 not found"
+ return
+fi
+
+if grep -q '$$<' $1; then
+ echo 'Error: illegal character sequence in input file: "$$<"'
+ return
+fi
+if grep -q '$ >' $1; then
+ echo 'Error: illegal character sequence in input file: "$ >"'
+ return
+fi
+if grep -q '$>' $1; then
+ echo 'Error: illegal character sequence in input file: "$>"'
+ return
+fi
+
+cat $1 | sed 's/<<$$>>/$ >/g;' > tmp1~
+clang-format -style=file:.clang-format tmp1~ > tmp2~
+cat tmp2~ | sed 's/$$<</>>>/g;s/$>/>>>/g;' > $1
+rm -f tmp1~
+rm -f tmp2~
diff --git a/build_support/clang-tidy-cuda.sh b/build_support/clang-tidy-cuda.sh
new file mode 100755
index 000000000..d16af0626
--- /dev/null
+++ b/build_support/clang-tidy-cuda.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+
+#
+# This file is part of NEST GPU.
+#
+# Copyright (C) 2021 The NEST Initiative
+#
+# NEST GPU is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# NEST GPU is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NEST GPU. If not, see .
+#
+
+cuda_default_path="/usr/local/cuda/include"
+
+if [ "$#" -eq 0 ]; then
+ echo "Usage: $0 [--include-path=INCLUDE_PATHS] [--cuda-path=CUDA_PATHS] [--mpi-path=MPI_PATHS] input-file"
+ echo "where INCLUDE_PATHS are optional header paths separated by colons,"
+ echo "CUDA_PATHS are the paths of CUDA headers separated by colons"
+ echo "(default: $cuda_default_path)"
+ echo "and MPI_PATHS are the paths of MPI headers separated by colons"
+ exit 0
+fi
+
+cuda_path=""
+mpi_path=""
+include_path=""
+
+for i in "$@"; do
+ case $i in
+ --include-path=*)
+ include_path="${i#*=}"
+ shift # past argument=value
+ ;;
+ --cuda-path=*)
+ cuda_path="${i#*=}"
+ shift # past argument=value
+ ;;
+ --mpi-path=*)
+ mpi_path="${i#*=}"
+ shift # past argument=value
+ ;;
+ -*|--*)
+ echo "Error: unknown option $i"
+ exit 1
+ ;;
+ *)
+ ;;
+ esac
+done
+
+if [[ -n $1 ]]; then
+ echo "Input file: $1"
+else
+ echo "Error: input file not specified."
+ exit 1
+fi
+
+if [ ! -f $1 ]; then
+ echo "Error: input file $1 not found."
+ exit 1
+fi
+
+if [ "$include_path" != "" ]; then
+ include_path=$(echo ":$include_path" | sed 's/::*/:/g;s/:$//;s/:/ -I /g')
+fi
+
+# Searches the paths of CUDA headers
+if [ "$cuda_path" == "" ]; then
+ cuda_path=":/usr/local/cuda/include"
+else
+ cuda_path=$(echo ":$cuda_path" | sed 's/::*/:/g;s/:$//')
+fi
+
+cuda_path_spaced=$(echo $cuda_path | tr ':' ' ')
+cuda_err=1
+for dn in $cuda_path_spaced; do
+ if test -f "$dn/cuda.h" ; then
+ echo "cuda.h found in path $dn"
+ cuda_err=0
+ break
+ fi
+done
+
+if [ $cuda_err -eq 1 ]; then
+ echo "cuda.h not found in path(s) $cuda_path_spaced"
+ echo "You can specify path for CUDA headers with the option --cuda-path=CUDA_PATHS"
+ echo "where CUDA_PATHS are the paths of CUDA headers separated by colons"
+ echo "(default: $cuda_default_path)"
+ exit 1
+fi
+
+cuda_include=$(echo $cuda_path | sed 's/:/ -isystem /g')
+
+#cat $1 | sed 's:////:#if 0:;s:////:#endif:' > tmp~
+
+#cat ../build_cmake/compile_commands.json | sed "s:-Xcompiler=-fPIC::;s:-forward-unknown-to-host-compiler::;s:--compiler-options='.*'::;s:--generate-code=arch=compute_80,code=\[compute_80,sm_80\]::;s:--maxrregcount=55::" > compile_commands.json
+
+# Searches the paths of MPI headers
+if [ "$mpi_path" == "" ]; then
+ mpi_include=$( \
+ for l in $(mpicc -showme); do \
+ echo $l; \
+ done | grep '^-I')
+ if [ "$mpi_include" == "" ]; then
+ echo "Error: cannot find MPI include paths"
+ echo "You can specify path for MPI headers with the option --mpi-path=MPI_PATHS"
+ echo "where MPI_PATHS are the paths of MPI headers separated by colons"
+ exit 1
+ fi
+ mpi_include=$(echo $mpi_include | sed 's/-I/ -isystem /g')
+ mpi_path_spaced=$(echo $mpi_include | sed 's/-I/ /g')
+else
+ mpi_path=$(echo ":$mpi_path" | sed 's/::*/:/g;s/:$//')
+ mpi_path_spaced=$(echo $mpi_path | tr ':' ' ')
+ mpi_include=$(echo $mpi_path | sed 's/:/ -isystem /g')
+fi
+
+mpi_err=1
+for dn in $mpi_path_spaced; do
+ if test -f "$dn/mpi.h" ; then
+ echo "mpi.h found in path $dn"
+ mpi_err=0
+ break
+ fi
+done
+
+if [ $mpi_err -eq 1 ]; then
+ echo "mpi.h not found in path(s) $mpi_path_spaced"
+ echo "You can specify path for MPI headers with the option --mpi-path=MPI_PATHS"
+ echo "where MPI_PATHS are the paths of MPI headers separated by colons"
+ exit 1
+fi
+
+echo "clang-tidy $1 -p . -- $include_path $mpi_include $cuda_include --no-cuda-version-check"
+
+clang-tidy $1 -p . -- $include_path $mpi_include $cuda_include --no-cuda-version-check
diff --git a/build_support/format_all_c_c++_cu_files.sh b/build_support/format_all_c_c++_cu_files.sh
new file mode 100755
index 000000000..b0ffed1af
--- /dev/null
+++ b/build_support/format_all_c_c++_cu_files.sh
@@ -0,0 +1,163 @@
+#!/bin/bash
+
+#
+# This file is part of NEST GPU.
+#
+# Copyright (C) 2021 The NEST Initiative
+#
+# NEST GPU is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# NEST GPU is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with NEST GPU. If not, see .
+#
+
+# With this script you can easily format all C/C++/CU files contained in
+# the src directory of NEST GPU. Internally it uses clang-format to do
+# the actual formatting.
+#
+# NEST GPU C/C++/CUDA code should be formatted according to clang-format
+# version 17.0.4. If you would like to see how the code will be formatted
+# with a different clang-format version, execute e.g.
+# `CLANG_FORMAT=clang-format-14 ./format_all_c_c++_cu_files.sh`.
+#
+# By default the script starts at the current working directory ($PWD), but
+# supply a different starting directory as the first argument to the command.
+
+CLANG_FORMAT=${CLANG_FORMAT:-clang-format}
+CLANG_FORMAT_FILE=${CLANG_FORMAT_FILE:-${PWD}/.clang-format}
+
+# Drop files that should not be checked
+FILES_TO_IGNORE="" # not used now, bult could be used in the future
+DIRS_TO_IGNORE="thirdparty" # not used now, bult could be used in the future
+
+CHANGE_COUNT=0
+
+function clang_format_cuda {
+ if [ ! -f $1 ]; then
+ echo "Error: input file $1 not found"
+ return
+ fi
+
+ if grep -q '$$<' $1; then
+ echo 'Error: illegal character sequence in input file: "$$<"'
+ return
+ fi
+ if grep -q '$ >' $1; then
+ echo 'Error: illegal character sequence in input file: "$ >"'
+ return
+ fi
+ if grep -q '$>' $1; then
+ echo 'Error: illegal character sequence in input file: "$>"'
+ return
+ fi
+
+ cat $1 | sed 's/<<$$>>/$ >/g;' > $TEMPD/tmp1~
+ #echo "CLANG_FORMAT_FILE: $CLANG_FORMAT_FILE"
+ clang-format -style=file:$CLANG_FORMAT_FILE $TEMPD/tmp1~ > $TEMPD/tmp2~
+ cat $TEMPD/tmp2~ | sed 's/$$<</>>>/g;s/$>/>>>/g;' > $TEMPD/tmp1~
+ if ! cmp -s $TEMPD/tmp1~ $1; then # file changed by clang-format
+ /bin/cp -f $TEMPD/tmp1~ $1
+ CHANGE_COUNT=$((CHANGE_COUNT+1))
+ echo " FILE CHANGED BY FORMATTING"
+ fi
+}
+
+# Recursively process all C/C++/CUDA files in all sub-directories.
+function process_dir {
+ dir=$1
+ echo "Process directory: $dir"
+
+ if [[ " $DIRS_TO_IGNORE " =~ .*[[:space:]]${dir##*/}[[:space:]].* ]]; then
+ echo " Directory explicitly ignored."
+ return
+ fi
+
+ for f in $dir/*; do
+ if [[ -d $f ]]; then
+ # Recursively process sub-directories.
+ process_dir $f
+ else
+ ignore_file=0
+
+ for FILE_TO_IGNORE in $FILES_TO_IGNORE; do
+ if [[ $f == *$FILE_TO_IGNORE* ]]; then
+ ignore_file=1
+ break
+ fi
+ done
+
+ if [ $ignore_file == 1 ] ; then
+ continue
+ fi
+
+ case $f in
+ *.cpp | *.cc | *.c | *.h | *.hpp | *.cu | *.cuh )
+ # Format C/C++/CUDA files.
+ echo " - Format C/C++/CUDA file: $f"
+ # $CLANG_FORMAT -i $f
+ clang_format_cuda $f
+ ;;
+ * )
+ # Ignore all other files.
+ esac
+ fi
+ done
+}
+
+function help_output {
+ echo "The $CLANG_FORMAT_FILE requires clang-format version 13 or later."
+ echo "Use like: [CLANG_FORMAT=] ./build_support/`basename $0` [start folder, defaults to '$PWD']"
+ exit 0
+}
+
+function make_temp_dir {
+ # Create a temporary directory and store its name in a variable.
+ TEMPD=$(mktemp -d)
+
+ # Exit if the temp directory wasn't created successfully.
+ if [ ! -e "$TEMPD" ]; then
+ >&2 echo "Failed to create temp directory"
+ exit 1
+ fi
+
+
+ # Make sure the temp directory gets removed on script exit.
+ trap "exit 1" HUP INT PIPE QUIT TERM
+ trap 'rm -rf "$TEMPD"' EXIT
+}
+
+make_temp_dir
+
+if [[ ! -f $CLANG_FORMAT_FILE ]]; then
+ echo "Cannot find $CLANG_FORMAT_FILE file. Please start '`basename $0`' from the NEST GPU base source directory."
+ help_output
+fi
+
+if [[ $# -eq 0 ]]; then
+ # Start with current directory.
+ startdir=$PWD
+elif [[ $# -eq 1 ]]; then
+ if [[ -d $1 ]]; then
+ # Start with given directory.
+ startdir=$1
+ else
+ # Not a directory.
+ help_output
+ fi
+else
+ # Two or more arguments...
+ help_output
+fi
+
+# Start formatting the $startdir and all subdirectories
+process_dir $startdir
+
+echo "$CHANGE_COUNT files have been changed by formatting"
diff --git a/c++/examples/brunel_mpi.cpp b/c++/examples/brunel_mpi.cpp
index fe9335e9f..d7f185e06 100644
--- a/c++/examples/brunel_mpi.cpp
+++ b/c++/examples/brunel_mpi.cpp
@@ -20,50 +20,48 @@
*
*/
-
-
-
-
-#include
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
NESTGPU ngpu;
- ngpu.ConnectMpiInit(argc, argv);
+ ngpu.ConnectMpiInit( argc, argv );
int mpi_np = ngpu.MpiNp();
- if (argc != 2 || mpi_np != 2) {
- cout << "Usage: mpirun -np 2 " << argv[0] << " n_neurons\n";
+ if ( argc != 2 || mpi_np != 2 )
+ {
+ cout << "Usage: mpirun -np 2 " << argv[ 0 ] << " n_neurons\n";
ngpu.MpiFinalize();
return 0;
}
int arg1;
- sscanf(argv[1], "%d", &arg1);
+ sscanf( argv[ 1 ], "%d", &arg1 );
int mpi_id = ngpu.MpiId();
- cout << "Building on host " << mpi_id << " ..." <
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
- if (argc != 2) {
- cout << "Usage: " << argv[0] << " n_neurons\n";
+ if ( argc != 2 )
+ {
+ cout << "Usage: " << argv[ 0 ] << " n_neurons\n";
return 0;
}
int arg1;
- sscanf(argv[1], "%d", &arg1);
+ sscanf( argv[ 1 ], "%d", &arg1 );
NESTGPU ngpu;
cout << "Building ...\n";
- ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers
-
+ ngpu.SetRandomSeed( 1234ULL ); // seed for GPU random numbers
+
int n_receptors = 2;
- int order = arg1/5;
+ int order = arg1 / 5;
int NE = 4 * order; // number of excitatory neurons
int NI = 1 * order; // number of inhibitory neurons
int n_neurons = NE + NI; // number of neurons in total
- int CE = 800; // number of excitatory synapses per neuron
- int CI = CE/4; // number of inhibitory synapses per neuron
+ int CE = 800; // number of excitatory synapses per neuron
+ int CI = CE / 4; // number of inhibitory synapses per neuron
float Wex = 0.05;
float Win = 0.35;
@@ -64,68 +62,66 @@ int main(int argc, char *argv[])
float poiss_delay = 0.2; // poisson signal delay in ms
// create poisson generator
- NodeSeq pg = ngpu.Create("poisson_generator");
- ngpu.SetNeuronParam(pg, "rate", poiss_rate);
+ NodeSeq pg = ngpu.Create( "poisson_generator" );
+ ngpu.SetNeuronParam( pg, "rate", poiss_rate );
// create n_neurons neurons with n_receptor receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons,
- n_receptors);
- NodeSeq exc_neuron = neuron.Subseq(0,NE-1); // excitatory neuron group
- NodeSeq inh_neuron = neuron.Subseq(NE, n_neurons-1); //inhibitory neuron group
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, n_receptors );
+ NodeSeq exc_neuron = neuron.Subseq( 0, NE - 1 ); // excitatory neuron group
+ NodeSeq inh_neuron = neuron.Subseq( NE, n_neurons - 1 ); // inhibitory neuron group
// neuron parameters
- float E_rev[] = {0.0, -85.0};
- float tau_decay[] = {1.0, 1.0};
- float tau_rise[] = {1.0, 1.0};
- ngpu.SetNeuronParam(neuron, "E_rev", E_rev, 2);
- ngpu.SetNeuronParam(neuron, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neuron, "tau_rise", tau_rise, 2);
-
+ float E_rev[] = { 0.0, -85.0 };
+ float tau_decay[] = { 1.0, 1.0 };
+ float tau_rise[] = { 1.0, 1.0 };
+ ngpu.SetNeuronParam( neuron, "E_rev", E_rev, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_decay", tau_decay, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_rise", tau_rise, 2 );
+
float mean_delay = 0.5;
float std_delay = 0.25;
float min_delay = 0.1;
// Excitatory connections
// connect excitatory neurons to port 0 of all neurons
// normally distributed delays, weight Wex and CE connections per neuron
- float *exc_delays = ngpu.RandomNormalClipped(CE*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
-
- ConnSpec conn_spec1(FIXED_INDEGREE, CE);
+ float* exc_delays =
+ ngpu.RandomNormalClipped( CE * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
+
+ ConnSpec conn_spec1( FIXED_INDEGREE, CE );
SynSpec syn_spec1;
- syn_spec1.SetParam("receptor", 0);
- syn_spec1.SetParam("weight", Wex);
- syn_spec1.SetParam("delay_array", exc_delays);
- ngpu.Connect(exc_neuron, neuron, conn_spec1, syn_spec1);
+ syn_spec1.SetParam( "receptor", 0 );
+ syn_spec1.SetParam( "weight", Wex );
+ syn_spec1.SetParam( "delay_array", exc_delays );
+ ngpu.Connect( exc_neuron, neuron, conn_spec1, syn_spec1 );
delete[] exc_delays;
// Inhibitory connections
// connect inhibitory neurons to port 1 of all neurons
// normally distributed delays, weight Win and CI connections per neuron
- float *inh_delays = ngpu.RandomNormalClipped(CI*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
+ float* inh_delays =
+ ngpu.RandomNormalClipped( CI * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
- ConnSpec conn_spec2(FIXED_INDEGREE, CI);
+ ConnSpec conn_spec2( FIXED_INDEGREE, CI );
SynSpec syn_spec2;
- syn_spec2.SetParam("receptor", 1);
- syn_spec2.SetParam("weight", Win);
- syn_spec2.SetParam("delay_array", inh_delays);
- ngpu.Connect(inh_neuron, neuron, conn_spec2, syn_spec2);
+ syn_spec2.SetParam( "receptor", 1 );
+ syn_spec2.SetParam( "weight", Win );
+ syn_spec2.SetParam( "delay_array", inh_delays );
+ ngpu.Connect( inh_neuron, neuron, conn_spec2, syn_spec2 );
delete[] inh_delays;
- ConnSpec conn_spec3(ALL_TO_ALL);
- SynSpec syn_spec3(STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0);
+ ConnSpec conn_spec3( ALL_TO_ALL );
+ SynSpec syn_spec3( STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0 );
// connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg, neuron, conn_spec3, syn_spec3);
+ ngpu.Connect( pg, neuron, conn_spec3, syn_spec3 );
char filename[] = "test_brunel_net.dat";
- int i_neuron_arr[] = {neuron[0], neuron[rand()%n_neurons],
- neuron[n_neurons-1]}; // any set of neuron indexes
+ int i_neuron_arr[] = {
+ neuron[ 0 ], neuron[ rand() % n_neurons ], neuron[ n_neurons - 1 ]
+ }; // any set of neuron indexes
// create multimeter record of V_m
- std::string var_name_arr[] = {"V_m", "V_m", "V_m"};
- ngpu.CreateRecord(string(filename), var_name_arr, i_neuron_arr, 3);
+ std::string var_name_arr[] = { "V_m", "V_m", "V_m" };
+ ngpu.CreateRecord( string( filename ), var_name_arr, i_neuron_arr, 3 );
ngpu.Simulate();
diff --git a/c++/examples/brunel_outdegree.cpp b/c++/examples/brunel_outdegree.cpp
index 3c2daf5a6..843ab73ba 100644
--- a/c++/examples/brunel_outdegree.cpp
+++ b/c++/examples/brunel_outdegree.cpp
@@ -20,40 +20,38 @@
*
*/
-
-
-
-
-#include
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
- if (argc != 2) {
- cout << "Usage: " << argv[0] << " n_neurons\n";
+ if ( argc != 2 )
+ {
+ cout << "Usage: " << argv[ 0 ] << " n_neurons\n";
return 0;
}
int arg1;
- sscanf(argv[1], "%d", &arg1);
+ sscanf( argv[ 1 ], "%d", &arg1 );
NESTGPU ngpu;
cout << "Building ...\n";
- ngpu.SetRandomSeed(12345ULL); // seed for GPU random numbers
-
+ ngpu.SetRandomSeed( 12345ULL ); // seed for GPU random numbers
+
int n_receptors = 2;
- int order = arg1/5;
+ int order = arg1 / 5;
int NE = 4 * order; // number of excitatory neurons
int NI = 1 * order; // number of inhibitory neurons
int n_neurons = NE + NI; // number of neurons in total
int CPN = 1000; // number of output connections per neuron
-
+
float Wex = 0.05;
float Win = 0.35;
@@ -63,73 +61,74 @@ int main(int argc, char *argv[])
float poiss_delay = 0.2; // poisson signal delay in ms
// create poisson generator
- NodeSeq pg = ngpu.Create("poisson_generator");
- ngpu.SetNeuronParam(pg, "rate", poiss_rate);
+ NodeSeq pg = ngpu.Create( "poisson_generator" );
+ ngpu.SetNeuronParam( pg, "rate", poiss_rate );
// create n_neurons neurons with n_receptor receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons,
- n_receptors);
- NodeSeq exc_neuron = neuron.Subseq(0,NE-1); // excitatory neuron group
- NodeSeq inh_neuron = neuron.Subseq(NE, n_neurons-1); //inhibitory neuron group
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, n_receptors );
+ NodeSeq exc_neuron = neuron.Subseq( 0, NE - 1 ); // excitatory neuron group
+ NodeSeq inh_neuron = neuron.Subseq( NE, n_neurons - 1 ); // inhibitory neuron group
// neuron parameters
- float E_rev[] = {0.0, -85.0};
- float tau_decay[] = {1.0, 1.0};
- float tau_rise[] = {1.0, 1.0};
- ngpu.SetNeuronParam(neuron, "E_rev", E_rev, 2);
- ngpu.SetNeuronParam(neuron, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neuron, "tau_rise", tau_rise, 2);
-
+ float E_rev[] = { 0.0, -85.0 };
+ float tau_decay[] = { 1.0, 1.0 };
+ float tau_rise[] = { 1.0, 1.0 };
+ ngpu.SetNeuronParam( neuron, "E_rev", E_rev, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_decay", tau_decay, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_rise", tau_rise, 2 );
+
float mean_delay = 0.5;
float std_delay = 0.25;
float min_delay = 0.1;
// Excitatory connections
// connect excitatory neurons to port 0 of all neurons
// normally distributed delays, weight Wex and CPN connections per neuron
- float *exc_delays = ngpu.RandomNormalClipped(CPN*NE, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
-
- ConnSpec conn_spec1(FIXED_OUTDEGREE, CPN);
+ float* exc_delays =
+ ngpu.RandomNormalClipped( CPN * NE, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
+
+ ConnSpec conn_spec1( FIXED_OUTDEGREE, CPN );
SynSpec syn_spec1;
- syn_spec1.SetParam("receptor", 0);
- syn_spec1.SetParam("weight", Wex);
- syn_spec1.SetParam("delay_array", exc_delays);
- ngpu.Connect(exc_neuron, neuron, conn_spec1, syn_spec1);
+ syn_spec1.SetParam( "receptor", 0 );
+ syn_spec1.SetParam( "weight", Wex );
+ syn_spec1.SetParam( "delay_array", exc_delays );
+ ngpu.Connect( exc_neuron, neuron, conn_spec1, syn_spec1 );
delete[] exc_delays;
// Inhibitory connections
// connect inhibitory neurons to port 1 of all neurons
// normally distributed delays, weight Win and CPN connections per neuron
- float *inh_delays = ngpu.RandomNormalClipped(CPN*NI, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
+ float* inh_delays =
+ ngpu.RandomNormalClipped( CPN * NI, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
- ConnSpec conn_spec2(FIXED_OUTDEGREE, CPN);
+ ConnSpec conn_spec2( FIXED_OUTDEGREE, CPN );
SynSpec syn_spec2;
- syn_spec2.SetParam("receptor", 1);
- syn_spec2.SetParam("weight", Win);
- syn_spec2.SetParam("delay_array", inh_delays);
- ngpu.Connect(inh_neuron, neuron, conn_spec2, syn_spec2);
+ syn_spec2.SetParam( "receptor", 1 );
+ syn_spec2.SetParam( "weight", Win );
+ syn_spec2.SetParam( "delay_array", inh_delays );
+ ngpu.Connect( inh_neuron, neuron, conn_spec2, syn_spec2 );
delete[] inh_delays;
- ConnSpec conn_spec3(ALL_TO_ALL);
- SynSpec syn_spec3(STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0);
+ ConnSpec conn_spec3( ALL_TO_ALL );
+ SynSpec syn_spec3( STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0 );
// connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg, neuron, conn_spec3, syn_spec3);
+ ngpu.Connect( pg, neuron, conn_spec3, syn_spec3 );
char filename[] = "test_brunel_outdegree.dat";
// any set of neuron indexes
- int i_neuron_arr[] = {neuron[0], neuron[rand()%n_neurons],
- neuron[rand()%n_neurons], neuron[rand()%n_neurons],
- neuron[rand()%n_neurons], neuron[rand()%n_neurons],
- neuron[rand()%n_neurons], neuron[rand()%n_neurons],
- neuron[rand()%n_neurons], neuron[n_neurons-1]};
+ int i_neuron_arr[] = { neuron[ 0 ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ rand() % n_neurons ],
+ neuron[ n_neurons - 1 ] };
// create multimeter record of V_m
- std::string var_name_arr[] = {"V_m", "V_m", "V_m", "V_m", "V_m", "V_m",
- "V_m", "V_m", "V_m", "V_m"};
- ngpu.CreateRecord(string(filename), var_name_arr, i_neuron_arr, 10);
+ std::string var_name_arr[] = { "V_m", "V_m", "V_m", "V_m", "V_m", "V_m", "V_m", "V_m", "V_m", "V_m" };
+ ngpu.CreateRecord( string( filename ), var_name_arr, i_neuron_arr, 10 );
ngpu.Simulate();
diff --git a/c++/examples/brunel_outdegree_mpi.cpp b/c++/examples/brunel_outdegree_mpi.cpp
index 38a8130dd..ca13bf222 100644
--- a/c++/examples/brunel_outdegree_mpi.cpp
+++ b/c++/examples/brunel_outdegree_mpi.cpp
@@ -20,55 +20,53 @@
*
*/
-
-
-
-
-#include
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
NESTGPU ngpu;
- ngpu.ConnectMpiInit(argc, argv);
+ ngpu.ConnectMpiInit( argc, argv );
int mpi_np = ngpu.MpiNp();
- if (argc != 2 || mpi_np != 2) {
- cout << "Usage: mpirun -np 2 " << argv[0] << " n_neurons\n";
+ if ( argc != 2 || mpi_np != 2 )
+ {
+ cout << "Usage: mpirun -np 2 " << argv[ 0 ] << " n_neurons\n";
ngpu.MpiFinalize();
return 0;
}
int arg1;
- sscanf(argv[1], "%d", &arg1);
-
+ sscanf( argv[ 1 ], "%d", &arg1 );
+
int mpi_id = ngpu.MpiId();
- cout << "Building on host " << mpi_id << " ..." <
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
- if (argc != 2) {
- cout << "Usage: " << argv[0] << " n_neurons\n";
+ if ( argc != 2 )
+ {
+ cout << "Usage: " << argv[ 0 ] << " n_neurons\n";
return 0;
}
int arg1;
- sscanf(argv[1], "%d", &arg1);
+ sscanf( argv[ 1 ], "%d", &arg1 );
NESTGPU ngpu;
cout << "Building ...\n";
- ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers
-
+ ngpu.SetRandomSeed( 1234ULL ); // seed for GPU random numbers
+
int n_receptors = 2;
- int order = arg1/5;
+ int order = arg1 / 5;
int NE = 4 * order; // number of excitatory neurons
int NI = 1 * order; // number of inhibitory neurons
int n_neurons = NE + NI; // number of neurons in total
- int CE = 800; // number of excitatory synapses per neuron
- int CI = CE/4; // number of inhibitory synapses per neuron
+ int CE = 800; // number of excitatory synapses per neuron
+ int CI = CE / 4; // number of inhibitory synapses per neuron
float Wex = 0.05;
float Win = 0.35;
@@ -64,72 +62,70 @@ int main(int argc, char *argv[])
float poiss_delay = 0.2; // poisson signal delay in ms
// create poisson generator
- NodeSeq pg = ngpu.Create("poisson_generator");
- ngpu.SetNeuronParam(pg, "rate", poiss_rate);
- std::vector pg_vect = pg.ToVector();
+ NodeSeq pg = ngpu.Create( "poisson_generator" );
+ ngpu.SetNeuronParam( pg, "rate", poiss_rate );
+ std::vector< int > pg_vect = pg.ToVector();
// create n_neurons neurons with n_receptor receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons,
- n_receptors);
- std::vector neuron_vect = neuron.ToVector();
- NodeSeq exc_neuron = neuron.Subseq(0,NE-1); // excitatory neuron group
- std::vector exc_neuron_vect = exc_neuron.ToVector();
- NodeSeq inh_neuron = neuron.Subseq(NE, n_neurons-1); //inhibitory neuron group
- std::vector inh_neuron_vect = inh_neuron.ToVector();
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, n_receptors );
+ std::vector< int > neuron_vect = neuron.ToVector();
+ NodeSeq exc_neuron = neuron.Subseq( 0, NE - 1 ); // excitatory neuron group
+ std::vector< int > exc_neuron_vect = exc_neuron.ToVector();
+ NodeSeq inh_neuron = neuron.Subseq( NE, n_neurons - 1 ); // inhibitory neuron group
+ std::vector< int > inh_neuron_vect = inh_neuron.ToVector();
// neuron parameters
- float E_rev[] = {0.0, -85.0};
- float tau_decay[] = {1.0, 1.0};
- float tau_rise[] = {1.0, 1.0};
- ngpu.SetNeuronParam(neuron_vect, "E_rev", E_rev, 2);
- ngpu.SetNeuronParam(neuron_vect, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neuron_vect, "tau_rise", tau_rise, 2);
-
+ float E_rev[] = { 0.0, -85.0 };
+ float tau_decay[] = { 1.0, 1.0 };
+ float tau_rise[] = { 1.0, 1.0 };
+ ngpu.SetNeuronParam( neuron_vect, "E_rev", E_rev, 2 );
+ ngpu.SetNeuronParam( neuron_vect, "tau_decay", tau_decay, 2 );
+ ngpu.SetNeuronParam( neuron_vect, "tau_rise", tau_rise, 2 );
+
float mean_delay = 0.5;
float std_delay = 0.25;
float min_delay = 0.1;
// Excitatory connections
// connect excitatory neurons to port 0 of all neurons
// normally distributed delays, weight Wex and CE connections per neuron
- float *exc_delays = ngpu.RandomNormalClipped(CE*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
-
- ConnSpec conn_spec1(FIXED_INDEGREE, CE);
+ float* exc_delays =
+ ngpu.RandomNormalClipped( CE * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
+
+ ConnSpec conn_spec1( FIXED_INDEGREE, CE );
SynSpec syn_spec1;
- syn_spec1.SetParam("receptor", 0);
- syn_spec1.SetParam("weight", Wex);
- syn_spec1.SetParam("delay_array", exc_delays);
- ngpu.Connect(exc_neuron_vect, neuron, conn_spec1, syn_spec1);
+ syn_spec1.SetParam( "receptor", 0 );
+ syn_spec1.SetParam( "weight", Wex );
+ syn_spec1.SetParam( "delay_array", exc_delays );
+ ngpu.Connect( exc_neuron_vect, neuron, conn_spec1, syn_spec1 );
delete[] exc_delays;
// Inhibitory connections
// connect inhibitory neurons to port 1 of all neurons
// normally distributed delays, weight Win and CI connections per neuron
- float *inh_delays = ngpu.RandomNormalClipped(CI*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
+ float* inh_delays =
+ ngpu.RandomNormalClipped( CI * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
- ConnSpec conn_spec2(FIXED_INDEGREE, CI);
+ ConnSpec conn_spec2( FIXED_INDEGREE, CI );
SynSpec syn_spec2;
- syn_spec2.SetParam("receptor", 1);
- syn_spec2.SetParam("weight", Win);
- syn_spec2.SetParam("delay_array", inh_delays);
- ngpu.Connect(inh_neuron, neuron_vect, conn_spec2, syn_spec2);
+ syn_spec2.SetParam( "receptor", 1 );
+ syn_spec2.SetParam( "weight", Win );
+ syn_spec2.SetParam( "delay_array", inh_delays );
+ ngpu.Connect( inh_neuron, neuron_vect, conn_spec2, syn_spec2 );
delete[] inh_delays;
- ConnSpec conn_spec3(ALL_TO_ALL);
- SynSpec syn_spec3(STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0);
+ ConnSpec conn_spec3( ALL_TO_ALL );
+ SynSpec syn_spec3( STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0 );
// connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg_vect, neuron_vect, conn_spec3, syn_spec3);
+ ngpu.Connect( pg_vect, neuron_vect, conn_spec3, syn_spec3 );
char filename[] = "test_brunel_vect.dat";
-
- int i_neuron_arr[] = {neuron[0], neuron[rand()%n_neurons],
- neuron[n_neurons-1]}; // any set of neuron indexes
+
+ int i_neuron_arr[] = {
+ neuron[ 0 ], neuron[ rand() % n_neurons ], neuron[ n_neurons - 1 ]
+ }; // any set of neuron indexes
// create multimeter record of V_m
- std::string var_name_arr[] = {"V_m", "V_m", "V_m"};
- ngpu.CreateRecord(string(filename), var_name_arr, i_neuron_arr, 3);
+ std::string var_name_arr[] = { "V_m", "V_m", "V_m" };
+ ngpu.CreateRecord( string( filename ), var_name_arr, i_neuron_arr, 3 );
ngpu.Simulate();
diff --git a/c++/examples/test_aeif_cond_beta.cpp b/c++/examples/test_aeif_cond_beta.cpp
index b5e2937e8..3fdf77779 100644
--- a/c++/examples/test_aeif_cond_beta.cpp
+++ b/c++/examples/test_aeif_cond_beta.cpp
@@ -20,65 +20,63 @@
*
*/
-
-
-
-
-#include
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
NESTGPU ngpu;
cout << "Building ...\n";
-
- srand(12345);
+
+ srand( 12345 );
int n_neurons = 10000;
-
+
// create n_neurons neurons with 3 receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons, 3);
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, 3 );
// neuron parameters
- float E_rev[] = {20.0, 0.0, -85.0};
- float tau_decay[] = {40.0, 20.0, 30.0};
- float tau_rise[] = {20.0, 10.0, 5.0};
- ngpu.SetNeuronParam(neuron, "E_rev", E_rev, 3);
- ngpu.SetNeuronParam(neuron, "tau_decay", tau_decay, 3);
- ngpu.SetNeuronParam(neuron, "tau_rise", tau_rise, 3);
- ngpu.SetNeuronParam(neuron, "a", 4.0);
- ngpu.SetNeuronParam(neuron, "b", 80.5);
- ngpu.SetNeuronParam(neuron, "E_L", -70.6);
- ngpu.SetNeuronParam(neuron, "g_L", 300.0);
+ float E_rev[] = { 20.0, 0.0, -85.0 };
+ float tau_decay[] = { 40.0, 20.0, 30.0 };
+ float tau_rise[] = { 20.0, 10.0, 5.0 };
+ ngpu.SetNeuronParam( neuron, "E_rev", E_rev, 3 );
+ ngpu.SetNeuronParam( neuron, "tau_decay", tau_decay, 3 );
+ ngpu.SetNeuronParam( neuron, "tau_rise", tau_rise, 3 );
+ ngpu.SetNeuronParam( neuron, "a", 4.0 );
+ ngpu.SetNeuronParam( neuron, "b", 80.5 );
+ ngpu.SetNeuronParam( neuron, "E_L", -70.6 );
+ ngpu.SetNeuronParam( neuron, "g_L", 300.0 );
- NodeSeq sg = ngpu.Create("spike_generator"); // create spike generator
+ NodeSeq sg = ngpu.Create( "spike_generator" ); // create spike generator
- float spike_times[] = {10.0, 400.0};
- float spike_heights[] = {1.0, 0.5};
+ float spike_times[] = { 10.0, 400.0 };
+ float spike_heights[] = { 1.0, 0.5 };
int n_spikes = 2;
// set spike times and height
- ngpu.SetNeuronParam(sg, "spike_times", spike_times, n_spikes);
- ngpu.SetNeuronParam(sg, "spike_heights", spike_heights, n_spikes);
-
- float delay[] = {1.0, 100.0, 130.0};
- float weight[] = {0.1, 0.2, 0.5};
+ ngpu.SetNeuronParam( sg, "spike_times", spike_times, n_spikes );
+ ngpu.SetNeuronParam( sg, "spike_heights", spike_heights, n_spikes );
+
+ float delay[] = { 1.0, 100.0, 130.0 };
+ float weight[] = { 0.1, 0.2, 0.5 };
- for (int i_port=0; i_port<3; i_port++) {
- ConnSpec conn_spec(ALL_TO_ALL);
- SynSpec syn_spec(STANDARD_SYNAPSE, weight[i_port], delay[i_port], i_port);
- ngpu.Connect(sg, neuron, conn_spec, syn_spec);
+ for ( int i_port = 0; i_port < 3; i_port++ )
+ {
+ ConnSpec conn_spec( ALL_TO_ALL );
+ SynSpec syn_spec( STANDARD_SYNAPSE, weight[ i_port ], delay[ i_port ], i_port );
+ ngpu.Connect( sg, neuron, conn_spec, syn_spec );
}
string filename = "test_aeif_cond_beta.dat";
- int i_neuron[] = {neuron[rand()%n_neurons]}; // any set of neuron indexes
- string var_name[] = {"V_m"};
+ int i_neuron[] = { neuron[ rand() % n_neurons ] }; // any set of neuron indexes
+ string var_name[] = { "V_m" };
// create multimeter record of V_m
- ngpu.CreateRecord(filename, var_name, i_neuron, 1);
+ ngpu.CreateRecord( filename, var_name, i_neuron, 1 );
- ngpu.Simulate(800.0);
+ ngpu.Simulate( 800.0 );
return 0;
}
diff --git a/c++/examples/test_connect.cpp b/c++/examples/test_connect.cpp
index d0f229758..359789e83 100644
--- a/c++/examples/test_connect.cpp
+++ b/c++/examples/test_connect.cpp
@@ -20,71 +20,70 @@
*
*/
-
-
-
-
-#include
#include
+#include
#include
#include "nestgpu.h"
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
const int N = 5;
-
+
NESTGPU ngpu;
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", 2*N);
- std::vector neuron_even;
- std::vector neuron_odd;
- for (int i=0; i neuron_even;
+ std::vector< int > neuron_odd;
+ for ( int i = 0; i < N; i++ )
+ {
+ neuron_even.push_back( neuron[ 2 * i ] );
+ neuron_odd.push_back( neuron[ 2 * i + 1 ] );
}
- float even_to_odd_delay[N*N];
- float even_to_odd_weight[N*N];
- float odd_to_even_delay[N*N];
- float odd_to_even_weight[N*N];
- for (int is=0; is conn_id
- = ngpu.GetConnections(neuron_even, neuron);
- std::vector conn_stat_vect
- = ngpu.GetConnectionStatus(conn_id);
+ std::vector< ConnectionId > conn_id = ngpu.GetConnections( neuron_even, neuron );
+ std::vector< ConnectionStatus > conn_stat_vect = ngpu.GetConnectionStatus( conn_id );
std::cout << "########################################\n";
std::cout << "Even to all\n";
- for (unsigned int i=0; i
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
NESTGPU ngpu;
cout << "Building ...\n";
-
- srand(12345);
+
+ srand( 12345 );
int n_neurons = 10000;
-
+
// create n_neurons neurons with 1 receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons, 1);
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, 1 );
// neuron parameters
- ngpu.SetNeuronParam(neuron, "a", 4.0);
- ngpu.SetNeuronParam(neuron, "b", 80.5);
- ngpu.SetNeuronParam(neuron, "E_L", -70.6);
- ngpu.SetNeuronParam(neuron, "I_e", 800.0);
+ ngpu.SetNeuronParam( neuron, "a", 4.0 );
+ ngpu.SetNeuronParam( neuron, "b", 80.5 );
+ ngpu.SetNeuronParam( neuron, "E_L", -70.6 );
+ ngpu.SetNeuronParam( neuron, "I_e", 800.0 );
string filename = "test_constcurr.dat";
- int i_neurons[] = {neuron[rand()%n_neurons]}; // any set of neuron indexes
- string var_name[] = {"V_m"};
+ int i_neurons[] = { neuron[ rand() % n_neurons ] }; // any set of neuron indexes
+ string var_name[] = { "V_m" };
// create multimeter record of V_m
- ngpu.CreateRecord(filename, var_name, i_neurons, 1);
+ ngpu.CreateRecord( filename, var_name, i_neurons, 1 );
ngpu.Simulate();
diff --git a/c++/examples/test_error.cpp b/c++/examples/test_error.cpp
index 32e2e9d5d..29ff5ba58 100644
--- a/c++/examples/test_error.cpp
+++ b/c++/examples/test_error.cpp
@@ -20,119 +20,117 @@
*
*/
-
-
-
-
-#include
-#include
-#include
-#include
#include "nestgpu.h"
#include "ngpu_exception.h"
+#include
+#include
+#include
+#include
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
- BEGIN_TRY {
- if (argc != 2) {
- cout << "Usage: " << argv[0] << " n_neurons\n";
+ BEGIN_TRY
+ {
+ if ( argc != 2 )
+ {
+ cout << "Usage: " << argv[ 0 ] << " n_neurons\n";
+ return 0;
+ }
+ int arg1;
+ sscanf( argv[ 1 ], "%d", &arg1 );
+ NESTGPU ngpu;
+ cout << "Building ...\n";
+
+ ngpu.SetRandomSeed( 1234ULL ); // seed for GPU random numbers
+
+ int n_receptors = 2;
+
+ int order = arg1 / 5;
+ int NE = 4 * order; // number of excitatory neurons
+ int NI = 1 * order; // number of inhibitory neurons
+ int n_neurons = NE + NI; // number of neurons in total
+
+ int CE = 800; // number of excitatory synapses per neuron
+ int CI = CE / 4; // number of inhibitory synapses per neuron
+
+ float Wex = 0.05;
+ float Win = 0.35;
+
+ // poisson generator parameters
+ float poiss_rate = 20000.0; // poisson signal rate in Hz
+ float poiss_weight = 0.37;
+ float poiss_delay = 0.2; // poisson signal delay in ms
+ int n_pg = n_neurons; // number of poisson generators
+ // create poisson generator
+ NodeSeq pg = ngpu.CreatePoissonGenerator( n_pg, poiss_rate );
+
+ // create n_neurons neurons with n_receptor receptor ports
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, n_receptors );
+
+ NodeSeq exc_neuron = neuron.Subseq( 0, NE - 1 ); // excitatory neuron group
+ NodeSeq inh_neuron = neuron.Subseq( NE, n_neurons - 1 ); // inhibitory neuron group
+
+ // neuron parameters
+ float E_rev[] = { 0.0, -85.0 };
+ float tau_decay[] = { 1.0, 1.0 };
+ float tau_rise[] = { 1.0, 1.0 };
+
+ ngpu.SetNeuronParam( neuron, "Non-existent", E_rev, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_decay", tau_decay, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_rise", tau_rise, 2 );
+
+ float mean_delay = 0.5;
+ float std_delay = 0.25;
+ float min_delay = 0.1;
+ // Excitatory connections
+ // connect excitatory neurons to port 0 of all neurons
+ // normally distributed delays, weight Wex and CE connections per neuron
+ float* exc_delays =
+ ngpu.RandomNormalClipped( CE * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
+
+ ConnSpec conn_spec1( FIXED_INDEGREE, CE );
+ SynSpec syn_spec1;
+ syn_spec1.SetParam( "receptor", 0 );
+ syn_spec1.SetParam( "weight", Wex );
+ syn_spec1.SetParam( "delay_array", exc_delays );
+ ngpu.Connect( exc_neuron, neuron, conn_spec1, syn_spec1 );
+ delete[] exc_delays;
+
+ // Inhibitory connections
+ // connect inhibitory neurons to port 1 of all neurons
+ // normally distributed delays, weight Win and CI connections per neuron
+ float* inh_delays =
+ ngpu.RandomNormalClipped( CI * n_neurons, mean_delay, std_delay, min_delay, mean_delay + 3 * std_delay );
+
+ ConnSpec conn_spec2( FIXED_INDEGREE, CI );
+ SynSpec syn_spec2;
+ syn_spec2.SetParam( "receptor", 1 );
+ syn_spec2.SetParam( "weight", Win );
+ syn_spec2.SetParam( "delay_array", inh_delays );
+ ngpu.Connect( inh_neuron, neuron, conn_spec2, syn_spec2 );
+
+ delete[] inh_delays;
+
+ ConnSpec conn_spec3( ONE_TO_ONE );
+ SynSpec syn_spec3( STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0 );
+ // connect poisson generator to port 0 of all neurons
+ ngpu.Connect( pg, neuron, conn_spec3, syn_spec3 );
+
+ char filename[] = "test_brunel_net.dat";
+ int i_neuron_arr[] = {
+ neuron[ 0 ], neuron[ rand() % n_neurons ], neuron[ n_neurons - 1 ]
+ }; // any set of neuron indexes
+ // create multimeter record of V_m
+ std::string var_name_arr[] = { "V_m", "V_m", "V_m" };
+ ngpu.CreateRecord( string( filename ), var_name_arr, i_neuron_arr, 3 );
+
+ ngpu.Simulate();
+
return 0;
}
- int arg1;
- sscanf(argv[1], "%d", &arg1);
- NESTGPU ngpu;
- cout << "Building ...\n";
-
- ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers
-
- int n_receptors = 2;
-
- int order = arg1/5;
- int NE = 4 * order; // number of excitatory neurons
- int NI = 1 * order; // number of inhibitory neurons
- int n_neurons = NE + NI; // number of neurons in total
-
- int CE = 800; // number of excitatory synapses per neuron
- int CI = CE/4; // number of inhibitory synapses per neuron
-
- float Wex = 0.05;
- float Win = 0.35;
-
- // poisson generator parameters
- float poiss_rate = 20000.0; // poisson signal rate in Hz
- float poiss_weight = 0.37;
- float poiss_delay = 0.2; // poisson signal delay in ms
- int n_pg = n_neurons; // number of poisson generators
- // create poisson generator
- NodeSeq pg = ngpu.CreatePoissonGenerator(n_pg, poiss_rate);
-
- // create n_neurons neurons with n_receptor receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons,
- n_receptors);
-
- NodeSeq exc_neuron = neuron.Subseq(0,NE-1); // excitatory neuron group
- NodeSeq inh_neuron = neuron.Subseq(NE, n_neurons-1); //inhibitory neuron group
-
- // neuron parameters
- float E_rev[] = {0.0, -85.0};
- float tau_decay[] = {1.0, 1.0};
- float tau_rise[] = {1.0, 1.0};
-
- ngpu.SetNeuronParam(neuron, "Non-existent", E_rev, 2);
- ngpu.SetNeuronParam(neuron, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neuron, "tau_rise", tau_rise, 2);
-
- float mean_delay = 0.5;
- float std_delay = 0.25;
- float min_delay = 0.1;
- // Excitatory connections
- // connect excitatory neurons to port 0 of all neurons
- // normally distributed delays, weight Wex and CE connections per neuron
- float *exc_delays = ngpu.RandomNormalClipped(CE*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
-
- ConnSpec conn_spec1(FIXED_INDEGREE, CE);
- SynSpec syn_spec1;
- syn_spec1.SetParam("receptor", 0);
- syn_spec1.SetParam("weight", Wex);
- syn_spec1.SetParam("delay_array", exc_delays);
- ngpu.Connect(exc_neuron, neuron, conn_spec1, syn_spec1);
- delete[] exc_delays;
-
- // Inhibitory connections
- // connect inhibitory neurons to port 1 of all neurons
- // normally distributed delays, weight Win and CI connections per neuron
- float *inh_delays = ngpu.RandomNormalClipped(CI*n_neurons, mean_delay,
- std_delay, min_delay,
- mean_delay+3*std_delay);
-
- ConnSpec conn_spec2(FIXED_INDEGREE, CI);
- SynSpec syn_spec2;
- syn_spec2.SetParam("receptor", 1);
- syn_spec2.SetParam("weight", Win);
- syn_spec2.SetParam("delay_array", inh_delays);
- ngpu.Connect(inh_neuron, neuron, conn_spec2, syn_spec2);
-
- delete[] inh_delays;
-
- ConnSpec conn_spec3(ONE_TO_ONE);
- SynSpec syn_spec3(STANDARD_SYNAPSE, poiss_weight, poiss_delay, 0);
- // connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg, neuron, conn_spec3, syn_spec3);
-
- char filename[] = "test_brunel_net.dat";
- int i_neuron_arr[] = {neuron[0], neuron[rand()%n_neurons],
- neuron[n_neurons-1]}; // any set of neuron indexes
- // create multimeter record of V_m
- std::string var_name_arr[] = {"V_m", "V_m", "V_m"};
- ngpu.CreateRecord(string(filename), var_name_arr, i_neuron_arr, 3);
-
- ngpu.Simulate();
-
- return 0;
- } END_TRY
+ END_TRY
return -1;
}
diff --git a/c++/examples/test_setvar.cpp b/c++/examples/test_setvar.cpp
index f161276c0..18a808c99 100644
--- a/c++/examples/test_setvar.cpp
+++ b/c++/examples/test_setvar.cpp
@@ -20,69 +20,68 @@
*
*/
-
-
-
-
-#include
+#include "nestgpu.h"
+#include
#include
+#include
#include
-#include
-#include "nestgpu.h"
using namespace std;
-int main(int argc, char *argv[])
+int
+main( int argc, char* argv[] )
{
NESTGPU ngpu;
cout << "Building ...\n";
-
- srand(12345);
+
+ srand( 12345 );
int n_neurons = 3;
-
+
// create n_neurons neurons with 2 receptor ports
- NodeSeq neuron = ngpu.Create("aeif_cond_beta", n_neurons, 2);
- float tau_decay[] = {60.0, 10.0};
- float tau_rise[] = {40.0, 5.0};
- ngpu.SetNeuronParam(neuron, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neuron, "tau_rise", tau_rise, 2);
-
- NodeSeq neuron0 = neuron.Subseq(0,0);
- NodeSeq neuron1 = neuron.Subseq(1,1);
- NodeSeq neuron2 = neuron.Subseq(2,2);
- float g11[] = {0.0, 0.1};
- float g12[] = {0.1, 0.0};
-
+ NodeSeq neuron = ngpu.Create( "aeif_cond_beta", n_neurons, 2 );
+ float tau_decay[] = { 60.0, 10.0 };
+ float tau_rise[] = { 40.0, 5.0 };
+ ngpu.SetNeuronParam( neuron, "tau_decay", tau_decay, 2 );
+ ngpu.SetNeuronParam( neuron, "tau_rise", tau_rise, 2 );
+
+ NodeSeq neuron0 = neuron.Subseq( 0, 0 );
+ NodeSeq neuron1 = neuron.Subseq( 1, 1 );
+ NodeSeq neuron2 = neuron.Subseq( 2, 2 );
+ float g11[] = { 0.0, 0.1 };
+ float g12[] = { 0.1, 0.0 };
+
// neuron variables
- ngpu.SetNeuronVar(neuron0, "V_m", -80.0);
- ngpu.SetNeuronVar(neuron1, "g1", g11, 2);
- ngpu.SetNeuronVar(neuron2, "g1", g12, 2);
+ ngpu.SetNeuronVar( neuron0, "V_m", -80.0 );
+ ngpu.SetNeuronVar( neuron1, "g1", g11, 2 );
+ ngpu.SetNeuronVar( neuron2, "g1", g12, 2 );
// reading parameters and variables test
- float *read_td = ngpu.GetNeuronParam(neuron, "tau_decay");
- float *read_tr = ngpu.GetNeuronParam(neuron, "tau_rise");
- float *read_Vm = ngpu.GetNeuronVar(neuron, "V_m");
- float *read_Vth = ngpu.GetNeuronParam(neuron, "V_th");
- float *read_g1 = ngpu.GetNeuronVar(neuron, "g1");
+ float* read_td = ngpu.GetNeuronParam( neuron, "tau_decay" );
+ float* read_tr = ngpu.GetNeuronParam( neuron, "tau_rise" );
+ float* read_Vm = ngpu.GetNeuronVar( neuron, "V_m" );
+ float* read_Vth = ngpu.GetNeuronParam( neuron, "V_th" );
+ float* read_g1 = ngpu.GetNeuronVar( neuron, "g1" );
- for (int in=0; in<3; in++) {
- printf("Neuron n. %d\n", in);
- printf("\tV_m: %f\n", read_Vm[in]);
- printf("\tV_th: %f\n", read_Vth[in]);
- for (int ip=0; ip<2; ip++) {
- printf("\tg1: %f\n", read_g1[in*2+ip]);
- printf("\ttau_rise: %f\n", read_tr[in*2+ip]);
- printf("\ttau_decay: %f\n", read_td[in*2+ip]);
+ for ( int in = 0; in < 3; in++ )
+ {
+ printf( "Neuron n. %d\n", in );
+ printf( "\tV_m: %f\n", read_Vm[ in ] );
+ printf( "\tV_th: %f\n", read_Vth[ in ] );
+ for ( int ip = 0; ip < 2; ip++ )
+ {
+ printf( "\tg1: %f\n", read_g1[ in * 2 + ip ] );
+ printf( "\ttau_rise: %f\n", read_tr[ in * 2 + ip ] );
+ printf( "\ttau_decay: %f\n", read_td[ in * 2 + ip ] );
}
- printf("\n");
+ printf( "\n" );
}
string filename = "test_setvar.dat";
- int i_neurons[] = {neuron[0], neuron[1], neuron[2]};
- string var_name[] = {"V_m", "V_m", "V_m"};
+ int i_neurons[] = { neuron[ 0 ], neuron[ 1 ], neuron[ 2 ] };
+ string var_name[] = { "V_m", "V_m", "V_m" };
// create multimeter record of V_m
- ngpu.CreateRecord(filename, var_name, i_neurons, 3);
+ ngpu.CreateRecord( filename, var_name, i_neurons, 3 );
ngpu.Simulate();
diff --git a/c++/tests/test_connections.cpp b/c++/tests/test_connections.cpp
index 018b1fe11..e69de29bb 100644
--- a/c++/tests/test_connections.cpp
+++ b/c++/tests/test_connections.cpp
@@ -1,145 +0,0 @@
-/*
- * test_connections.cpp
- *
- * This file is part of NEST GPU.
- *
- * Copyright (C) 2021 The NEST Initiative
- *
- * NEST GPU is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * NEST GPU is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NEST GPU. If not, see .
- *
- */
-
-
-
-
-
-#include
-#include
-#include
-#include
-#include
-#include "nestgpu.h"
-
-using namespace std;
-
-int main(int argc, char *argv[])
-{
- // Intializes C random number generator
- // srand((unsigned) time(&t));
-
- NESTGPU ngpu;
- cout << "Building ...\n";
-
- ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers
-
- // poisson generator parameters
- float poiss_rate = 5000.0; // poisson signal rate in Hz
- float poiss_weight = 1.0;
- float poiss_delay = 0.2; // poisson signal delay in ms
-
- // create poisson generator
- NodeSeq pg = ngpu.Create("poisson_generator");
- ngpu.SetNeuronParam(pg, "rate", poiss_rate);
-
- int n_recept = 3; // number of receptors
- // create 3 neuron groups
- int n_neur1 = 100; // number of neurons
- int n_neur2 = 20;
- int n_neur3 = 50;
- int n_neurons = n_neur1 + n_neur2 + n_neur3;
-
- NodeSeq neur_group = ngpu.Create("aeif_cond_beta", n_neurons, n_recept);
- NodeSeq neur_group1 = neur_group.Subseq(0, n_neur1 - 1);
- NodeSeq neur_group2 = neur_group.Subseq(n_neur1, n_neur1 + n_neur2 - 1);
- NodeSeq neur_group3 = neur_group.Subseq(n_neur1 + n_neur2, n_neurons - 1);
-
- // neuron parameters
- float E_rev[] = {0.0, 0.0, 0.0};
- float tau_decay[] = {1.0, 1.0, 1.0};
- float tau_rise[] = {1.0, 1.0, 1.0};
- ngpu.SetNeuronParam(neur_group1, "E_rev", E_rev, 3);
- ngpu.SetNeuronParam(neur_group1, "tau_decay", tau_decay, 3);
- ngpu.SetNeuronParam(neur_group1, "tau_rise", tau_rise, 3);
- ngpu.SetNeuronParam(neur_group2, "E_rev", E_rev, 3);
- ngpu.SetNeuronParam(neur_group2, "tau_decay", tau_decay, 3);
- ngpu.SetNeuronParam(neur_group2, "tau_rise", tau_rise, 3);
- ngpu.SetNeuronParam(neur_group3, "E_rev", E_rev, 3);
- ngpu.SetNeuronParam(neur_group3, "tau_decay", tau_decay, 3);
- ngpu.SetNeuronParam(neur_group3, "tau_rise", tau_rise, 3);
-
- int i11 = neur_group1[rand()%n_neur1];
- int i12 = neur_group2[rand()%n_neur2];
- int i13 = neur_group2[rand()%n_neur2];
- int i14 = neur_group3[rand()%n_neur3];
-
- int i21 = neur_group2[rand()%n_neur2];
-
- int i31 = neur_group1[rand()%n_neur1];
- int i32 = neur_group3[rand()%n_neur3];
-
- int it1 = neur_group1[rand()%n_neur1];
- int it2 = neur_group2[rand()%n_neur2];
- int it3 = neur_group3[rand()%n_neur3];
-
- // connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg[0], i11, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i12, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i13, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i14, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i21, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i31, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i32, 0, 0, poiss_weight, poiss_delay);
-
- float weight = 0.01; // connection weight
- float delay = 0.2; // connection delay in ms
-
- // connect neurons to target neuron n. 1
- ngpu.Connect(i11, it1, 0, 0, weight, delay);
- ngpu.Connect(i12, it1, 1, 0, weight, delay);
- ngpu.Connect(i13, it1, 1, 0, weight, delay);
- ngpu.Connect(i14, it1, 2, 0, weight, delay);
-
- // connect neuron to target neuron n. 2
- ngpu.Connect(i21, it2, 0, 0, weight, delay);
-
- // connect neurons to target neuron n. 3
- ngpu.Connect(i31, it3, 0, 0, weight, delay);
- ngpu.Connect(i32, it3, 1, 0, weight, delay);
-
- // create multimeter record n.1
- string filename1 = "test_connections_voltage.dat";
- int i_neuron_arr1[] = {i11, i12, i13, i14, i21, i31, i32, it1, it2, it3};
- std::string var_name_arr1[] = {"V_m", "V_m", "V_m", "V_m", "V_m", "V_m",
- "V_m", "V_m", "V_m", "V_m"};
- ngpu.CreateRecord(filename1, var_name_arr1, i_neuron_arr1, 10);
-
- // create multimeter record n.2
- string filename2 = "test_connections_g1.dat";
- int i_neuron_arr2[] = {it1, it1, it1, it2, it3, it3};
- int i_receptor_arr[] = {0, 1, 2, 0, 0, 1};
- std::string var_name_arr2[] = {"g1", "g1", "g1", "g1", "g1", "g1"};
- ngpu.CreateRecord(filename2, var_name_arr2, i_neuron_arr2,
- i_receptor_arr, 6);
-
- // create multimeter record n.3
- string filename3 = "test_connections_spikes.dat";
- int i_neuron_arr3[] = {i11, i12, i13, i14, i21, i31, i32};
- std::string var_name_arr3[] = {"spike", "spike", "spike", "spike", "spike",
- "spike", "spike"};
- ngpu.CreateRecord(filename3, var_name_arr3, i_neuron_arr3, 7);
-
- ngpu.Simulate();
-
- return 0;
-}
diff --git a/c++/tests/test_neuron_groups.cpp b/c++/tests/test_neuron_groups.cpp
index 5a824105b..e69de29bb 100644
--- a/c++/tests/test_neuron_groups.cpp
+++ b/c++/tests/test_neuron_groups.cpp
@@ -1,162 +0,0 @@
-/*
- * test_neuron_groups.cpp
- *
- * This file is part of NEST GPU.
- *
- * Copyright (C) 2021 The NEST Initiative
- *
- * NEST GPU is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * NEST GPU is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with NEST GPU. If not, see .
- *
- */
-
-
-
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "nestgpu.h"
-
-using namespace std;
-
-int main(int argc, char *argv[])
-{
- // Intializes C random number generator
- // srand((unsigned) time(&t));
-
- NESTGPU ngpu;
- cout << "Building ...\n";
-
- ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers
-
- // poisson generator parameters
- float poiss_rate = 5000.0; // poisson signal rate in Hz
- float poiss_weight = 1.0;
- float poiss_delay = 0.2; // poisson signal delay in ms
-
- // create poisson generator
- NodeSeq pg = ngpu.Create("poisson_generator");
- ngpu.SetNeuronParam(pg, "rate", poiss_rate);
-
- // create 3 neuron groups
- int n_neur1 = 100; // number of neurons
- int n_recept1 = 3; // number of receptors
- NodeSeq neur_group1 = ngpu.Create("aeif_cond_beta", n_neur1, n_recept1);
- int n_neur2 = 20; // number of neurons
- int n_recept2 = 1; // number of receptors
- NodeSeq neur_group2 = ngpu.Create("aeif_cond_beta", n_neur2, n_recept2);
- int n_neur3 = 50; // number of neurons
- int n_recept3 = 2; // number of receptors
- NodeSeq neur_group3 = ngpu.Create("aeif_cond_beta", n_neur3, n_recept3);
-
- // neuron parameters
- float E_rev[] = {0.0, 0.0, 0.0};
- float tau_decay[] = {1.0, 1.0, 1.0};
- float tau_rise[] = {1.0, 1.0, 1.0};
- ngpu.SetNeuronParam(neur_group1, "E_rev", E_rev, 3);
- ngpu.SetNeuronParam(neur_group1, "tau_decay", tau_decay, 3);
- ngpu.SetNeuronParam(neur_group1, "tau_rise", tau_rise, 3);
- ngpu.SetNeuronParam(neur_group2, "E_rev", E_rev, 1);
- ngpu.SetNeuronParam(neur_group2, "tau_decay", tau_decay, 1);
- ngpu.SetNeuronParam(neur_group2, "tau_rise", tau_rise, 1);
- ngpu.SetNeuronParam(neur_group3, "E_rev", E_rev, 2);
- ngpu.SetNeuronParam(neur_group3, "tau_decay", tau_decay, 2);
- ngpu.SetNeuronParam(neur_group3, "tau_rise", tau_rise, 2);
-
- int i11 = neur_group1[rand()%n_neur1];
- int i12 = neur_group2[rand()%n_neur2];
- int i13 = neur_group2[rand()%n_neur2];
- int i14 = neur_group3[rand()%n_neur3];
-
- int i21 = neur_group2[rand()%n_neur2];
-
- int i31 = neur_group1[rand()%n_neur1];
- int i32 = neur_group3[rand()%n_neur3];
-
- int it1 = neur_group1[rand()%n_neur1];
- int it2 = neur_group2[rand()%n_neur2];
- int it3 = neur_group3[rand()%n_neur3];
-
- // connect poisson generator to port 0 of all neurons
- ngpu.Connect(pg[0], i11, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i12, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i13, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i14, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i21, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i31, 0, 0, poiss_weight, poiss_delay);
- ngpu.Connect(pg[0], i32, 0, 0, poiss_weight, poiss_delay);
-
- float weight = 0.01; // connection weight
- float delay = 0.2; // connection delay in ms
-
- // connect neurons to target neuron n. 1
- ngpu.Connect(i11, it1, 0, 0, weight, delay);
- ngpu.Connect(i12, it1, 1, 0, weight, delay);
- ngpu.Connect(i13, it1, 1, 0, weight, delay);
- ngpu.Connect(i14, it1, 2, 0, weight, delay);
-
- // connect neuron to target neuron n. 2
- ngpu.Connect(i21, it2, 0, 0, weight, delay);
-
- // connect neurons to target neuron n. 3
- ngpu.Connect(i31, it3, 0, 0, weight, delay);
- ngpu.Connect(i32, it3, 1, 0, weight, delay);
-
- // create multimeter record n.1
- string filename1 = "test_neuron_groups_voltage.dat";
- int i_neuron_arr1[] = {i11, i12, i13, i14, i21, i31, i32, it1, it2, it3};
- string var_name_arr1[] = {"V_m", "V_m", "V_m", "V_m", "V_m", "V_m",
- "V_m", "V_m", "V_m", "V_m"};
- int record1 = ngpu.CreateRecord(filename1, var_name_arr1,
- i_neuron_arr1, 10);
-
- // create multimeter record n.2
- string filename2 = "test_neuron_groups_g1.dat";
- int i_neuron_arr2[] = {it1, it1, it1, it2, it3, it3};
- int i_receptor_arr[] = {0, 1, 2, 0, 0, 1};
- string var_name_arr2[] = {"g1", "g1", "g1", "g1", "g1", "g1"};
- //int record2 =
- ngpu.CreateRecord(filename2, var_name_arr2,
- i_neuron_arr2, i_receptor_arr, 6);
-
- // create multimeter record n.3
- string filename3 = "test_neuron_groups_spikes.dat";
- int i_neuron_arr3[] = {i11, i12, i13, i14, i21, i31, i32};
- string var_name_arr3[] = {"spike", "spike", "spike", "spike", "spike",
- "spike", "spike"};
- //int record3 =
- ngpu.CreateRecord(filename3, var_name_arr3,
- i_neuron_arr3, 7);
-
- ngpu.Simulate();
-
- std::vector> data_vect1 =
- *ngpu.GetRecordData(record1);
-
- FILE *fp=fopen("test_neuron_group_record.dat", "w");
- for (uint i=0; i vect = data_vect1[i];
- for (uint j=0; jfull_test.dat
+:>full_req_mem.dat
+:>full_out_of_mem.dat
+
+for T in 0 1; do
+ for P in $(cat n_mpi_list.txt); do
+ for N in $(cat n_neuron_list.txt); do
+ R=0
+ id=P$P-N$N-R$R
+ for iP in $(seq 0 $(($P-1))); do
+ :> test_$iP.dat
+ :> req_mem_$iP.dat
+ done
+ mpirun -np $P python3 test.py --N=$N --R=$R --T=$T |& tee log_$id.txt
+ for iP in $(seq 0 $(($P-1))); do
+ cat test_$iP.dat >> full_test.dat
+ cat req_mem_$iP.dat >> full_req_mem.dat
+ done
+ l=$(cat test_0.dat | wc -l)
+ if [ $l -eq 0 ]; then
+ cat req_mem_0.dat >> full_out_of_mem.dat
+ fi
+ for C in $(cat n_conn_list.txt); do
+ for R in 1 2 3; do
+ id=P$P-N$N-C$C-R$R
+ for iP in $(seq 0 $(($P-1))); do
+ :> test_$iP.dat
+ :> req_mem_$iP.dat
+ done
+ mpirun -np $P python3 test.py --N=$N --C=$C --R=$R --T=$T |& tee log_$id.txt
+ for iP in $(seq 0 $(($P-1))); do
+ cat test_$iP.dat >> full_test.dat
+ cat req_mem_$iP.dat >> full_req_mem.dat
+ done
+ l=$(cat test_0.dat | wc -l)
+ if [ $l -eq 0 ]; then
+ cat req_mem_0.dat >> full_out_of_mem.dat
+ fi
+ done
+ done
+
+ R=4
+ id=P$P-N$N-R$R
+ for iP in $(seq 0 $(($P-1))); do
+ :> test_$iP.dat
+ :> req_mem_$iP.dat
+ done
+ mpirun -np $P python3 test.py --N=$N --R=$R --T=$T |& tee log_$id.txt
+ for iP in $(seq 0 $(($P-1))); do
+ cat test_$iP.dat >> full_test.dat
+ cat req_mem_$iP.dat >> full_req_mem.dat
+ done
+ l=$(cat test_0.dat | wc -l)
+ if [ $l -eq 0 ]; then
+ cat req_mem_0.dat >> full_out_of_mem.dat
+ fi
+ done
+ done
+done
+
+./summary.sh | tee summary.txt
diff --git a/python/mpi_mem_check/n_conn_list.txt b/python/mpi_mem_check/n_conn_list.txt
new file mode 100644
index 000000000..7262e0bf9
--- /dev/null
+++ b/python/mpi_mem_check/n_conn_list.txt
@@ -0,0 +1 @@
+1 10 100 1000 10000
diff --git a/python/mpi_mem_check/n_mpi_list.txt b/python/mpi_mem_check/n_mpi_list.txt
new file mode 100644
index 000000000..78d399bc3
--- /dev/null
+++ b/python/mpi_mem_check/n_mpi_list.txt
@@ -0,0 +1 @@
+2 3 4 5 6
diff --git a/python/mpi_mem_check/n_neuron_list.txt b/python/mpi_mem_check/n_neuron_list.txt
new file mode 100644
index 000000000..78fa7cf7c
--- /dev/null
+++ b/python/mpi_mem_check/n_neuron_list.txt
@@ -0,0 +1 @@
+1 10 100 1000 10000
diff --git a/python/mpi_mem_check/run_terminal.sh b/python/mpi_mem_check/run_terminal.sh
new file mode 100644
index 000000000..f12529e4b
--- /dev/null
+++ b/python/mpi_mem_check/run_terminal.sh
@@ -0,0 +1,8 @@
+#!/bin/bash -x
+
+NP=2
+if [ ! -z $1 ]; then
+ NP=$1
+fi
+
+mpirun -np $NP python3 test.py |& tee log.txt
diff --git a/python/mpi_mem_check/summary.sh b/python/mpi_mem_check/summary.sh
new file mode 100755
index 000000000..9b337025a
--- /dev/null
+++ b/python/mpi_mem_check/summary.sh
@@ -0,0 +1,66 @@
+#evaluates total number of MPI processes launched by benchmark_terminal script
+n_mpi=$(cat n_mpi_list.txt | head -1 | sed 's/^ *//;s/ *$//;s/ */+/g' | bc -l)
+n_loop_neur=$(cat n_neuron_list.txt | head -1 | awk '{print NF}')
+n_loop_conn=$(cat n_conn_list.txt | head -1 | awk '{print NF}')
+Ntot_th=$(( 2 * ( $n_mpi * $n_loop_neur * ( 2 + 3 * $n_loop_conn ) ) )) # 3400
+
+cat full_req_mem.dat | awk '{print $1, $2, $3, $4, $5}' | sort -n > list_all.dat
+Ntot_proc=$(cat list_all.dat | wc -l)
+echo "$Ntot_proc MPI processes out of $Ntot_th expected have been processed"
+if [ $Ntot_proc -lt $Ntot_th ]; then
+ echo "Error: not all expected MPI processes have been processed"
+elif [ $Ntot_proc -gt $Ntot_th ]; then
+ echo "Error: number of processed MPI processes is larger than expected"
+fi
+
+N_complete=$(cat full_test.dat | wc -l)
+echo "$N_complete MPI processes have been completed"
+N_passed=$(cat full_test.dat | awk '{print $10}' | grep '^1' | wc -l)
+echo "$N_passed MPI processes out of $N_complete completed have GPU memory usage in the predicted range"
+N_notpassed=$(($N_complete - $N_passed))
+if [ $N_notpassed -ne 0 ]; then
+ cat full_test.dat | awk '{print $10}' | grep '^0'
+ echo "$N_notpassed MPI processes out of $N_complete completed do not have GPU memory usage in the predicted range"
+ echo "TEST NOT PASSED"
+ exit 1
+fi
+
+cat full_test.dat | awk '{print $1, $2, $3, $4, $5}' | sort -n > list_complete.dat
+diff list_complete.dat list_all.dat | grep '>' | awk '{print $2, $4, $5, $6}' | sort -n | uniq > list_not_complete.dat
+diff list_complete.dat list_all.dat | grep '>' | awk '{print $2, $3, $4, $5, $6}' | sort -n > list_not_complete_proc.dat
+
+N_not_complete_mpirun=$(cat list_not_complete.dat | wc -l)
+echo "$N_not_complete_mpirun mpirun launches have not been completed"
+N_not_complete=$(($Ntot_proc - $N_complete))
+echo "$N_not_complete MPI processes have not been completed"
+N_not_complete_check=$(cat list_not_complete_proc.dat | wc -l)
+if [ $N_not_complete_check -ne $N_not_complete ]; then
+ echo "Error: inconsistent number of MPI processes that have not been completed. Check this script"
+fi
+
+cat full_req_mem.dat | while read a b c d e f g h i; do
+ out_of_mem=$(echo "($i * $a) > $g" | bc -l)
+ echo "$a $b $c $d $e $f $g $h $i $out_of_mem"
+done | grep '1$' | awk '{print $1, $2, $3, $4, $5, $6, $7, $8, $9}' | sort -n > list_out_of_mem_proc.dat
+
+N_not_complete_expected=0
+N_not_complete_unexpected=0
+while read l; do
+ if grep -q "^$l" list_out_of_mem_proc.dat; then
+ N_not_complete_expected=$(( $N_not_complete_expected + 1 ))
+ else
+ N_not_complete_unexpected=$(( $N_not_complete_unexpected + 1 ))
+ fi
+done <<< "$(cat list_not_complete_proc.dat)"
+
+echo -n "$N_not_complete_expected MPI processes out of $N_not_complete MPI processes that have not been completed"
+echo " are in the list of the procesess that were predicted to go out of memory"
+echo -n "$N_not_complete_unexpected MPI processes out of $N_not_complete MPI processes that have not been completed"
+echo " are NOT in the list of the procesess that were predicted to go out of memory"
+if [ $N_not_complete_unexpected -eq 0 ]; then
+ echo "TEST PASSED"
+ exit 0
+else
+ echo "TEST NOT PASSED"
+ exit 1
+fi
diff --git a/python/mpi_mem_check/test.py b/python/mpi_mem_check/test.py
index 4caaeab2d..5e5ab9084 100644
--- a/python/mpi_mem_check/test.py
+++ b/python/mpi_mem_check/test.py
@@ -18,10 +18,13 @@
2 -> Fixed outdegree rule.
3 -> Fixed total number rule.
4 -> All to all connections. Argument C will be ignored.
+ T: Connection struct type. Intege
+ 0 -> 12 byte connection structure
+ 1 -> 16 byte connection structure
"""
-
+from mpi4py import MPI
import nestgpu as ngpu
from argparse import ArgumentParser
@@ -31,6 +34,7 @@
parser.add_argument("--N", type=int, default=1000)
parser.add_argument("--C", type=int, default=10000)
parser.add_argument("--R", type=int, default=1)
+parser.add_argument("--T", type=int, default=0)
args = parser.parse_args()
rules_dict = {
@@ -41,12 +45,13 @@
4: [{"rule": "all_to_all"}],
}
-assert args.N > 0 and args.C > 0 and args.R in rules_dict
+conn_struct_type = args.T
+assert args.N > 0 and args.C > 0 and args.R in rules_dict and args.T >= 0 and args.T <= 1
+ngpu.SetKernelStatus({"verbosity_level": 5, "conn_struct_type": conn_struct_type})
ngpu.ConnectMpiInit()
-
mpi_id = ngpu.HostId()
mpi_np = ngpu.HostNum()
rank_list = list(range(mpi_np))
@@ -64,6 +69,60 @@
print(f"Creating {args.N} neurons per MPI rank")
print(f"Connection rule: {rule}")
+block_size = 10000000
+bytes_per_storage = 4
+bytes_per_node = 4
+if conn_struct_type==0:
+ bytes_per_conn = 12
+else:
+ bytes_per_conn = 16
+
+margin = 10 # margin in MB
+
+if args.R==0:
+ cuda_mem_exp = 0
+ cuda_mem_exp_woh = 0
+else:
+ if args.R==1 or args.R==2:
+ n_conn = int(args.C*args.N)
+ elif args.R==3:
+ n_conn = int(args.C)
+ elif args.R==4:
+ n_conn = int(args.N*args.N)
+ else:
+ n_conn = int(0)
+
+ n_blocks = (n_conn*(mpi_np - 1) - 1) // block_size + 1
+
+ cuda_mem_exp = (n_blocks*block_size*bytes_per_conn \
+ + block_size*bytes_per_storage)/1024/1024
+
+ cuda_mem_exp_oh = n_conn*bytes_per_node/1024/1024
+
+ cuda_mem_exp_woh = cuda_mem_exp + cuda_mem_exp_oh
+
+# Total CUDA memory (for all hosts)
+cuda_mem_tot = ngpu.getCUDAMemTotal()/1024/1024
+
+# Free CUDA memory (for all hosts)
+cuda_mem_free = ngpu.getCUDAMemFree()/1024/1024
+
+
+req_mem_str = f"{mpi_np}\t{mpi_id}\t{args.N}\t{args.C}\t{args.R}\t" \
+ f"{cuda_mem_tot:>9.3f}\t{cuda_mem_free:>9.3f}\t" \
+ f"{cuda_mem_exp:>9.3f}\t{cuda_mem_exp_woh:>9.3f}\n"
+
+print(f"CUDA available and requested memory summary\n"
+ f"mpi_np\tmpi_id\tN\tC\tR\ttotal (MB)\tfree (MB)\t"
+ f"exp/hst(no OH)\texp/hst(+OH)\n" + req_mem_str)
+
+req_mem_file_name = f"req_mem_{mpi_id}.dat"
+with open(req_mem_file_name, "w") as req_mem_file:
+ req_mem_file.write(req_mem_str)
+
+
+comm = MPI.COMM_WORLD
+comm.Barrier()
neurons = []
for i in rank_list:
@@ -76,6 +135,28 @@
if i != j:
ngpu.RemoteConnect(i, neurons[i], j, neurons[j], rule[0], {})
+cuda_mem_used = ngpu.getCUDAMemHostUsed()/1024/1024
+
+cuda_mem_max = ngpu.getCUDAMemHostPeak()/1024/1024
+
+if cuda_mem_max>=cuda_mem_exp and cuda_mem_max<(cuda_mem_exp_woh+margin):
+ test_passed = 1
+else:
+ test_passed = 0
+
+out_str = f"{mpi_np}\t{mpi_id}\t{args.N}\t{args.C}\t{args.R}\t" \
+ f"{cuda_mem_used:>9.3f}\t{cuda_mem_max:>9.3f}\t" \
+ f"{cuda_mem_exp:>9.3f}\t{cuda_mem_exp_woh:>9.3f}\t" \
+ f"{test_passed}\n"
+
+print(f"CUDA memory usage summary\n"
+ f"mpi_np\tmpi_id\tN\tC\tR\tused (MB)\tmax (MB)\t"
+ f"exp/hst(no OH)\texp/hst(+OH)\t"
+ f"passed\n" + out_str)
+
+test_file_name = f"test_{mpi_id}.dat"
+with open(test_file_name, "w") as test_file:
+ test_file.write(out_str)
ngpu.MpiFinalize()
diff --git a/python/test/log_remote_connect.txt b/python/test/log_remote_connect.txt
new file mode 100644
index 000000000..fe87f23dd
--- /dev/null
+++ b/python/test/log_remote_connect.txt
@@ -0,0 +1,36 @@
+CHECK 0 {'index': 0, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 150.0, 'weight': 5.0}
+CHECK 0 {'index': 10, 'source': 11, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 100.0, 'weight': 25.0}
+CHECK 0 {'index': 11, 'source': 11, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 150.0, 'weight': 25.0}
+CHECK 0 {'index': 1, 'source': 6, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 5.0}
+CHECK 0 {'index': 2, 'source': 7, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 100.0, 'weight': 15.0}
+CHECK 0 {'index': 3, 'source': 7, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 15.0}
+CHECK 0 {'index': 4, 'source': 8, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 100.0, 'weight': 25.0}
+CHECK 0 {'index': 5, 'source': 8, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 150.0, 'weight': 25.0}
+CHECK 0 {'index': 6, 'source': 9, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 150.0, 'weight': 5.0}
+CHECK 0 {'index': 7, 'source': 9, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 5.0}
+CHECK 0 {'index': 8, 'source': 10, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 100.0, 'weight': 15.0}
+CHECK 0 {'index': 9, 'source': 10, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 15.0}
+CHECK 1 {'index': 0, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 250.0, 'weight': 5.0}
+CHECK 1 {'index': 10, 'source': 11, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 25.0}
+CHECK 1 {'index': 11, 'source': 11, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 250.0, 'weight': 25.0}
+CHECK 1 {'index': 1, 'source': 6, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 5.0}
+CHECK 1 {'index': 2, 'source': 7, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 15.0}
+CHECK 1 {'index': 3, 'source': 7, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 15.0}
+CHECK 1 {'index': 4, 'source': 8, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 25.0}
+CHECK 1 {'index': 5, 'source': 8, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 250.0, 'weight': 25.0}
+CHECK 1 {'index': 6, 'source': 9, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 250.0, 'weight': 5.0}
+CHECK 1 {'index': 7, 'source': 9, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 5.0}
+CHECK 1 {'index': 8, 'source': 10, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 200.0, 'weight': 15.0}
+CHECK 1 {'index': 9, 'source': 10, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 15.0}
+CHECK 2 {'index': 0, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 350.0, 'weight': 5.0}
+CHECK 2 {'index': 10, 'source': 11, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 25.0}
+CHECK 2 {'index': 11, 'source': 11, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 350.0, 'weight': 25.0}
+CHECK 2 {'index': 1, 'source': 6, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 400.0, 'weight': 5.0}
+CHECK 2 {'index': 2, 'source': 7, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 15.0}
+CHECK 2 {'index': 3, 'source': 7, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 400.0, 'weight': 15.0}
+CHECK 2 {'index': 4, 'source': 8, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 25.0}
+CHECK 2 {'index': 5, 'source': 8, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 350.0, 'weight': 25.0}
+CHECK 2 {'index': 6, 'source': 9, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 350.0, 'weight': 5.0}
+CHECK 2 {'index': 7, 'source': 9, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 400.0, 'weight': 5.0}
+CHECK 2 {'index': 8, 'source': 10, 'target': 0, 'port': 0, 'syn_group': 0, 'delay': 300.0, 'weight': 15.0}
+CHECK 2 {'index': 9, 'source': 10, 'target': 2, 'port': 0, 'syn_group': 0, 'delay': 400.0, 'weight': 15.0}
diff --git a/python/test/logp3_connect.txt b/python/test/logp3_connect.txt
index 98e6af519..b0bd8aad5 100644
--- a/python/test/logp3_connect.txt
+++ b/python/test/logp3_connect.txt
@@ -10,31 +10,31 @@
########################################
Even to all
-{'index': 0, 'source': 0, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 1.0, 'weight': 100.0}
-{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 3.0, 'weight': 300.0}
-{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 5.0, 'weight': 500.0}
-{'index': 3, 'source': 0, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 7.0, 'weight': 700.0}
-{'index': 4, 'source': 0, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 9.0, 'weight': 900.0}
-{'index': 10, 'source': 2, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 21.0, 'weight': 2100.0}
-{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 23.0, 'weight': 2300.0}
-{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 25.0, 'weight': 2500.0}
-{'index': 13, 'source': 2, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 27.0, 'weight': 2700.0}
-{'index': 14, 'source': 2, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 29.0, 'weight': 2900.0}
-{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 41.0, 'weight': 4100.0}
-{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 43.0, 'weight': 4300.0}
-{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 45.0, 'weight': 4500.0}
-{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 47.0, 'weight': 4700.0}
-{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 49.0, 'weight': 4900.0}
-{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 61.0, 'weight': 6100.0}
-{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 63.0, 'weight': 6300.0}
-{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 65.0, 'weight': 6500.0}
-{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 67.0, 'weight': 6700.0}
-{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 69.0, 'weight': 6900.0}
-{'index': 40, 'source': 8, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 81.0, 'weight': 8100.0}
-{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 83.0, 'weight': 8300.0}
-{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 85.0, 'weight': 8500.0}
-{'index': 43, 'source': 8, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 87.0, 'weight': 8700.0}
-{'index': 44, 'source': 8, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 89.0, 'weight': 8900.0}
+{'index': 0, 'source': 0, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 1.0, 'weight': 100.0}
+{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 3.0, 'weight': 300.0}
+{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 5.0, 'weight': 500.0}
+{'index': 3, 'source': 0, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 7.0, 'weight': 700.0}
+{'index': 4, 'source': 0, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 9.0, 'weight': 900.0}
+{'index': 10, 'source': 2, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 21.0, 'weight': 2100.0}
+{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 23.0, 'weight': 2300.0}
+{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 25.0, 'weight': 2500.0}
+{'index': 13, 'source': 2, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 27.0, 'weight': 2700.0}
+{'index': 14, 'source': 2, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 29.0, 'weight': 2900.0}
+{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 41.0, 'weight': 4100.0}
+{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 43.0, 'weight': 4300.0}
+{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 45.0, 'weight': 4500.0}
+{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 47.0, 'weight': 4700.0}
+{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 49.0, 'weight': 4900.0}
+{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 61.0, 'weight': 6100.0}
+{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 63.0, 'weight': 6300.0}
+{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 65.0, 'weight': 6500.0}
+{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 67.0, 'weight': 6700.0}
+{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 69.0, 'weight': 6900.0}
+{'index': 40, 'source': 8, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 81.0, 'weight': 8100.0}
+{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 83.0, 'weight': 8300.0}
+{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 85.0, 'weight': 8500.0}
+{'index': 43, 'source': 8, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 87.0, 'weight': 8700.0}
+{'index': 44, 'source': 8, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 89.0, 'weight': 8900.0}
########################################
@@ -45,59 +45,59 @@ Even to all weight, delat
########################################
All to odd
-{'index': 0, 'source': 0, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 1.0, 'weight': 100.0}
-{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 3.0, 'weight': 300.0}
-{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 5.0, 'weight': 500.0}
-{'index': 3, 'source': 0, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 7.0, 'weight': 700.0}
-{'index': 4, 'source': 0, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 9.0, 'weight': 900.0}
-{'index': 10, 'source': 2, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 21.0, 'weight': 2100.0}
-{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 23.0, 'weight': 2300.0}
-{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 25.0, 'weight': 2500.0}
-{'index': 13, 'source': 2, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 27.0, 'weight': 2700.0}
-{'index': 14, 'source': 2, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 29.0, 'weight': 2900.0}
-{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 41.0, 'weight': 4100.0}
-{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 43.0, 'weight': 4300.0}
-{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 45.0, 'weight': 4500.0}
-{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 47.0, 'weight': 4700.0}
-{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 49.0, 'weight': 4900.0}
-{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 61.0, 'weight': 6100.0}
-{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 63.0, 'weight': 6300.0}
-{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 65.0, 'weight': 6500.0}
-{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 67.0, 'weight': 6700.0}
-{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 69.0, 'weight': 6900.0}
-{'index': 40, 'source': 8, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 81.0, 'weight': 8100.0}
-{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 83.0, 'weight': 8300.0}
-{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 85.0, 'weight': 8500.0}
-{'index': 43, 'source': 8, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 87.0, 'weight': 8700.0}
-{'index': 44, 'source': 8, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 89.0, 'weight': 8900.0}
+{'index': 0, 'source': 0, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 1.0, 'weight': 100.0}
+{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 3.0, 'weight': 300.0}
+{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 5.0, 'weight': 500.0}
+{'index': 3, 'source': 0, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 7.0, 'weight': 700.0}
+{'index': 4, 'source': 0, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 9.0, 'weight': 900.0}
+{'index': 10, 'source': 2, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 21.0, 'weight': 2100.0}
+{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 23.0, 'weight': 2300.0}
+{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 25.0, 'weight': 2500.0}
+{'index': 13, 'source': 2, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 27.0, 'weight': 2700.0}
+{'index': 14, 'source': 2, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 29.0, 'weight': 2900.0}
+{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 41.0, 'weight': 4100.0}
+{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 43.0, 'weight': 4300.0}
+{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 45.0, 'weight': 4500.0}
+{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 47.0, 'weight': 4700.0}
+{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 49.0, 'weight': 4900.0}
+{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 61.0, 'weight': 6100.0}
+{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 63.0, 'weight': 6300.0}
+{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 65.0, 'weight': 6500.0}
+{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 67.0, 'weight': 6700.0}
+{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 69.0, 'weight': 6900.0}
+{'index': 40, 'source': 8, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 81.0, 'weight': 8100.0}
+{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 83.0, 'weight': 8300.0}
+{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 85.0, 'weight': 8500.0}
+{'index': 43, 'source': 8, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 87.0, 'weight': 8700.0}
+{'index': 44, 'source': 8, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 89.0, 'weight': 8900.0}
########################################
Even to 3,4,5,6
-{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 3.0, 'weight': 300.0}
-{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 5.0, 'weight': 500.0}
-{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 23.0, 'weight': 2300.0}
-{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 25.0, 'weight': 2500.0}
-{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 43.0, 'weight': 4300.0}
-{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 45.0, 'weight': 4500.0}
-{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 63.0, 'weight': 6300.0}
-{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 65.0, 'weight': 6500.0}
-{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 83.0, 'weight': 8300.0}
-{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 85.0, 'weight': 8500.0}
+{'index': 1, 'source': 0, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 3.0, 'weight': 300.0}
+{'index': 2, 'source': 0, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 5.0, 'weight': 500.0}
+{'index': 11, 'source': 2, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 23.0, 'weight': 2300.0}
+{'index': 12, 'source': 2, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 25.0, 'weight': 2500.0}
+{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 43.0, 'weight': 4300.0}
+{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 45.0, 'weight': 4500.0}
+{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 63.0, 'weight': 6300.0}
+{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 65.0, 'weight': 6500.0}
+{'index': 41, 'source': 8, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 83.0, 'weight': 8300.0}
+{'index': 42, 'source': 8, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 85.0, 'weight': 8500.0}
########################################
3,4,5,6 to odd
-{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 41.0, 'weight': 4100.0}
-{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 43.0, 'weight': 4300.0}
-{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 45.0, 'weight': 4500.0}
-{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 47.0, 'weight': 4700.0}
-{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 49.0, 'weight': 4900.0}
-{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': b'\x00', 'delay': 61.0, 'weight': 6100.0}
-{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': b'\x00', 'delay': 63.0, 'weight': 6300.0}
-{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': b'\x00', 'delay': 65.0, 'weight': 6500.0}
-{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': b'\x00', 'delay': 67.0, 'weight': 6700.0}
-{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': b'\x00', 'delay': 69.0, 'weight': 6900.0}
+{'index': 20, 'source': 4, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 41.0, 'weight': 4100.0}
+{'index': 21, 'source': 4, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 43.0, 'weight': 4300.0}
+{'index': 22, 'source': 4, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 45.0, 'weight': 4500.0}
+{'index': 23, 'source': 4, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 47.0, 'weight': 4700.0}
+{'index': 24, 'source': 4, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 49.0, 'weight': 4900.0}
+{'index': 30, 'source': 6, 'target': 1, 'port': 0, 'syn_group': 0, 'delay': 61.0, 'weight': 6100.0}
+{'index': 31, 'source': 6, 'target': 3, 'port': 0, 'syn_group': 0, 'delay': 63.0, 'weight': 6300.0}
+{'index': 32, 'source': 6, 'target': 5, 'port': 0, 'syn_group': 0, 'delay': 65.0, 'weight': 6500.0}
+{'index': 33, 'source': 6, 'target': 7, 'port': 0, 'syn_group': 0, 'delay': 67.0, 'weight': 6700.0}
+{'index': 34, 'source': 6, 'target': 9, 'port': 0, 'syn_group': 0, 'delay': 69.0, 'weight': 6900.0}
Calibrating ...
diff --git a/python/test/test_mpi.sh b/python/test/test_mpi.sh
index 9560bb926..56f3e7ba8 100755
--- a/python/test/test_mpi.sh
+++ b/python/test/test_mpi.sh
@@ -11,3 +11,4 @@ for fn in test_brunel_mpi.py test_brunel_outdegree_mpi.py test_izh_psc_exp_2s_mp
fi
echo $fn : ${mpi_pass_str[$res]}
done
+. test_remote_connect.sh
diff --git a/python/test/test_remote_connect.py b/python/test/test_remote_connect.py
new file mode 100644
index 000000000..e586560ef
--- /dev/null
+++ b/python/test/test_remote_connect.py
@@ -0,0 +1,59 @@
+import sys
+import math
+import ctypes
+import nestgpu as ngpu
+from random import randrange
+import numpy as np
+
+
+ngpu.ConnectMpiInit();
+mpi_np = ngpu.HostNum()
+
+if mpi_np != 3:
+ print ("Usage: mpirun -np 3 python %s" % sys.argv[0])
+ quit()
+
+mpi_id = ngpu.HostId()
+print("Building on host ", mpi_id, " ...")
+
+ngpu.SetKernelStatus("rnd_seed", 1234) # seed for GPU random numbers
+
+neuron = ngpu.Create('iaf_psc_exp_g', 3)
+
+spike = ngpu.Create("spike_generator", 3)
+
+for i in range(3):
+ spike_times = [1.0*(mpi_id*20 + i*5 + 10), 50.0 + 1.0*(mpi_id*20 + i*5 + 10)]
+ n_spikes = 2
+ # set spike times and height
+ ngpu.SetStatus([spike[i]], {"spike_times": spike_times})
+
+
+conn_spec = {"rule": "one_to_one"}
+
+for ish in range(3):
+ for ith in range(3):
+ if ish != ith:
+ for isn in range(3):
+ for itn in range(3):
+ if itn != isn:
+ delay = 100 + 100.0*ith + 50.0*itn
+ weight = 5.0 + 10.0*isn
+ syn_spec = {'weight': weight, 'delay': delay}
+ #print (ish, [spike[isn]], ith, [neuron[itn]])
+ #ngpu.RemoteConnect(ish, spike[isn:isn+1], \
+ # ith, neuron[itn:itn+1], \
+ # conn_spec, syn_spec)
+ ngpu.RemoteConnect(ish, [spike[isn]], \
+ ith, [neuron[itn]], \
+ conn_spec, syn_spec)
+
+
+ngpu.Simulate(1)
+conn_id = ngpu.GetConnections()
+conn_status_dict = ngpu.GetStatus(conn_id)
+for i in range(len(conn_status_dict)):
+ print ("CHECK", mpi_id, conn_status_dict[i])
+print()
+print()
+ngpu.MpiFinalize()
diff --git a/python/test/test_remote_connect.sh b/python/test/test_remote_connect.sh
new file mode 100644
index 000000000..aebea1c6a
--- /dev/null
+++ b/python/test/test_remote_connect.sh
@@ -0,0 +1,7 @@
+pass_str[0]="TEST PASSED"
+pass_str[1]="TEST NOT PASSED"
+fn=test_remote_connect.py
+mpirun -np 3 python3 $fn | grep CHECK | sort -n > tmp
+diff -qs tmp log_remote_connect.txt 2>&1 >> log.txt
+res=$?
+echo $fn : ${pass_str[$res]}
diff --git a/python/test/test_stdp/cases/test_all.sh b/python/test/test_stdp/cases/test_all.sh
index 3cf5c02d1..b87eeda89 100755
--- a/python/test/test_stdp/cases/test_all.sh
+++ b/python/test/test_stdp/cases/test_all.sh
@@ -1 +1 @@
-for i in $(seq 1 10); do python3 case$i.py | tail -1; done
+for i in $(seq 1 10); do python3 case$i.py | grep '^dw'; done
diff --git a/python/test/tmp.py b/python/test/tmp.py
deleted file mode 100644
index d3760f533..000000000
--- a/python/test/tmp.py
+++ /dev/null
@@ -1,151 +0,0 @@
-import sys
-import math
-import ctypes
-import nestgpu as ngpu
-from random import randrange
-import numpy as np
-
-order = 200
-n_test = 100
-
-expected_rate = 30.78
-print("Building ...")
-
-ngpu.SetKernelStatus("rnd_seed", 1234) # seed for GPU random numbers
-
-n_receptors = 2
-
-NE = 4 * order # number of excitatory neurons
-NI = 1 * order # number of inhibitory neurons
-n_neurons = NE + NI # number of neurons in total
-
-CE = 800 # number of excitatory synapses per neuron
-CI = CE//4 # number of inhibitory synapses per neuron
-
-Wex = 0.05
-Win = 0.35
-
-# poisson generator parameters
-poiss_rate = 20000.0 # poisson signal rate in Hz
-poiss_weight = 0.37
-poiss_delay = 0.2 # poisson signal delay in ms
-
-# create poisson generator
-pg = ngpu.Create("poisson_generator")
-ngpu.SetStatus(pg, "rate", poiss_rate)
-pg_list = pg.ToList()
-
-# Create n_neurons neurons with n_receptor receptor ports
-neuron = ngpu.Create("user_m1", n_neurons, n_receptors)
-exc_neuron = neuron[0:NE] # excitatory neurons
-inh_neuron = neuron[NE:n_neurons] # inhibitory neurons
-neuron_list = neuron.ToList()
-exc_neuron_list = exc_neuron.ToList()
-inh_neuron_list = inh_neuron.ToList()
-
-# receptor parameters
-E_rev = [0.0, -85.0]
-tau_decay = [1.0, 1.0]
-tau_rise = [1.0, 1.0]
-ngpu.SetStatus(neuron, {"E_rev":E_rev, "tau_decay":tau_decay,
- "tau_rise":tau_rise})
-
-
-mean_delay = 0.5
-std_delay = 0.25
-min_delay = 0.1
-# Excitatory connections
-# connect excitatory neurons to port 0 of all neurons
-# normally distributed delays, weight Wex and CE connections per neuron
-exc_conn_dict={"rule": "fixed_indegree", "indegree": CE}
-exc_syn_dict={"weight": Wex, "delay": {"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":0}
-ngpu.Connect(exc_neuron, neuron_list, exc_conn_dict, exc_syn_dict)
-
-# Inhibitory connections
-# connect inhibitory neurons to port 1 of all neurons
-# normally distributed delays, weight Win and CI connections per neuron
-inh_conn_dict={"rule": "fixed_indegree", "indegree": CI}
-inh_syn_dict={"weight": Win, "delay":{"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":1}
-ngpu.Connect(inh_neuron_list, exc_neuron_list, inh_conn_dict, inh_syn_dict)
-ngpu.Connect(inh_neuron_list, inh_neuron, inh_conn_dict, inh_syn_dict)
-
-#connect poisson generator to port 0 of all neurons
-pg_conn_dict={"rule": "all_to_all"}
-pg_syn_dict={"weight": poiss_weight, "delay": poiss_delay,
- "receptor":0}
-
-ngpu.Connect(pg_list, neuron_list, pg_conn_dict, pg_syn_dict)
-
-i_neuron_list = [neuron[0], neuron[n_neurons-1]]
-i_receptor_list = [0, 0]
-var_name_list = ["spike", "spike"]
-
-for i in range(n_test-2):
- i_neuron_list.append(neuron[randrange(n_neurons)])
- i_receptor_list.append(0)
- var_name_list.append("spike")
-
-# create multimeter record of spikes
-record = ngpu.CreateRecord("", var_name_list, i_neuron_list, i_receptor_list)
-
-ngpu.Simulate()
-
-data_list = ngpu.GetRecordData(record)
-
-for i in range(1000):
- conn_id = ngpu.GetConnections(i+1)
- n_out_conn = len(conn_id)
- if (n_out_conn!=NE+NI):
- print("Expected number of out connections per neuron: ", NE+NI)
- print("Number of out connections of neuron ", i + 1, ": ", \
- n_out_conn)
- #sys.exit(1)
-
-
-for i in range(10):
- i_target = randrange(n_neurons)
- conn_id = ngpu.GetConnections(target=i_target+1)
- n_in_conn = len(conn_id)
- if (n_in_conn!=NE+NI+1):
- print("Expected number of in connections per neuron: ", NE+NI+1)
- print("Number of in connections of neuron ", i_target, ": ", \
- n_in_conn)
- #sys.exit(1)
-
-
-row_sum = list(data_list[0])
-for row in data_list[1:len(data_list)]:
- for i in range(len(row_sum)):
- row_sum[i] = row_sum[i] + row[i]
-
-spike = row_sum[1:len(row_sum)]
-spike_arr = np.array(spike)
-
-min_spike_num = np.min(spike_arr)
-max_spike_num = np.max(spike_arr)
-if (min_spike_num < expected_rate - 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Min rate :", min_spike_num)
- sys.exit(1)
-
-if (max_spike_num > expected_rate + 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Max rate :", max_spike_num)
- sys.exit(1)
-
-mean_spike_num = np.mean(spike_arr)
-diff = abs(mean_spike_num - expected_rate)
-max_diff = 3.0*np.sqrt(expected_rate)/np.sqrt(n_test)
-print ("Expected rate: ", expected_rate)
-print("Mean rate: ", mean_spike_num)
-if diff > max_diff:
- sys.exit(1)
-else:
- sys.exit(0)
-
diff --git a/python/test/tmp2.py b/python/test/tmp2.py
deleted file mode 100644
index bab70d9c1..000000000
--- a/python/test/tmp2.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import sys
-import math
-import ctypes
-import nestgpu as ngpu
-from random import randrange
-import numpy as np
-
-order = 200
-n_test = 100
-
-expected_rate = 30.78
-print("Building ...")
-
-ngpu.SetKernelStatus("rnd_seed", 1234) # seed for GPU random numbers
-
-n_receptors = 2
-
-NE = 4 * order # number of excitatory neurons
-NI = 1 * order # number of inhibitory neurons
-n_neurons = NE + NI # number of neurons in total
-
-CPN = 1000 # number of connections per neuron
-
-Wex = 0.05
-Win = 0.35
-
-# poisson generator parameters
-poiss_rate = 20000.0 # poisson signal rate in Hz
-poiss_weight = 0.37
-poiss_delay = 0.2 # poisson signal delay in ms
-
-# create poisson generator
-pg = ngpu.Create("poisson_generator")
-ngpu.SetStatus(pg, "rate", poiss_rate)
-pg_list = pg.ToList()
-
-# Create n_neurons neurons with n_receptor receptor ports
-neuron = ngpu.Create("aeif_cond_beta", n_neurons, n_receptors)
-exc_neuron = neuron[0:NE] # excitatory neurons
-inh_neuron = neuron[NE:n_neurons] # inhibitory neurons
-neuron_list = neuron.ToList()
-exc_neuron_list = exc_neuron.ToList()
-inh_neuron_list = inh_neuron.ToList()
-
-# receptor parameters
-E_rev = [0.0, -85.0]
-tau_decay = [1.0, 1.0]
-tau_rise = [1.0, 1.0]
-ngpu.SetStatus(neuron, {"E_rev":E_rev, "tau_decay":tau_decay,
- "tau_rise":tau_rise})
-
-
-mean_delay = 0.5
-std_delay = 0.25
-min_delay = 0.1
-# Excitatory connections
-# connect excitatory neurons to port 0 of all neurons
-# normally distributed delays, weight Wex and CPN connections per neuron
-exc_conn_dict={"rule": "fixed_total_number", "total_num": CPN*NE}
-exc_syn_dict={"weight": Wex, "delay": {"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":0}
-ngpu.Connect(exc_neuron, neuron_list, exc_conn_dict, exc_syn_dict)
-
-# Inhibitory connections
-# connect inhibitory neurons to port 1 of all neurons
-# normally distributed delays, weight Win and CPN connections per neuron
-inh_conn_dict={"rule": "fixed_total_number", "total_num": CPN*NI}
-inh_syn_dict={"weight": Win, "delay":{"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":1}
-ngpu.Connect(inh_neuron_list, neuron, inh_conn_dict, inh_syn_dict)
-
-#connect poisson generator to port 0 of all neurons
-pg_conn_dict={"rule": "all_to_all"}
-pg_syn_dict={"weight": poiss_weight, "delay": poiss_delay, "receptor":0}
-
-ngpu.Connect(pg_list, neuron_list, pg_conn_dict, pg_syn_dict)
-
-i_neuron_list = [neuron[0], neuron[n_neurons-1]]
-i_receptor_list = [0, 0]
-var_name_list = ["spike", "spike"]
-
-for i in range(n_test-2):
- i_neuron_list.append(neuron[randrange(n_neurons)])
- i_receptor_list.append(0)
- var_name_list.append("spike")
-
-# create multimeter record of spikes
-record = ngpu.CreateRecord("", var_name_list, i_neuron_list, i_receptor_list)
-
-ngpu.Simulate()
-
-data_list = ngpu.GetRecordData(record)
-
-n_conn_tot = 0
-for i in range(10):
- conn_id = ngpu.GetConnections(i+1)
- n_out_conn = len(conn_id)
- n_conn_tot = n_conn_tot + n_out_conn
-
-if (n_conn_tot!=(NE+NI)*CPN):
- print("Expected total number of connections: ", (NE+NI)*CPN)
- print("Total number of connections ", n_conn_tot)
- #sys.exit(1)
-
-row_sum = list(data_list[0])
-for row in data_list[1:len(data_list)]:
- for i in range(len(row_sum)):
- row_sum[i] = row_sum[i] + row[i]
-
-spike = row_sum[1:len(row_sum)]
-spike_arr = np.array(spike)
-
-min_spike_num = np.min(spike_arr)
-max_spike_num = np.max(spike_arr)
-if (min_spike_num < expected_rate - 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Min rate :", min_spike_num)
- sys.exit(1)
-
-if (max_spike_num > expected_rate + 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Max rate :", max_spike_num)
- sys.exit(1)
-
-mean_spike_num = np.mean(spike_arr)
-diff = abs(mean_spike_num - expected_rate)
-max_diff = 3.0*np.sqrt(expected_rate)/np.sqrt(n_test)
-print ("Expected rate: ", expected_rate)
-print("Mean rate: ", mean_spike_num)
-if diff > max_diff:
- sys.exit(1)
-else:
- sys.exit(0)
-
diff --git a/python/test/tmp3.py b/python/test/tmp3.py
deleted file mode 100644
index 4e48a56e2..000000000
--- a/python/test/tmp3.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import sys
-import math
-import ctypes
-import nestgpu as ngpu
-from random import randrange
-import numpy as np
-
-order = 200
-n_test = 100
-
-expected_rate = 30.78
-print("Building ...")
-
-ngpu.SetKernelStatus("rnd_seed", 1234) # seed for GPU random numbers
-
-n_receptors = 2
-
-NE = 4 * order # number of excitatory neurons
-NI = 1 * order # number of inhibitory neurons
-n_neurons = NE + NI # number of neurons in total
-
-CPN = 1000 # number of connections per neuron
-
-Wex = 0.05
-Win = 0.35
-
-# poisson generator parameters
-poiss_rate = 20000.0 # poisson signal rate in Hz
-poiss_weight = 0.37
-poiss_delay = 0.2 # poisson signal delay in ms
-
-# create poisson generator
-pg = ngpu.Create("poisson_generator")
-ngpu.SetStatus(pg, "rate", poiss_rate)
-pg_list = pg.ToList()
-
-# Create n_neurons neurons with n_receptor receptor ports
-neuron = ngpu.Create("aeif_cond_beta", n_neurons, n_receptors)
-exc_neuron = neuron[0:NE] # excitatory neurons
-inh_neuron = neuron[NE:n_neurons] # inhibitory neurons
-neuron_list = neuron.ToList()
-exc_neuron_list = exc_neuron.ToList()
-inh_neuron_list = inh_neuron.ToList()
-
-# receptor parameters
-E_rev = [0.0, -85.0]
-tau_decay = [1.0, 1.0]
-tau_rise = [1.0, 1.0]
-ngpu.SetStatus(neuron, {"E_rev":E_rev, "tau_decay":tau_decay,
- "tau_rise":tau_rise})
-
-
-mean_delay = 0.5
-std_delay = 0.25
-min_delay = 0.1
-# Excitatory connections
-# connect excitatory neurons to port 0 of all neurons
-# normally distributed delays, weight Wex and CPN connections per neuron
-exc_conn_dict={"rule": "fixed_total_number", "total_num": CPN*NE}
-exc_syn_dict={"weight": Wex, "delay": {"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":0}
-ngpu.Connect(exc_neuron, neuron_list, exc_conn_dict, exc_syn_dict)
-
-# Inhibitory connections
-# connect inhibitory neurons to port 1 of all neurons
-# normally distributed delays, weight Win and CPN connections per neuron
-inh_conn_dict={"rule": "fixed_total_number", "total_num": CPN*NI}
-inh_syn_dict={"weight": Win, "delay":{"distribution":"normal_clipped",
- "mu":mean_delay, "low":min_delay,
- "high":mean_delay+3*std_delay,
- "sigma":std_delay}, "receptor":1}
-ngpu.Connect(inh_neuron_list, neuron, inh_conn_dict, inh_syn_dict)
-
-#connect poisson generator to port 0 of all neurons
-pg_conn_dict={"rule": "all_to_all"}
-pg_syn_dict={"weight": poiss_weight, "delay": poiss_delay, "receptor":0}
-
-ngpu.Connect(pg_list, neuron_list, pg_conn_dict, pg_syn_dict)
-
-i_neuron_list = [neuron[0], neuron[n_neurons-1]]
-i_receptor_list = [0, 0]
-var_name_list = ["spike", "spike"]
-
-for i in range(n_test-2):
- i_neuron_list.append(neuron[randrange(n_neurons)])
- i_receptor_list.append(0)
- var_name_list.append("spike")
-
-# create multimeter record of spikes
-record = ngpu.CreateRecord("", var_name_list, i_neuron_list, i_receptor_list)
-
-ngpu.Simulate()
-
-data_list = ngpu.GetRecordData(record)
-
-n_conn_tot = 0
-for i in range(1):
- conn_id = ngpu.GetConnections(i+1)
- n_out_conn = len(conn_id)
- n_conn_tot = n_conn_tot + n_out_conn
-
-if (n_conn_tot!=(NE+NI)*CPN):
- print("Expected total number of connections: ", (NE+NI)*CPN)
- print("Total number of connections ", n_conn_tot)
- #sys.exit(1)
-
-row_sum = list(data_list[0])
-for row in data_list[1:len(data_list)]:
- for i in range(len(row_sum)):
- row_sum[i] = row_sum[i] + row[i]
-
-spike = row_sum[1:len(row_sum)]
-spike_arr = np.array(spike)
-
-min_spike_num = np.min(spike_arr)
-max_spike_num = np.max(spike_arr)
-if (min_spike_num < expected_rate - 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Min rate :", min_spike_num)
- sys.exit(1)
-
-if (max_spike_num > expected_rate + 3.0*math.sqrt(expected_rate)):
- print ("Expected rate: ", expected_rate)
- print("Max rate :", max_spike_num)
- sys.exit(1)
-
-mean_spike_num = np.mean(spike_arr)
-diff = abs(mean_spike_num - expected_rate)
-max_diff = 3.0*np.sqrt(expected_rate)/np.sqrt(n_test)
-print ("Expected rate: ", expected_rate)
-print("Mean rate: ", mean_spike_num)
-if diff > max_diff:
- sys.exit(1)
-else:
- sys.exit(0)
-
diff --git a/python/test/tmp4.py b/python/test/tmp4.py
deleted file mode 100644
index 09ddc141a..000000000
--- a/python/test/tmp4.py
+++ /dev/null
@@ -1,61 +0,0 @@
-import sys
-import nestgpu as ngpu
-
-tolerance = 1.0e-6
-dt_step = 0.1
-N = 5
-fact = 0.2
-offset = 0.03
-
-syn_group = ngpu.CreateSynGroup("test_syn_model")
-ngpu.SetSynGroupParam(syn_group, "fact", fact)
-ngpu.SetSynGroupParam(syn_group, "offset", offset)
-
-sg = ngpu.Create("spike_generator", N)
-neuron = ngpu.Create("aeif_cond_beta", 2*N)
-ngpu.SetStatus(neuron, {"t_ref": 10.0})
-neuron0 = neuron[0:N]
-neuron1 = neuron[N:2*N]
-dt_list = []
-for i in range(N):
- dt_list.append(dt_step*(-0.5*(N-1) + i))
-
-spike_time = [50.0]
-spike_height = [1.0]
-n_spikes = 1
-time_diff = 10.0
-
-# set spike times and height
-ngpu.SetStatus(sg, {"spike_times": spike_time, "spike_heights":spike_height})
-delay0 = 1.0
-delay1 = delay0 + time_diff
-weight_sg = 17.9
-weight_test = 0.0
-
-conn_dict={"rule": "one_to_one"}
-syn_dict0={"weight":weight_sg, "delay":delay0, "receptor":0, "synapse_group":0}
-syn_dict1={"weight":weight_sg, "delay":delay1, "receptor":0, "synapse_group":0}
-
-ngpu.Connect(sg, neuron0, conn_dict, syn_dict0)
-ngpu.Connect(sg, neuron1, conn_dict, syn_dict1)
-
-for i in range(N):
- delay_test = time_diff - dt_list[i]
- syn_dict_test={"weight":weight_test, "delay":delay_test, "receptor":0, \
- "synapse_group":syn_group}
- ngpu.Connect([neuron0[i]], [neuron1[i]], conn_dict, syn_dict_test)
-
-ngpu.Simulate(200.0)
-
-conn_id = ngpu.GetConnections(neuron0, neuron1)
-conn_status_dict = ngpu.GetStatus(conn_id, ["weight", "delay"])
-print (conn_status_dict)
-for i in range(N):
- print (dt_list[i], conn_status_dict[0][i])
- expect_w = dt_list[i]*fact + offset
- if abs(expect_w - conn_status_dict[0][i])>tolerance:
- print("Expected weight: ", expect_w, " simulated: ", \
- conn_status_dict[i][0])
- #sys.exit(1)
-
-sys.exit(0)
diff --git a/python/test/tmp5.py b/python/test/tmp5.py
deleted file mode 100644
index 54f6d3461..000000000
--- a/python/test/tmp5.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import ctypes
-import nestgpu as ngpu
-
-N = 5
-
-neuron = ngpu.Create("aeif_cond_beta", 2*N)
-neuron_even = []
-neuron_odd = []
-for i in range(N):
- neuron_even.append(neuron[2*i])
- neuron_odd.append(neuron[2*i+1])
-
-even_to_odd_delay = []
-even_to_odd_weight = []
-odd_to_even_delay = []
-odd_to_even_weight = []
-
-for isrc in range(N):
- ise = 2*isrc
- iso = 2*isrc + 1
-
- for itgt in range(N):
- ite = 2*itgt
- ito = 2*itgt + 1
- even_to_odd_delay.append(2.0*N*ise + ito)
- even_to_odd_weight.append(100.0*(2.0*N*ise + ito))
- odd_to_even_delay.append(2.0*N*iso + ite)
- odd_to_even_weight.append(100.0*(2.0*N*iso + ite))
-
-
-conn_dict={"rule": "all_to_all"}
-even_to_odd_syn_dict={
- "weight_array":even_to_odd_weight,
- "delay_array":even_to_odd_delay}
-
-odd_to_even_syn_dict={
- "weight_array":odd_to_even_weight,
- "delay_array":odd_to_even_delay}
-
-ngpu.Connect(neuron_even, neuron_odd, conn_dict, even_to_odd_syn_dict);
-ngpu.Connect(neuron_odd, neuron_even, conn_dict, odd_to_even_syn_dict);
-
-ngpu.Calibrate()
-# Even to all
-conn_id = ngpu.GetConnections(neuron_even, neuron)
-conn_status_dict = ngpu.GetStatus(conn_id)
-print("########################################")
-print("Even to all")
-for i in range(len(conn_status_dict)):
- print (conn_status_dict[i])
-print()
-print()
-
-# Even to all weight, delay
-conn_status_dict = ngpu.GetStatus(conn_id, ["weight", "delay"])
-print("########################################")
-print("Even to all weight, delat")
-for i in range(len(conn_status_dict)):
- print (conn_status_dict[i])
-print()
-print()
-
-conn_id = ngpu.GetConnections(neuron, neuron_odd)
-conn_status_dict = ngpu.GetStatus(conn_id)
-print("########################################")
-print("All to odd")
-for i in range(len(conn_status_dict)):
- print (conn_status_dict[i])
-print()
-print()
-
-# Even to 3,4,5,6
-neuron_3_6 = neuron[3:7]
-conn_id = ngpu.GetConnections(neuron_even, neuron_3_6)
-conn_status_dict = ngpu.GetStatus(conn_id)
-print("########################################")
-print("Even to 3,4,5,6")
-for i in range(len(conn_status_dict)):
- print (conn_status_dict[i])
-print()
-print()
-
-
-# 3,4,5,6 to odd
-conn_id = ngpu.GetConnections(neuron_3_6, neuron_odd)
-conn_status_dict = ngpu.GetStatus(conn_id)
-print("########################################")
-print("3,4,5,6 to odd")
-for i in range(len(conn_status_dict)):
- print (conn_status_dict[i])
-print()
-print()
-
-
diff --git a/pythonlib/nestgpu.py b/pythonlib/nestgpu.py
index 3570f2dcf..890027ee8 100644
--- a/pythonlib/nestgpu.py
+++ b/pythonlib/nestgpu.py
@@ -48,7 +48,7 @@ class NodeSeq(object):
def __init__(self, i0, n=1):
if i0 == None:
i0 = 0
- n = -1
+ n = 0 # -1
self.i0 = i0
self.n = n
@@ -1394,7 +1394,6 @@ def SetNeuronStatus(nodes, var_name, val):
if (type(nodes)!=list) & (type(nodes)!=tuple) & (type(nodes)!=NodeSeq):
raise ValueError("Unknown node type")
if (type(val)==dict):
- # print("pok0")
if ((type(nodes)==NodeSeq
and (IsNeuronScalParam(nodes.i0, var_name)
or IsNeuronScalVar(nodes.i0, var_name)
@@ -1404,10 +1403,8 @@ def SetNeuronStatus(nodes, var_name, val):
or IsNeuronScalVar(nodes[0], var_name)
or IsNeuronPortParam(nodes[0], var_name)
or IsNeuronPortVar(nodes[0], var_name)):
- # print("pok1")
for dict_param_name in val:
pval = val[dict_param_name]
- # print("pok2 ", dict_param_name, pval)
if dict_param_name=="array":
arr = (ctypes.c_float * len(pval))(*pval)
array_pt = ctypes.cast(arr, ctypes.c_void_p)
@@ -1417,7 +1414,6 @@ def SetNeuronStatus(nodes, var_name, val):
elif dict_param_name=="distribution":
distr_idx = distribution_dict[pval]
SetDistributionIntParam("distr_idx", distr_idx)
- # print("pok3 distr_idx", distr_idx)
else:
if IsDistributionFloatParam(dict_param_name):
if ((type(nodes)==NodeSeq
@@ -1425,11 +1421,8 @@ def SetNeuronStatus(nodes, var_name, val):
or IsNeuronScalVar(nodes.i0, var_name)))
or IsNeuronScalParam(nodes[0], var_name)
or IsNeuronScalVar(nodes[0], var_name)):
- # print("pok4")
SetDistributionIntParam("vect_size", 1)
- # print("pok5 ", dict_param_name, pval)
SetDistributionScalParam(dict_param_name, pval)
- # print("pok6 ", dict_param_name, pval)
elif ((type(nodes)==NodeSeq
and (IsNeuronPortParam(nodes.i0, var_name)
or IsNeuronPortVar(nodes.i0, var_name)))
@@ -1442,16 +1435,12 @@ def SetNeuronStatus(nodes, var_name, val):
else:
print("Parameter name: ", dict_param_name)
raise ValueError("Unknown distribution parameter")
- # print("pok7")
# set values from array or from distribution
if type(nodes)==NodeSeq:
- # print("pok8")
if IsNeuronScalParam(nodes.i0, var_name):
SetNeuronScalParamDistr(nodes.i0, nodes.n, var_name)
elif IsNeuronScalVar(nodes.i0, var_name):
- # print("pok9")
SetNeuronScalVarDistr(nodes.i0, nodes.n, var_name)
- # print("pok10")
elif IsNeuronPortParam(nodes.i0, var_name):
SetNeuronPortParamDistr(nodes.i0, nodes.n, var_name)
elif IsNeuronPortVar(nodes.i0, var_name):
@@ -1622,6 +1611,42 @@ def HostNum():
return ret
+NESTGPU_getCUDAMemHostUsed = _nestgpu.NESTGPU_getCUDAMemHostUsed
+NESTGPU_getCUDAMemHostUsed.restype = ctypes.c_size_t
+def getCUDAMemHostUsed():
+ "Get CUDA memory currently used by this host"
+ ret = NESTGPU_getCUDAMemHostUsed()
+ if GetErrorCode() != 0:
+ raise ValueError(GetErrorMessage())
+ return ret
+
+NESTGPU_getCUDAMemHostPeak = _nestgpu.NESTGPU_getCUDAMemHostPeak
+NESTGPU_getCUDAMemHostPeak.restype = ctypes.c_size_t
+def getCUDAMemHostPeak():
+ "Get maximum CUDA memory used by this host"
+ ret = NESTGPU_getCUDAMemHostPeak()
+ if GetErrorCode() != 0:
+ raise ValueError(GetErrorMessage())
+ return ret
+
+NESTGPU_getCUDAMemTotal = _nestgpu.NESTGPU_getCUDAMemTotal
+NESTGPU_getCUDAMemTotal.restype = ctypes.c_size_t
+def getCUDAMemTotal():
+ "Get total CUDA memory"
+ ret = NESTGPU_getCUDAMemTotal()
+ if GetErrorCode() != 0:
+ raise ValueError(GetErrorMessage())
+ return ret
+
+NESTGPU_getCUDAMemFree = _nestgpu.NESTGPU_getCUDAMemFree
+NESTGPU_getCUDAMemFree.restype = ctypes.c_size_t
+def getCUDAMemFree():
+ "Get free CUDA memory"
+ ret = NESTGPU_getCUDAMemFree()
+ if GetErrorCode() != 0:
+ raise ValueError(GetErrorMessage())
+ return ret
+
NESTGPU_MpiFinalize = _nestgpu.NESTGPU_MpiFinalize
NESTGPU_MpiFinalize.restype = ctypes.c_int
def MpiFinalize():
@@ -2220,7 +2245,7 @@ def GetConnections(source=None, target=None, syn_group=-1):
NESTGPU_GetConnectionStatus = _nestgpu.NESTGPU_GetConnectionStatus
NESTGPU_GetConnectionStatus.argtypes = (c_int64_p, ctypes.c_int64,
c_int_p, c_int_p,
- c_int_p, c_char_p,
+ c_int_p, c_int_p,
c_float_p, c_float_p)
NESTGPU_GetConnectionStatus.restype = ctypes.c_int
def GetConnectionStatus(conn):
@@ -2237,14 +2262,13 @@ def GetConnectionStatus(conn):
i_source = (ctypes.c_int * n_conn)()
i_target = (ctypes.c_int * n_conn)()
i_port = (ctypes.c_int * n_conn)()
- i_syn_group = (ctypes.c_char * n_conn)()
+ i_syn_group = (ctypes.c_int * n_conn)()
delay = (ctypes.c_float * n_conn)()
weight = (ctypes.c_float * n_conn)()
NESTGPU_GetConnectionStatus(conn_arr, n_conn, i_source,
i_target, i_port, i_syn_group,
delay, weight)
-
status_list = []
for i in range(n_conn):
status_dict = {}
@@ -2257,9 +2281,10 @@ def GetConnectionStatus(conn):
status_dict["weight"] = weight[i]
status_list.append(status_dict)
-
+
return status_list
+
NESTGPU_IsConnectionFloatParam = _nestgpu.NESTGPU_IsConnectionFloatParam
NESTGPU_IsConnectionFloatParam.argtypes = (c_char_p,)
NESTGPU_IsConnectionFloatParam.restype = ctypes.c_int
@@ -2972,7 +2997,7 @@ def IsIntParam(param_name):
c_param_name = ctypes.create_string_buffer(to_byte_str(param_name),
len(param_name)+1)
- ret = (NESTGPU_IsIntParam(c_param_name)!=0)
+ ret = (NESTGPU_IsIntParam(c_param_name)!=0)
if GetErrorCode() != 0:
raise ValueError(GetErrorMessage())
return ret
diff --git a/src/.clang-format b/src/.clang-format
new file mode 100644
index 000000000..c40becf81
--- /dev/null
+++ b/src/.clang-format
@@ -0,0 +1,124 @@
+Language: Cpp
+AccessModifierOffset: -2
+AlignAfterOpenBracket: DontAlign
+AlignConsecutiveMacros: false
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Left
+AlignOperands: false
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: AllDefinitions
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: false
+BinPackParameters: false
+BraceWrapping:
+ AfterCaseLabel: true
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: false
+ AfterExternBlock: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Allman
+BreakBeforeInheritanceComma: false
+BreakInheritanceList: BeforeColon
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeComma
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 2
+ContinuationIndentWidth: 2
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+InsertBraces: true
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 4
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: true
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: true
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: true
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: true
+SpacesInParentheses: true
+SpacesInSquareBrackets: true
+Standard: Cpp03
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 8
+UseTab: Never
diff --git a/src/.clang-tidy b/src/.clang-tidy
new file mode 100644
index 000000000..e02b1c455
--- /dev/null
+++ b/src/.clang-tidy
@@ -0,0 +1 @@
+Checks: '-*,modernize-use-nullptr,modernize-use-override,bugprone,modernize-redundant-void-arg'
diff --git a/src/.clang-tidy-ignore b/src/.clang-tidy-ignore
new file mode 100644
index 000000000..fbb2a9235
--- /dev/null
+++ b/src/.clang-tidy-ignore
@@ -0,0 +1 @@
+*.cuh
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3bae95d0e..ee83c35fe 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -45,6 +45,8 @@ base_neuron.h
connect.h
connect_rules.h
connect_spec.h
+conn12b.h
+conn16b.h
copass_kernels.h
copass_sort.h
cuda_error.h
@@ -112,6 +114,8 @@ aeif_psc_exp_multisynapse.cu
base_neuron.cu
connect.cu
connect_rules.cu
+conn12b.cu
+conn16b.cu
copass_kernels.cu
copass_sort.cu
distribution.cu
diff --git a/src/aeif_cond_alpha.cu b/src/aeif_cond_alpha.cu
index 43509eb3e..058e80583 100644
--- a/src/aeif_cond_alpha.cu
+++ b/src/aeif_cond_alpha.cu
@@ -20,25 +20,20 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_cond_alpha.h"
#include "aeif_cond_alpha_kernel.h"
#include "rk5.h"
-#include "aeif_cond_alpha.h"
+#include
+#include
+#include
namespace aeif_cond_alpha_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_cond_alpha_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
V_th = -50.4;
Delta_T = 2.0;
@@ -67,11 +62,10 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
g1_in = 0;
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_alpha_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
refractory_step = 0;
// use normalization for alpha function
@@ -79,28 +73,27 @@ void NodeCalibrate(int n_var, int n_param, double x, float *y,
g0_in = M_E / tau_syn_in;
}
-}
-
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_alpha_rk5 data_struct)
+} // namespace aeif_cond_alpha_ns
+
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_rk5 data_struct )
{
- aeif_cond_alpha_ns::NodeInit(n_var, n_param, x, y, param, data_struct);
+ aeif_cond_alpha_ns::NodeInit( n_var, n_param, x, y, param, data_struct );
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_alpha_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_rk5 data_struct )
{
- aeif_cond_alpha_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct);
+ aeif_cond_alpha_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct );
}
using namespace aeif_cond_alpha_ns;
-int aeif_cond_alpha::Init(int i_node_0, int n_node, int n_port,
- int i_group) {
- BaseNeuron::Init(i_node_0, n_node, n_port, i_group);
+int
+aeif_cond_alpha::Init( int i_node_0, int n_node, int n_port, int i_group )
+{
+ BaseNeuron::Init( i_node_0, n_node, n_port, i_group );
node_type_ = i_aeif_cond_alpha_model;
n_scal_var_ = N_SCAL_VAR;
n_var_ = n_scal_var_;
@@ -108,45 +101,48 @@ int aeif_cond_alpha::Init(int i_node_0, int n_node, int n_port,
n_param_ = n_scal_param_;
n_group_param_ = N_GROUP_PARAM;
- group_param_ = new float[N_GROUP_PARAM];
-
+ group_param_ = new float[ N_GROUP_PARAM ];
+
scal_var_name_ = aeif_cond_alpha_scal_var_name;
scal_param_name_ = aeif_cond_alpha_scal_param_name;
group_param_name_ = aeif_cond_alpha_group_param_name;
- //rk5_data_struct_.node_type_ = i_aeif_cond_alpha_model;
+ // rk5_data_struct_.node_type_ = i_aeif_cond_alpha_model;
rk5_data_struct_.i_node_0_ = i_node_0_;
- SetGroupParam("h_min_rel", 1.0e-3);
- SetGroupParam("h0_rel", 1.0e-2);
- h_ = h0_rel_* 0.1;
-
- rk5_.Init(n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_);
+ SetGroupParam( "h_min_rel", 1.0e-3 );
+ SetGroupParam( "h0_rel", 1.0e-2 );
+ h_ = h0_rel_ * 0.1;
+
+ rk5_.Init( n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_ );
var_arr_ = rk5_.GetYArr();
param_arr_ = rk5_.GetParamArr();
- port_weight_arr_ = GetParamArr() + GetScalParamIdx("g0_ex");
+ port_weight_arr_ = GetParamArr() + GetScalParamIdx( "g0_ex" );
port_weight_arr_step_ = n_param_;
port_weight_port_step_ = 1;
- port_input_arr_ = GetVarArr() + GetScalVarIdx("g1_ex");
+ port_input_arr_ = GetVarArr() + GetScalVarIdx( "g1_ex" );
port_input_arr_step_ = n_var_;
port_input_port_step_ = 1;
- den_delay_arr_ = GetParamArr() + GetScalParamIdx("den_delay");
+ den_delay_arr_ = GetParamArr() + GetScalParamIdx( "den_delay" );
return 0;
}
-int aeif_cond_alpha::Calibrate(double time_min, float time_resolution)
+int
+aeif_cond_alpha::Calibrate( double time_min, float time_resolution )
{
- h_min_ = h_min_rel_* time_resolution;
- h_ = h0_rel_* time_resolution;
- rk5_.Calibrate(time_min, h_, rk5_data_struct_);
-
+ h_min_ = h_min_rel_ * time_resolution;
+ h_ = h0_rel_ * time_resolution;
+ rk5_.Calibrate( time_min, h_, rk5_data_struct_ );
+
return 0;
}
-int aeif_cond_alpha::Update(long long it, double t1) {
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+int
+aeif_cond_alpha::Update( long long it, double t1 )
+{
+ rk5_.Update< N_SCAL_VAR, N_SCAL_PARAM >( t1, h_min_, rk5_data_struct_ );
return 0;
}
diff --git a/src/aeif_cond_alpha.h b/src/aeif_cond_alpha.h
index a89575a1f..46a14a52b 100644
--- a/src/aeif_cond_alpha.h
+++ b/src/aeif_cond_alpha.h
@@ -20,22 +20,19 @@
*
*/
-
-
-
-
#ifndef AEIFCONDALPHA_H
#define AEIFCONDALPHA_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
-/* BeginUserDocs: neuron, integrate-and-fire, adaptive threshold, conductance-based
+/* BeginUserDocs: neuron, integrate-and-fire, adaptive threshold,
+conductance-based
Short description
+++++++++++++++++
@@ -45,7 +42,7 @@ Conductance-based adaptive exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_cond_alpha`` is a conductance-based adaptive exponential
+``aeif_cond_alpha`` is a conductance-based adaptive exponential
integrate-and-fire neuron model according to [1]_ with synaptic
conductance modeled by an alpha function, as described in [2]_
@@ -56,7 +53,8 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ g_{ex}(t) (V - E_{rev\_ ex,i}) + g_{in}(t) (V - E_{rev\_ in,i}) - w + I_e
The differential equation for the spike-adaptation current `w` is
@@ -71,8 +69,9 @@ When the neuron fires a spike, the adaptation current :math:`w <- w + b`.
Although this is not multisynapse, the port (excitatory or inhibitory)
to be chosen must be specified using the synapse property ``receptor``.
- The excitatory port has index 0, whereas the inhibitory one has index 1. Differently from
- NEST, the connection weights related to the inhibitory port must be positive.
+ The excitatory port has index 0, whereas the inhibitory one has index 1.
+Differently from NEST, the connection weights related to the inhibitory port
+must be positive.
Parameters
++++++++++
@@ -111,21 +110,23 @@ The following parameters can be set in the status dictionary.
tau_w ms Adaptation time constant
======== ======= ==================================
-=========== ============= ========================================================
+=========== =============
+========================================================
**Synaptic parameters**
----------------------------------------------------------------------------------
E_rev_ex mV Excitatory reversal potential
E_rev_in mV Inhibitory reversal potential
tau_syn_ex ms Time constant of excitatory synaptic conductance
tau_syn_in ms Time constant of inhibitory synaptic conductance
-=========== ============= ========================================================
+=========== =============
+========================================================
============= ======= =========================================================
**Integration parameters**
-------------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
============= ======= =========================================================
@@ -148,7 +149,7 @@ aeif_cond_alpha_multisynapse, aeif_cond_beta
EndUserDocs */
-//#define MAX_PORT_NUM 20
+// #define MAX_PORT_NUM 20
struct aeif_cond_alpha_rk5
{
@@ -157,30 +158,32 @@ struct aeif_cond_alpha_rk5
class aeif_cond_alpha : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_cond_alpha_rk5 > rk5_;
float h_min_;
float h_;
aeif_cond_alpha_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_cond_alpha_kernel.h b/src/aeif_cond_alpha_kernel.h
index 52a31ec17..e638b9fb0 100644
--- a/src/aeif_cond_alpha_kernel.h
+++ b/src/aeif_cond_alpha_kernel.h
@@ -20,26 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFCONDALPHAKERNEL_H
#define AEIFCONDALPHAKERNEL_H
#include
- //#include
-#include "spike_buffer.h"
-#include "node_group.h"
+// #include
#include "aeif_cond_alpha.h"
+#include "node_group.h"
+#include "spike_buffer.h"
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_cond_alpha_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_g_ex = 0,
i_g_in,
i_g1_ex,
@@ -49,7 +46,8 @@ enum ScalVarIndexes {
N_SCAL_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_g0_ex = 0,
i_g0_in,
i_E_rev_ex,
@@ -73,22 +71,16 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
-const std::string aeif_cond_alpha_scal_var_name[N_SCAL_VAR] = {
- "g_ex",
- "g_in",
- "g1_ex",
- "g1_in",
- "V_m",
- "w"
-};
+const std::string aeif_cond_alpha_scal_var_name[ N_SCAL_VAR ] = { "g_ex", "g_in", "g1_ex", "g1_in", "V_m", "w" };
-const std::string aeif_cond_alpha_scal_param_name[N_SCAL_PARAM] = {
+const std::string aeif_cond_alpha_scal_param_name[ N_SCAL_PARAM ] = {
"g0_ex",
"g0_in",
"E_rev_ex",
@@ -111,75 +103,69 @@ const std::string aeif_cond_alpha_scal_param_name[N_SCAL_PARAM] = {
"den_delay",
};
-const std::string aeif_cond_alpha_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_cond_alpha_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define g_ex y[i_g_ex]
-#define g1_ex y[i_g1_ex]
-#define g_in y[i_g_in]
-#define g1_in y[i_g1_in]
-#define V_m y[i_V_m]
-#define w y[i_w]
-
-#define dg_exdt dydx[i_g_ex]
-#define dg1_exdt dydx[i_g1_ex]
-#define dg_indt dydx[i_g_in]
-#define dg1_indt dydx[i_g1_in]
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-
-#define g0_ex param[i_g0_ex]
-#define g0_in param[i_g0_in]
-#define E_rev_ex param[i_E_rev_ex]
-#define E_rev_in param[i_E_rev_in]
-#define tau_syn_ex param[i_tau_syn_ex]
-#define tau_syn_in param[i_tau_syn_in]
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_alpha_rk5 data_struct)
+#define g_ex y[ i_g_ex ]
+#define g1_ex y[ i_g1_ex ]
+#define g_in y[ i_g_in ]
+#define g1_in y[ i_g1_in ]
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+
+#define dg_exdt dydx[ i_g_ex ]
+#define dg1_exdt dydx[ i_g1_ex ]
+#define dg_indt dydx[ i_g_in ]
+#define dg1_indt dydx[ i_g1_in ]
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+
+#define g0_ex param[ i_g0_ex ]
+#define g0_in param[ i_g0_in ]
+#define E_rev_ex param[ i_E_rev_ex ]
+#define E_rev_in param[ i_E_rev_in ]
+#define tau_syn_ex param[ i_tau_syn_ex ]
+#define tau_syn_in param[ i_tau_syn_in ]
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_alpha_rk5 data_struct )
{
float I_syn_ex = 0.0;
float I_syn_in = 0.0;
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
+ float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak );
- I_syn_ex += g_ex*(E_rev_ex - V);
- I_syn_in += g_in*(E_rev_in - V);
+ I_syn_ex += g_ex * ( E_rev_ex - V );
+ I_syn_in += g_in * ( E_rev_in - V );
- float V_spike = Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn_ex + I_syn_in - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn_ex + I_syn_in - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
+ dwdt = ( a * ( V - E_L ) - w ) / tau_w;
// Synaptic conductance derivative
dg1_exdt = -g1_ex / tau_syn_ex;
dg_exdt = g1_ex - g_ex / tau_syn_ex;
@@ -187,67 +173,65 @@ __device__
dg_indt = g1_in - g_in / tau_syn_in;
}
- template //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_cond_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_alpha_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)::round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) ::round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
+}; // namespace aeif_cond_alpha_ns
-};
-
-int Update(long long it, double t1);
+int Update( long long it, double t1 );
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_alpha_rk5 data_struct )
{
- aeif_cond_alpha_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_cond_alpha_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_alpha_rk5 data_struct )
{
- aeif_cond_alpha_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_cond_alpha_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_cond_alpha_multisynapse.cu b/src/aeif_cond_alpha_multisynapse.cu
index 73d7ce656..095fbd20f 100644
--- a/src/aeif_cond_alpha_multisynapse.cu
+++ b/src/aeif_cond_alpha_multisynapse.cu
@@ -20,26 +20,21 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_cond_alpha_multisynapse.h"
#include "aeif_cond_alpha_multisynapse_kernel.h"
#include "rk5.h"
-#include "aeif_cond_alpha_multisynapse.h"
+#include
+#include
+#include
namespace aeif_cond_alpha_multisynapse_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_cond_alpha_multisynapse_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
- int n_port = (n_var-N_SCAL_VAR)/N_PORT_VAR;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ int n_port = ( n_var - N_SCAL_VAR ) / N_PORT_VAR;
V_th = -50.4;
Delta_T = 2.0;
@@ -54,54 +49,54 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
V_reset = -60.0;
t_ref = 0.0;
den_delay = 0.0;
-
+
V_m = E_L;
w = 0;
refractory_step = 0;
- for (int i = 0; i
-int aeif_cond_alpha_multisynapse::UpdateNR<0>(long long it, double t1)
+int
+aeif_cond_alpha_multisynapse::UpdateNR< 0 >( long long it, double t1 )
{
return 0;
}
-int aeif_cond_alpha_multisynapse::Update(long long it, double t1) {
- UpdateNR(it, t1);
+int
+aeif_cond_alpha_multisynapse::Update( long long it, double t1 )
+{
+ UpdateNR< MAX_PORT_NUM >( it, t1 );
return 0;
}
diff --git a/src/aeif_cond_alpha_multisynapse.h b/src/aeif_cond_alpha_multisynapse.h
index 0a4b2074f..fa3e856fb 100644
--- a/src/aeif_cond_alpha_multisynapse.h
+++ b/src/aeif_cond_alpha_multisynapse.h
@@ -20,23 +20,19 @@
*
*/
-
-
-
-
#ifndef AEIFCONDALPHAMULTISYNAPSE_H
#define AEIFCONDALPHAMULTISYNAPSE_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
-
-/* BeginUserDocs: neuron, integrate-and-fire, adaptive threshold, conductance-based
+/* BeginUserDocs: neuron, integrate-and-fire, adaptive threshold,
+conductance-based
Short description
+++++++++++++++++
@@ -46,7 +42,7 @@ Conductance-based adaptive exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_cond_alpha_multisynapse`` is a conductance-based adaptive exponential
+``aeif_cond_alpha_multisynapse`` is a conductance-based adaptive exponential
integrate-and-fire neuron model according to [1]_ with multiple
synaptic time constants, and synaptic conductance modeled by an
alpha function.
@@ -61,7 +57,8 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ I_{syn_{tot}}(V, t)- w + I_e
where
@@ -82,12 +79,13 @@ When the neuron fires a spike, the adaptation current :math:`w <- w + b`.
.. note::
- The number of receptor ports must be specified at neuron creation (default value is 1) and
- the receptor index starts from 0 (and not from 1 as in NEST multisynapse models).
- The time constants are supplied by an array, ``tau_syn``, and the pertaining
- synaptic reversal potentials are supplied by the array ``E_rev``. Port numbers
- are automatically assigned in the range 0 to ``n_receptors-1``.
- During connection, the ports are selected with the synapse property ``receptor``.
+ The number of receptor ports must be specified at neuron creation (default
+value is 1) and the receptor index starts from 0 (and not from 1 as in NEST
+multisynapse models). The time constants are supplied by an array, ``tau_syn``,
+and the pertaining synaptic reversal potentials are supplied by the array
+``E_rev``. Port numbers are automatically assigned in the range 0 to
+``n_receptors-1``. During connection, the ports are selected with the synapse
+property ``receptor``.
Parameters
++++++++++
@@ -134,9 +132,9 @@ tau_syn list of ms Time constant of synaptic conductance
============= ======= =========================================================
**Integration parameters**
-------------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
============= ======= =========================================================
@@ -159,7 +157,6 @@ aeif_cond_beta_multisynapse
EndUserDocs */
-
#define MAX_PORT_NUM 20
struct aeif_cond_alpha_multisynapse_rk5
@@ -169,29 +166,32 @@ struct aeif_cond_alpha_multisynapse_rk5
class aeif_cond_alpha_multisynapse : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_cond_alpha_multisynapse_rk5 > rk5_;
float h_min_;
float h_;
aeif_cond_alpha_multisynapse_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_cond_alpha_multisynapse_kernel.h b/src/aeif_cond_alpha_multisynapse_kernel.h
index b4d206f85..7c80e1888 100644
--- a/src/aeif_cond_alpha_multisynapse_kernel.h
+++ b/src/aeif_cond_alpha_multisynapse_kernel.h
@@ -20,38 +20,37 @@
*
*/
-
-
-
-
#ifndef AEIFCONDALPHAMULTISYNAPSEKERNEL_H
#define AEIFCONDALPHAMULTISYNAPSEKERNEL_H
#include
- //#include
-#include "spike_buffer.h"
-#include "node_group.h"
+// #include
#include "aeif_cond_alpha_multisynapse.h"
+#include "node_group.h"
+#include "spike_buffer.h"
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_cond_alpha_multisynapse_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_V_m = 0,
i_w,
N_SCAL_VAR
};
-enum PortVarIndexes {
+enum PortVarIndexes
+{
i_g = 0,
i_g1,
N_PORT_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_V_th = 0,
i_Delta_T,
i_g_L,
@@ -69,31 +68,26 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum PortParamIndexes {
+enum PortParamIndexes
+{
i_E_rev = 0,
i_tau_syn,
i_g0,
N_PORT_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
-const std::string aeif_cond_alpha_multisynapse_scal_var_name[N_SCAL_VAR] = {
- "V_m",
- "w"
-};
+const std::string aeif_cond_alpha_multisynapse_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" };
-const std::string aeif_cond_alpha_multisynapse_port_var_name[N_PORT_VAR] = {
- "g",
- "g1"
-};
+const std::string aeif_cond_alpha_multisynapse_port_var_name[ N_PORT_VAR ] = { "g", "g1" };
-const std::string aeif_cond_alpha_multisynapse_scal_param_name[N_SCAL_PARAM] = {
- "V_th",
+const std::string aeif_cond_alpha_multisynapse_scal_param_name[ N_SCAL_PARAM ] = { "V_th",
"Delta_T",
"g_L",
"E_L",
@@ -106,164 +100,158 @@ const std::string aeif_cond_alpha_multisynapse_scal_param_name[N_SCAL_PARAM] = {
"V_reset",
"t_ref",
"refractory_step",
- "den_delay"
-};
+ "den_delay" };
-const std::string aeif_cond_alpha_multisynapse_port_param_name[N_PORT_PARAM] = {
- "E_rev",
- "tau_syn",
- "g0"
-};
+const std::string aeif_cond_alpha_multisynapse_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_syn", "g0" };
-const std::string aeif_cond_alpha_multisynapse_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_cond_alpha_multisynapse_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define V_m y[i_V_m]
-#define w y[i_w]
-#define g(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_g]
-#define g1(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_g1]
-
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-#define dgdt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_g]
-#define dg1dt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_g1]
-
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define E_rev(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_E_rev]
-#define tau_syn(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_tau_syn]
-#define g0(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_g0]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_alpha_multisynapse_rk5 data_struct)
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+#define g( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_g ]
+#define g1( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_g1 ]
+
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+#define dgdt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_g ]
+#define dg1dt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_g1 ]
+
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define E_rev( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_E_rev ]
+#define tau_syn( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_tau_syn ]
+#define g0( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_g0 ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct )
{
- enum { n_port = (NVAR-N_SCAL_VAR)/N_PORT_VAR };
+ enum
+ {
+ n_port = ( NVAR - N_SCAL_VAR ) / N_PORT_VAR
+ };
float I_syn = 0.0;
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
- for (int i = 0; i 0 ) ? V_reset : MIN( V_m, V_peak );
+ for ( int i = 0; i < n_port; i++ )
+ {
+ I_syn += g( i ) * ( E_rev( i ) - V );
}
- float V_spike = Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
- for (int i=0; i //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_cond_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_alpha_multisynapse_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)::round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) ::round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
-
-};
+}; // namespace aeif_cond_alpha_multisynapse_ns
template <>
-int aeif_cond_alpha_multisynapse::UpdateNR<0>(long long it, double t1);
+int aeif_cond_alpha_multisynapse::UpdateNR< 0 >( long long it, double t1 );
-template
-int aeif_cond_alpha_multisynapse::UpdateNR(long long it, double t1)
+template < int N_PORT >
+int
+aeif_cond_alpha_multisynapse::UpdateNR( long long it, double t1 )
{
- if (N_PORT == n_port_) {
- const int NVAR = aeif_cond_alpha_multisynapse_ns::N_SCAL_VAR
- + aeif_cond_alpha_multisynapse_ns::N_PORT_VAR*N_PORT;
- const int NPARAM = aeif_cond_alpha_multisynapse_ns::N_SCAL_PARAM
- + aeif_cond_alpha_multisynapse_ns::N_PORT_PARAM*N_PORT;
+ if ( N_PORT == n_port_ )
+ {
+ const int NVAR = aeif_cond_alpha_multisynapse_ns::N_SCAL_VAR + aeif_cond_alpha_multisynapse_ns::N_PORT_VAR * N_PORT;
+ const int NPARAM =
+ aeif_cond_alpha_multisynapse_ns::N_SCAL_PARAM + aeif_cond_alpha_multisynapse_ns::N_PORT_PARAM * N_PORT;
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+ rk5_.Update< NVAR, NPARAM >( t1, h_min_, rk5_data_struct_ );
}
- else {
- UpdateNR(it, t1);
+ else
+ {
+ UpdateNR< N_PORT - 1 >( it, t1 );
}
return 0;
}
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct )
{
- aeif_cond_alpha_multisynapse_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_cond_alpha_multisynapse_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_alpha_multisynapse_rk5 data_struct )
{
- aeif_cond_alpha_multisynapse_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_cond_alpha_multisynapse_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_cond_alpha_multisynapse_rk5.h b/src/aeif_cond_alpha_multisynapse_rk5.h
index 159a18eca..96ee690e7 100644
--- a/src/aeif_cond_alpha_multisynapse_rk5.h
+++ b/src/aeif_cond_alpha_multisynapse_rk5.h
@@ -20,32 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFCONDALPHAMULTISYNAPSERK5_H
#define AEIFCONDALPHAMULTISYNAPSERK5_H
struct aeif_cond_alpha_multisynapse_rk5;
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct );
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_alpha_multisynapse_rk5 data_struct);
-
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_alpha_multisynapse_rk5 data_struct);
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_alpha_multisynapse_rk5 data_struct );
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_alpha_multisynapse_rk5 data_struct);
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct );
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_alpha_multisynapse_rk5 data_struct);
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_alpha_multisynapse_rk5 data_struct );
#endif
diff --git a/src/aeif_cond_beta.cu b/src/aeif_cond_beta.cu
index 5208c99a0..559a5ded9 100644
--- a/src/aeif_cond_beta.cu
+++ b/src/aeif_cond_beta.cu
@@ -20,26 +20,21 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_cond_beta.h"
#include "aeif_cond_beta_kernel.h"
#include "rk5.h"
-#include "aeif_cond_beta.h"
+#include
+#include
+#include
namespace aeif_cond_beta_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_cond_beta_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
-
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+
V_th = -50.4;
Delta_T = 2.0;
g_L = 30.0;
@@ -59,7 +54,7 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
tau_decay_in = 20.0;
tau_rise_ex = 2.0;
tau_rise_in = 2.0;
-
+
V_m = E_L;
w = 0;
refractory_step = 0;
@@ -69,71 +64,75 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
g1_in = 0;
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_beta_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
-
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+
refractory_step = 0;
-
+
// denominator is computed here to check that it is != 0
float denom1 = tau_decay_ex - tau_rise_ex;
float denom2 = 0;
- if (denom1 != 0) {
+ if ( denom1 != 0 )
+ {
// peak time
- float t_p = tau_decay_ex*tau_rise_ex*log(tau_decay_ex/tau_rise_ex) / denom1;
+ float t_p = tau_decay_ex * tau_rise_ex * log( tau_decay_ex / tau_rise_ex ) / denom1;
// another denominator is computed here to check that it is != 0
- denom2 = exp(-t_p / tau_decay_ex) - exp(-t_p / tau_rise_ex);
+ denom2 = exp( -t_p / tau_decay_ex ) - exp( -t_p / tau_rise_ex );
}
- if (denom2 == 0) { // if rise time == decay time use alpha function
+ if ( denom2 == 0 )
+ { // if rise time == decay time use alpha function
// use normalization for alpha function in this case
g0_ex = M_E / tau_decay_ex;
}
- else { // if rise time != decay time use beta function
+ else
+ { // if rise time != decay time use beta function
// normalization factor for conductance
g0_ex = ( 1. / tau_rise_ex - 1. / tau_decay_ex ) / denom2;
}
denom1 = tau_decay_in - tau_rise_in;
denom2 = 0;
- if (denom1 != 0) {
+ if ( denom1 != 0 )
+ {
// peak time
- float t_p = tau_decay_in*tau_rise_in*log(tau_decay_in/tau_rise_in) / denom1;
+ float t_p = tau_decay_in * tau_rise_in * log( tau_decay_in / tau_rise_in ) / denom1;
// another denominator is computed here to check that it is != 0
- denom2 = exp(-t_p / tau_decay_in) - exp(-t_p / tau_rise_in);
+ denom2 = exp( -t_p / tau_decay_in ) - exp( -t_p / tau_rise_in );
}
- if (denom2 == 0) { // if rise time == decay time use alpha function
+ if ( denom2 == 0 )
+ { // if rise time == decay time use alpha function
// use normalization for alpha function in this case
g0_in = M_E / tau_decay_in;
}
- else { // if rise time != decay time use beta function
+ else
+ { // if rise time != decay time use beta function
// normalization factor for conductance
g0_in = ( 1. / tau_rise_in - 1. / tau_decay_in ) / denom2;
}
}
-}
-
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_beta_rk5 data_struct)
+} // namespace aeif_cond_beta_ns
+
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_rk5 data_struct )
{
- aeif_cond_beta_ns::NodeInit(n_var, n_param, x, y, param, data_struct);
+ aeif_cond_beta_ns::NodeInit( n_var, n_param, x, y, param, data_struct );
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_beta_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_rk5 data_struct )
{
- aeif_cond_beta_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct);
+ aeif_cond_beta_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct );
}
using namespace aeif_cond_beta_ns;
-int aeif_cond_beta::Init(int i_node_0, int n_node, int n_port,
- int i_group) {
- BaseNeuron::Init(i_node_0, n_node, n_port, i_group);
+int
+aeif_cond_beta::Init( int i_node_0, int n_node, int n_port, int i_group )
+{
+ BaseNeuron::Init( i_node_0, n_node, n_port, i_group );
node_type_ = i_aeif_cond_beta_model;
n_scal_var_ = N_SCAL_VAR;
n_scal_param_ = N_SCAL_PARAM;
@@ -142,45 +141,48 @@ int aeif_cond_beta::Init(int i_node_0, int n_node, int n_port,
n_var_ = n_scal_var_;
n_param_ = n_scal_param_;
- group_param_ = new float[N_GROUP_PARAM];
+ group_param_ = new float[ N_GROUP_PARAM ];
scal_var_name_ = aeif_cond_beta_scal_var_name;
scal_param_name_ = aeif_cond_beta_scal_param_name;
group_param_name_ = aeif_cond_beta_group_param_name;
- //rk5_data_struct_.node_type_ = i_aeif_cond_beta_model;
+ // rk5_data_struct_.node_type_ = i_aeif_cond_beta_model;
rk5_data_struct_.i_node_0_ = i_node_0_;
- SetGroupParam("h_min_rel", 1.0e-3);
- SetGroupParam("h0_rel", 1.0e-2);
- h_ = h0_rel_* 0.1;
-
- rk5_.Init(n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_);
+ SetGroupParam( "h_min_rel", 1.0e-3 );
+ SetGroupParam( "h0_rel", 1.0e-2 );
+ h_ = h0_rel_ * 0.1;
+
+ rk5_.Init( n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_ );
var_arr_ = rk5_.GetYArr();
param_arr_ = rk5_.GetParamArr();
- port_weight_arr_ = GetParamArr() + GetScalParamIdx("g0_ex");
+ port_weight_arr_ = GetParamArr() + GetScalParamIdx( "g0_ex" );
port_weight_arr_step_ = n_param_;
port_weight_port_step_ = 1;
- port_input_arr_ = GetVarArr() + GetScalVarIdx("g1_ex");
+ port_input_arr_ = GetVarArr() + GetScalVarIdx( "g1_ex" );
port_input_arr_step_ = n_var_;
port_input_port_step_ = 1;
- den_delay_arr_ = GetParamArr() + GetScalParamIdx("den_delay");
+ den_delay_arr_ = GetParamArr() + GetScalParamIdx( "den_delay" );
return 0;
}
-int aeif_cond_beta::Calibrate(double time_min, float time_resolution)
+int
+aeif_cond_beta::Calibrate( double time_min, float time_resolution )
{
- h_min_ = h_min_rel_* time_resolution;
- h_ = h0_rel_* time_resolution;
- rk5_.Calibrate(time_min, h_, rk5_data_struct_);
-
+ h_min_ = h_min_rel_ * time_resolution;
+ h_ = h0_rel_ * time_resolution;
+ rk5_.Calibrate( time_min, h_, rk5_data_struct_ );
+
return 0;
}
-int aeif_cond_beta::Update(long long it, double t1) {
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+int
+aeif_cond_beta::Update( long long it, double t1 )
+{
+ rk5_.Update< N_SCAL_VAR, N_SCAL_PARAM >( t1, h_min_, rk5_data_struct_ );
return 0;
}
diff --git a/src/aeif_cond_beta.h b/src/aeif_cond_beta.h
index 8721be54a..4f0c00815 100644
--- a/src/aeif_cond_beta.h
+++ b/src/aeif_cond_beta.h
@@ -20,23 +20,19 @@
*
*/
-
-
-
-
#ifndef AEIFCONDBETA_H
#define AEIFCONDBETA_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
-
-/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire, conductance-based
+/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire,
+conductance-based
Short description
+++++++++++++++++
@@ -46,7 +42,7 @@ Conductance-based adaptive exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_cond_beta`` is a conductance-based adaptive exponential
+``aeif_cond_beta`` is a conductance-based adaptive exponential
integrate-and-fire neuron model according to [1]_ with synaptic
conductance modeled by a beta function, as described in [2]_.
@@ -57,7 +53,8 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ g_{ex}(t) (V - E_{rev\_ ex,i}) + g_{in}(t) (V - E_{rev\_ in,i}) - w + I_e
The differential equation for the spike-adaptation current `w` is
@@ -72,8 +69,9 @@ When the neuron fires a spike, the adaptation current `w <- w + b`.
Although this model is not multisynapse, the port (excitatory or inhibitory)
to be chosen must be specified using the synapse property ``receptor``.
- The excitatory port has index 0, whereas the inhibitory one has index 1. Differently from
- NEST, the connection weights related to the inhibitory port must be positive.
+ The excitatory port has index 0, whereas the inhibitory one has index 1.
+Differently from NEST, the connection weights related to the inhibitory port
+must be positive.
Parameters
++++++++++
@@ -112,23 +110,26 @@ The following parameters can be set in the status dictionary.
tau_w ms Adaptation time constant
======== ======= ==================================
-============ ============= ======================================================
+============ =============
+======================================================
**Synaptic parameters**
---------------------------------------------------------------------------------
E_rev_ex mV Excitatory reversal potential
E_rev_in mV Inhibitory reversal potential
tau_rise_ex ms Rise time constant of excitatory synaptic conductance
tau_rise_in ms Rise time constant of inhibitory synaptic conductance
-tau_decay_ex ms Decay time constant of excitatory synaptic conductance
-tau_decay_in ms Decay time constant of inhibitory synaptic conductance
-============ ============= ======================================================
+tau_decay_ex ms Decay time constant of excitatory synaptic
+conductance tau_decay_in ms Decay time constant of inhibitory
+synaptic conductance
+============ =============
+======================================================
========= ======= =========================================================
**Integration parameters**
---------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
========= ======= =========================================================
@@ -151,8 +152,7 @@ aeif_cond_beta_multisynapse, aeif_cond_alpha
EndUserDocs */
-
-//#define MAX_PORT_NUM 20
+// #define MAX_PORT_NUM 20
struct aeif_cond_beta_rk5
{
@@ -161,30 +161,32 @@ struct aeif_cond_beta_rk5
class aeif_cond_beta : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_cond_beta_rk5 > rk5_;
float h_min_;
float h_;
aeif_cond_beta_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_cond_beta_kernel.h b/src/aeif_cond_beta_kernel.h
index f324342c5..5eafb29ef 100644
--- a/src/aeif_cond_beta_kernel.h
+++ b/src/aeif_cond_beta_kernel.h
@@ -20,26 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFCONDBETAKERNEL_H
#define AEIFCONDBETAKERNEL_H
-#include
-#include
-#include "spike_buffer.h"
-#include "node_group.h"
#include "aeif_cond_beta.h"
+#include "node_group.h"
+#include "spike_buffer.h"
+#include
+#include
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_cond_beta_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_g_ex = 0,
i_g_in,
i_g1_ex,
@@ -49,7 +46,8 @@ enum ScalVarIndexes {
N_SCAL_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_g0_ex = 0,
i_g0_in,
i_E_rev_ex,
@@ -75,24 +73,16 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
+const std::string aeif_cond_beta_scal_var_name[ N_SCAL_VAR ] = { "g_ex", "g_in", "g1_ex", "g1_in", "V_m", "w" };
-const std::string aeif_cond_beta_scal_var_name[N_SCAL_VAR] = {
- "g_ex",
- "g_in",
- "g1_ex",
- "g1_in",
- "V_m",
- "w"
-};
-
-const std::string aeif_cond_beta_scal_param_name[N_SCAL_PARAM] = {
- "g0_ex",
+const std::string aeif_cond_beta_scal_param_name[ N_SCAL_PARAM ] = { "g0_ex",
"g0_in",
"E_rev_ex",
"E_rev_in",
@@ -113,145 +103,136 @@ const std::string aeif_cond_beta_scal_param_name[N_SCAL_PARAM] = {
"V_reset",
"t_ref",
"refractory_step",
- "den_delay"
-};
+ "den_delay" };
-const std::string aeif_cond_beta_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_cond_beta_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define g_ex y[i_g_ex]
-#define g1_ex y[i_g1_ex]
-#define g_in y[i_g_in]
-#define g1_in y[i_g1_in]
-#define V_m y[i_V_m]
-#define w y[i_w]
-
-#define dg_exdt dydx[i_g_ex]
-#define dg1_exdt dydx[i_g1_ex]
-#define dg_indt dydx[i_g_in]
-#define dg1_indt dydx[i_g1_in]
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-
-#define g0_ex param[i_g0_ex]
-#define g0_in param[i_g0_in]
-#define E_rev_ex param[i_E_rev_ex]
-#define E_rev_in param[i_E_rev_in]
-#define tau_rise_ex param[i_tau_rise_ex]
-#define tau_rise_in param[i_tau_rise_in]
-#define tau_decay_ex param[i_tau_decay_ex]
-#define tau_decay_in param[i_tau_decay_in]
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_beta_rk5 data_struct)
+#define g_ex y[ i_g_ex ]
+#define g1_ex y[ i_g1_ex ]
+#define g_in y[ i_g_in ]
+#define g1_in y[ i_g1_in ]
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+
+#define dg_exdt dydx[ i_g_ex ]
+#define dg1_exdt dydx[ i_g1_ex ]
+#define dg_indt dydx[ i_g_in ]
+#define dg1_indt dydx[ i_g1_in ]
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+
+#define g0_ex param[ i_g0_ex ]
+#define g0_in param[ i_g0_in ]
+#define E_rev_ex param[ i_E_rev_ex ]
+#define E_rev_in param[ i_E_rev_in ]
+#define tau_rise_ex param[ i_tau_rise_ex ]
+#define tau_rise_in param[ i_tau_rise_in ]
+#define tau_decay_ex param[ i_tau_decay_ex ]
+#define tau_decay_in param[ i_tau_decay_in ]
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_beta_rk5 data_struct )
{
float I_syn_in = 0.0;
float I_syn_ex = 0.0;
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
- I_syn_ex += g_ex*(E_rev_ex - V);
- I_syn_in += g_in*(E_rev_in - V);
+ float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak );
+ I_syn_ex += g_ex * ( E_rev_ex - V );
+ I_syn_in += g_in * ( E_rev_in - V );
- float V_spike = Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn_ex + I_syn_in - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn_ex + I_syn_in - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
+ dwdt = ( a * ( V - E_L ) - w ) / tau_w;
dg1_exdt = -g1_ex / tau_rise_ex;
dg_exdt = g1_ex - g_ex / tau_decay_ex;
dg1_indt = -g1_in / tau_rise_in;
dg_indt = g1_in - g_in / tau_decay_in;
}
- template //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_cond_beta_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_beta_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
+}; // namespace aeif_cond_beta_ns
-};
-
-int Update(long long it, double t1);
+int Update( long long it, double t1 );
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_beta_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_beta_rk5 data_struct )
{
- aeif_cond_beta_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_cond_beta_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_beta_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_beta_rk5 data_struct )
{
- aeif_cond_beta_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_cond_beta_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_cond_beta_multisynapse.cu b/src/aeif_cond_beta_multisynapse.cu
index 93a83e070..e4aaa42fa 100644
--- a/src/aeif_cond_beta_multisynapse.cu
+++ b/src/aeif_cond_beta_multisynapse.cu
@@ -20,26 +20,21 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_cond_beta_multisynapse.h"
#include "aeif_cond_beta_multisynapse_kernel.h"
#include "rk5.h"
-#include "aeif_cond_beta_multisynapse.h"
+#include
+#include
+#include
namespace aeif_cond_beta_multisynapse_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_cond_beta_multisynapse_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_multisynapse_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
- int n_port = (n_var-N_SCAL_VAR)/N_PORT_VAR;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ int n_port = ( n_var - N_SCAL_VAR ) / N_PORT_VAR;
V_th = -50.4;
Delta_T = 2.0;
@@ -54,72 +49,73 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
V_reset = -60.0;
t_ref = 0.0;
den_delay = 0.0;
-
+
V_m = E_L;
w = 0;
refractory_step = 0;
- for (int i = 0; i
-int aeif_cond_beta_multisynapse::UpdateNR<0>(long long it, double t1)
+int
+aeif_cond_beta_multisynapse::UpdateNR< 0 >( long long it, double t1 )
{
return 0;
}
-int aeif_cond_beta_multisynapse::Update(long long it, double t1) {
- UpdateNR(it, t1);
+int
+aeif_cond_beta_multisynapse::Update( long long it, double t1 )
+{
+ UpdateNR< MAX_PORT_NUM >( it, t1 );
return 0;
}
diff --git a/src/aeif_cond_beta_multisynapse.h b/src/aeif_cond_beta_multisynapse.h
index 5c9d01ae1..3749616d1 100644
--- a/src/aeif_cond_beta_multisynapse.h
+++ b/src/aeif_cond_beta_multisynapse.h
@@ -20,23 +20,19 @@
*
*/
-
-
-
-
#ifndef AEIFCONDBETAMULTISYNAPSE_H
#define AEIFCONDBETAMULTISYNAPSE_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
-
-/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire, conductance-based
+/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire,
+conductance-based
Short description
+++++++++++++++++
@@ -46,7 +42,7 @@ Conductance-based adaptive exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_cond_beta_multisynapse`` is a conductance-based adaptive exponential
+``aeif_cond_beta_multisynapse`` is a conductance-based adaptive exponential
integrate-and-fire neuron model according to [1]_ with
multiple synaptic rise time and decay time constants, and synaptic conductance
modeled by a beta function.
@@ -61,7 +57,8 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ I_{syn_{tot}}(V, t)- w + I_e
where:
@@ -82,13 +79,14 @@ When the neuron fires a spike, the adaptation current `w <- w + b`.
.. note::
- The number of receptor ports must be specified at neuron creation (default value is 1) and
- the receptor index starts from 0 (and not from 1 as in NEST multisynapse models).
- The time constants are supplied by by two arrays, ``tau_rise`` and ``tau_decay`` for
- the synaptic rise time and decay time, respectively. The synaptic
- reversal potentials are supplied by the array ``E_rev``. Port numbers
- are automatically assigned in the range 0 to ``n_receptors-1``.
- During connection, the ports are selected with the synapse property ``receptor``.
+ The number of receptor ports must be specified at neuron creation (default
+value is 1) and the receptor index starts from 0 (and not from 1 as in NEST
+multisynapse models). The time constants are supplied by by two arrays,
+``tau_rise`` and ``tau_decay`` for the synaptic rise time and decay time,
+respectively. The synaptic reversal potentials are supplied by the array
+``E_rev``. Port numbers are automatically assigned in the range 0 to
+``n_receptors-1``. During connection, the ports are selected with the synapse
+property ``receptor``.
Parameters
++++++++++
@@ -136,9 +134,9 @@ tau_decay list of ms Decay time constant of synaptic conductance
========= ======= =========================================================
**Integration parameters**
---------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
========= ======= =========================================================
@@ -161,7 +159,6 @@ aeif_cond_alpha_multisynapse
EndUserDocs */
-
#define MAX_PORT_NUM 20
struct aeif_cond_beta_multisynapse_rk5
@@ -171,29 +168,32 @@ struct aeif_cond_beta_multisynapse_rk5
class aeif_cond_beta_multisynapse : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_cond_beta_multisynapse_rk5 > rk5_;
float h_min_;
float h_;
aeif_cond_beta_multisynapse_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_cond_beta_multisynapse_kernel.h b/src/aeif_cond_beta_multisynapse_kernel.h
index 798cfa871..6d0d181b9 100644
--- a/src/aeif_cond_beta_multisynapse_kernel.h
+++ b/src/aeif_cond_beta_multisynapse_kernel.h
@@ -20,38 +20,37 @@
*
*/
-
-
-
-
#ifndef AEIFCONDBETAMULTISYNAPSEKERNEL_H
#define AEIFCONDBETAMULTISYNAPSEKERNEL_H
-#include
-#include
-#include "spike_buffer.h"
-#include "node_group.h"
#include "aeif_cond_beta_multisynapse.h"
+#include "node_group.h"
+#include "spike_buffer.h"
+#include
+#include
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_cond_beta_multisynapse_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_V_m = 0,
i_w,
N_SCAL_VAR
};
-enum PortVarIndexes {
+enum PortVarIndexes
+{
i_g = 0,
i_g1,
N_PORT_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_V_th = 0,
i_Delta_T,
i_g_L,
@@ -69,7 +68,8 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum PortParamIndexes {
+enum PortParamIndexes
+{
i_E_rev = 0,
i_tau_rise,
i_tau_decay,
@@ -77,25 +77,18 @@ enum PortParamIndexes {
N_PORT_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
+const std::string aeif_cond_beta_multisynapse_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" };
-const std::string aeif_cond_beta_multisynapse_scal_var_name[N_SCAL_VAR] = {
- "V_m",
- "w"
-};
-
-const std::string aeif_cond_beta_multisynapse_port_var_name[N_PORT_VAR] = {
- "g",
- "g1"
-};
+const std::string aeif_cond_beta_multisynapse_port_var_name[ N_PORT_VAR ] = { "g", "g1" };
-const std::string aeif_cond_beta_multisynapse_scal_param_name[N_SCAL_PARAM] = {
- "V_th",
+const std::string aeif_cond_beta_multisynapse_scal_param_name[ N_SCAL_PARAM ] = { "V_th",
"Delta_T",
"g_L",
"E_L",
@@ -108,165 +101,161 @@ const std::string aeif_cond_beta_multisynapse_scal_param_name[N_SCAL_PARAM] = {
"V_reset",
"t_ref",
"refractory_step",
- "den_delay"
-};
+ "den_delay" };
-const std::string aeif_cond_beta_multisynapse_port_param_name[N_PORT_PARAM] = {
- "E_rev",
+const std::string aeif_cond_beta_multisynapse_port_param_name[ N_PORT_PARAM ] = { "E_rev",
"tau_rise",
"tau_decay",
- "g0"
-};
+ "g0" };
-const std::string aeif_cond_beta_multisynapse_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_cond_beta_multisynapse_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define V_m y[i_V_m]
-#define w y[i_w]
-#define g(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_g]
-#define g1(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_g1]
-
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-#define dgdt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_g]
-#define dg1dt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_g1]
-
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define E_rev(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_E_rev]
-#define tau_rise(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_tau_rise]
-#define tau_decay(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_tau_decay]
-#define g0(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_g0]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_beta_multisynapse_rk5 data_struct)
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+#define g( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_g ]
+#define g1( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_g1 ]
+
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+#define dgdt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_g ]
+#define dg1dt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_g1 ]
+
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define E_rev( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_E_rev ]
+#define tau_rise( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_tau_rise ]
+#define tau_decay( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_tau_decay ]
+#define g0( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_g0 ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_beta_multisynapse_rk5 data_struct )
{
- enum { n_port = (NVAR-N_SCAL_VAR)/N_PORT_VAR };
+ enum
+ {
+ n_port = ( NVAR - N_SCAL_VAR ) / N_PORT_VAR
+ };
float I_syn = 0.0;
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
- for (int i = 0; i 0 ) ? V_reset : MIN( V_m, V_peak );
+ for ( int i = 0; i < n_port; i++ )
+ {
+ I_syn += g( i ) * ( E_rev( i ) - V );
}
- float V_spike = Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
- for (int i=0; i //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_cond_beta_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_beta_multisynapse_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
-
-};
+}; // namespace aeif_cond_beta_multisynapse_ns
template <>
-int aeif_cond_beta_multisynapse::UpdateNR<0>(long long it, double t1);
+int aeif_cond_beta_multisynapse::UpdateNR< 0 >( long long it, double t1 );
-template
-int aeif_cond_beta_multisynapse::UpdateNR(long long it, double t1)
+template < int N_PORT >
+int
+aeif_cond_beta_multisynapse::UpdateNR( long long it, double t1 )
{
- if (N_PORT == n_port_) {
- const int NVAR = aeif_cond_beta_multisynapse_ns::N_SCAL_VAR
- + aeif_cond_beta_multisynapse_ns::N_PORT_VAR*N_PORT;
- const int NPARAM = aeif_cond_beta_multisynapse_ns::N_SCAL_PARAM
- + aeif_cond_beta_multisynapse_ns::N_PORT_PARAM*N_PORT;
+ if ( N_PORT == n_port_ )
+ {
+ const int NVAR = aeif_cond_beta_multisynapse_ns::N_SCAL_VAR + aeif_cond_beta_multisynapse_ns::N_PORT_VAR * N_PORT;
+ const int NPARAM =
+ aeif_cond_beta_multisynapse_ns::N_SCAL_PARAM + aeif_cond_beta_multisynapse_ns::N_PORT_PARAM * N_PORT;
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+ rk5_.Update< NVAR, NPARAM >( t1, h_min_, rk5_data_struct_ );
}
- else {
- UpdateNR(it, t1);
+ else
+ {
+ UpdateNR< N_PORT - 1 >( it, t1 );
}
return 0;
}
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_beta_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_beta_multisynapse_rk5 data_struct )
{
- aeif_cond_beta_multisynapse_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_cond_beta_multisynapse_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_beta_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_beta_multisynapse_rk5 data_struct )
{
- aeif_cond_beta_multisynapse_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_cond_beta_multisynapse_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_cond_beta_multisynapse_rk5.h b/src/aeif_cond_beta_multisynapse_rk5.h
index 543ed5879..9bb14f932 100644
--- a/src/aeif_cond_beta_multisynapse_rk5.h
+++ b/src/aeif_cond_beta_multisynapse_rk5.h
@@ -20,32 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFCONDBETAMULTISYNAPSERK5_H
#define AEIFCONDBETAMULTISYNAPSERK5_H
struct aeif_cond_beta_multisynapse_rk5;
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_cond_beta_multisynapse_rk5 data_struct );
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_cond_beta_multisynapse_rk5 data_struct);
-
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_cond_beta_multisynapse_rk5 data_struct);
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_cond_beta_multisynapse_rk5 data_struct );
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_beta_multisynapse_rk5 data_struct);
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_multisynapse_rk5 data_struct );
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_cond_beta_multisynapse_rk5 data_struct);
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_cond_beta_multisynapse_rk5 data_struct );
#endif
diff --git a/src/aeif_psc_alpha.cu b/src/aeif_psc_alpha.cu
index 1cf89bc48..d2a51cf7d 100644
--- a/src/aeif_psc_alpha.cu
+++ b/src/aeif_psc_alpha.cu
@@ -20,25 +20,20 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_psc_alpha.h"
#include "aeif_psc_alpha_kernel.h"
#include "rk5.h"
-#include "aeif_psc_alpha.h"
+#include
+#include
+#include
namespace aeif_psc_alpha_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_psc_alpha_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
V_th = -50.4;
Delta_T = 2.0;
@@ -53,7 +48,7 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
V_reset = -60.0;
t_ref = 0.0;
den_delay = 0.0;
-
+
V_m = E_L;
w = 0.0;
refractory_step = 0;
@@ -65,89 +60,91 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
tau_syn_in = 2.0;
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_alpha_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
refractory_step = 0;
// set the right threshold depending on Delta_T
- if (Delta_T <= 0.0) {
+ if ( Delta_T <= 0.0 )
+ {
V_peak = V_th; // same as IAF dynamics for spikes if Delta_T == 0.
}
I0_ex = M_E / tau_syn_ex;
I0_in = M_E / tau_syn_in;
}
-}
+} // namespace aeif_psc_alpha_ns
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_alpha_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_rk5 data_struct )
{
- aeif_psc_alpha_ns::NodeInit(n_var, n_param, x, y, param, data_struct);
+ aeif_psc_alpha_ns::NodeInit( n_var, n_param, x, y, param, data_struct );
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_alpha_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_rk5 data_struct )
{
- aeif_psc_alpha_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct);
+ aeif_psc_alpha_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct );
}
using namespace aeif_psc_alpha_ns;
-int aeif_psc_alpha::Init(int i_node_0, int n_node, int n_port,
- int i_group) {
- BaseNeuron::Init(i_node_0, n_node, n_port, i_group);
+int
+aeif_psc_alpha::Init( int i_node_0, int n_node, int n_port, int i_group )
+{
+ BaseNeuron::Init( i_node_0, n_node, n_port, i_group );
node_type_ = i_aeif_psc_alpha_model;
n_scal_var_ = N_SCAL_VAR;
n_scal_param_ = N_SCAL_PARAM;
- n_group_param_ = N_GROUP_PARAM;
+ n_group_param_ = N_GROUP_PARAM;
n_var_ = n_scal_var_;
n_param_ = n_scal_param_;
- group_param_ = new float[N_GROUP_PARAM];
+ group_param_ = new float[ N_GROUP_PARAM ];
scal_var_name_ = aeif_psc_alpha_scal_var_name;
scal_param_name_ = aeif_psc_alpha_scal_param_name;
group_param_name_ = aeif_psc_alpha_group_param_name;
- //rk5_data_struct_.node_type_ = i_aeif_psc_alpha_model;
+ // rk5_data_struct_.node_type_ = i_aeif_psc_alpha_model;
rk5_data_struct_.i_node_0_ = i_node_0_;
- SetGroupParam("h_min_rel", 1.0e-3);
- SetGroupParam("h0_rel", 1.0e-2);
- h_ = h0_rel_* 0.1;
+ SetGroupParam( "h_min_rel", 1.0e-3 );
+ SetGroupParam( "h0_rel", 1.0e-2 );
+ h_ = h0_rel_ * 0.1;
- rk5_.Init(n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_);
+ rk5_.Init( n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_ );
var_arr_ = rk5_.GetYArr();
param_arr_ = rk5_.GetParamArr();
- port_weight_arr_ = GetParamArr() + GetScalParamIdx("I0_ex");
+ port_weight_arr_ = GetParamArr() + GetScalParamIdx( "I0_ex" );
port_weight_arr_step_ = n_param_;
port_weight_port_step_ = 1;
-
- port_input_arr_ = GetVarArr() + GetScalVarIdx("I1_syn_ex");
+
+ port_input_arr_ = GetVarArr() + GetScalVarIdx( "I1_syn_ex" );
port_input_arr_step_ = n_var_;
port_input_port_step_ = 1;
- den_delay_arr_ = GetParamArr() + GetScalParamIdx("den_delay");
+ den_delay_arr_ = GetParamArr() + GetScalParamIdx( "den_delay" );
return 0;
}
-int aeif_psc_alpha::Calibrate(double time_min, float time_resolution)
+int
+aeif_psc_alpha::Calibrate( double time_min, float time_resolution )
{
- h_min_ = h_min_rel_* time_resolution;
- h_ = h0_rel_* time_resolution;
- rk5_.Calibrate(time_min, h_, rk5_data_struct_);
-
+ h_min_ = h_min_rel_ * time_resolution;
+ h_ = h0_rel_ * time_resolution;
+ rk5_.Calibrate( time_min, h_, rk5_data_struct_ );
+
return 0;
}
-int aeif_psc_alpha::Update(long long it, double t1) {
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+int
+aeif_psc_alpha::Update( long long it, double t1 )
+{
+ rk5_.Update< N_SCAL_VAR, N_SCAL_PARAM >( t1, h_min_, rk5_data_struct_ );
return 0;
}
diff --git a/src/aeif_psc_alpha.h b/src/aeif_psc_alpha.h
index 7e2152697..52c845c68 100644
--- a/src/aeif_psc_alpha.h
+++ b/src/aeif_psc_alpha.h
@@ -20,20 +20,16 @@
*
*/
-
-
-
-
#ifndef AEIFPSCALPHA_H
#define AEIFPSCALPHA_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire, current-based
@@ -45,8 +41,8 @@ Current-based exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_psc_alpha`` is the adaptive exponential integrate and fire neuron according
-to [1]_. Synaptic currents are modeled as alpha functions.
+``aeif_psc_alpha`` is the adaptive exponential integrate and fire neuron
+according to [1]_. Synaptic currents are modeled as alpha functions.
This implementation uses the 5th order Runge-Kutta solver with
adaptive step size to integrate the differential equation.
@@ -55,11 +51,12 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ I_{syn\_ ex}(V, t) - I_{syn\_ in}(V, t) - w + I_e
-where `I_syn_ex` and `I_syn_in` are the excitatory and inhibitory synaptic currents
-modeled as alpha functions.
+where `I_syn_ex` and `I_syn_in` are the excitatory and inhibitory synaptic
+currents modeled as alpha functions.
The differential equation for the spike-adaptation current `w` is:
@@ -71,8 +68,9 @@ The differential equation for the spike-adaptation current `w` is:
Although this model is not multisynapse, the port (excitatory or inhibitory)
to be chosen must be specified using the synapse property ``receptor``.
- The excitatory port has index 0, whereas the inhibitory one has index 1. Differently from
- NEST, the connection weights related to the inhibitory port must be positive.
+ The excitatory port has index 0, whereas the inhibitory one has index 1.
+Differently from NEST, the connection weights related to the inhibitory port
+must be positive.
Parameters
++++++++++
@@ -121,9 +119,9 @@ The following parameters can be set in the status dictionary.
============= ======= =========================================================
**Integration parameters**
-------------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
============= ======= =========================================================
@@ -142,7 +140,7 @@ aeif_psc_alpha_multisynapse, iaf_psc_alpha, aeif_cond_alpha
EndUserDocs */
-//#define MAX_PORT_NUM 20
+// #define MAX_PORT_NUM 20
struct aeif_psc_alpha_rk5
{
@@ -151,30 +149,32 @@ struct aeif_psc_alpha_rk5
class aeif_psc_alpha : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_psc_alpha_rk5 > rk5_;
float h_min_;
float h_;
aeif_psc_alpha_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_psc_alpha_kernel.h b/src/aeif_psc_alpha_kernel.h
index c396c02b1..8fd503731 100644
--- a/src/aeif_psc_alpha_kernel.h
+++ b/src/aeif_psc_alpha_kernel.h
@@ -20,26 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFPSCALPHAKERNEL_H
#define AEIFPSCALPHAKERNEL_H
-#include
-#include
-#include "spike_buffer.h"
-#include "node_group.h"
#include "aeif_psc_alpha.h"
+#include "node_group.h"
+#include "spike_buffer.h"
+#include
+#include
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_psc_alpha_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_I_syn_ex = 0,
i_I_syn_in,
i_I1_syn_ex,
@@ -49,7 +46,8 @@ enum ScalVarIndexes {
N_SCAL_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_tau_syn_ex = 0,
i_tau_syn_in,
i_I0_ex,
@@ -71,24 +69,21 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
-
-const std::string aeif_psc_alpha_scal_var_name[N_SCAL_VAR] = {
- "I_syn_ex",
+const std::string aeif_psc_alpha_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex",
"I_syn_in",
"I1_syn_ex",
"I1_syn_in",
"V_m",
- "w"
-};
+ "w" };
-const std::string aeif_psc_alpha_scal_param_name[N_SCAL_PARAM] = {
- "tau_syn_ex",
+const std::string aeif_psc_alpha_scal_param_name[ N_SCAL_PARAM ] = { "tau_syn_ex",
"tau_syn_in",
"I0_ex",
"I0_in",
@@ -105,140 +100,130 @@ const std::string aeif_psc_alpha_scal_param_name[N_SCAL_PARAM] = {
"V_reset",
"t_ref",
"refractory_step",
- "den_delay"
-};
+ "den_delay" };
-const std::string aeif_psc_alpha_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_psc_alpha_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define I_syn_ex y[i_I_syn_ex]
-#define I_syn_in y[i_I_syn_in]
-#define I1_syn_ex y[i_I1_syn_ex]
-#define I1_syn_in y[i_I1_syn_in]
-#define V_m y[i_V_m]
-#define w y[i_w]
-
-#define dI_syn_exdt dydx[i_I_syn_ex]
-#define dI_syn_indt dydx[i_I_syn_in]
-#define dI1_syn_exdt dydx[i_I1_syn_ex]
-#define dI1_syn_indt dydx[i_I1_syn_in]
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-
-#define I0_ex param[i_I0_ex]
-#define I0_in param[i_I0_in]
-#define tau_syn_ex param[i_tau_syn_ex]
-#define tau_syn_in param[i_tau_syn_in]
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_psc_alpha_rk5 data_struct)
+#define I_syn_ex y[ i_I_syn_ex ]
+#define I_syn_in y[ i_I_syn_in ]
+#define I1_syn_ex y[ i_I1_syn_ex ]
+#define I1_syn_in y[ i_I1_syn_in ]
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+
+#define dI_syn_exdt dydx[ i_I_syn_ex ]
+#define dI_syn_indt dydx[ i_I_syn_in ]
+#define dI1_syn_exdt dydx[ i_I1_syn_ex ]
+#define dI1_syn_indt dydx[ i_I1_syn_in ]
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+
+#define I0_ex param[ i_I0_ex ]
+#define I0_in param[ i_I0_in ]
+#define tau_syn_ex param[ i_tau_syn_ex ]
+#define tau_syn_in param[ i_tau_syn_in ]
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_alpha_rk5 data_struct )
{
float I_syn_tot = 0.0;
-
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
+ float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak );
I_syn_tot += I_syn_ex - I_syn_in;
- float V_spike = Delta_T == 0. ? 0. : Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T == 0. ? 0. : Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn_tot - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn_tot - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
- dI1_syn_exdt = -I1_syn_ex/tau_syn_ex;
- dI1_syn_indt = -I1_syn_in/tau_syn_in;
- dI_syn_exdt = I1_syn_ex - I_syn_ex/tau_syn_ex;
- dI_syn_indt = I1_syn_in - I_syn_in/tau_syn_in;
+ dwdt = ( a * ( V - E_L ) - w ) / tau_w;
+ dI1_syn_exdt = -I1_syn_ex / tau_syn_ex;
+ dI1_syn_indt = -I1_syn_in / tau_syn_in;
+ dI_syn_exdt = I1_syn_ex - I_syn_ex / tau_syn_ex;
+ dI_syn_indt = I1_syn_in - I_syn_in / tau_syn_in;
}
- template //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_psc_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_alpha_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
+}; // namespace aeif_psc_alpha_ns
-};
+int Update( long long it, double t1 );
-int Update(long long it, double t1);
-
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_psc_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_alpha_rk5 data_struct )
{
- aeif_psc_alpha_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_psc_alpha_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_psc_alpha_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_alpha_rk5 data_struct )
{
- aeif_psc_alpha_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_psc_alpha_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_psc_alpha_multisynapse.cu b/src/aeif_psc_alpha_multisynapse.cu
index c9c068275..09398a794 100644
--- a/src/aeif_psc_alpha_multisynapse.cu
+++ b/src/aeif_psc_alpha_multisynapse.cu
@@ -20,26 +20,21 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_psc_alpha_multisynapse.h"
#include "aeif_psc_alpha_multisynapse_kernel.h"
#include "rk5.h"
-#include "aeif_psc_alpha_multisynapse.h"
+#include
+#include
+#include
namespace aeif_psc_alpha_multisynapse_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_psc_alpha_multisynapse_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
- int n_port = (n_var-N_SCAL_VAR)/N_PORT_VAR;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ int n_port = ( n_var - N_SCAL_VAR ) / N_PORT_VAR;
V_th = -50.4;
Delta_T = 2.0;
@@ -54,56 +49,57 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
V_reset = -60.0;
t_ref = 0.0;
den_delay = 0.0;
-
+
V_m = E_L;
w = 0.0;
refractory_step = 0;
- for (int i = 0; i
-int aeif_psc_alpha_multisynapse::UpdateNR<0>(long long it, double t1)
+int
+aeif_psc_alpha_multisynapse::UpdateNR< 0 >( long long it, double t1 )
{
return 0;
}
-int aeif_psc_alpha_multisynapse::Update(long long it, double t1) {
- UpdateNR(it, t1);
+int
+aeif_psc_alpha_multisynapse::Update( long long it, double t1 )
+{
+ UpdateNR< MAX_PORT_NUM >( it, t1 );
return 0;
}
diff --git a/src/aeif_psc_alpha_multisynapse.h b/src/aeif_psc_alpha_multisynapse.h
index fa085d776..820dec825 100644
--- a/src/aeif_psc_alpha_multisynapse.h
+++ b/src/aeif_psc_alpha_multisynapse.h
@@ -20,20 +20,16 @@
*
*/
-
-
-
-
#ifndef AEIFPSCALPHAMULTISYNAPSE_H
#define AEIFPSCALPHAMULTISYNAPSE_H
-#include
-#include
-#include "cuda_error.h"
-#include "rk5.h"
-#include "node_group.h"
#include "base_neuron.h"
+#include "cuda_error.h"
#include "neuron_models.h"
+#include "node_group.h"
+#include "rk5.h"
+#include
+#include
/* BeginUserDocs: neuron, adaptive threshold, integrate-and-fire, current-based
@@ -45,8 +41,8 @@ Current-based exponential integrate-and-fire neuron model
Description
+++++++++++
-``aeif_psc_alpha_multisynapse`` is the adaptive exponential integrate and fire neuron according
-to [1]_. Synaptic currents are modeled as alpha functions.
+``aeif_psc_alpha_multisynapse`` is the adaptive exponential integrate and fire
+neuron according to [1]_. Synaptic currents are modeled as alpha functions.
This implementation uses the 5th order Runge-Kutta solver with
adaptive step size to integrate the differential equation.
@@ -55,7 +51,8 @@ The membrane potential is given by the following differential equation:
.. math::
- C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T \exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ C_m \frac{dV}{dt} = -g_L(V-E_L) + g_L\Delta_T
+\exp\left(\frac{V-V_{th}}{\Delta_T}\right)
+ I_{syn}(V, t)- w + I_e
where ``I_syn (V,t)`` is the sum of excitatory and inhibitory synaptic currents
@@ -69,11 +66,12 @@ The differential equation for the spike-adaptation current `w` is:
.. note::
- The number of receptor ports must be specified at neuron creation (default value is 1) and
- the receptor index starts from 0 (and not from 1 as in NEST multisynapse models).
- The time constants are supplied by an array, ``tau_syn``. Port numbers
- are automatically assigned in the range 0 to ``n_receptors-1``.
- During connection, the ports are selected with the synapse property ``receptor``.
+ The number of receptor ports must be specified at neuron creation (default
+value is 1) and the receptor index starts from 0 (and not from 1 as in NEST
+multisynapse models). The time constants are supplied by an array, ``tau_syn``.
+Port numbers are automatically assigned in the range 0 to ``n_receptors-1``.
+ During connection, the ports are selected with the synapse property
+``receptor``.
Parameters
++++++++++
@@ -120,9 +118,9 @@ The following parameters can be set in the status dictionary.
============= ======= =========================================================
**Integration parameters**
-------------------------------------------------------------------------------
-h0_rel real Starting step in ODE integration relative to time
+h0_rel real Starting step in ODE integration relative to time
resolution
-h_min_rel real Minimum step in ODE integration relative to time
+h_min_rel real Minimum step in ODE integration relative to time
resolution
============= ======= =========================================================
@@ -150,29 +148,32 @@ struct aeif_psc_alpha_multisynapse_rk5
class aeif_psc_alpha_multisynapse : public BaseNeuron
{
- public:
- RungeKutta5 rk5_;
+public:
+ RungeKutta5< aeif_psc_alpha_multisynapse_rk5 > rk5_;
float h_min_;
float h_;
aeif_psc_alpha_multisynapse_rk5 rk5_data_struct_;
-
- int Init(int i_node_0, int n_neuron, int n_port, int i_group);
-
- int Calibrate(double time_min, float time_resolution);
-
- int Update(long long it, double t1);
-
- int GetX(int i_neuron, int n_node, double *x) {
- return rk5_.GetX(i_neuron, n_node, x);
+
+ int Init( int i_node_0, int n_neuron, int n_port, int i_group );
+
+ int Calibrate( double time_min, float time_resolution );
+
+ int Update( long long it, double t1 );
+
+ int
+ GetX( int i_neuron, int n_node, double* x )
+ {
+ return rk5_.GetX( i_neuron, n_node, x );
}
-
- int GetY(int i_var, int i_neuron, int n_node, float *y) {
- return rk5_.GetY(i_var, i_neuron, n_node, y);
+
+ int
+ GetY( int i_var, int i_neuron, int n_node, float* y )
+ {
+ return rk5_.GetY( i_var, i_neuron, n_node, y );
}
-
- template
- int UpdateNR(long long it, double t1);
+ template < int N_PORT >
+ int UpdateNR( long long it, double t1 );
};
#endif
diff --git a/src/aeif_psc_alpha_multisynapse_kernel.h b/src/aeif_psc_alpha_multisynapse_kernel.h
index 61a34e895..b7adae578 100644
--- a/src/aeif_psc_alpha_multisynapse_kernel.h
+++ b/src/aeif_psc_alpha_multisynapse_kernel.h
@@ -20,38 +20,37 @@
*
*/
-
-
-
-
#ifndef AEIFPSCALPHAMULTISYNAPSEKERNEL_H
#define AEIFPSCALPHAMULTISYNAPSEKERNEL_H
-#include
-#include
-#include "spike_buffer.h"
-#include "node_group.h"
#include "aeif_psc_alpha_multisynapse.h"
+#include "node_group.h"
+#include "spike_buffer.h"
+#include
+#include
-#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
extern __constant__ float NESTGPUTimeResolution;
namespace aeif_psc_alpha_multisynapse_ns
{
-enum ScalVarIndexes {
+enum ScalVarIndexes
+{
i_V_m = 0,
i_w,
N_SCAL_VAR
};
-enum PortVarIndexes {
+enum PortVarIndexes
+{
i_I_syn = 0,
i_I1_syn,
N_PORT_VAR
};
-enum ScalParamIndexes {
+enum ScalParamIndexes
+{
i_V_th = 0,
i_Delta_T,
i_g_L,
@@ -69,31 +68,25 @@ enum ScalParamIndexes {
N_SCAL_PARAM
};
-enum PortParamIndexes {
+enum PortParamIndexes
+{
i_tau_syn = 0,
i_I0,
N_PORT_PARAM
};
-enum GroupParamIndexes {
- i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
- i_h0_rel, // Starting step in ODE integr. relative to time resolution
+enum GroupParamIndexes
+{
+ i_h_min_rel = 0, // Min. step in ODE integr. relative to time resolution
+ i_h0_rel, // Starting step in ODE integr. relative to time resolution
N_GROUP_PARAM
};
+const std::string aeif_psc_alpha_multisynapse_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" };
-const std::string aeif_psc_alpha_multisynapse_scal_var_name[N_SCAL_VAR] = {
- "V_m",
- "w"
-};
-
-const std::string aeif_psc_alpha_multisynapse_port_var_name[N_PORT_VAR] = {
- "I_syn",
- "I1_syn"
-};
+const std::string aeif_psc_alpha_multisynapse_port_var_name[ N_PORT_VAR ] = { "I_syn", "I1_syn" };
-const std::string aeif_psc_alpha_multisynapse_scal_param_name[N_SCAL_PARAM] = {
- "V_th",
+const std::string aeif_psc_alpha_multisynapse_scal_param_name[ N_SCAL_PARAM ] = { "V_th",
"Delta_T",
"g_L",
"E_L",
@@ -106,162 +99,156 @@ const std::string aeif_psc_alpha_multisynapse_scal_param_name[N_SCAL_PARAM] = {
"V_reset",
"t_ref",
"refractory_step",
- "den_delay"
-};
+ "den_delay" };
-const std::string aeif_psc_alpha_multisynapse_port_param_name[N_PORT_PARAM] = {
- "tau_syn",
- "I0"
-};
+const std::string aeif_psc_alpha_multisynapse_port_param_name[ N_PORT_PARAM ] = { "tau_syn", "I0" };
-const std::string aeif_psc_alpha_multisynapse_group_param_name[N_GROUP_PARAM] = {
- "h_min_rel",
- "h0_rel"
-};
+const std::string aeif_psc_alpha_multisynapse_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" };
//
// I know that defines are "bad", but the defines below make the
// following equations much more readable.
// For every rule there is some exceptions!
//
-#define V_m y[i_V_m]
-#define w y[i_w]
-#define I_syn(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_I_syn]
-#define I1_syn(i) y[N_SCAL_VAR + N_PORT_VAR*i + i_I1_syn]
-
-#define dVdt dydx[i_V_m]
-#define dwdt dydx[i_w]
-#define dI_syndt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_I_syn]
-#define dI1_syndt(i) dydx[N_SCAL_VAR + N_PORT_VAR*i + i_I1_syn]
-#define I0(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_I0]
-
-#define V_th param[i_V_th]
-#define Delta_T param[i_Delta_T]
-#define g_L param[i_g_L]
-#define E_L param[i_E_L]
-#define C_m param[i_C_m]
-#define a param[i_a]
-#define b param[i_b]
-#define tau_w param[i_tau_w]
-#define I_e param[i_I_e]
-#define V_peak param[i_V_peak]
-#define V_reset param[i_V_reset]
-#define t_ref param[i_t_ref]
-#define refractory_step param[i_refractory_step]
-#define den_delay param[i_den_delay]
-
-#define tau_syn(i) param[N_SCAL_PARAM + N_PORT_PARAM*i + i_tau_syn]
-
-#define h_min_rel_ group_param_[i_h_min_rel]
-#define h0_rel_ group_param_[i_h0_rel]
-
-
- template //, class DataStruct>
-__device__
- void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_psc_alpha_multisynapse_rk5 data_struct)
+#define V_m y[ i_V_m ]
+#define w y[ i_w ]
+#define I_syn( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_I_syn ]
+#define I1_syn( i ) y[ N_SCAL_VAR + N_PORT_VAR * i + i_I1_syn ]
+
+#define dVdt dydx[ i_V_m ]
+#define dwdt dydx[ i_w ]
+#define dI_syndt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_I_syn ]
+#define dI1_syndt( i ) dydx[ N_SCAL_VAR + N_PORT_VAR * i + i_I1_syn ]
+#define I0( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_I0 ]
+
+#define V_th param[ i_V_th ]
+#define Delta_T param[ i_Delta_T ]
+#define g_L param[ i_g_L ]
+#define E_L param[ i_E_L ]
+#define C_m param[ i_C_m ]
+#define a param[ i_a ]
+#define b param[ i_b ]
+#define tau_w param[ i_tau_w ]
+#define I_e param[ i_I_e ]
+#define V_peak param[ i_V_peak ]
+#define V_reset param[ i_V_reset ]
+#define t_ref param[ i_t_ref ]
+#define refractory_step param[ i_refractory_step ]
+#define den_delay param[ i_den_delay ]
+
+#define tau_syn( i ) param[ N_SCAL_PARAM + N_PORT_PARAM * i + i_tau_syn ]
+
+#define h_min_rel_ group_param_[ i_h_min_rel ]
+#define h0_rel_ group_param_[ i_h0_rel ]
+
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct )
{
- enum { n_port = (NVAR-N_SCAL_VAR)/N_PORT_VAR };
+ enum
+ {
+ n_port = ( NVAR - N_SCAL_VAR ) / N_PORT_VAR
+ };
float I_syn_tot = 0.0;
-
- float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak);
- for (int i = 0; i 0 ) ? V_reset : MIN( V_m, V_peak );
+ for ( int i = 0; i < n_port; i++ )
+ {
+ I_syn_tot += I_syn( i );
}
- float V_spike = Delta_T == 0. ? 0. : Delta_T*exp((V - V_th)/Delta_T);
+ float V_spike = Delta_T == 0. ? 0. : Delta_T * exp( ( V - V_th ) / Delta_T );
- dVdt = ( refractory_step > 0 ) ? 0 :
- ( -g_L*(V - E_L - V_spike) + I_syn_tot - w + I_e) / C_m;
+ dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) + I_syn_tot - w + I_e ) / C_m;
// Adaptation current w.
- dwdt = (a*(V - E_L) - w) / tau_w;
- for (int i=0; i //, class DataStruct>
-__device__
- void ExternalUpdate
- (double x, float *y, float *param, bool end_time_step,
- aeif_psc_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM > //, class DataStruct>
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_alpha_multisynapse_rk5 data_struct )
{
- if ( V_m < -1.0e3) { // numerical instability
- printf("V_m out of lower bound\n");
+ if ( V_m < -1.0e3 )
+ { // numerical instability
+ printf( "V_m out of lower bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if ( w < -1.0e6 || w > 1.0e6) { // numerical instability
- printf("w out of bound\n");
+ if ( w < -1.0e6 || w > 1.0e6 )
+ { // numerical instability
+ printf( "w out of bound\n" );
V_m = V_reset;
- w=0;
+ w = 0;
return;
}
- if (refractory_step > 0.0) {
+ if ( refractory_step > 0.0 )
+ {
V_m = V_reset;
- if (end_time_step) {
+ if ( end_time_step )
+ {
refractory_step -= 1.0;
}
}
- else {
- if ( V_m >= V_peak ) { // send spike
+ else
+ {
+ if ( V_m >= V_peak )
+ { // send spike
int neuron_idx = threadIdx.x + blockIdx.x * blockDim.x;
- PushSpike(data_struct.i_node_0_ + neuron_idx, 1.0);
+ PushSpike( data_struct.i_node_0_ + neuron_idx, 1.0 );
V_m = V_reset;
w += b; // spike-driven adaptation
- refractory_step = (int)round(t_ref/NESTGPUTimeResolution);
- if (refractory_step<0) {
- refractory_step = 0;
+ refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution );
+ if ( refractory_step < 0 )
+ {
+ refractory_step = 0;
}
}
}
}
-
-};
+}; // namespace aeif_psc_alpha_multisynapse_ns
template <>
-int aeif_psc_alpha_multisynapse::UpdateNR<0>(long long it, double t1);
+int aeif_psc_alpha_multisynapse::UpdateNR< 0 >( long long it, double t1 );
-template
-int aeif_psc_alpha_multisynapse::UpdateNR(long long it, double t1)
+template < int N_PORT >
+int
+aeif_psc_alpha_multisynapse::UpdateNR( long long it, double t1 )
{
- if (N_PORT == n_port_) {
- const int NVAR = aeif_psc_alpha_multisynapse_ns::N_SCAL_VAR
- + aeif_psc_alpha_multisynapse_ns::N_PORT_VAR*N_PORT;
- const int NPARAM = aeif_psc_alpha_multisynapse_ns::N_SCAL_PARAM
- + aeif_psc_alpha_multisynapse_ns::N_PORT_PARAM*N_PORT;
+ if ( N_PORT == n_port_ )
+ {
+ const int NVAR = aeif_psc_alpha_multisynapse_ns::N_SCAL_VAR + aeif_psc_alpha_multisynapse_ns::N_PORT_VAR * N_PORT;
+ const int NPARAM =
+ aeif_psc_alpha_multisynapse_ns::N_SCAL_PARAM + aeif_psc_alpha_multisynapse_ns::N_PORT_PARAM * N_PORT;
- rk5_.Update(t1, h_min_, rk5_data_struct_);
+ rk5_.Update< NVAR, NPARAM >( t1, h_min_, rk5_data_struct_ );
}
- else {
- UpdateNR(it, t1);
+ else
+ {
+ UpdateNR< N_PORT - 1 >( it, t1 );
}
return 0;
}
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_psc_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct )
{
- aeif_psc_alpha_multisynapse_ns::Derivatives(x, y, dydx, param,
- data_struct);
+ aeif_psc_alpha_multisynapse_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct );
}
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_psc_alpha_multisynapse_rk5 data_struct)
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_alpha_multisynapse_rk5 data_struct )
{
- aeif_psc_alpha_multisynapse_ns::ExternalUpdate(x, y, param,
- end_time_step,
- data_struct);
+ aeif_psc_alpha_multisynapse_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct );
}
-
#endif
diff --git a/src/aeif_psc_alpha_multisynapse_rk5.h b/src/aeif_psc_alpha_multisynapse_rk5.h
index 3f0c82cad..bb670abde 100644
--- a/src/aeif_psc_alpha_multisynapse_rk5.h
+++ b/src/aeif_psc_alpha_multisynapse_rk5.h
@@ -20,32 +20,23 @@
*
*/
-
-
-
-
#ifndef AEIFPSCALPHAMULTISYNAPSERK5_H
#define AEIFPSCALPHAMULTISYNAPSERK5_H
struct aeif_psc_alpha_multisynapse_rk5;
+template < int NVAR, int NPARAM >
+__device__ void
+Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct );
-template
-__device__
-void Derivatives(double x, float *y, float *dydx, float *param,
- aeif_psc_alpha_multisynapse_rk5 data_struct);
-
-template
-__device__
-void ExternalUpdate(double x, float *y, float *param, bool end_time_step,
- aeif_psc_alpha_multisynapse_rk5 data_struct);
+template < int NVAR, int NPARAM >
+__device__ void
+ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_alpha_multisynapse_rk5 data_struct );
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_alpha_multisynapse_rk5 data_struct);
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct );
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_alpha_multisynapse_rk5 data_struct);
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_alpha_multisynapse_rk5 data_struct );
#endif
diff --git a/src/aeif_psc_delta.cu b/src/aeif_psc_delta.cu
index 82e472cef..29e9538f1 100644
--- a/src/aeif_psc_delta.cu
+++ b/src/aeif_psc_delta.cu
@@ -20,25 +20,20 @@
*
*/
-
-
-
-
-#include
-#include
-#include
+#include "aeif_psc_delta.h"
#include "aeif_psc_delta_kernel.h"
#include "rk5.h"
-#include "aeif_psc_delta.h"
+#include
+#include
+#include
namespace aeif_psc_delta_ns
{
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y, float *param,
- aeif_psc_delta_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
V_th = -50.4;
Delta_T = 2.0;
@@ -53,100 +48,100 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param,
V_reset = -60.0;
t_ref = 0.0;
den_delay = 0.0;
-
+
V_m = E_L;
w = 0;
refractory_step = 0;
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_delta_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_rk5 data_struct )
{
- //int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
- //int n_port = (n_var-N_SCAL_VAR)/N_PORT_VAR;
+ // int array_idx = threadIdx.x + blockIdx.x * blockDim.x;
+ // int n_port = (n_var-N_SCAL_VAR)/N_PORT_VAR;
refractory_step = 0;
// set the right threshold depending on Delta_T
- if (Delta_T <= 0.0) {
+ if ( Delta_T <= 0.0 )
+ {
V_peak = V_th; // same as IAF dynamics for spikes if Delta_T == 0.
}
}
-}
+} // namespace aeif_psc_delta_ns
-__device__
-void NodeInit(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_delta_rk5 data_struct)
+__device__ void
+NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_rk5 data_struct )
{
- aeif_psc_delta_ns::NodeInit(n_var, n_param, x, y, param, data_struct);
+ aeif_psc_delta_ns::NodeInit( n_var, n_param, x, y, param, data_struct );
}
-__device__
-void NodeCalibrate(int n_var, int n_param, double x, float *y,
- float *param, aeif_psc_delta_rk5 data_struct)
+__device__ void
+NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_rk5 data_struct )
{
- aeif_psc_delta_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct);
+ aeif_psc_delta_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct );
}
using namespace aeif_psc_delta_ns;
-int aeif_psc_delta::Init(int i_node_0, int n_node, int n_port,
- int i_group) {
- BaseNeuron::Init(i_node_0, n_node, n_port, i_group);
+int
+aeif_psc_delta::Init( int i_node_0, int n_node, int n_port, int i_group )
+{
+ BaseNeuron::Init( i_node_0, n_node, n_port, i_group );
node_type_ = i_aeif_psc_delta_model;
n_scal_var_ = N_SCAL_VAR;
n_scal_param_ = N_SCAL_PARAM;
n_group_param_ = N_GROUP_PARAM;
- n_var_ = n_scal_var_ + n_port_var_*n_port;
- n_param_ = n_scal_param_ + n_port_param_*n_port;
+ n_var_ = n_scal_var_ + n_port_var_ * n_port;
+ n_param_ = n_scal_param_ + n_port_param_ * n_port;
+
+ group_param_ = new float[ N_GROUP_PARAM ];
- group_param_ = new float[N_GROUP_PARAM];
-
scal_var_name_ = aeif_psc_delta_scal_var_name;
scal_param_name_ = aeif_psc_delta_scal_param_name;
group_param_name_ = aeif_psc_delta_group_param_name;
- //rk5_data_struct_.node_type_ = i_aeif_psc_delta_model;
+ // rk5_data_struct_.node_type_ = i_aeif_psc_delta_model;
rk5_data_struct_.i_node_0_ = i_node_0_;
- SetGroupParam("h_min_rel", 1.0e-3);
- SetGroupParam("h0_rel", 1.0e-2);
- h_ = h0_rel_* 0.1;
-
- rk5_.Init(n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_);
+ SetGroupParam( "h_min_rel", 1.0e-3 );
+ SetGroupParam( "h0_rel", 1.0e-2 );
+ h_ = h0_rel_ * 0.1;
+
+ rk5_.Init( n_node, n_var_, n_param_, 0.0, h_, rk5_data_struct_ );
var_arr_ = rk5_.GetYArr();
param_arr_ = rk5_.GetParamArr();
// multiplication factor of input signal is always 1 for all nodes
float input_weight = 1.0;
- CUDAMALLOCCTRL("&port_weight_arr_",&port_weight_arr_, sizeof(float));
- gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight,
- sizeof(float), cudaMemcpyHostToDevice));
+ CUDAMALLOCCTRL( "&port_weight_arr_", &port_weight_arr_, sizeof( float ) );
+ gpuErrchk( cudaMemcpy( port_weight_arr_, &input_weight, sizeof( float ), cudaMemcpyHostToDevice ) );
port_weight_arr_step_ = 0;
port_weight_port_step_ = 0;
- port_input_arr_ = GetVarArr() + GetScalVarIdx("V_m");
+ port_input_arr_ = GetVarArr() + GetScalVarIdx( "V_m" );
port_input_arr_step_ = n_var_;
port_input_port_step_ = n_port_var_;
- den_delay_arr_ = GetParamArr() + GetScalParamIdx("den_delay");
+ den_delay_arr_ = GetParamArr() + GetScalParamIdx( "den_delay" );
return 0;
}
-int aeif_psc_delta::Calibrate(double time_min, float time_resolution)
+int
+aeif_psc_delta::Calibrate( double time_min, float time_resolution )
{
- h_min_ = h_min_rel_* time_resolution;
- h_ = h0_rel_* time_resolution;
- rk5_.Calibrate(time_min, h_, rk5_data_struct_);
-
+ h_min_ = h_min_rel_ * time_resolution;
+ h_ = h0_rel_ * time_resolution;
+ rk5_.Calibrate( time_min, h_, rk5_data_struct_ );
+
return 0;
}
-int aeif_psc_delta::Update(long long it, double t1)
+int
+aeif_psc_delta::Update( long long it, double t1 )
{
- rk5_.Update(t1, h_min_, rk5_data_struct_);
-
+ rk5_.Update< N_SCAL_VAR, N_SCAL_PARAM >( t1, h_min_, rk5_data_struct_ );
+
return 0;
}
diff --git a/src/aeif_psc_delta.h b/src/aeif_psc_delta.h
index 3eb3724db..ee986cf09 100644
--- a/src/aeif_psc_delta.h
+++ b/src/aeif_psc_delta.h
@@ -20,28 +20,24 @@
*
*/
-
-
-
-
#ifndef AEIFPSCDELTA_H
#define AEIFPSCDELTA_H
-#include
-#include