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/build_support/log.txt b/build_support/log.txt new file mode 100644 index 000000000..c8ec400c0 --- /dev/null +++ b/build_support/log.txt @@ -0,0 +1,522 @@ +~/nest-gpu-git/golosio/nest-gpu/build_support ~/nest-gpu-git/golosio/nest-gpu/build_support +ls: cannot access '*.cc': No such file or directory +ls: cannot access '*.c': No such file or directory +ls: cannot access '*.cuh': No such file or directory +ls: cannot access '*.hpp': No such file or directory +ls: cannot access '*.cc': No such file or directory +ls: cannot access '*.c': No such file or directory + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_cond_alpha.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_cond_alpha.cu +Input file: aeif_cond_alpha.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_cond_alpha.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_cond_alpha_multisynapse.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_cond_alpha_multisynapse.cu +Input file: aeif_cond_alpha_multisynapse.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_cond_alpha_multisynapse.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_cond_beta.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_cond_beta.cu +Input file: aeif_cond_beta.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_cond_beta.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_cond_beta_multisynapse.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_cond_beta_multisynapse.cu +Input file: aeif_cond_beta_multisynapse.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_cond_beta_multisynapse.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_psc_alpha.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_psc_alpha.cu +Input file: aeif_psc_alpha.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_psc_alpha.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_psc_alpha_multisynapse.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_psc_alpha_multisynapse.cu +Input file: aeif_psc_alpha_multisynapse.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_psc_alpha_multisynapse.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_psc_delta.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_psc_delta.cu +Input file: aeif_psc_delta.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_psc_delta.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_psc_exp.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_psc_exp.cu +Input file: aeif_psc_exp.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_psc_exp.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: aeif_psc_exp_multisynapse.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config aeif_psc_exp_multisynapse.cu +Input file: aeif_psc_exp_multisynapse.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy aeif_psc_exp_multisynapse.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: base_neuron.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config base_neuron.cu +Input file: base_neuron.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy base_neuron.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: connect.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config connect.cu +Input file: connect.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy connect.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: connect_mpi.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config connect_mpi.cu +Input file: connect_mpi.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy connect_mpi.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: connect_rules.cpp +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config connect_rules.cpp +Input file: connect_rules.cpp +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy connect_rules.cpp -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated. +warning: argument unused during compilation: '--no-cuda-version-check' [clang-diagnostic-unused-command-line-argument] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: dummyfile.cpp +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config dummyfile.cpp +Input file: dummyfile.cpp +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy dummyfile.cpp -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated. +warning: argument unused during compilation: '--no-cuda-version-check' [clang-diagnostic-unused-command-line-argument] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: ext_neuron.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config ext_neuron.cu +Input file: ext_neuron.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy ext_neuron.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: getRealTime.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config getRealTime.cu +Input file: getRealTime.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy getRealTime.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: get_spike.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config get_spike.cu +Input file: get_spike.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy get_spike.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: iaf_psc_alpha.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config iaf_psc_alpha.cu +Input file: iaf_psc_alpha.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy iaf_psc_alpha.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: iaf_psc_exp.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config iaf_psc_exp.cu +Input file: iaf_psc_exp.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy iaf_psc_exp.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: iaf_psc_exp_g.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config iaf_psc_exp_g.cu +Input file: iaf_psc_exp_g.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy iaf_psc_exp_g.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: iaf_psc_exp_hc.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config iaf_psc_exp_hc.cu +Input file: iaf_psc_exp_hc.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy iaf_psc_exp_hc.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: izhikevich_cond_beta.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config izhikevich_cond_beta.cu +Input file: izhikevich_cond_beta.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy izhikevich_cond_beta.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: izhikevich.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config izhikevich.cu +Input file: izhikevich.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy izhikevich.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: izhikevich_psc_exp_2s.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config izhikevich_psc_exp_2s.cu +Input file: izhikevich_psc_exp_2s.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy izhikevich_psc_exp_2s.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: izhikevich_psc_exp_5s.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config izhikevich_psc_exp_5s.cu +Input file: izhikevich_psc_exp_5s.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy izhikevich_psc_exp_5s.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: izhikevich_psc_exp.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config izhikevich_psc_exp.cu +Input file: izhikevich_psc_exp.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy izhikevich_psc_exp.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: locate.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config locate.cu +Input file: locate.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy locate.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: multimeter.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config multimeter.cu +Input file: multimeter.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy multimeter.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: nestgpu_C.cpp +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config nestgpu_C.cpp +Input file: nestgpu_C.cpp +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy nestgpu_C.cpp -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated. +warning: argument unused during compilation: '--no-cuda-version-check' [clang-diagnostic-unused-command-line-argument] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: nestgpu.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config nestgpu.cu +Input file: nestgpu.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy nestgpu.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: neuron_models.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config neuron_models.cu +Input file: neuron_models.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy neuron_models.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: node_group.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config node_group.cu +Input file: node_group.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy node_group.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +3 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 2 warnings (2 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: parrot_neuron.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config parrot_neuron.cu +Input file: parrot_neuron.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy parrot_neuron.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: poiss_gen.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config poiss_gen.cu +Input file: poiss_gen.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy poiss_gen.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: poisson.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config poisson.cu +Input file: poisson.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy poisson.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: prefix_scan.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config prefix_scan.cu +Input file: prefix_scan.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy prefix_scan.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: propagator_stability.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config propagator_stability.cu +Input file: propagator_stability.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy propagator_stability.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: random.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config random.cu +Input file: random.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy random.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: rev_spike.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config rev_spike.cu +Input file: rev_spike.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy rev_spike.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: rk5.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config rk5.cu +Input file: rk5.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy rk5.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: scan.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config scan.cu +Input file: scan.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy scan.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: send_spike.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config send_spike.cu +Input file: send_spike.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy send_spike.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: spike_buffer.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config spike_buffer.cu +Input file: spike_buffer.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy spike_buffer.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: spike_detector.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config spike_detector.cu +Input file: spike_detector.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy spike_detector.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: spike_generator.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config spike_generator.cu +Input file: spike_generator.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy spike_generator.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: spike_mpi.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config spike_mpi.cu +Input file: spike_mpi.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy spike_mpi.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: stdp.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config stdp.cu +Input file: stdp.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy stdp.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: syn_model.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config syn_model.cu +Input file: syn_model.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy syn_model.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +2 warnings generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Suppressed 1 warnings (1 in non-user code). +Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED + - Check with clang-tidy-cuda.sh C/C++/CUDA file: test_syn_model.cu +/tmp/tmp.gXRoMuKv8t/clang-tidy-cuda.sh --include-path=/tmp/tmp.gXRoMuKv8t/config test_syn_model.cu +Input file: test_syn_model.cu +cuda.h found in path /usr/local/cuda/include +mpi.h found in path /usr/lib/x86_64-linux-gnu/openmpi/include +clang-tidy test_syn_model.cu -p . -- -I /tmp/tmp.gXRoMuKv8t/config -isystem /usr/lib/x86_64-linux-gnu/openmpi/include -isystem /usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -isystem /usr/local/cuda/include --no-cuda-version-check +1 warning generated when compiling for host. +warning: CUDA version is newer than the latest partially supported version 12.1 [clang-diagnostic-unknown-cuda-version] +Resource filename: /home/golosio/.local/lib/python3.10/site-packages/clang_tidy/data/bin/clang-tidy +PASSED +~/nest-gpu-git/golosio/nest-gpu/build_support +Checked 49 files with clang-tidy-cuda.sh +All tests PASSED diff --git a/c++/examples/brunel_mpi.cpp b/c++/examples/brunel_mpi.cpp index fe9335e9f..be6f0d196 100644 --- a/c++/examples/brunel_mpi.cpp +++ b/c++/examples/brunel_mpi.cpp @@ -21,49 +21,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 +63,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..1a50f019a 100644 --- a/c++/examples/brunel_outdegree.cpp +++ b/c++/examples/brunel_outdegree.cpp @@ -21,39 +21,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 +62,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..2803449f8 100644 --- a/c++/examples/brunel_outdegree_mpi.cpp +++ b/c++/examples/brunel_outdegree_mpi.cpp @@ -21,54 +21,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 +63,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..93e855c6a 100644 --- a/c++/examples/test_aeif_cond_beta.cpp +++ b/c++/examples/test_aeif_cond_beta.cpp @@ -21,64 +21,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..1acca648e 100644 --- a/c++/examples/test_connect.cpp +++ b/c++/examples/test_connect.cpp @@ -21,70 +21,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..a58005257 100644 --- a/c++/examples/test_error.cpp +++ b/c++/examples/test_error.cpp @@ -21,118 +21,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..b51a0be01 100644 --- a/c++/examples/test_setvar.cpp +++ b/c++/examples/test_setvar.cpp @@ -21,68 +21,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..4d4b3947e 100644 --- a/c++/tests/test_connections.cpp +++ b/c++/tests/test_connections.cpp @@ -21,19 +21,17 @@ */ - - - +#include "nestgpu.h" +#include +#include #include #include -#include #include -#include -#include "nestgpu.h" using namespace std; -int main(int argc, char *argv[]) +int +main( int argc, char* argv[] ) { // Intializes C random number generator // srand((unsigned) time(&t)); @@ -41,16 +39,16 @@ int main(int argc, char *argv[]) NESTGPU ngpu; cout << "Building ...\n"; - ngpu.SetRandomSeed(1234ULL); // seed for GPU random numbers - + 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); + NodeSeq pg = ngpu.Create( "poisson_generator" ); + ngpu.SetNeuronParam( pg, "rate", poiss_rate ); int n_recept = 3; // number of receptors // create 3 neuron groups @@ -58,86 +56,83 @@ int main(int argc, char *argv[]) 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); - + + 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]; - + 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); + 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 + 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); + 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); + 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 ); - // 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); + 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); + 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); + 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(); diff --git a/c++/tests/test_neuron_groups.cpp b/c++/tests/test_neuron_groups.cpp index 5a824105b..7bf6fe9fc 100644 --- a/c++/tests/test_neuron_groups.cpp +++ b/c++/tests/test_neuron_groups.cpp @@ -21,28 +21,26 @@ */ - - - +#include "nestgpu.h" +#include +#include #include #include -#include #include -#include #include -#include "nestgpu.h" using namespace std; -int main(int argc, char *argv[]) +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 + + ngpu.SetRandomSeed( 1234ULL ); // seed for GPU random numbers // poisson generator parameters float poiss_rate = 5000.0; // poisson signal rate in Hz @@ -50,113 +48,109 @@ 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 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 + 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 + 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); - + 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]; - + 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); + 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 + 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); + 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); + 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 ); - // 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); + 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); + 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); + 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); + std::vector< std::vector< float > > 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; j vect = data_vect1[ i ]; + for ( uint j = 0; j < vect.size() - 1; j++ ) + { + fprintf( fp, "%f\t", vect[ j ] ); } - fprintf(fp,"%f\n", vect[vect.size()-1]); + fprintf( fp, "%f\n", vect[ vect.size() - 1 ] ); } - fclose(fp); - + fclose( fp ); + return 0; } diff --git a/python/test/test_stdp/cases/test_all.sh b/python/test/test_stdp/cases/test_all.sh index 3cf5c02d1..1e2c6c71e 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/w'; done diff --git a/src/aeif_cond_alpha.cu b/src/aeif_cond_alpha.cu index 65cccda6f..d5606150e 100644 --- a/src/aeif_cond_alpha.cu +++ b/src/aeif_cond_alpha.cu @@ -21,24 +21,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 +63,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 @@ -80,27 +75,26 @@ void NodeCalibrate(int n_var, int n_param, double x, float *y, } } - -__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 ) { - 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, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); +int +aeif_cond_alpha::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_aeif_cond_alpha_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; @@ -108,45 +102,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 226241fe9..0338879a6 100644 --- a/src/aeif_cond_alpha.h +++ b/src/aeif_cond_alpha.h @@ -21,19 +21,16 @@ */ - - - #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 @@ -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]_ @@ -123,9 +120,9 @@ 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 +145,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 +154,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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..80c529251 100644 --- a/src/aeif_cond_alpha_kernel.h +++ b/src/aeif_cond_alpha_kernel.h @@ -21,25 +21,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 +47,8 @@ enum ScalVarIndexes { N_SCAL_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_g0_ex = 0, i_g0_in, i_E_rev_ex, @@ -73,22 +72,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 +104,70 @@ 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,39 +175,44 @@ __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; } } } @@ -228,25 +221,20 @@ __device__ }; -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 ); } diff --git a/src/aeif_cond_alpha_multisynapse.cu b/src/aeif_cond_alpha_multisynapse.cu index 3a03604a5..fbec4db7a 100644 --- a/src/aeif_cond_alpha_multisynapse.cu +++ b/src/aeif_cond_alpha_multisynapse.cu @@ -21,25 +21,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 +50,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 4a72b895d..63fc34238 100644 --- a/src/aeif_cond_alpha_multisynapse.h +++ b/src/aeif_cond_alpha_multisynapse.h @@ -21,19 +21,16 @@ */ - - - #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 @@ -46,7 +43,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. @@ -134,9 +131,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 ============= ======= ========================================================= @@ -169,30 +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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..fc9424a35 100644 --- a/src/aeif_cond_alpha_multisynapse_kernel.h +++ b/src/aeif_cond_alpha_multisynapse_kernel.h @@ -21,37 +21,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 +69,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,117 +101,117 @@ 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; } } } @@ -226,43 +221,40 @@ __device__ }; 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 ); } diff --git a/src/aeif_cond_alpha_multisynapse_rk5.h b/src/aeif_cond_alpha_multisynapse_rk5.h index 159a18eca..433b0e4e1 100644 --- a/src/aeif_cond_alpha_multisynapse_rk5.h +++ b/src/aeif_cond_alpha_multisynapse_rk5.h @@ -21,31 +21,24 @@ */ - - - #ifndef AEIFCONDALPHAMULTISYNAPSERK5_H #define AEIFCONDALPHAMULTISYNAPSERK5_H struct aeif_cond_alpha_multisynapse_rk5; -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 ); -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 7d9b196d9..2749a75c6 100644 --- a/src/aeif_cond_beta.cu +++ b/src/aeif_cond_beta.cu @@ -21,25 +21,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 +55,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 +65,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) + +__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, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); +int +aeif_cond_beta::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_aeif_cond_beta_model; n_scal_var_ = N_SCAL_VAR; n_scal_param_ = N_SCAL_PARAM; @@ -142,45 +142,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 b76f9cdf9..c761d7f53 100644 --- a/src/aeif_cond_beta.h +++ b/src/aeif_cond_beta.h @@ -21,19 +21,16 @@ */ - - - #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 @@ -46,7 +43,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]_. @@ -126,9 +123,9 @@ tau_decay_in ms Decay time constant of inhibitory synaptic conductanc ========= ======= ========================================================= **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 ========= ======= ========================================================= @@ -152,7 +149,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 +158,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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..d6af173c7 100644 --- a/src/aeif_cond_beta_kernel.h +++ b/src/aeif_cond_beta_kernel.h @@ -21,25 +21,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 +47,8 @@ enum ScalVarIndexes { N_SCAL_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_g0_ex = 0, i_g0_in, i_E_rev_ex, @@ -75,24 +74,17 @@ 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,117 +105,116 @@ 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; } } } @@ -232,25 +223,20 @@ __device__ }; -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 ); } diff --git a/src/aeif_cond_beta_multisynapse.cu b/src/aeif_cond_beta_multisynapse.cu index f184dab7e..afe3d4347 100644 --- a/src/aeif_cond_beta_multisynapse.cu +++ b/src/aeif_cond_beta_multisynapse.cu @@ -21,25 +21,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 +50,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 e207a8326..0195e7b90 100644 --- a/src/aeif_cond_beta_multisynapse.h +++ b/src/aeif_cond_beta_multisynapse.h @@ -21,19 +21,16 @@ */ - - - #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 @@ -46,7 +43,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. @@ -136,9 +133,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 ========= ======= ========================================================= @@ -171,30 +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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..625aa3f00 100644 --- a/src/aeif_cond_beta_multisynapse_kernel.h +++ b/src/aeif_cond_beta_multisynapse_kernel.h @@ -21,37 +21,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 +69,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -77,25 +78,19 @@ 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,118 +103,120 @@ 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; } } } @@ -229,43 +226,40 @@ __device__ }; 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 ); } diff --git a/src/aeif_cond_beta_multisynapse_rk5.h b/src/aeif_cond_beta_multisynapse_rk5.h index 543ed5879..e931e2bc9 100644 --- a/src/aeif_cond_beta_multisynapse_rk5.h +++ b/src/aeif_cond_beta_multisynapse_rk5.h @@ -21,31 +21,24 @@ */ - - - #ifndef AEIFCONDBETAMULTISYNAPSERK5_H #define AEIFCONDBETAMULTISYNAPSERK5_H struct aeif_cond_beta_multisynapse_rk5; -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 ); -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 401c59dc8..27083a7a9 100644 --- a/src/aeif_psc_alpha.cu +++ b/src/aeif_psc_alpha.cu @@ -21,24 +21,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 +49,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,14 +61,14 @@ 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; @@ -81,73 +77,75 @@ void NodeCalibrate(int n_var, int n_param, double x, float *y, } -__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, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); +int +aeif_psc_alpha::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); 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 be7e7e6a0..55694cfca 100644 --- a/src/aeif_psc_alpha.h +++ b/src/aeif_psc_alpha.h @@ -21,19 +21,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 @@ -121,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 ============= ======= ========================================================= @@ -142,7 +139,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 +148,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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..f33690de3 100644 --- a/src/aeif_psc_alpha_kernel.h +++ b/src/aeif_psc_alpha_kernel.h @@ -21,25 +21,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 +47,8 @@ enum ScalVarIndexes { N_SCAL_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_tau_syn_ex = 0, i_tau_syn_in, i_I0_ex, @@ -71,24 +70,22 @@ 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,112 +102,111 @@ 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; } } } @@ -219,25 +215,20 @@ __device__ }; -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 ); } diff --git a/src/aeif_psc_alpha_multisynapse.cu b/src/aeif_psc_alpha_multisynapse.cu index db8d2db14..fa69108b6 100644 --- a/src/aeif_psc_alpha_multisynapse.cu +++ b/src/aeif_psc_alpha_multisynapse.cu @@ -21,25 +21,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 +50,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 d01e8f223..6235c6be6 100644 --- a/src/aeif_psc_alpha_multisynapse.h +++ b/src/aeif_psc_alpha_multisynapse.h @@ -21,19 +21,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 @@ -120,9 +117,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,30 +147,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, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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..225a85f01 100644 --- a/src/aeif_psc_alpha_multisynapse_kernel.h +++ b/src/aeif_psc_alpha_multisynapse_kernel.h @@ -21,37 +21,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 +69,26 @@ 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,115 +101,116 @@ 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; } } } @@ -224,43 +220,40 @@ __device__ }; 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 ); } diff --git a/src/aeif_psc_alpha_multisynapse_rk5.h b/src/aeif_psc_alpha_multisynapse_rk5.h index 3f0c82cad..8baf73324 100644 --- a/src/aeif_psc_alpha_multisynapse_rk5.h +++ b/src/aeif_psc_alpha_multisynapse_rk5.h @@ -21,31 +21,24 @@ */ - - - #ifndef AEIFPSCALPHAMULTISYNAPSERK5_H #define AEIFPSCALPHAMULTISYNAPSERK5_H struct aeif_psc_alpha_multisynapse_rk5; -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 ); -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 2b4d6adb1..8bcc58e30 100644 --- a/src/aeif_psc_delta.cu +++ b/src/aeif_psc_delta.cu @@ -21,24 +21,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 +49,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. } } } -__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, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, n_port, i_group, seed); +int +aeif_psc_delta::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, n_port, i_group, seed ); 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; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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 3824991b9..a9b87faae 100644 --- a/src/aeif_psc_delta.h +++ b/src/aeif_psc_delta.h @@ -21,19 +21,16 @@ */ - - - #ifndef AEIFPSCDELTA_H #define AEIFPSCDELTA_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 @@ -119,9 +116,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,27 +147,29 @@ struct aeif_psc_delta_rk5 class aeif_psc_delta : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< aeif_psc_delta_rk5 > rk5_; float h_min_; float h_; aeif_psc_delta_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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 ); } - }; #endif diff --git a/src/aeif_psc_delta_kernel.h b/src/aeif_psc_delta_kernel.h index c193fd76a..1a5d863f9 100644 --- a/src/aeif_psc_delta_kernel.h +++ b/src/aeif_psc_delta_kernel.h @@ -21,35 +21,35 @@ */ - - - #ifndef AEIFPSCDELTAKERNEL_H #define AEIFPSCDELTAKERNEL_H -#include -#include -#include "spike_buffer.h" -#include "node_group.h" #include "aeif_psc_delta.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_delta_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ N_PORT_VAR = 0 }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -67,20 +67,17 @@ 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_delta_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string aeif_psc_delta_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string aeif_psc_delta_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string aeif_psc_delta_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -93,13 +90,9 @@ const std::string aeif_psc_delta_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string aeif_psc_delta_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string aeif_psc_delta_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" }; // @@ -107,80 +100,83 @@ const std::string aeif_psc_delta_group_param_name[N_GROUP_PARAM] = { // 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 dVdt dydx[i_V_m] -#define dwdt dydx[i_w] - -#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_delta_rk5 data_struct) +#define V_m y[ i_V_m ] +#define w y[ i_w ] + +#define dVdt dydx[ i_V_m ] +#define dwdt dydx[ i_w ] + +#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_delta_rk5 data_struct ) { - - float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak); - float V_spike = Delta_T == 0. ? 0. : Delta_T*exp((V - V_th)/Delta_T); + float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak ); + + 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) - w + I_e) / C_m; + dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) - w + I_e ) / C_m; // Adaptation current w. - dwdt = (a*(V - E_L) - w) / tau_w; + dwdt = ( a * ( V - E_L ) - w ) / tau_w; } - template //, class DataStruct> -__device__ - void ExternalUpdate - (double x, float *y, float *param, bool end_time_step, - aeif_psc_delta_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_delta_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; } } } @@ -190,23 +186,18 @@ __device__ }; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - aeif_psc_delta_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_delta_rk5 data_struct ) { - aeif_psc_delta_ns::Derivatives(x, y, dydx, param, - data_struct); + aeif_psc_delta_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_delta_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_delta_rk5 data_struct ) { - aeif_psc_delta_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + aeif_psc_delta_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/aeif_psc_delta_rk5.h b/src/aeif_psc_delta_rk5.h index 281634952..9af1b8c40 100644 --- a/src/aeif_psc_delta_rk5.h +++ b/src/aeif_psc_delta_rk5.h @@ -21,31 +21,24 @@ */ - - - #ifndef AEIFPSCDELTAMULTISYNAPSERK5_H #define AEIFPSCDELTAMULTISYNAPSERK5_H struct aeif_psc_delta_multisynapse_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - aeif_psc_delta_multisynapse_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_delta_multisynapse_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - aeif_psc_delta_multisynapse_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_delta_multisynapse_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_delta_multisynapse_rk5 data_struct); +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_multisynapse_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_delta_multisynapse_rk5 data_struct); +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_delta_multisynapse_rk5 data_struct ); #endif diff --git a/src/aeif_psc_exp.cu b/src/aeif_psc_exp.cu index 07431485d..6a4dd6b3c 100644 --- a/src/aeif_psc_exp.cu +++ b/src/aeif_psc_exp.cu @@ -21,24 +21,20 @@ */ - - - -#include -#include -#include +#include "aeif_psc_exp.h" #include "aeif_psc_exp_kernel.h" #include "rk5.h" -#include "aeif_psc_exp.h" +#include +#include +#include namespace aeif_psc_exp_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - aeif_psc_exp_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_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 +49,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; - + I_syn_ex = 0; I_syn_in = 0; V_m = E_L; @@ -61,95 +57,95 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param, tau_syn_ex = 0.2; tau_syn_in = 2.0; refractory_step = 0; - } -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_exp_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_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. } } } -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_exp_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_rk5 data_struct ) { - aeif_psc_exp_ns::NodeInit(n_var, n_param, x, y, param, data_struct); + aeif_psc_exp_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_exp_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_rk5 data_struct ) { - aeif_psc_exp_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct); + aeif_psc_exp_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct ); } using namespace aeif_psc_exp_ns; -int aeif_psc_exp::Init(int i_node_0, int n_node, int n_port, - int i_group, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); +int +aeif_psc_exp::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_aeif_psc_exp_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_exp_scal_var_name; scal_param_name_ = aeif_psc_exp_scal_param_name; group_param_name_ = aeif_psc_exp_group_param_name; - //rk5_data_struct_.node_type_ = i_aeif_psc_exp_model; + // rk5_data_struct_.node_type_ = i_aeif_psc_exp_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; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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("I_syn_ex"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_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_exp::Calibrate(double time_min, float time_resolution) +int +aeif_psc_exp::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_exp::Update(long long it, double t1) { - rk5_.Update(t1, h_min_, rk5_data_struct_); +int +aeif_psc_exp::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_exp.h b/src/aeif_psc_exp.h index 4f7f4a37a..db41baa53 100644 --- a/src/aeif_psc_exp.h +++ b/src/aeif_psc_exp.h @@ -21,19 +21,16 @@ */ - - - #ifndef AEIFPSCEXP_H #define AEIFPSCEXP_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, current-based @@ -47,7 +44,7 @@ Description +++++++++++ aeif_psc_exp is the adaptive exponential integrate and fire neuron -according to [1]_, with postsynaptic currents in the form of +according to [1]_, with postsynaptic currents in the form of truncated exponentials. This implementation uses the embedded 5th order Runge-Kutta @@ -125,9 +122,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 ============= ======= ========================================================= @@ -147,7 +144,7 @@ aeif_psc_exp_multisynapse, iaf_psc_exp, aeif_psc_alpha EndUserDocs */ -//#define MAX_PORT_NUM 20 +// #define MAX_PORT_NUM 20 struct aeif_psc_exp_rk5 { @@ -156,30 +153,32 @@ struct aeif_psc_exp_rk5 class aeif_psc_exp : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< aeif_psc_exp_rk5 > rk5_; float h_min_; float h_; aeif_psc_exp_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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_exp_kernel.h b/src/aeif_psc_exp_kernel.h index 4314266ed..6870f3a2e 100644 --- a/src/aeif_psc_exp_kernel.h +++ b/src/aeif_psc_exp_kernel.h @@ -21,25 +21,23 @@ */ - - - #ifndef AEIFPSCEXPKERNEL_H #define AEIFPSCEXPKERNEL_H -#include -#include -#include "spike_buffer.h" -#include "node_group.h" #include "aeif_psc_exp.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_exp_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_I_syn_ex = 0, i_I_syn_in, i_V_m, @@ -47,7 +45,8 @@ enum ScalVarIndexes { N_SCAL_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_tau_syn_ex = 0, i_tau_syn_in, i_V_th, @@ -67,21 +66,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_psc_exp_scal_var_name[N_SCAL_VAR] = { - "I_syn_ex", - "I_syn_in", - "V_m", - "w" -}; +const std::string aeif_psc_exp_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex", "I_syn_in", "V_m", "w" }; -const std::string aeif_psc_exp_scal_param_name[N_SCAL_PARAM] = { - "tau_syn_ex", +const std::string aeif_psc_exp_scal_param_name[ N_SCAL_PARAM ] = { "tau_syn_ex", "tau_syn_in", "V_th", "Delta_T", @@ -96,103 +90,102 @@ const std::string aeif_psc_exp_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string aeif_psc_exp_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string aeif_psc_exp_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 V_m y[i_V_m] -#define w y[i_w] - -#define dVdt dydx[i_V_m] -#define dwdt dydx[i_w] -#define dI_syn_exdt dydx[i_I_syn_ex] -#define dI_syn_indt dydx[i_I_syn_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_exp_rk5 data_struct) +#define I_syn_ex y[ i_I_syn_ex ] +#define I_syn_in y[ i_I_syn_in ] +#define V_m y[ i_V_m ] +#define w y[ i_w ] + +#define dVdt dydx[ i_V_m ] +#define dwdt dydx[ i_w ] +#define dI_syn_exdt dydx[ i_I_syn_ex ] +#define dI_syn_indt dydx[ i_I_syn_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_exp_rk5 data_struct ) { float I_syn_tot = 0.0; I_syn_tot += I_syn_ex - I_syn_in; - float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak); + float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak ); - 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; + dwdt = ( a * ( V - E_L ) - w ) / tau_w; dI_syn_exdt = -I_syn_ex / tau_syn_ex; dI_syn_indt = -I_syn_in / tau_syn_in; } - template //, class DataStruct> -__device__ - void ExternalUpdate - (double x, float *y, float *param, bool end_time_step, - aeif_psc_exp_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_exp_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; } } } @@ -202,25 +195,20 @@ __device__ }; -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_exp_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_exp_rk5 data_struct ) { - aeif_psc_exp_ns::Derivatives(x, y, dydx, param, - data_struct); + aeif_psc_exp_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_exp_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_exp_rk5 data_struct ) { - aeif_psc_exp_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + aeif_psc_exp_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/aeif_psc_exp_multisynapse.cu b/src/aeif_psc_exp_multisynapse.cu index 9262f0af5..ad729b9c2 100644 --- a/src/aeif_psc_exp_multisynapse.cu +++ b/src/aeif_psc_exp_multisynapse.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include +#include "aeif_psc_exp_multisynapse.h" #include "aeif_psc_exp_multisynapse_kernel.h" #include "rk5.h" -#include "aeif_psc_exp_multisynapse.h" +#include +#include +#include namespace aeif_psc_exp_multisynapse_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - aeif_psc_exp_multisynapse_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_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,52 +50,52 @@ 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_psc_exp_multisynapse::UpdateNR<0>(long long it, double t1) +int +aeif_psc_exp_multisynapse::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int aeif_psc_exp_multisynapse::Update(long long it, double t1) { - UpdateNR(it, t1); +int +aeif_psc_exp_multisynapse::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/aeif_psc_exp_multisynapse.h b/src/aeif_psc_exp_multisynapse.h index 4ba576183..fb2a701ac 100644 --- a/src/aeif_psc_exp_multisynapse.h +++ b/src/aeif_psc_exp_multisynapse.h @@ -21,19 +21,16 @@ */ - - - #ifndef AEIFPSCEXPMULTISYNAPSE_H #define AEIFPSCEXPMULTISYNAPSE_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, current-based @@ -47,7 +44,7 @@ Description +++++++++++ aeif_psc_exp_multisynapse is the adaptive exponential integrate and fire neuron -according to [1]_, with postsynaptic currents in the form of +according to [1]_, with postsynaptic currents in the form of truncated exponentials. This implementation uses the embedded 5th order Runge-Kutta @@ -123,9 +120,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 ============= ======= ========================================================= @@ -154,30 +151,32 @@ struct aeif_psc_exp_multisynapse_rk5 class aeif_psc_exp_multisynapse : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< aeif_psc_exp_multisynapse_rk5 > rk5_; float h_min_; float h_; aeif_psc_exp_multisynapse_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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_exp_multisynapse_kernel.h b/src/aeif_psc_exp_multisynapse_kernel.h index 7b735dc63..d7dbe5329 100644 --- a/src/aeif_psc_exp_multisynapse_kernel.h +++ b/src/aeif_psc_exp_multisynapse_kernel.h @@ -21,36 +21,36 @@ */ - - - #ifndef AEIFPSCEXPMULTISYNAPSEKERNEL_H #define AEIFPSCEXPMULTISYNAPSEKERNEL_H -#include -#include -#include "spike_buffer.h" -#include "node_group.h" #include "aeif_psc_exp_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_exp_multisynapse_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ i_I_syn = 0, N_PORT_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -68,28 +68,24 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_tau_syn = 0, 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_exp_multisynapse_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string aeif_psc_exp_multisynapse_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string aeif_psc_exp_multisynapse_port_var_name[N_PORT_VAR] = { - "I_syn" -}; +const std::string aeif_psc_exp_multisynapse_port_var_name[ N_PORT_VAR ] = { "I_syn" }; -const std::string aeif_psc_exp_multisynapse_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string aeif_psc_exp_multisynapse_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -102,110 +98,114 @@ const std::string aeif_psc_exp_multisynapse_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string aeif_psc_exp_multisynapse_port_param_name[N_PORT_PARAM] = { +const std::string aeif_psc_exp_multisynapse_port_param_name[ N_PORT_PARAM ] = { "tau_syn", }; -const std::string aeif_psc_exp_multisynapse_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string aeif_psc_exp_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 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 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_exp_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 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 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_exp_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_exp_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_exp_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; } } } @@ -215,43 +215,39 @@ __device__ }; template <> -int aeif_psc_exp_multisynapse::UpdateNR<0>(long long it, double t1); +int aeif_psc_exp_multisynapse::UpdateNR< 0 >( long long it, double t1 ); -template -int aeif_psc_exp_multisynapse::UpdateNR(long long it, double t1) +template < int N_PORT > +int +aeif_psc_exp_multisynapse::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = aeif_psc_exp_multisynapse_ns::N_SCAL_VAR - + aeif_psc_exp_multisynapse_ns::N_PORT_VAR*N_PORT; - const int NPARAM = aeif_psc_exp_multisynapse_ns::N_SCAL_PARAM - + aeif_psc_exp_multisynapse_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = aeif_psc_exp_multisynapse_ns::N_SCAL_VAR + aeif_psc_exp_multisynapse_ns::N_PORT_VAR * N_PORT; + const int NPARAM = aeif_psc_exp_multisynapse_ns::N_SCAL_PARAM + aeif_psc_exp_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_exp_multisynapse_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_exp_multisynapse_rk5 data_struct ) { - aeif_psc_exp_multisynapse_ns::Derivatives(x, y, dydx, param, - data_struct); + aeif_psc_exp_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_exp_multisynapse_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_exp_multisynapse_rk5 data_struct ) { - aeif_psc_exp_multisynapse_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + aeif_psc_exp_multisynapse_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/aeif_psc_exp_multisynapse_rk5.h b/src/aeif_psc_exp_multisynapse_rk5.h index 211b05a11..34d600669 100644 --- a/src/aeif_psc_exp_multisynapse_rk5.h +++ b/src/aeif_psc_exp_multisynapse_rk5.h @@ -21,31 +21,23 @@ */ - - - #ifndef AEIFPSCEXPMULTISYNAPSERK5_H #define AEIFPSCEXPMULTISYNAPSERK5_H struct aeif_psc_exp_multisynapse_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - aeif_psc_exp_multisynapse_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, aeif_psc_exp_multisynapse_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - aeif_psc_exp_multisynapse_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, aeif_psc_exp_multisynapse_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_exp_multisynapse_rk5 data_struct); +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_multisynapse_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, aeif_psc_exp_multisynapse_rk5 data_struct); +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, aeif_psc_exp_multisynapse_rk5 data_struct ); #endif diff --git a/src/base_neuron.cu b/src/base_neuron.cu index 3439b1da0..9a056e90b 100644 --- a/src/base_neuron.cu +++ b/src/base_neuron.cu @@ -21,193 +21,204 @@ */ - - - -#include -#include -#include "ngpu_exception.h" -#include "cuda_error.h" #include "base_neuron.h" -#include "spike_buffer.h" -#include "scan.h" +#include "cuda_error.h" #include "locate.h" +#include "ngpu_exception.h" +#include "scan.h" +#include "spike_buffer.h" +#include +#include // set equally spaced (index i*step) elements of array arr to value val -__global__ void BaseNeuronSetIntArray(int *arr, int n_elem, int step, - int val) +__global__ void +BaseNeuronSetIntArray( int* arr, int n_elem, int step, int val ) { int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx>> - (param_pt, n_neuron, n_param_, val); +int +BaseNeuron::SetScalParam( int i_neuron, int n_neuron, std::string param_name, float val ) +{ + if ( !IsScalParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar parameter " ) + param_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* param_pt = GetParamPt( i_neuron, param_name ); + BaseNeuronSetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( param_pt, n_neuron, n_param_, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } // set scalar parameter param_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to value val -int BaseNeuron::SetScalParam(int *i_neuron, int n_neuron, - std::string param_name, float val) +int +BaseNeuron::SetScalParam( int* i_neuron, int n_neuron, std::string param_name, float val ) { - if (!IsScalParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized scalar parameter ") - + param_name); + if ( !IsScalParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar parameter " ) + param_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronSetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - float *param_pt = GetParamPt(0, param_name); - BaseNeuronSetFloatPtArray<<<(n_neuron+1023)/1024, 1024>>> - (param_pt, d_i_neuron, n_neuron, n_param_, val); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + float* param_pt = GetParamPt( 0, param_name ); + BaseNeuronSetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( param_pt, d_i_neuron, n_neuron, n_param_, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); - + gpuErrchk( cudaFree( d_i_neuron ) ); + return 0; } // set receptor-port parameter param_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 // to value val -int BaseNeuron::SetPortParam(int i_neuron, int n_neuron, - std::string param_name, float *param, - int vect_size) -{ - if (!IsPortParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized port parameter ") - + param_name); - } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - if (vect_size != n_port_) { - throw ngpu_exception("Parameter array size must be equal " - "to the number of ports."); - } - float *param_pt; - - for (int i_vect=0; i_vect>> - (param_pt, n_neuron, n_param_, param[i_vect]); +int +BaseNeuron::SetPortParam( int i_neuron, int n_neuron, std::string param_name, float* param, int vect_size ) +{ + if ( !IsPortParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port parameter " ) + param_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + if ( vect_size != n_port_ ) + { + throw ngpu_exception( + "Parameter array size must be equal " + "to the number of ports." ); + } + float* param_pt; + + for ( int i_vect = 0; i_vect < vect_size; i_vect++ ) + { + param_pt = GetParamPt( i_neuron, param_name, i_vect ); + BaseNeuronSetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( param_pt, n_neuron, n_param_, param[ i_vect ] ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } @@ -291,31 +300,32 @@ int BaseNeuron::SetPortParam(int i_neuron, int n_neuron, // set receptor-port parameter param_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to value val -int BaseNeuron::SetPortParam(int *i_neuron, int n_neuron, - std::string param_name, float *param, - int vect_size) +int +BaseNeuron::SetPortParam( int* i_neuron, int n_neuron, std::string param_name, float* param, int vect_size ) { - if (!IsPortParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized port parameter ") - + param_name); + if ( !IsPortParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port parameter " ) + param_name ); } - if (vect_size != n_port_) { - throw ngpu_exception("Parameter array size must be equal " - "to the number of ports."); + if ( vect_size != n_port_ ) + { + throw ngpu_exception( + "Parameter array size must be equal " + "to the number of ports." ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronSetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - for (int i_vect=0; i_vect>> - (param_pt, d_i_neuron, n_neuron, n_param_, param[i_vect]); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + for ( int i_vect = 0; i_vect < vect_size; i_vect++ ) + { + float* param_pt = GetParamPt( 0, param_name, i_vect ); + BaseNeuronSetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + param_pt, d_i_neuron, n_neuron, n_param_, param[ i_vect ] ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaFree(d_i_neuron)); + gpuErrchk( cudaFree( d_i_neuron ) ); return 0; } @@ -324,155 +334,148 @@ int BaseNeuron::SetPortParam(int *i_neuron, int n_neuron, // i_neuron, ..., i_neuron + n_neuron -1 // to values array[0], ... , array[array_size-1] // Must be defined in derived classes -int BaseNeuron::SetArrayParam(int i_neuron, int n_neuron, - std::string param_name, float *array, - int array_size) +int +BaseNeuron::SetArrayParam( int i_neuron, int n_neuron, std::string param_name, float* array, int array_size ) { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } // set array parameter param_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to values array[0], ... , array[array_size-1] // Must be defined in derived classes -int BaseNeuron::SetArrayParam(int *i_neuron, int n_neuron, - std::string param_name, float *array, - int array_size) +int +BaseNeuron::SetArrayParam( int* i_neuron, int n_neuron, std::string param_name, float* array, int array_size ) { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } // set neuron-group parameter param_name to value val -int BaseNeuron::SetGroupParam(std::string param_name, float val) +int +BaseNeuron::SetGroupParam( std::string param_name, float val ) { int i_param; - for (i_param=0; i_param>> - (var_pt, n_neuron, 1, val); +int +BaseNeuron::SetIntVar( int i_neuron, int n_neuron, std::string var_name, int val ) +{ + if ( !IsIntVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized integer variable " ) + var_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + int* var_pt = GetIntVarPt( i_neuron, var_name ); + BaseNeuronSetIntArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, n_neuron, 1, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } // set integer variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to value val -int BaseNeuron::SetIntVar(int *i_neuron, int n_neuron, - std::string var_name, int val) +int +BaseNeuron::SetIntVar( int* i_neuron, int n_neuron, std::string var_name, int val ) { - if (!IsIntVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized integer variable ") - + var_name); + if ( !IsIntVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized integer variable " ) + var_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronSetIntPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - int *var_pt = GetIntVarPt(0, var_name); - BaseNeuronSetIntPtArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, d_i_neuron, n_neuron, 1, val); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + int* var_pt = GetIntVarPt( 0, var_name ); + BaseNeuronSetIntPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, d_i_neuron, n_neuron, 1, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); - + gpuErrchk( cudaFree( d_i_neuron ) ); + return 0; } // set scalar state-variable var_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 // to value val -int BaseNeuron::SetScalVar(int i_neuron, int n_neuron, - std::string var_name, float val) -{ - if (!IsScalVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized scalar variable ") - + var_name); - } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - float *var_pt = GetVarPt(i_neuron, var_name); - BaseNeuronSetFloatArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, n_neuron, n_var_, val); +int +BaseNeuron::SetScalVar( int i_neuron, int n_neuron, std::string var_name, float val ) +{ + if ( !IsScalVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar variable " ) + var_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* var_pt = GetVarPt( i_neuron, var_name ); + BaseNeuronSetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, n_neuron, n_var_, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } // set scalar state-variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to value val -int BaseNeuron::SetScalVar(int *i_neuron, int n_neuron, - std::string var_name, float val) +int +BaseNeuron::SetScalVar( int* i_neuron, int n_neuron, std::string var_name, float val ) { - if (!IsScalVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized scalar variable ") - + var_name); + if ( !IsScalVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar variable " ) + var_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronSetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - float *var_pt = GetVarPt(0, var_name); - BaseNeuronSetFloatPtArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, d_i_neuron, n_neuron, n_var_, val); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + float* var_pt = GetVarPt( 0, var_name ); + BaseNeuronSetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, d_i_neuron, n_neuron, n_var_, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); - + gpuErrchk( cudaFree( d_i_neuron ) ); + return 0; } // set receptor-port state-variable var_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 // to value val -int BaseNeuron::SetPortVar(int i_neuron, int n_neuron, - std::string var_name, float *var, - int vect_size) -{ - if (!IsPortVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized port variable ") - + var_name); - } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - if (vect_size != n_port_) { - throw ngpu_exception("Variable array size must be equal " - "to the number of ports."); - } - float *var_pt; - - for (int i_vect=0; i_vect>> - (var_pt, n_neuron, n_var_, var[i_vect]); +int +BaseNeuron::SetPortVar( int i_neuron, int n_neuron, std::string var_name, float* var, int vect_size ) +{ + if ( !IsPortVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port variable " ) + var_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + if ( vect_size != n_port_ ) + { + throw ngpu_exception( + "Variable array size must be equal " + "to the number of ports." ); + } + float* var_pt; + + for ( int i_vect = 0; i_vect < vect_size; i_vect++ ) + { + var_pt = GetVarPt( i_neuron, var_name, i_vect ); + BaseNeuronSetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, n_neuron, n_var_, var[ i_vect ] ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } @@ -482,31 +485,32 @@ int BaseNeuron::SetPortVar(int i_neuron, int n_neuron, // set receptor-port state-variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to value val -int BaseNeuron::SetPortVar(int *i_neuron, int n_neuron, - std::string var_name, float *var, - int vect_size) +int +BaseNeuron::SetPortVar( int* i_neuron, int n_neuron, std::string var_name, float* var, int vect_size ) { - if (!IsPortVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized port variable ") - + var_name); + if ( !IsPortVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port variable " ) + var_name ); } - if (vect_size != n_port_) { - throw ngpu_exception("Variable array size must be equal " - "to the number of ports."); + if ( vect_size != n_port_ ) + { + throw ngpu_exception( + "Variable array size must be equal " + "to the number of ports." ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronSetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - for (int i_vect=0; i_vect>> - (var_pt, d_i_neuron, n_neuron, n_var_, var[i_vect]); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + for ( int i_vect = 0; i_vect < vect_size; i_vect++ ) + { + float* var_pt = GetVarPt( 0, var_name, i_vect ); + BaseNeuronSetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + var_pt, d_i_neuron, n_neuron, n_var_, var[ i_vect ] ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaFree(d_i_neuron)); + gpuErrchk( cudaFree( d_i_neuron ) ); return 0; } @@ -515,868 +519,961 @@ int BaseNeuron::SetPortVar(int *i_neuron, int n_neuron, // i_neuron, ..., i_neuron + n_neuron -1 // to values array[0], ... , array[array_size-1] // Must be defined in derived classes -int BaseNeuron::SetArrayVar(int i_neuron, int n_neuron, - std::string var_name, float *array, - int array_size) +int +BaseNeuron::SetArrayVar( int i_neuron, int n_neuron, std::string var_name, float* array, int array_size ) { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } // set array variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] // to values array[0], ... , array[array_size-1] // Must be defined in derived classes -int BaseNeuron::SetArrayVar(int *i_neuron, int n_neuron, - std::string var_name, float *array, - int array_size) +int +BaseNeuron::SetArrayVar( int* i_neuron, int n_neuron, std::string var_name, float* array, int array_size ) { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } // get scalar parameters param_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 -float *BaseNeuron::GetScalParam(int i_neuron, int n_neuron, - std::string param_name) +float* +BaseNeuron::GetScalParam( int i_neuron, int n_neuron, std::string param_name ) { - if (!IsScalParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized scalar parameter ") - + param_name); + if ( !IsScalParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar parameter " ) + param_name ); } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - float *param_pt = GetParamPt(i_neuron, param_name); + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* param_pt = GetParamPt( i_neuron, param_name ); - float *d_param_arr; - gpuErrchk(cudaMalloc(&d_param_arr, n_neuron*sizeof(float))); - float *h_param_arr = (float*)malloc(n_neuron*sizeof(float)); + float* d_param_arr; + gpuErrchk( cudaMalloc( &d_param_arr, n_neuron * sizeof( float ) ) ); + float* h_param_arr = ( float* ) malloc( n_neuron * sizeof( float ) ); - BaseNeuronGetFloatArray<<<(n_neuron+1023)/1024, 1024>>> - (param_pt, d_param_arr, n_neuron, n_param_, 1); + BaseNeuronGetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( param_pt, d_param_arr, n_neuron, n_param_, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - - gpuErrchk(cudaMemcpy(h_param_arr, d_param_arr, n_neuron*sizeof(float), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_param_arr)); - + + gpuErrchk( cudaMemcpy( h_param_arr, d_param_arr, n_neuron * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_param_arr ) ); + return h_param_arr; } // get scalar parameters param_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] -float *BaseNeuron::GetScalParam(int *i_neuron, int n_neuron, - std::string param_name) +float* +BaseNeuron::GetScalParam( int* i_neuron, int n_neuron, std::string param_name ) { - if (!IsScalParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized scalar parameter ") - + param_name); + if ( !IsScalParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar parameter " ) + param_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronGetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - float *param_pt = GetParamPt(0, param_name); - - float *d_param_arr; - gpuErrchk(cudaMalloc(&d_param_arr, n_neuron*sizeof(float))); - float *h_param_arr = (float*)malloc(n_neuron*sizeof(float)); - - BaseNeuronGetFloatPtArray<<<(n_neuron+1023)/1024, 1024>>> - (param_pt, d_param_arr, d_i_neuron, n_neuron, n_param_, 1); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + float* param_pt = GetParamPt( 0, param_name ); + + float* d_param_arr; + gpuErrchk( cudaMalloc( &d_param_arr, n_neuron * sizeof( float ) ) ); + float* h_param_arr = ( float* ) malloc( n_neuron * sizeof( float ) ); + + BaseNeuronGetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + param_pt, d_param_arr, d_i_neuron, n_neuron, n_param_, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); + gpuErrchk( cudaFree( d_i_neuron ) ); - gpuErrchk(cudaMemcpy(h_param_arr, d_param_arr, n_neuron*sizeof(float), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_param_arr)); + gpuErrchk( cudaMemcpy( h_param_arr, d_param_arr, n_neuron * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_param_arr ) ); return h_param_arr; } // get receptor-port parameters param_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 -float *BaseNeuron::GetPortParam(int i_neuron, int n_neuron, - std::string param_name) -{ - if (!IsPortParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized port parameter ") - + param_name); - } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - float *param_pt; - - float *d_param_arr; - gpuErrchk(cudaMalloc(&d_param_arr, n_neuron*n_port_*sizeof(float))); - float *h_param_arr = (float*)malloc(n_neuron*n_port_*sizeof(float)); - - for (int port=0; port>> - (param_pt, d_param_arr + port, n_neuron, n_param_, n_port_); +float* +BaseNeuron::GetPortParam( int i_neuron, int n_neuron, std::string param_name ) +{ + if ( !IsPortParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port parameter " ) + param_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* param_pt; + + float* d_param_arr; + gpuErrchk( cudaMalloc( &d_param_arr, n_neuron * n_port_ * sizeof( float ) ) ); + float* h_param_arr = ( float* ) malloc( n_neuron * n_port_ * sizeof( float ) ); + + for ( int port = 0; port < n_port_; port++ ) + { + param_pt = GetParamPt( i_neuron, param_name, port ); + BaseNeuronGetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + param_pt, d_param_arr + port, n_neuron, n_param_, n_port_ ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaMemcpy(h_param_arr, d_param_arr, n_neuron*n_port_ - *sizeof(float), cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_param_arr)); - + gpuErrchk( cudaMemcpy( h_param_arr, d_param_arr, n_neuron * n_port_ * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_param_arr ) ); + return h_param_arr; } // get receptor-port parameters param_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] -float *BaseNeuron::GetPortParam(int *i_neuron, int n_neuron, - std::string param_name) +float* +BaseNeuron::GetPortParam( int* i_neuron, int n_neuron, std::string param_name ) { - if (!IsPortParam(param_name)) { - throw ngpu_exception(std::string("Unrecognized port parameter ") - + param_name); + if ( !IsPortParam( param_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port parameter " ) + param_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronGetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - - float *d_param_arr; - gpuErrchk(cudaMalloc(&d_param_arr, n_neuron*n_port_*sizeof(float))); - float *h_param_arr = (float*)malloc(n_neuron*n_port_*sizeof(float)); - - for (int port=0; port>> - (param_pt, d_param_arr+port, d_i_neuron, n_neuron, n_param_, - n_port_); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + + float* d_param_arr; + gpuErrchk( cudaMalloc( &d_param_arr, n_neuron * n_port_ * sizeof( float ) ) ); + float* h_param_arr = ( float* ) malloc( n_neuron * n_port_ * sizeof( float ) ); + + for ( int port = 0; port < n_port_; port++ ) + { + float* param_pt = GetParamPt( 0, param_name, port ); + BaseNeuronGetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + param_pt, d_param_arr + port, d_i_neuron, n_neuron, n_param_, n_port_ ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaFree(d_i_neuron)); - - gpuErrchk(cudaMemcpy(h_param_arr, d_param_arr, n_neuron*n_port_ - *sizeof(float), cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_param_arr)); - + gpuErrchk( cudaFree( d_i_neuron ) ); + + gpuErrchk( cudaMemcpy( h_param_arr, d_param_arr, n_neuron * n_port_ * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_param_arr ) ); + return h_param_arr; } // get array-parameter param_name of neuron i_neuron // must be defined in the derived classes -float *BaseNeuron::GetArrayParam(int i_neuron, std::string param_name) +float* +BaseNeuron::GetArrayParam( int i_neuron, std::string param_name ) { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } // get neuron-group parameter param_name -float BaseNeuron::GetGroupParam(std::string param_name) +float +BaseNeuron::GetGroupParam( std::string param_name ) { int i_param; - for (i_param=0; i_param>> - (var_pt, d_var_arr, n_neuron, 1, 1); + BaseNeuronGetIntArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, d_var_arr, n_neuron, 1, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*sizeof(int), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); - + + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * sizeof( int ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); + return h_var_arr; } // get integer variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] -int *BaseNeuron::GetIntVar(int *i_neuron, int n_neuron, - std::string var_name) +int* +BaseNeuron::GetIntVar( int* i_neuron, int n_neuron, std::string var_name ) { - if (!IsIntVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized integer variable ") - + var_name); + if ( !IsIntVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized integer variable " ) + var_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronGetIntPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - int *var_pt = GetIntVarPt(0, var_name); - - int *d_var_arr; - gpuErrchk(cudaMalloc(&d_var_arr, n_neuron*sizeof(int))); - int *h_var_arr = (int*)malloc(n_neuron*sizeof(int)); - - BaseNeuronGetIntPtArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, d_var_arr, d_i_neuron, n_neuron, 1, 1); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + int* var_pt = GetIntVarPt( 0, var_name ); + + int* d_var_arr; + gpuErrchk( cudaMalloc( &d_var_arr, n_neuron * sizeof( int ) ) ); + int* h_var_arr = ( int* ) malloc( n_neuron * sizeof( int ) ); + + BaseNeuronGetIntPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, d_var_arr, d_i_neuron, n_neuron, 1, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); + gpuErrchk( cudaFree( d_i_neuron ) ); + + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * sizeof( int ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*sizeof(int), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); - return h_var_arr; } // get scalar state-variable var_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 -float *BaseNeuron::GetScalVar(int i_neuron, int n_neuron, - std::string var_name) +float* +BaseNeuron::GetScalVar( int i_neuron, int n_neuron, std::string var_name ) { - if (!IsScalVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized scalar variable ") - + var_name); + if ( !IsScalVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar variable " ) + var_name ); } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - float *var_pt = GetVarPt(i_neuron, var_name); + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* var_pt = GetVarPt( i_neuron, var_name ); - float *d_var_arr; - gpuErrchk(cudaMalloc(&d_var_arr, n_neuron*sizeof(float))); - float *h_var_arr = (float*)malloc(n_neuron*sizeof(float)); + float* d_var_arr; + gpuErrchk( cudaMalloc( &d_var_arr, n_neuron * sizeof( float ) ) ); + float* h_var_arr = ( float* ) malloc( n_neuron * sizeof( float ) ); - BaseNeuronGetFloatArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, d_var_arr, n_neuron, n_var_, 1); + BaseNeuronGetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( var_pt, d_var_arr, n_neuron, n_var_, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*sizeof(float), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); - + + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); + return h_var_arr; } // get scalar state-variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] -float *BaseNeuron::GetScalVar(int *i_neuron, int n_neuron, - std::string var_name) +float* +BaseNeuron::GetScalVar( int* i_neuron, int n_neuron, std::string var_name ) { - if (!IsScalVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized scalar variable ") - + var_name); + if ( !IsScalVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized scalar variable " ) + var_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronGetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - float *var_pt = GetVarPt(0, var_name); - - float *d_var_arr; - gpuErrchk(cudaMalloc(&d_var_arr, n_neuron*sizeof(float))); - float *h_var_arr = (float*)malloc(n_neuron*sizeof(float)); - - BaseNeuronGetFloatPtArray<<<(n_neuron+1023)/1024, 1024>>> - (var_pt, d_var_arr, d_i_neuron, n_neuron, n_var_, 1); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + float* var_pt = GetVarPt( 0, var_name ); + + float* d_var_arr; + gpuErrchk( cudaMalloc( &d_var_arr, n_neuron * sizeof( float ) ) ); + float* h_var_arr = ( float* ) malloc( n_neuron * sizeof( float ) ); + + BaseNeuronGetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + var_pt, d_var_arr, d_i_neuron, n_neuron, n_var_, 1 ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_i_neuron)); + gpuErrchk( cudaFree( d_i_neuron ) ); - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*sizeof(float), - cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); return h_var_arr; } // get receptor-port state-variable var_name of neurons // i_neuron, ..., i_neuron + n_neuron -1 -float *BaseNeuron::GetPortVar(int i_neuron, int n_neuron, - std::string var_name) -{ - if (!IsPortVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized port variable ") - + var_name); - } - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); - float *var_pt; - - float *d_var_arr; - gpuErrchk(cudaMalloc(&d_var_arr, n_neuron*n_port_*sizeof(float))); - float *h_var_arr = (float*)malloc(n_neuron*n_port_*sizeof(float)); - - for (int port=0; port>> - (var_pt, d_var_arr + port, n_neuron, n_var_, n_port_); +float* +BaseNeuron::GetPortVar( int i_neuron, int n_neuron, std::string var_name ) +{ + if ( !IsPortVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port variable " ) + var_name ); + } + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); + float* var_pt; + + float* d_var_arr; + gpuErrchk( cudaMalloc( &d_var_arr, n_neuron * n_port_ * sizeof( float ) ) ); + float* h_var_arr = ( float* ) malloc( n_neuron * n_port_ * sizeof( float ) ); + + for ( int port = 0; port < n_port_; port++ ) + { + var_pt = GetVarPt( i_neuron, var_name, port ); + BaseNeuronGetFloatArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + var_pt, d_var_arr + port, n_neuron, n_var_, n_port_ ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*n_port_ - *sizeof(float), cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); - + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * n_port_ * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); + return h_var_arr; } // get receptor-port state-variable var_name of neurons // i_neuron[0], ..., i_neuron[n_neuron -1] -float *BaseNeuron::GetPortVar(int *i_neuron, int n_neuron, - std::string var_name) +float* +BaseNeuron::GetPortVar( int* i_neuron, int n_neuron, std::string var_name ) { - if (!IsPortVar(var_name)) { - throw ngpu_exception(std::string("Unrecognized port variable ") - + var_name); + if ( !IsPortVar( var_name ) ) + { + throw ngpu_exception( std::string( "Unrecognized port variable " ) + var_name ); } - int *d_i_neuron; - gpuErrchk(cudaMalloc(&d_i_neuron, n_neuron*sizeof(int))); + int* d_i_neuron; + gpuErrchk( cudaMalloc( &d_i_neuron, n_neuron * sizeof( int ) ) ); // Memcopy will be synchronized with BaseNeuronGetFloatPtArray kernel - gpuErrchk(cudaMemcpyAsync(d_i_neuron, i_neuron, n_neuron*sizeof(int), - cudaMemcpyHostToDevice)); - - float *d_var_arr; - gpuErrchk(cudaMalloc(&d_var_arr, n_neuron*n_port_*sizeof(float))); - float *h_var_arr = (float*)malloc(n_neuron*n_port_*sizeof(float)); - - for (int port=0; port>> - (var_pt, d_var_arr+port, d_i_neuron, n_neuron, n_var_, n_port_); + gpuErrchk( cudaMemcpyAsync( d_i_neuron, i_neuron, n_neuron * sizeof( int ), cudaMemcpyHostToDevice ) ); + + float* d_var_arr; + gpuErrchk( cudaMalloc( &d_var_arr, n_neuron * n_port_ * sizeof( float ) ) ); + float* h_var_arr = ( float* ) malloc( n_neuron * n_port_ * sizeof( float ) ); + + for ( int port = 0; port < n_port_; port++ ) + { + float* var_pt = GetVarPt( 0, var_name, port ); + BaseNeuronGetFloatPtArray<<< ( n_neuron + 1023 ) / 1024, 1024 >>>( + var_pt, d_var_arr + port, d_i_neuron, n_neuron, n_var_, n_port_ ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); } - gpuErrchk(cudaFree(d_i_neuron)); - - gpuErrchk(cudaMemcpy(h_var_arr, d_var_arr, n_neuron*n_port_ - *sizeof(float), cudaMemcpyDeviceToHost)); - gpuErrchk(cudaFree(d_var_arr)); - + gpuErrchk( cudaFree( d_i_neuron ) ); + + gpuErrchk( cudaMemcpy( h_var_arr, d_var_arr, n_neuron * n_port_ * sizeof( float ), cudaMemcpyDeviceToHost ) ); + gpuErrchk( cudaFree( d_var_arr ) ); + return h_var_arr; } // get array variable var_name of neuron i_neuron -float *BaseNeuron::GetArrayVar(int i_neuron, std::string var_name) +float* +BaseNeuron::GetArrayVar( int i_neuron, std::string var_name ) { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } // get index of integer variable var_name -int BaseNeuron::GetIntVarIdx(std::string var_name) +int +BaseNeuron::GetIntVarIdx( std::string var_name ) { int i_var; - for (i_var=0; i_var=0 and =n_node_) { - throw ngpu_exception("Neuron index must be lower then n. of neurons"); + if ( i_neuron >= n_node_ ) + { + throw ngpu_exception( "Neuron index must be lower then n. of neurons" ); } - else if (i_neuron<0) { - throw ngpu_exception("Neuron index must be >= 0"); + else if ( i_neuron < 0 ) + { + throw ngpu_exception( "Neuron index must be >= 0" ); } return 0; } // check if index port is >=0 and =n_port_) { - throw ngpu_exception("Port index must be lower then n. of ports"); + if ( port >= n_port_ ) + { + throw ngpu_exception( "Port index must be lower then n. of ports" ); } - else if (port<0) { - throw ngpu_exception("Port index must be >= 0"); + else if ( port < 0 ) + { + throw ngpu_exception( "Port index must be >= 0" ); } return 0; } // return pointer to integer variable var_name for neuron i_neuron -int *BaseNeuron::GetIntVarPt(int i_neuron, std::string var_name) +int* +BaseNeuron::GetIntVarPt( int i_neuron, std::string var_name ) { - CheckNeuronIdx(i_neuron); - - if (IsIntVar(var_name)) { - int i_var = GetIntVarIdx(var_name); - return int_var_pt_[i_var] + i_neuron; + CheckNeuronIdx( i_neuron ); + + if ( IsIntVar( var_name ) ) + { + int i_var = GetIntVarIdx( var_name ); + return int_var_pt_[ i_var ] + i_neuron; } - else { - throw ngpu_exception(std::string("Unrecognized integer variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized integer variable " ) + var_name ); } } // return pointer to variable var_name for neuron i_neuron // (and specified receptor port in case of a port variable) -float *BaseNeuron::GetVarPt(int i_neuron, std::string var_name, - int port /*=0*/) +float* +BaseNeuron::GetVarPt( int i_neuron, std::string var_name, int port /*=0*/ ) { - CheckNeuronIdx(i_neuron); - if (port!=0) { - CheckPortIdx(port); + CheckNeuronIdx( i_neuron ); + if ( port != 0 ) + { + CheckPortIdx( port ); } - - if (IsScalVar(var_name)) { - int i_var = GetScalVarIdx(var_name); - return GetVarArr() + i_neuron*n_var_ + i_var; + + if ( IsScalVar( var_name ) ) + { + int i_var = GetScalVarIdx( var_name ); + return GetVarArr() + i_neuron * n_var_ + i_var; } - else if (IsPortVar(var_name)) { - int i_vvar = GetPortVarIdx(var_name); - return GetVarArr() + i_neuron*n_var_ + n_scal_var_ - + port*n_port_var_ + i_vvar; + else if ( IsPortVar( var_name ) ) + { + int i_vvar = GetPortVarIdx( var_name ); + return GetVarArr() + i_neuron * n_var_ + n_scal_var_ + port * n_port_var_ + i_vvar; } - else { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } } // return pointer to parameter param_name for neuron i_neuron // (and specified receptor port in case of a port parameter) -float *BaseNeuron::GetParamPt(int i_neuron, std::string param_name, - int port /*=0*/) +float* +BaseNeuron::GetParamPt( int i_neuron, std::string param_name, int port /*=0*/ ) { - CheckNeuronIdx(i_neuron); - if (port!=0) { - CheckPortIdx(port); + CheckNeuronIdx( i_neuron ); + if ( port != 0 ) + { + CheckPortIdx( port ); } - if (IsScalParam(param_name)) { - int i_param = GetScalParamIdx(param_name); - return GetParamArr() + i_neuron*n_param_ + i_param; + if ( IsScalParam( param_name ) ) + { + int i_param = GetScalParamIdx( param_name ); + return GetParamArr() + i_neuron * n_param_ + i_param; } - else if (IsPortParam(param_name)) { - int i_vparam = GetPortParamIdx(param_name); - return GetParamArr() + i_neuron*n_param_ + n_scal_param_ - + port*n_port_param_ + i_vparam; + else if ( IsPortParam( param_name ) ) + { + int i_vparam = GetPortParamIdx( param_name ); + return GetParamArr() + i_neuron * n_param_ + n_scal_param_ + port * n_port_param_ + i_vparam; } - else { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } } -// return spike multiplicity (spike_height) of neuron i_neuron +// return spike multiplicity (spike_height) of neuron i_neuron // if neuron emitted a spike in the current time step // otherwise return 0 -float BaseNeuron::GetSpikeActivity(int i_neuron) +float +BaseNeuron::GetSpikeActivity( int i_neuron ) { - CheckNeuronIdx(i_neuron); + CheckNeuronIdx( i_neuron ); int i_spike_buffer = i_neuron + i_node_0_; int Ns; - gpuErrchk(cudaMemcpy(&Ns, d_SpikeBufferSize + i_spike_buffer, - sizeof(int), cudaMemcpyDeviceToHost)); - if (Ns==0) { + gpuErrchk( cudaMemcpy( &Ns, d_SpikeBufferSize + i_spike_buffer, sizeof( int ), cudaMemcpyDeviceToHost ) ); + if ( Ns == 0 ) + { return 0.0; } - + int is0; - gpuErrchk(cudaMemcpy(&is0, d_SpikeBufferIdx0 + i_spike_buffer, - sizeof(int), cudaMemcpyDeviceToHost)); - int i_arr = is0*h_NSpikeBuffer+i_spike_buffer; // spike index in array + gpuErrchk( cudaMemcpy( &is0, d_SpikeBufferIdx0 + i_spike_buffer, sizeof( int ), cudaMemcpyDeviceToHost ) ); + int i_arr = is0 * h_NSpikeBuffer + i_spike_buffer; // spike index in array int time_idx; // get first (most recent) spike from buffer - gpuErrchk(cudaMemcpy(&time_idx, d_SpikeBufferTimeIdx + i_arr, - sizeof(int), cudaMemcpyDeviceToHost)); - if (time_idx!=0) { // neuron is not spiking now + gpuErrchk( cudaMemcpy( &time_idx, d_SpikeBufferTimeIdx + i_arr, sizeof( int ), cudaMemcpyDeviceToHost ) ); + if ( time_idx != 0 ) + { // neuron is not spiking now return 0.0; } float spike_height; - gpuErrchk(cudaMemcpy(&spike_height, d_SpikeBufferHeight + i_arr, - sizeof(float), cudaMemcpyDeviceToHost)); + gpuErrchk( cudaMemcpy( &spike_height, d_SpikeBufferHeight + i_arr, sizeof( float ), cudaMemcpyDeviceToHost ) ); return spike_height; } // get all names of integer variables -std::vector BaseNeuron::GetIntVarNames() +std::vector< std::string > +BaseNeuron::GetIntVarNames() { return int_var_name_; } // get all names of scalar state variables -std::vector BaseNeuron::GetScalVarNames() +std::vector< std::string > +BaseNeuron::GetScalVarNames() { - std::vector var_name_vect; - for (int i=0; i var_name_vect; + for ( int i = 0; i < n_scal_var_; i++ ) + { + var_name_vect.push_back( scal_var_name_[ i ] ); } - + return var_name_vect; } // get number of scalar state variables -int BaseNeuron::GetNScalVar() +int +BaseNeuron::GetNScalVar() { return n_scal_var_; } // get number of integer variables -int BaseNeuron::GetNIntVar() +int +BaseNeuron::GetNIntVar() { - return (int)int_var_name_.size(); + return ( int ) int_var_name_.size(); } // get all names of receptor-port state variables -std::vector BaseNeuron::GetPortVarNames() +std::vector< std::string > +BaseNeuron::GetPortVarNames() { - std::vector var_name_vect; - for (int i=0; i var_name_vect; + for ( int i = 0; i < n_port_var_; i++ ) + { + var_name_vect.push_back( port_var_name_[ i ] ); } - + return var_name_vect; } -// get number of receptor-port variables -int BaseNeuron::GetNPortVar() +// get number of receptor-port variables +int +BaseNeuron::GetNPortVar() { return n_port_var_; } // get all names of scalar parameters -std::vector BaseNeuron::GetScalParamNames() +std::vector< std::string > +BaseNeuron::GetScalParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < n_scal_param_; i++ ) + { + param_name_vect.push_back( scal_param_name_[ i ] ); } - + return param_name_vect; } // get number of scalar parameters -int BaseNeuron::GetNScalParam() +int +BaseNeuron::GetNScalParam() { return n_scal_param_; } // get all names of receptor-port parameters -std::vector BaseNeuron::GetPortParamNames() +std::vector< std::string > +BaseNeuron::GetPortParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < n_port_param_; i++ ) + { + param_name_vect.push_back( port_param_name_[ i ] ); } - + return param_name_vect; } // get number of receptor-port parameters -int BaseNeuron::GetNPortParam() +int +BaseNeuron::GetNPortParam() { return n_port_param_; } // get all names of neuron-group parameters -std::vector BaseNeuron::GetGroupParamNames() +std::vector< std::string > +BaseNeuron::GetGroupParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < n_group_param_; i++ ) + { + param_name_vect.push_back( group_param_name_[ i ] ); } - + return param_name_vect; } // get number of neuron-group parameters -int BaseNeuron::GetNGroupParam() +int +BaseNeuron::GetNGroupParam() { return n_group_param_; } // get all names of array variables -std::vector BaseNeuron::GetArrayVarNames() +std::vector< std::string > +BaseNeuron::GetArrayVarNames() { - std::vector var_name_vect; - for (int i=0; i var_name_vect; + for ( int i = 0; i < GetNArrayVar(); i++ ) + { + var_name_vect.push_back( array_var_name_[ i ] ); } - + return var_name_vect; } // get number of array variables -int BaseNeuron::GetNArrayVar() +int +BaseNeuron::GetNArrayVar() { - return (int)array_var_name_.size(); + return ( int ) array_var_name_.size(); } // get all names of array parameters -std::vector BaseNeuron::GetArrayParamNames() +std::vector< std::string > +BaseNeuron::GetArrayParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < GetNArrayParam(); i++ ) + { + param_name_vect.push_back( array_param_name_[ i ] ); } - + return param_name_vect; } // get number of array parameters -int BaseNeuron::GetNArrayParam() +int +BaseNeuron::GetNArrayParam() { - return (int)array_param_name_.size(); + return ( int ) array_param_name_.size(); } // activate spike count for all neurons of the group -int BaseNeuron::ActivateSpikeCount() +int +BaseNeuron::ActivateSpikeCount() { const std::string s = "spike_count"; - if (std::find(int_var_name_.begin(), int_var_name_.end(), s) - == int_var_name_.end()) { // add it if not already present - int_var_name_.push_back(s); + if ( std::find( int_var_name_.begin(), int_var_name_.end(), s ) == int_var_name_.end() ) + { // add it if not already present + int_var_name_.push_back( s ); - gpuErrchk(cudaMalloc(&spike_count_, n_node_*sizeof(int))); - gpuErrchk(cudaMemset(spike_count_, 0, n_node_*sizeof(int))); - int_var_pt_.push_back(spike_count_); + gpuErrchk( cudaMalloc( &spike_count_, n_node_ * sizeof( int ) ) ); + gpuErrchk( cudaMemset( spike_count_, 0, n_node_ * sizeof( int ) ) ); + int_var_pt_.push_back( spike_count_ ); } - else { - throw ngpu_exception("Spike count already activated"); + else + { + throw ngpu_exception( "Spike count already activated" ); } @@ -1384,41 +1481,43 @@ int BaseNeuron::ActivateSpikeCount() } // activate spike-time recording for all neurons of the group -int BaseNeuron::ActivateRecSpikeTimes(int max_n_rec_spike_times) +int +BaseNeuron::ActivateRecSpikeTimes( int max_n_rec_spike_times ) { - if(max_n_rec_spike_times<=0) { - throw ngpu_exception("Maximum number of recorded spike times " - "must be greater than 0"); + if ( max_n_rec_spike_times <= 0 ) + { + throw ngpu_exception( + "Maximum number of recorded spike times " + "must be greater than 0" ); } const std::string s = "n_rec_spike_times"; - if (std::find(int_var_name_.begin(), int_var_name_.end(), s) - == int_var_name_.end()) { // add it if not already present - int_var_name_.push_back(s); - - gpuErrchk(cudaMalloc(&n_rec_spike_times_, n_node_*sizeof(int))); - gpuErrchk(cudaMalloc(&n_rec_spike_times_cumul_, - (n_node_+1)*sizeof(int))); - gpuErrchk(cudaMemset(n_rec_spike_times_, 0, n_node_*sizeof(int))); - int_var_pt_.push_back(n_rec_spike_times_); - + if ( std::find( int_var_name_.begin(), int_var_name_.end(), s ) == int_var_name_.end() ) + { // add it if not already present + int_var_name_.push_back( s ); + + gpuErrchk( cudaMalloc( &n_rec_spike_times_, n_node_ * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &n_rec_spike_times_cumul_, ( n_node_ + 1 ) * sizeof( int ) ) ); + gpuErrchk( cudaMemset( n_rec_spike_times_, 0, n_node_ * sizeof( int ) ) ); + int_var_pt_.push_back( n_rec_spike_times_ ); + max_n_rec_spike_times_ = max_n_rec_spike_times; - gpuErrchk(cudaMalloc(&rec_spike_times_, n_node_*max_n_rec_spike_times - *sizeof(int))); - gpuErrchk(cudaMalloc(&rec_spike_times_pack_, n_node_*max_n_rec_spike_times - *sizeof(int))); - spike_times_pt_vect_.resize(n_node_, NULL); - n_spike_times_vect_.resize(n_node_, 0); - spike_times_vect_.resize(n_node_); + gpuErrchk( cudaMalloc( &rec_spike_times_, n_node_ * max_n_rec_spike_times * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &rec_spike_times_pack_, n_node_ * max_n_rec_spike_times * sizeof( int ) ) ); + spike_times_pt_vect_.resize( n_node_, NULL ); + n_spike_times_vect_.resize( n_node_, 0 ); + spike_times_vect_.resize( n_node_ ); } - else { - throw ngpu_exception("Spike times recording already activated"); + else + { + throw ngpu_exception( "Spike times recording already activated" ); } return 0; } // set number of time steps for buffering recorded spike times -int BaseNeuron::SetRecSpikeTimesStep(int rec_spike_times_step) +int +BaseNeuron::SetRecSpikeTimesStep( int rec_spike_times_step ) { rec_spike_times_step_ = rec_spike_times_step; @@ -1426,155 +1525,165 @@ int BaseNeuron::SetRecSpikeTimesStep(int rec_spike_times_step) } // get number of spikes recorded for neuron i_neuron -int BaseNeuron::GetNRecSpikeTimes(int i_neuron) +int +BaseNeuron::GetNRecSpikeTimes( int i_neuron ) { - CheckNeuronIdx(i_neuron); - if(max_n_rec_spike_times_<=0) { - throw ngpu_exception("Spike times recording was not activated"); + CheckNeuronIdx( i_neuron ); + if ( max_n_rec_spike_times_ <= 0 ) + { + throw ngpu_exception( "Spike times recording was not activated" ); } int n_spikes; - - gpuErrchk(cudaMemcpy(&n_spikes, &n_rec_spike_times_[i_neuron], sizeof(int), - cudaMemcpyDeviceToHost)); + + gpuErrchk( cudaMemcpy( &n_spikes, &n_rec_spike_times_[ i_neuron ], sizeof( int ), cudaMemcpyDeviceToHost ) ); return n_spikes; } // get input spikes from external interface // Must be defined in derived classes -float *BaseNeuron::GetExtNeuronInputSpikes(int *n_node, int *n_port) +float* +BaseNeuron::GetExtNeuronInputSpikes( int* n_node, int* n_port ) { - throw ngpu_exception("Cannot get extern neuron input spikes from this model"); + throw ngpu_exception( "Cannot get extern neuron input spikes from this model" ); } // set neuron-group parameter param_name to value val // Must be defined in derived classes -int BaseNeuron::SetNeuronGroupParam(std::string param_name, float val) +int +BaseNeuron::SetNeuronGroupParam( std::string param_name, float val ) { - throw ngpu_exception(std::string("Unrecognized neuron group parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized neuron group parameter " ) + param_name ); } - // kernel for packing spike times of neurons // i_neuron, ..., i_neuron + n_neuron -1 -// in contiguous locations in GPU memory -__global__ void PackSpikeTimesKernel(int n_neuron, int *n_rec_spike_times_cumul, - float *rec_spike_times, float *rec_spike_times_pack, - int n_spike_tot, int max_n_rec_spike_times) -{ - // array_idx: index on one-dimensional packed spike array +// in contiguous locations in GPU memory +__global__ void +PackSpikeTimesKernel( int n_neuron, + int* n_rec_spike_times_cumul, + float* rec_spike_times, + float* rec_spike_times_pack, + int n_spike_tot, + int max_n_rec_spike_times ) +{ + // array_idx: index on one-dimensional packed spike array int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx0) { + if ( n_spike_tot > 0 ) + { // pack spike times in GPU memory - PackSpikeTimesKernel<<<(n_spike_tot+1023)/1024, 1024>>>(n_node_, - n_rec_spike_times_cumul_, - rec_spike_times_, - rec_spike_times_pack_, - n_spike_tot, max_n_rec_spike_times_); - - float *h_rec_spike_times_pack = new float[n_spike_tot]; - gpuErrchk(cudaMemcpy(h_rec_spike_times_pack, - rec_spike_times_pack_, - sizeof(float)*n_spike_tot, cudaMemcpyDeviceToHost)); + PackSpikeTimesKernel<<< ( n_spike_tot + 1023 ) / 1024, 1024 >>>( + n_node_, n_rec_spike_times_cumul_, rec_spike_times_, rec_spike_times_pack_, n_spike_tot, max_n_rec_spike_times_ ); + + float* h_rec_spike_times_pack = new float[ n_spike_tot ]; + gpuErrchk( cudaMemcpy( + h_rec_spike_times_pack, rec_spike_times_pack_, sizeof( float ) * n_spike_tot, cudaMemcpyDeviceToHost ) ); // push the packed spike array and the cumulative sum in the buffers - spike_times_buffer_.push_back(h_rec_spike_times_pack); - n_spike_times_cumul_buffer_.push_back(h_n_rec_spike_times_cumul); - gpuErrchk(cudaMemset(n_rec_spike_times_, 0, n_node_*sizeof(int))); + spike_times_buffer_.push_back( h_rec_spike_times_pack ); + n_spike_times_cumul_buffer_.push_back( h_n_rec_spike_times_cumul ); + gpuErrchk( cudaMemset( n_rec_spike_times_, 0, n_node_ * sizeof( int ) ) ); } - else { + else + { delete[] h_n_rec_spike_times_cumul; } - + return 0; } // get recorded spike times -int BaseNeuron::GetRecSpikeTimes(int **n_spike_times_pt, - float ***spike_times_pt) +int +BaseNeuron::GetRecSpikeTimes( int** n_spike_times_pt, float*** spike_times_pt ) { - if(max_n_rec_spike_times_<=0) { - throw ngpu_exception("Spike times recording was not activated"); + if ( max_n_rec_spike_times_ <= 0 ) + { + throw ngpu_exception( "Spike times recording was not activated" ); } // push all spikes and cumulative sums left in the buffers BufferRecSpikeTimes(); // first evaluate the total number of spikes for each node - for (int i_node=0; i_node -#include #include "dir_connect.h" #include +#include +#include class NESTGPU; class BaseNeuron { - protected: +protected: friend class NESTGPU; int node_type_; bool ext_neuron_flag_; @@ -44,7 +41,7 @@ class BaseNeuron int n_node_; int n_port_; int i_group_; - unsigned long long *seed_; + unsigned long long* seed_; int n_int_var_; int n_scal_var_; @@ -54,265 +51,260 @@ class BaseNeuron int n_group_param_; int n_var_; int n_param_; - - double *get_spike_array_; - float *port_weight_arr_; + + double* get_spike_array_; + float* port_weight_arr_; int port_weight_arr_step_; int port_weight_port_step_; - float *port_input_arr_; + float* port_input_arr_; int port_input_arr_step_; int port_input_port_step_; - std::vector int_var_pt_; - float *var_arr_; - float *param_arr_; - float *group_param_; - std::vector int_var_name_; - const std::string *scal_var_name_; - const std::string *port_var_name_; - const std::string *scal_param_name_; - const std::string *port_param_name_; - const std::string *group_param_name_; - std::vector array_var_name_; - std::vector array_param_name_; - - DirectConnection *d_dir_conn_array_; + std::vector< int* > int_var_pt_; + float* var_arr_; + float* param_arr_; + float* group_param_; + std::vector< std::string > int_var_name_; + const std::string* scal_var_name_; + const std::string* port_var_name_; + const std::string* scal_param_name_; + const std::string* port_param_name_; + const std::string* group_param_name_; + std::vector< std::string > array_var_name_; + std::vector< std::string > array_param_name_; + + DirectConnection* d_dir_conn_array_; uint64_t n_dir_conn_; // = 0; - bool has_dir_conn_; // = false; + bool has_dir_conn_; // = false; - int *spike_count_; - float *rec_spike_times_; - float *rec_spike_times_pack_; - int *n_rec_spike_times_; - int *n_rec_spike_times_cumul_; + int* spike_count_; + float* rec_spike_times_; + float* rec_spike_times_pack_; + int* n_rec_spike_times_; + int* n_rec_spike_times_cumul_; int max_n_rec_spike_times_; int rec_spike_times_step_; - float *den_delay_arr_; - std::vector n_spike_times_cumul_buffer_; - std::vector spike_times_buffer_; - std::vector spike_times_pt_vect_; - std::vector n_spike_times_vect_; - std::vector< std::vector > spike_times_vect_; + float* den_delay_arr_; + std::vector< int* > n_spike_times_cumul_buffer_; + std::vector< float* > spike_times_buffer_; + std::vector< float* > spike_times_pt_vect_; + std::vector< int > n_spike_times_vect_; + std::vector< std::vector< float > > spike_times_vect_; + + std::vector< float > port_weight_vect_; + std::vector< float > port_input_vect_; + + std::vector< float > ext_neuron_input_spikes_; - std::vector port_weight_vect_; - std::vector port_input_vect_; +public: + virtual ~BaseNeuron() + { + } - std::vector ext_neuron_input_spikes_; - - public: - virtual ~BaseNeuron() {} - - virtual int Init(int i_node_0, int n_neuron, int n_port, - int i_neuron_group, unsigned long long *seed); + virtual int Init( int i_node_0, int n_neuron, int n_port, int i_neuron_group, unsigned long long* seed ); virtual int AllocVarArr(); - + virtual int AllocParamArr(); virtual int FreeVarArr(); - + virtual int FreeParamArr(); - - int GetNodeType() { + + int + GetNodeType() + { return node_type_; } - bool IsExtNeuron() + bool + IsExtNeuron() { return ext_neuron_flag_; } - - virtual int Calibrate(double time_min, float time_resolution) {return 0;} - - virtual int Update(long long it, double t1) {return 0;} - - virtual int GetX(int i_neuron, int n_neuron, double *x) {return 0;} - - virtual int GetY(int i_var, int i_neuron, int n_neuron, float *y) {return 0;} - - virtual int SetScalParam(int i_neuron, int n_neuron, std::string param_name, - float val); - virtual int SetScalParam(int *i_neuron, int n_neuron, std::string param_name, - float val); - - virtual int SetPortParam(int i_neuron, int n_neuron, std::string param_name, - float *param, int vect_size); - - virtual int SetPortParam(int *i_neuron, int n_neuron, - std::string param_name, float *param, - int vect_size); + virtual int + Calibrate( double time_min, float time_resolution ) + { + return 0; + } + + virtual int + Update( long long it, double t1 ) + { + return 0; + } + + virtual int + GetX( int i_neuron, int n_neuron, double* x ) + { + return 0; + } + + virtual int + GetY( int i_var, int i_neuron, int n_neuron, float* y ) + { + return 0; + } + + virtual int SetScalParam( int i_neuron, int n_neuron, std::string param_name, float val ); + + virtual int SetScalParam( int* i_neuron, int n_neuron, std::string param_name, float val ); + + virtual int SetPortParam( int i_neuron, int n_neuron, std::string param_name, float* param, int vect_size ); + + virtual int SetPortParam( int* i_neuron, int n_neuron, std::string param_name, float* param, int vect_size ); + + virtual int SetArrayParam( int i_neuron, int n_neuron, std::string param_name, float* array, int array_size ); - virtual int SetArrayParam(int i_neuron, int n_neuron, std::string param_name, - float *array, int array_size); - - virtual int SetArrayParam(int *i_neuron, int n_neuron, - std::string param_name, float *array, - int array_size); + virtual int SetArrayParam( int* i_neuron, int n_neuron, std::string param_name, float* array, int array_size ); - virtual int SetGroupParam(std::string param_name, float val); + virtual int SetGroupParam( std::string param_name, float val ); - virtual int SetIntVar(int i_neuron, int n_neuron, std::string var_name, - int val); + virtual int SetIntVar( int i_neuron, int n_neuron, std::string var_name, int val ); - virtual int SetIntVar(int *i_neuron, int n_neuron, std::string var_name, - int val); + virtual int SetIntVar( int* i_neuron, int n_neuron, std::string var_name, int val ); - virtual int SetScalVar(int i_neuron, int n_neuron, std::string var_name, - float val); + virtual int SetScalVar( int i_neuron, int n_neuron, std::string var_name, float val ); - virtual int SetScalVar(int *i_neuron, int n_neuron, std::string var_name, - float val); - - virtual int SetPortVar(int i_neuron, int n_neuron, std::string var_name, - float *var, int vect_size); - - virtual int SetPortVar(int *i_neuron, int n_neuron, - std::string var_name, float *var, - int vect_size); + virtual int SetScalVar( int* i_neuron, int n_neuron, std::string var_name, float val ); - virtual int SetArrayVar(int i_neuron, int n_neuron, std::string var_name, - float *array, int array_size); - - virtual int SetArrayVar(int *i_neuron, int n_neuron, - std::string var_name, float *array, - int array_size); + virtual int SetPortVar( int i_neuron, int n_neuron, std::string var_name, float* var, int vect_size ); - virtual float *GetScalParam(int i_neuron, int n_neuron, - std::string param_name); + virtual int SetPortVar( int* i_neuron, int n_neuron, std::string var_name, float* var, int vect_size ); - virtual float *GetScalParam(int *i_neuron, int n_neuron, - std::string param_name); + virtual int SetArrayVar( int i_neuron, int n_neuron, std::string var_name, float* array, int array_size ); - virtual float *GetPortParam(int i_neuron, int n_neuron, - std::string param_name); + virtual int SetArrayVar( int* i_neuron, int n_neuron, std::string var_name, float* array, int array_size ); - virtual float *GetPortParam(int *i_neuron, int n_neuron, - std::string param_name); + virtual float* GetScalParam( int i_neuron, int n_neuron, std::string param_name ); - virtual float *GetArrayParam(int i_neuron, std::string param_name); + virtual float* GetScalParam( int* i_neuron, int n_neuron, std::string param_name ); - virtual float GetGroupParam(std::string param_name); + virtual float* GetPortParam( int i_neuron, int n_neuron, std::string param_name ); - virtual int *GetIntVar(int i_neuron, int n_neuron, - std::string var_name); + virtual float* GetPortParam( int* i_neuron, int n_neuron, std::string param_name ); - virtual int *GetIntVar(int *i_neuron, int n_neuron, - std::string var_name); + virtual float* GetArrayParam( int i_neuron, std::string param_name ); - virtual float *GetScalVar(int i_neuron, int n_neuron, - std::string var_name); + virtual float GetGroupParam( std::string param_name ); - virtual float *GetScalVar(int *i_neuron, int n_neuron, - std::string var_name); + virtual int* GetIntVar( int i_neuron, int n_neuron, std::string var_name ); - virtual float *GetPortVar(int i_neuron, int n_neuron, - std::string var_name); + virtual int* GetIntVar( int* i_neuron, int n_neuron, std::string var_name ); - virtual float *GetPortVar(int *i_neuron, int n_neuron, - std::string var_name); + virtual float* GetScalVar( int i_neuron, int n_neuron, std::string var_name ); - virtual float *GetArrayVar(int i_neuron, std::string var_name); + virtual float* GetScalVar( int* i_neuron, int n_neuron, std::string var_name ); - virtual int GetIntVarIdx(std::string var_name); - - virtual int GetScalVarIdx(std::string var_name); + virtual float* GetPortVar( int i_neuron, int n_neuron, std::string var_name ); - virtual int GetPortVarIdx(std::string var_name); + virtual float* GetPortVar( int* i_neuron, int n_neuron, std::string var_name ); - virtual int GetScalParamIdx(std::string param_name); + virtual float* GetArrayVar( int i_neuron, std::string var_name ); - virtual int GetPortParamIdx(std::string param_name); + virtual int GetIntVarIdx( std::string var_name ); - virtual float *GetVarArr(); + virtual int GetScalVarIdx( std::string var_name ); - virtual float *GetParamArr(); + virtual int GetPortVarIdx( std::string var_name ); - virtual int GetArrayVarSize(int i_neuron, std::string var_name); - - virtual int GetArrayParamSize(int i_neuron, std::string param_name); + virtual int GetScalParamIdx( std::string param_name ); - virtual int GetVarSize(std::string var_name); + virtual int GetPortParamIdx( std::string param_name ); - virtual int GetParamSize(std::string param_name); + virtual float* GetVarArr(); - virtual bool IsIntVar(std::string var_name); + virtual float* GetParamArr(); - virtual bool IsScalVar(std::string var_name); + virtual int GetArrayVarSize( int i_neuron, std::string var_name ); - virtual bool IsPortVar(std::string var_name); + virtual int GetArrayParamSize( int i_neuron, std::string param_name ); - virtual bool IsArrayVar(std::string var_name); - - virtual bool IsScalParam(std::string param_name); + virtual int GetVarSize( std::string var_name ); - virtual bool IsPortParam(std::string param_name); + virtual int GetParamSize( std::string param_name ); - virtual bool IsArrayParam(std::string param_name); + virtual bool IsIntVar( std::string var_name ); - virtual bool IsGroupParam(std::string param_name); + virtual bool IsScalVar( std::string var_name ); - int CheckNeuronIdx(int i_neuron); + virtual bool IsPortVar( std::string var_name ); - int CheckPortIdx(int port); + virtual bool IsArrayVar( std::string var_name ); - virtual int *GetIntVarPt(int i_neuron, std::string var_name); - - virtual float *GetVarPt(int i_neuron, std::string var_name, int port=0); + virtual bool IsScalParam( std::string param_name ); - virtual float *GetParamPt(int i_neuron, std::string param_name, - int port=0); - virtual float GetSpikeActivity(int i_neuron); + virtual bool IsPortParam( std::string param_name ); - virtual int SendDirectSpikes(double t, float time_step) {return 0;} + virtual bool IsArrayParam( std::string param_name ); - virtual std::vector GetIntVarNames(); + virtual bool IsGroupParam( std::string param_name ); + + int CheckNeuronIdx( int i_neuron ); + + int CheckPortIdx( int port ); + + virtual int* GetIntVarPt( int i_neuron, std::string var_name ); + + virtual float* GetVarPt( int i_neuron, std::string var_name, int port = 0 ); + + virtual float* GetParamPt( int i_neuron, std::string param_name, int port = 0 ); + virtual float GetSpikeActivity( int i_neuron ); + + virtual int + SendDirectSpikes( double t, float time_step ) + { + return 0; + } + + virtual std::vector< std::string > GetIntVarNames(); virtual int GetNIntVar(); - - virtual std::vector GetScalVarNames(); - + + virtual std::vector< std::string > GetScalVarNames(); + virtual int GetNScalVar(); - virtual std::vector GetPortVarNames(); - + virtual std::vector< std::string > GetPortVarNames(); + virtual int GetNPortVar(); - virtual std::vector GetScalParamNames(); - + virtual std::vector< std::string > GetScalParamNames(); + virtual int GetNScalParam(); - virtual std::vector GetPortParamNames(); - + virtual std::vector< std::string > GetPortParamNames(); + virtual int GetNPortParam(); - virtual std::vector GetArrayVarNames(); - + virtual std::vector< std::string > GetArrayVarNames(); + virtual int GetNArrayVar(); - virtual std::vector GetArrayParamNames(); - + virtual std::vector< std::string > GetArrayParamNames(); + virtual int GetNArrayParam(); - virtual std::vector GetGroupParamNames(); - + virtual std::vector< std::string > GetGroupParamNames(); + virtual int GetNGroupParam(); virtual int ActivateSpikeCount(); - virtual int ActivateRecSpikeTimes(int max_n_rec_spike_times); + virtual int ActivateRecSpikeTimes( int max_n_rec_spike_times ); - virtual int GetNRecSpikeTimes(int i_neuron); + virtual int GetNRecSpikeTimes( int i_neuron ); virtual int BufferRecSpikeTimes(); - - virtual int GetRecSpikeTimes(int **n_spike_times_pt, float ***spike_times_pt); - virtual int SetRecSpikeTimesStep(int rec_spike_times_step); + virtual int GetRecSpikeTimes( int** n_spike_times_pt, float*** spike_times_pt ); + + virtual int SetRecSpikeTimesStep( int rec_spike_times_step ); - virtual float *GetExtNeuronInputSpikes(int *n_node, int *n_port); + virtual float* GetExtNeuronInputSpikes( int* n_node, int* n_port ); - virtual int SetNeuronGroupParam(std::string param_name, float val); + virtual int SetNeuronGroupParam( std::string param_name, float val ); }; #endif diff --git a/src/connect.cu b/src/connect.cu index 8cbfda98c..1feac2527 100644 --- a/src/connect.cu +++ b/src/connect.cu @@ -21,162 +21,189 @@ */ - - - +#include #include #include -#include -#include #include +#include -#include "ngpu_exception.h" #include "connect.h" +#include "ngpu_exception.h" extern bool ConnectionSpikeTimeFlag; // provare a mettere nella classe? -int NetConnection::Connect(int i_source, int i_target, unsigned char port, - unsigned char syn_group, float weight, float delay) +int +NetConnection::Connect( int i_source, + int i_target, + unsigned char port, + unsigned char syn_group, + float weight, + float delay ) { - if (delay= time resolution"); + if ( delay < time_resolution_ ) + { + throw ngpu_exception( "Delay must be >= time resolution" ); } - //TEMPORARY, TO BE IMPROVED - if (syn_group>=1) { - ConnectionSpikeTimeFlag=true; + // TEMPORARY, TO BE IMPROVED + if ( syn_group >= 1 ) + { + ConnectionSpikeTimeFlag = true; } - - int d_int = (int)round(delay/time_resolution_) - 1; - TargetSyn tg = {i_target, port, syn_group, weight}; - Insert(d_int, i_source, tg); - + + int d_int = ( int ) round( delay / time_resolution_ ) - 1; + TargetSyn tg = { i_target, port, syn_group, weight }; + Insert( d_int, i_source, tg ); + return 0; } -int NetConnection::Insert(int d_int, int i_source, TargetSyn tg) +int +NetConnection::Insert( int d_int, int i_source, TargetSyn tg ) { int id; - std::vector &conn = connection_[i_source]; + std::vector< ConnGroup >& conn = connection_[ i_source ]; int conn_size = conn.size(); - for (id=0; idconn[id].delay; id++) {} - if (id==conn_size || d_int!=conn[id].delay) { + for ( id = 0; id < conn_size && d_int > conn[ id ].delay; id++ ) + { + } + if ( id == conn_size || d_int != conn[ id ].delay ) + { ConnGroup new_conn; new_conn.delay = d_int; - new_conn.target_vect.push_back(tg); - std::vector::iterator it = conn.begin() + id; - conn.insert(it, new_conn); + new_conn.target_vect.push_back( tg ); + std::vector< ConnGroup >::iterator it = conn.begin() + id; + conn.insert( it, new_conn ); } - else { - conn[id].target_vect.push_back(tg); + else + { + conn[ id ].target_vect.push_back( tg ); } - + return 0; } -int NetConnection::Print() +int +NetConnection::Print() { - for (unsigned int i_source=0; i_source &conn = connection_[i_source]; - for (unsigned int id=0; id tv = conn[id].target_vect; + std::vector< ConnGroup >& conn = connection_[ i_source ]; + for ( unsigned int id = 0; id < conn.size(); id++ ) + { + std::cout << "\tDelay: " << conn[ id ].delay << std::endl; + std::vector< TargetSyn > tv = conn[ id ].target_vect; std::cout << "\tTargets: " << std::endl; - for (unsigned int i=0; i &conn = connection_[i_node]; + for ( unsigned int i_node = 0; i_node < connection_.size(); i_node++ ) + { + std::vector< ConnGroup >& conn = connection_[ i_node ]; int n_delays = conn.size(); - if (n_delays > max_delay_num) max_delay_num = n_delays; + if ( n_delays > max_delay_num ) + { + max_delay_num = n_delays; + } } return max_delay_num; } -unsigned int NetConnection::StoredNConnections() +unsigned int +NetConnection::StoredNConnections() { - if (n_conn_==0) { + if ( n_conn_ == 0 ) + { n_conn_ = NConnections(); } - + return n_conn_; } -unsigned int NetConnection::NConnections() +unsigned int +NetConnection::NConnections() { unsigned int n_conn = 0; - for (unsigned int i_node=0; i_node &conn = connection_[i_node]; - for (unsigned int id=0; id& conn = connection_[ i_node ]; + for ( unsigned int id = 0; id < conn.size(); id++ ) + { + unsigned int n_target = conn.at( id ).target_vect.size(); n_conn += n_target; } } - + return n_conn; } -template<> -int GetINode(int i_node, int in) +template <> +int +GetINode< int >( int i_node, int in ) { return i_node + in; } -template<> -int GetINode(int* i_node, int in) +template <> +int +GetINode< int* >( int* i_node, int in ) { - return *(i_node + in); + return *( i_node + in ); } -ConnectionStatus NetConnection::GetConnectionStatus(ConnectionId conn_id) +ConnectionStatus +NetConnection::GetConnectionStatus( ConnectionId conn_id ) { int i_source = conn_id.i_source_; int i_group = conn_id.i_group_; int i_conn = conn_id.i_conn_; - std::vector &conn = connection_[i_source]; - std::vector tv = conn[i_group].target_vect; - + std::vector< ConnGroup >& conn = connection_[ i_source ]; + std::vector< TargetSyn > tv = conn[ i_group ].target_vect; + ConnectionStatus conn_stat; conn_stat.i_source = i_source; - conn_stat.i_target = tv[i_conn].node; - conn_stat.port = tv[i_conn].port; - conn_stat.syn_group = tv[i_conn].syn_group; - conn_stat.delay = time_resolution_*(conn[i_group].delay + 1); - conn_stat.weight = tv[i_conn].weight; + conn_stat.i_target = tv[ i_conn ].node; + conn_stat.port = tv[ i_conn ].port; + conn_stat.syn_group = tv[ i_conn ].syn_group; + conn_stat.delay = time_resolution_ * ( conn[ i_group ].delay + 1 ); + conn_stat.weight = tv[ i_conn ].weight; return conn_stat; } -std::vector NetConnection::GetConnectionStatus - (std::vector &conn_id_vect) +std::vector< ConnectionStatus > +NetConnection::GetConnectionStatus( std::vector< ConnectionId >& conn_id_vect ) { - std::vector conn_stat_vect; - - for (unsigned int i=0; i conn_stat_vect; + + for ( unsigned int i = 0; i < conn_id_vect.size(); i++ ) + { + ConnectionId conn_id = conn_id_vect[ i ]; + ConnectionStatus conn_stat = GetConnectionStatus( conn_id ); + conn_stat_vect.push_back( conn_stat ); } - + return conn_stat_vect; } diff --git a/src/connect.h b/src/connect.h index b57965b85..65274e9f0 100644 --- a/src/connect.h +++ b/src/connect.h @@ -21,20 +21,18 @@ */ - - - #ifndef CONNECT_H #define CONNECT_H -#include #include +#include #define PORT_N_SHIFT 1 #define POW2_PORT_N_SHIFT 2 // 2^PORT_N_SHIFT -#define PORT_MASK 0x1FFFFF // in the highest byte the lowest PORT_N_SHIFT bits - // are 1, the other are 0 -#define MAX_N_NEURON POW2_PORT_N_SHIFT*16*1024*1024 -#define MAX_N_PORT 256/POW2_PORT_N_SHIFT +#define PORT_MASK \ + 0x1FFFFF // in the highest byte the lowest PORT_N_SHIFT bits + // are 1, the other are 0 +#define MAX_N_NEURON POW2_PORT_N_SHIFT * 16 * 1024 * 1024 +#define MAX_N_PORT 256 / POW2_PORT_N_SHIFT extern float TimeResolution; @@ -62,11 +60,11 @@ struct TargetSyn unsigned char syn_group; float weight; }; - + struct ConnGroup // connections from the same source node with same delay { int delay; - std::vector target_vect; + std::vector< TargetSyn > target_vect; }; struct RemoteConnection @@ -79,123 +77,126 @@ struct RemoteConnection float delay; }; -template -int GetINode(T node, int in); +template < class T > +int GetINode( T node, int in ); class NetConnection { unsigned int n_conn_; unsigned int n_rev_conn_; - public: + +public: float time_resolution_; - NetConnection() {n_conn_ = 0;} - - std::vector > connection_; + NetConnection() + { + n_conn_ = 0; + } - int Insert(int d_int, int i_source, TargetSyn tg); + std::vector< std::vector< ConnGroup > > connection_; - int Connect(int i_source, int i_target, unsigned char port, - unsigned char syn_group, float weight, float delay); + int Insert( int d_int, int i_source, TargetSyn tg ); + + int Connect( int i_source, int i_target, unsigned char port, unsigned char syn_group, float weight, float delay ); int Print(); - - int ConnGroupPrint(int i_source); + + int ConnGroupPrint( int i_source ); int MaxDelayNum(); - + unsigned int StoredNConnections(); - + unsigned int NConnections(); - unsigned int NRevConnections() {return n_rev_conn_;} + unsigned int + NRevConnections() + { + return n_rev_conn_; + } - int SetNRevConnections(unsigned int n_rev_conn) { + int + SetNRevConnections( unsigned int n_rev_conn ) + { n_rev_conn_ = n_rev_conn; return 0; } - ConnectionStatus GetConnectionStatus(ConnectionId conn_id); + ConnectionStatus GetConnectionStatus( ConnectionId conn_id ); - std::vector GetConnectionStatus(std::vector - &conn_id_vect); - + std::vector< ConnectionStatus > GetConnectionStatus( std::vector< ConnectionId >& conn_id_vect ); - template - std::vector GetConnections(T source, int n_source, - int i_target, int n_target, - int syn_group=-1); - template - std::vector GetConnections(T source, int n_source, - int *i_target, int n_target, - int syn_group=-1); + template < class T > + std::vector< ConnectionId > GetConnections( T source, int n_source, int i_target, int n_target, int syn_group = -1 ); + template < class T > + std::vector< ConnectionId > GetConnections( T source, int n_source, int* i_target, int n_target, int syn_group = -1 ); }; -template -std::vector NetConnection::GetConnections(T source, - int n_source, - int i_target, - int n_target, - int /*syn_group*/) +template < class T > +std::vector< ConnectionId > +NetConnection::GetConnections( T source, int n_source, int i_target, int n_target, int /*syn_group*/ ) { - std::vector conn_id_vect; - for (int is=0; is(source, is); - std::vector &conn = connection_[i_source]; - for (unsigned int id=0; id tv = conn[id].target_vect; - for (unsigned int i=0; i=i_target) && (itg conn_id_vect; + for ( int is = 0; is < n_source; is++ ) + { + int i_source = GetINode< T >( source, is ); + std::vector< ConnGroup >& conn = connection_[ i_source ]; + for ( unsigned int id = 0; id < conn.size(); id++ ) + { + std::vector< TargetSyn > tv = conn[ id ].target_vect; + for ( unsigned int i = 0; i < tv.size(); i++ ) + { + int itg = tv[ i ].node; + if ( ( itg >= i_target ) && ( itg < i_target + n_target ) ) + { + ConnectionId conn_id; + conn_id.i_source_ = i_source; + conn_id.i_group_ = id; + conn_id.i_conn_ = i; + conn_id_vect.push_back( conn_id ); + } } } } - + return conn_id_vect; } -template -std::vector NetConnection::GetConnections(T source, - int n_source, - int *i_target, - int n_target, - int /*syn_group*/) +template < class T > +std::vector< ConnectionId > +NetConnection::GetConnections( T source, int n_source, int* i_target, int n_target, int /*syn_group*/ ) { - std::vector target_vect(i_target, i_target+n_target); - std::sort(target_vect.begin(), target_vect.end()); - - std::vector conn_id_vect; - for (int is=0; is(source, is); - std::vector &conn = connection_[i_source]; - for (unsigned int id=0; id tv = conn[id].target_vect; - for (unsigned int i=0; i::iterator it = std::lower_bound(target_vect.begin(), - target_vect.end(), - itg); - if (it != target_vect.end() && *it == itg) { // we found the element - ConnectionId conn_id; - conn_id.i_source_ = i_source; - conn_id.i_group_ = id; - conn_id.i_conn_ = i; - conn_id_vect.push_back(conn_id); - } + std::vector< int > target_vect( i_target, i_target + n_target ); + std::sort( target_vect.begin(), target_vect.end() ); + + std::vector< ConnectionId > conn_id_vect; + for ( int is = 0; is < n_source; is++ ) + { + int i_source = GetINode< T >( source, is ); + std::vector< ConnGroup >& conn = connection_[ i_source ]; + for ( unsigned int id = 0; id < conn.size(); id++ ) + { + std::vector< TargetSyn > tv = conn[ id ].target_vect; + for ( unsigned int i = 0; i < tv.size(); i++ ) + { + int itg = tv[ i ].node; + // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup + // check if itg is in target_vect + std::vector< int >::iterator it = std::lower_bound( target_vect.begin(), target_vect.end(), itg ); + if ( it != target_vect.end() && *it == itg ) + { // we found the element + ConnectionId conn_id; + conn_id.i_source_ = i_source; + conn_id.i_group_ = id; + conn_id.i_conn_ = i; + conn_id_vect.push_back( conn_id ); + } } } } - + return conn_id_vect; } diff --git a/src/connect_mpi.cu b/src/connect_mpi.cu index 1bb962dac..2894724a4 100644 --- a/src/connect_mpi.cu +++ b/src/connect_mpi.cu @@ -21,109 +21,120 @@ */ - - - #include #ifdef HAVE_MPI -#include #include +#include #include #include "connect_mpi.h" -int ConnectMpi::MPI_Recv_int(int *int_val, int n, int sender_id) +int +ConnectMpi::MPI_Recv_int( int* int_val, int n, int sender_id ) { MPI_Status Stat; int tag = 1; - MPI_Recv(int_val, n, MPI_INT, sender_id, tag, MPI_COMM_WORLD, &Stat); + MPI_Recv( int_val, n, MPI_INT, sender_id, tag, MPI_COMM_WORLD, &Stat ); return 0; } -int ConnectMpi::MPI_Recv_float(float *float_val, int n, int sender_id) +int +ConnectMpi::MPI_Recv_float( float* float_val, int n, int sender_id ) { MPI_Status Stat; int tag = 1; - MPI_Recv(float_val, n, MPI_FLOAT, sender_id, tag, MPI_COMM_WORLD, &Stat); + MPI_Recv( float_val, n, MPI_FLOAT, sender_id, tag, MPI_COMM_WORLD, &Stat ); return 0; } -int ConnectMpi::MPI_Recv_uchar(unsigned char *uchar_val, int n, int sender_id) +int +ConnectMpi::MPI_Recv_uchar( unsigned char* uchar_val, int n, int sender_id ) { MPI_Status Stat; int tag = 1; - MPI_Recv(uchar_val, n, MPI_UNSIGNED_CHAR, sender_id, tag, MPI_COMM_WORLD, - &Stat); + MPI_Recv( uchar_val, n, MPI_UNSIGNED_CHAR, sender_id, tag, MPI_COMM_WORLD, &Stat ); return 0; } -int ConnectMpi::MPI_Send_int(int *int_val, int n, int target_id) +int +ConnectMpi::MPI_Send_int( int* int_val, int n, int target_id ) { int tag = 1; - MPI_Send(int_val, n, MPI_INT, target_id, tag, MPI_COMM_WORLD); + MPI_Send( int_val, n, MPI_INT, target_id, tag, MPI_COMM_WORLD ); return 0; } -int ConnectMpi::MPI_Send_float(float *float_val, int n, int target_id) +int +ConnectMpi::MPI_Send_float( float* float_val, int n, int target_id ) { int tag = 1; - MPI_Send(float_val, n, MPI_FLOAT, target_id, tag, MPI_COMM_WORLD); + MPI_Send( float_val, n, MPI_FLOAT, target_id, tag, MPI_COMM_WORLD ); return 0; } -int ConnectMpi::MPI_Send_uchar(unsigned char *uchar_val, int n, int target_id) +int +ConnectMpi::MPI_Send_uchar( unsigned char* uchar_val, int n, int target_id ) { int tag = 1; - MPI_Send(uchar_val, n, MPI_UNSIGNED_CHAR, target_id, tag, MPI_COMM_WORLD); + MPI_Send( uchar_val, n, MPI_UNSIGNED_CHAR, target_id, tag, MPI_COMM_WORLD ); return 0; } -int ConnectMpi::MpiInit(int argc, char *argv[]) +int +ConnectMpi::MpiInit( int argc, char* argv[] ) { int initialized; - MPI_Initialized(&initialized); - if (!initialized) { - MPI_Init(&argc,&argv); + MPI_Initialized( &initialized ); + if ( !initialized ) + { + MPI_Init( &argc, &argv ); } - MPI_Comm_size(MPI_COMM_WORLD, &mpi_np_); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_id_); + MPI_Comm_size( MPI_COMM_WORLD, &mpi_np_ ); + MPI_Comm_rank( MPI_COMM_WORLD, &mpi_id_ ); mpi_master_ = 0; - + return 0; } -bool ConnectMpi::ProcMaster() +bool +ConnectMpi::ProcMaster() { - if (mpi_id_==mpi_master_) return true; - else return false; + if ( mpi_id_ == mpi_master_ ) + { + return true; + } + else + { + return false; + } } /* // CHECK: using net_connection_->connection_.push_back(conn) // connection_size() should be aligned with node_group_map_.size() int ConnectMpi::RemoteConnect(int i_source_host, int i_source_node, - int i_target_host, int i_target_node, - unsigned char port, unsigned char syn_group, - float weight, float delay) + int i_target_host, int i_target_node, + unsigned char port, unsigned char syn_group, + float weight, float delay) { int i_remote_node; - + if (mpi_id_==i_source_host && i_source_host==i_target_host) { return net_connection_->Connect(i_source_node, i_target_node, port, - syn_group, weight, delay); + syn_group, weight, delay); } else if (mpi_id_ == i_target_host) { MPI_Recv_int(&i_remote_node, 1, i_source_host); @@ -135,16 +146,16 @@ int ConnectMpi::RemoteConnect(int i_source_host, int i_source_node, MPI_Send_int(&i_remote_node, 1, i_source_host); } net_connection_->Connect(i_remote_node, i_target_node, port, syn_group, - weight, delay); + weight, delay); } else if (mpi_id_ == i_source_host) { i_remote_node = -1; for (vector::iterator it = - extern_connection_[i_source_node].begin(); - it < extern_connection_[i_source_node].end(); it++) { + extern_connection_[i_source_node].begin(); + it < extern_connection_[i_source_node].end(); it++) { if ((*it).target_host_id == i_target_host) { - i_remote_node = (*it).remote_node_id; - break; + i_remote_node = (*it).remote_node_id; + break; } } MPI_Send_int(&i_remote_node, 1, i_target_host); diff --git a/src/connect_mpi.h b/src/connect_mpi.h index ea6eef2c7..e605ea8fb 100644 --- a/src/connect_mpi.h +++ b/src/connect_mpi.h @@ -21,15 +21,12 @@ */ - - - #ifdef HAVE_MPI #ifndef CONNECTMPI_H #define CONNECTMPI_H -#include -#include #include "connect.h" +#include +#include struct ExternalConnectionNode { @@ -39,55 +36,53 @@ struct ExternalConnectionNode class ConnectMpi { - public: - NetConnection *net_connection_; +public: + NetConnection* net_connection_; int mpi_id_; int mpi_np_; int mpi_master_; bool remote_spike_height_; - + double SendSpikeToRemote_MPI_time_; double RecvSpikeFromRemote_MPI_time_; double SendSpikeToRemote_CUDAcp_time_; double RecvSpikeFromRemote_CUDAcp_time_; double JoinSpike_time_; - - - std::vector > extern_connection_; - int MPI_Recv_int(int *int_val, int n, int sender_id); - - int MPI_Recv_float(float *float_val, int n, int sender_id); - int MPI_Recv_uchar(unsigned char *uchar_val, int n, int sender_id); - - int MPI_Send_int(int *int_val, int n, int target_id); - - int MPI_Send_float(float *float_val, int n, int target_id); + std::vector< std::vector< ExternalConnectionNode > > extern_connection_; + + int MPI_Recv_int( int* int_val, int n, int sender_id ); + + int MPI_Recv_float( float* float_val, int n, int sender_id ); + + int MPI_Recv_uchar( unsigned char* uchar_val, int n, int sender_id ); - int MPI_Send_uchar(unsigned char *uchar_val, int n, int target_id); + int MPI_Send_int( int* int_val, int n, int target_id ); + + int MPI_Send_float( float* float_val, int n, int target_id ); + + int MPI_Send_uchar( unsigned char* uchar_val, int n, int target_id ); /* int RemoteConnect(int i_source_host, int i_source_node, - int i_target_host, int i_target_node, - unsigned char port, unsigned char syn_group, - float weight, float delay); + int i_target_host, int i_target_node, + unsigned char port, unsigned char syn_group, + float weight, float delay); */ - int MpiInit(int argc, char *argv[]); - + int MpiInit( int argc, char* argv[] ); + bool ProcMaster(); - - int ExternalSpikeInit(int n_node, int n_hosts, int max_spike_per_host); - int SendSpikeToRemote(int n_hosts, int max_spike_per_host); + int ExternalSpikeInit( int n_node, int n_hosts, int max_spike_per_host ); - int RecvSpikeFromRemote(int n_hosts, int max_spike_per_host); + int SendSpikeToRemote( int n_hosts, int max_spike_per_host ); - int CopySpikeFromRemote(int n_hosts, int max_spike_per_host, - int i_remote_node_0); + int RecvSpikeFromRemote( int n_hosts, int max_spike_per_host ); - int JoinSpikes(int n_hosts, int max_spike_per_host); + int CopySpikeFromRemote( int n_hosts, int max_spike_per_host, int i_remote_node_0 ); + int JoinSpikes( int n_hosts, int max_spike_per_host ); }; #endif diff --git a/src/connect_rules.cpp b/src/connect_rules.cpp index 84b1dde39..44b87efcd 100644 --- a/src/connect_rules.cpp +++ b/src/connect_rules.cpp @@ -21,18 +21,15 @@ */ - - - - -#include -#include -#include "ngpu_exception.h" #include "connect.h" -#include "nestgpu.h" #include "connect_rules.h" +#include "nestgpu.h" +#include "ngpu_exception.h" +#include +#include -int ConnSpec::Init() +int +ConnSpec::Init() { rule_ = ALL_TO_ALL; total_num_ = 0; @@ -40,82 +37,98 @@ int ConnSpec::Init() outdegree_ = 0; return 0; } - + ConnSpec::ConnSpec() { Init(); } -int ConnSpec::Init(int rule, int degree /*=0*/) +int +ConnSpec::Init( int rule, int degree /*=0*/ ) { Init(); - if (rule<0 || rule>N_CONN_RULE) { - throw ngpu_exception("Unknown connection rule"); + if ( rule < 0 || rule > N_CONN_RULE ) + { + throw ngpu_exception( "Unknown connection rule" ); } - if ((rule==ALL_TO_ALL || rule==ONE_TO_ONE) && (degree != 0)) { - throw ngpu_exception(std::string("Connection rule ") + conn_rule_name[rule] - + " does not have a degree"); + if ( ( rule == ALL_TO_ALL || rule == ONE_TO_ONE ) && ( degree != 0 ) ) + { + throw ngpu_exception( std::string( "Connection rule " ) + conn_rule_name[ rule ] + " does not have a degree" ); } rule_ = rule; - if (rule==FIXED_TOTAL_NUMBER) { + if ( rule == FIXED_TOTAL_NUMBER ) + { total_num_ = degree; } - else if (rule==FIXED_INDEGREE) { + else if ( rule == FIXED_INDEGREE ) + { indegree_ = degree; } - else if (rule==FIXED_OUTDEGREE) { + else if ( rule == FIXED_OUTDEGREE ) + { outdegree_ = degree; } - + return 0; } -ConnSpec::ConnSpec(int rule, int degree /*=0*/) +ConnSpec::ConnSpec( int rule, int degree /*=0*/ ) { - Init(rule, degree); + Init( rule, degree ); } -int ConnSpec::SetParam(std::string param_name, int value) +int +ConnSpec::SetParam( std::string param_name, int value ) { - if (param_name=="rule") { - if (value<0 || value>N_CONN_RULE) { - throw ngpu_exception("Unknown connection rule"); + if ( param_name == "rule" ) + { + if ( value < 0 || value > N_CONN_RULE ) + { + throw ngpu_exception( "Unknown connection rule" ); } rule_ = value; return 0; } - else if (param_name=="indegree") { - if (value<0) { - throw ngpu_exception("Indegree must be >=0"); + else if ( param_name == "indegree" ) + { + if ( value < 0 ) + { + throw ngpu_exception( "Indegree must be >=0" ); } indegree_ = value; return 0; } - else if (param_name=="outdegree") { - if (value<0) { - throw ngpu_exception("Outdegree must be >=0"); + else if ( param_name == "outdegree" ) + { + if ( value < 0 ) + { + throw ngpu_exception( "Outdegree must be >=0" ); } outdegree_ = value; return 0; } - else if (param_name=="total_num") { - if (value<0) { - throw ngpu_exception("total_num must be >=0"); + else if ( param_name == "total_num" ) + { + if ( value < 0 ) + { + throw ngpu_exception( "total_num must be >=0" ); } total_num_ = value; return 0; } - throw ngpu_exception("Unknown connection int parameter"); + throw ngpu_exception( "Unknown connection int parameter" ); } -bool ConnSpec::IsParam(std::string param_name) +bool +ConnSpec::IsParam( std::string param_name ) { - if (param_name=="rule" || param_name=="indegree" || param_name=="outdegree" - || param_name=="total_num") { + if ( param_name == "rule" || param_name == "indegree" || param_name == "outdegree" || param_name == "total_num" ) + { return true; } - else { + else + { return false; } } @@ -126,7 +139,8 @@ SynSpec::SynSpec() } -int SynSpec::Init() +int +SynSpec::Init() { syn_group_ = 0; port_ = 0; @@ -141,378 +155,446 @@ int SynSpec::Init() } -SynSpec::SynSpec(float weight, float delay) +SynSpec::SynSpec( float weight, float delay ) { - Init(weight, delay); + Init( weight, delay ); } -int SynSpec::Init(float weight, float delay) +int +SynSpec::Init( float weight, float delay ) { - if (delay<0) { - throw ngpu_exception("Delay must be >=0"); + if ( delay < 0 ) + { + throw ngpu_exception( "Delay must be >=0" ); } Init(); weight_ = weight; delay_ = delay; return 0; - } +} -SynSpec::SynSpec(int syn_group, float weight, float delay, int port /*=0*/) +SynSpec::SynSpec( int syn_group, float weight, float delay, int port /*=0*/ ) { - Init(syn_group, weight, delay, port); + Init( syn_group, weight, delay, port ); } -int SynSpec::Init(int syn_group, float weight, float delay, int port /*=0*/) +int +SynSpec::Init( int syn_group, float weight, float delay, int port /*=0*/ ) { - if (syn_group<0) { // || syn_group>n_syn_group) { - throw ngpu_exception("Unknown synapse group"); + if ( syn_group < 0 ) + { // || syn_group>n_syn_group) { + throw ngpu_exception( "Unknown synapse group" ); } - if (port<0) { - throw ngpu_exception("Port index must be >=0"); + if ( port < 0 ) + { + throw ngpu_exception( "Port index must be >=0" ); } - Init(weight, delay); + Init( weight, delay ); syn_group_ = syn_group; port_ = port; return 0; - } +} -int SynSpec::SetParam(std::string param_name, int value) +int +SynSpec::SetParam( std::string param_name, int value ) { - if (param_name=="synapse_group") { - if (value<0) { // || value>n_syn_group) { - throw ngpu_exception("Unknown synapse group"); + if ( param_name == "synapse_group" ) + { + if ( value < 0 ) + { // || value>n_syn_group) { + throw ngpu_exception( "Unknown synapse group" ); } syn_group_ = value; return 0; } - else if (param_name=="receptor") { - if (value<0) { - throw ngpu_exception("Port index must be >=0"); + else if ( param_name == "receptor" ) + { + if ( value < 0 ) + { + throw ngpu_exception( "Port index must be >=0" ); } port_ = value; return 0; } - - throw ngpu_exception("Unknown synapse int parameter"); + + throw ngpu_exception( "Unknown synapse int parameter" ); } -bool SynSpec::IsIntParam(std::string param_name) +bool +SynSpec::IsIntParam( std::string param_name ) { - if (param_name=="synapse_group" || param_name=="receptor") { + if ( param_name == "synapse_group" || param_name == "receptor" ) + { return true; } - else { + else + { return false; } } -int SynSpec::SetParam(std::string param_name, float value) +int +SynSpec::SetParam( std::string param_name, float value ) { - if (param_name=="weight") { + if ( param_name == "weight" ) + { weight_ = value; } - else if (param_name=="delay") { - if (value<0) { - throw ngpu_exception("Delay must be >=0"); + else if ( param_name == "delay" ) + { + if ( value < 0 ) + { + throw ngpu_exception( "Delay must be >=0" ); } delay_ = value; } - else { - throw ngpu_exception("Unknown synapse float parameter"); + else + { + throw ngpu_exception( "Unknown synapse float parameter" ); } return 0; } -bool SynSpec::IsFloatParam(std::string param_name) +bool +SynSpec::IsFloatParam( std::string param_name ) { - if (param_name=="weight" || param_name=="delay") { + if ( param_name == "weight" || param_name == "delay" ) + { return true; } - else { + else + { return false; } } - -int SynSpec::SetParam(std::string param_name, float *array_pt) + +int +SynSpec::SetParam( std::string param_name, float* array_pt ) { - if (param_name=="weight_array") { + if ( param_name == "weight_array" ) + { weight_array_ = array_pt; } - else if (param_name=="delay_array") { + else if ( param_name == "delay_array" ) + { delay_array_ = array_pt; } - else { - throw ngpu_exception("Unknown synapse array parameter"); + else + { + throw ngpu_exception( "Unknown synapse array parameter" ); } - + return 0; } -bool SynSpec::IsFloatPtParam(std::string param_name) +bool +SynSpec::IsFloatPtParam( std::string param_name ) { - if (param_name=="weight_array" || param_name=="delay_array") { + if ( param_name == "weight_array" || param_name == "delay_array" ) + { return true; } - else { + else + { return false; } } -int NESTGPU::Connect(int i_source_node, int i_target_node, - unsigned char port, unsigned char syn_group, - float weight, float delay) +int +NESTGPU::Connect( int i_source_node, + int i_target_node, + unsigned char port, + unsigned char syn_group, + float weight, + float delay ) { - CheckUncalibrated("Connections cannot be created after calibration"); - net_connection_->Connect(i_source_node, i_target_node, - port, syn_group, weight, delay); + CheckUncalibrated( "Connections cannot be created after calibration" ); + net_connection_->Connect( i_source_node, i_target_node, port, syn_group, weight, delay ); return 0; } -template<> -int NESTGPU::_SingleConnect -(int i_source0, int i_source, int i_target0, - int i_target, float weight, float delay, - int i_array, SynSpec &syn_spec) -{ - return net_connection_->Connect(i_source0 + i_source, i_target0 + i_target, - syn_spec.port_, syn_spec.syn_group_, - weight, delay); -} - -template<> -int NESTGPU::_SingleConnect -(int i_source0, int i_source, - int *i_target0, int i_target, - float weight, float delay, - int i_array, SynSpec &syn_spec) -{ - return net_connection_->Connect(i_source0 + i_source, - *(i_target0 + i_target), - syn_spec.port_, syn_spec.syn_group_, - weight, delay); -} - -template<> -int NESTGPU::_SingleConnect -(int *i_source0, int i_source, - int i_target0, int i_target, - float weight, float delay, - int i_array, SynSpec &syn_spec) -{ - return net_connection_->Connect(*(i_source0 + i_source), - i_target0 + i_target, - syn_spec.port_, syn_spec.syn_group_, - weight, delay); -} - -template<> -int NESTGPU::_SingleConnect -(int *i_source0, int i_source, - int *i_target0, int i_target, - float weight, float delay, - int i_array, SynSpec &syn_spec) -{ - return net_connection_->Connect(*(i_source0 + i_source), - *(i_target0 + i_target), - syn_spec.port_, syn_spec.syn_group_, - weight, delay); -} - - -template<> -int NESTGPU::_RemoteSingleConnect -(int i_source, int i_target0, - int i_target, float weight, float delay, - int i_array, SynSpec &syn_spec) -{ - - RemoteConnection rc = {i_source, i_target0 + i_target, - syn_spec.port_, syn_spec.syn_group_, - weight, delay}; - remote_connection_vect_.push_back(rc); +template <> +int +NESTGPU::_SingleConnect< int, int >( int i_source0, + int i_source, + int i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) +{ + return net_connection_->Connect( + i_source0 + i_source, i_target0 + i_target, syn_spec.port_, syn_spec.syn_group_, weight, delay ); +} + +template <> +int +NESTGPU::_SingleConnect< int, int* >( int i_source0, + int i_source, + int* i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) +{ + return net_connection_->Connect( + i_source0 + i_source, *( i_target0 + i_target ), syn_spec.port_, syn_spec.syn_group_, weight, delay ); +} + +template <> +int +NESTGPU::_SingleConnect< int*, int >( int* i_source0, + int i_source, + int i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) +{ + return net_connection_->Connect( + *( i_source0 + i_source ), i_target0 + i_target, syn_spec.port_, syn_spec.syn_group_, weight, delay ); +} + +template <> +int +NESTGPU::_SingleConnect< int*, int* >( int* i_source0, + int i_source, + int* i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) +{ + return net_connection_->Connect( + *( i_source0 + i_source ), *( i_target0 + i_target ), syn_spec.port_, syn_spec.syn_group_, weight, delay ); +} + + +template <> +int +NESTGPU::_RemoteSingleConnect< int >( int i_source, + int i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) +{ + + RemoteConnection rc = { i_source, i_target0 + i_target, syn_spec.port_, syn_spec.syn_group_, weight, delay }; + remote_connection_vect_.push_back( rc ); return 0; } -template<> -int NESTGPU::_RemoteSingleConnect -(int i_source, - int *i_target0, int i_target, - float weight, float delay, - int i_array, SynSpec &syn_spec) +template <> +int +NESTGPU::_RemoteSingleConnect< int* >( int i_source, + int* i_target0, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) { - RemoteConnection rc = {i_source, *(i_target0 + i_target), - syn_spec.port_, syn_spec.syn_group_, - weight, delay}; - remote_connection_vect_.push_back(rc); - return 0; + RemoteConnection rc = { i_source, *( i_target0 + i_target ), syn_spec.port_, syn_spec.syn_group_, weight, delay }; + remote_connection_vect_.push_back( rc ); + return 0; } -int NESTGPU::Connect(int i_source, int n_source, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( int i_source, int n_source, int i_target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(i_source, n_source, i_target, n_target, - conn_spec, syn_spec); + return _Connect< int, int >( i_source, n_source, i_target, n_target, conn_spec, syn_spec ); } -int NESTGPU::Connect(int i_source, int n_source, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( int i_source, int n_source, int* target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(i_source, n_source, target, n_target, - conn_spec, syn_spec); + return _Connect< int, int* >( i_source, n_source, target, n_target, conn_spec, syn_spec ); } -int NESTGPU::Connect(int* source, int n_source, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( int* source, int n_source, int i_target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source, n_source, i_target, n_target, - conn_spec, syn_spec); + return _Connect< int*, int >( source, n_source, i_target, n_target, conn_spec, syn_spec ); } -int NESTGPU::Connect(int* source, int n_source, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( int* source, int n_source, int* target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source, n_source, target, n_target, - conn_spec, syn_spec); + return _Connect< int*, int* >( source, n_source, target, n_target, conn_spec, syn_spec ); } -int NESTGPU::Connect(NodeSeq source, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( NodeSeq source, NodeSeq target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source.i0, source.n, target.i0, target.n, - conn_spec, syn_spec); + return _Connect< int, int >( source.i0, source.n, target.i0, target.n, conn_spec, syn_spec ); } -int NESTGPU::Connect(NodeSeq source, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( NodeSeq source, std::vector< int > target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source.i0, source.n, target.data(), - target.size(), conn_spec, syn_spec); + return _Connect< int, int* >( source.i0, source.n, target.data(), target.size(), conn_spec, syn_spec ); } -int NESTGPU::Connect(std::vector source, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( std::vector< int > source, NodeSeq target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source.data(), source.size(), target.i0, - target.n, conn_spec, syn_spec); + return _Connect< int*, int >( source.data(), source.size(), target.i0, target.n, conn_spec, syn_spec ); } -int NESTGPU::Connect(std::vector source, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::Connect( std::vector< int > source, std::vector< int > target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - return _Connect(source.data(), source.size(), target.data(), - target.size(), conn_spec, syn_spec); + return _Connect< int*, int* >( source.data(), source.size(), target.data(), target.size(), conn_spec, syn_spec ); } -int NESTGPU::RemoteConnect(int i_source_host, int i_source, int n_source, - int i_target_host, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int i_target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, i_source); - RemoteNode rtarget(i_target_host, i_target); - return _RemoteConnect(rsource, n_source, rtarget, n_target, - conn_spec, syn_spec); + RemoteNode< int > rsource( i_source_host, i_source ); + RemoteNode< int > rtarget( i_target_host, i_target ); + return _RemoteConnect< int, int >( rsource, n_source, rtarget, n_target, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, int i_source, int n_source, - int i_target_host, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int* target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, i_source); - RemoteNode rtarget(i_target_host, target); - return _RemoteConnect(rsource, n_source, rtarget, n_target, - conn_spec, syn_spec); + RemoteNode< int > rsource( i_source_host, i_source ); + RemoteNode< int* > rtarget( i_target_host, target ); + return _RemoteConnect< int, int* >( rsource, n_source, rtarget, n_target, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, int* source, int n_source, - int i_target_host, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + int* source, + int n_source, + int i_target_host, + int i_target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source); - RemoteNode rtarget(i_target_host, i_target); + RemoteNode< int* > rsource( i_source_host, source ); + RemoteNode< int > rtarget( i_target_host, i_target ); - return _RemoteConnect(rsource, n_source, rtarget, n_target, - conn_spec, syn_spec); + return _RemoteConnect< int*, int >( rsource, n_source, rtarget, n_target, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, int* source, int n_source, - int i_target_host, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + int* source, + int n_source, + int i_target_host, + int* target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source); - RemoteNode rtarget(i_target_host, target); + RemoteNode< int* > rsource( i_source_host, source ); + RemoteNode< int* > rtarget( i_target_host, target ); - return _RemoteConnect(rsource, n_source, rtarget, n_target, - conn_spec, syn_spec); + return _RemoteConnect< int*, int* >( rsource, n_source, rtarget, n_target, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, NodeSeq source, - int i_target_host, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + NodeSeq source, + int i_target_host, + NodeSeq target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source.i0); - RemoteNode rtarget(i_target_host, target.i0); - - return _RemoteConnect(rsource, source.n, rtarget, target.n, - conn_spec, syn_spec); + RemoteNode< int > rsource( i_source_host, source.i0 ); + RemoteNode< int > rtarget( i_target_host, target.i0 ); + + return _RemoteConnect< int, int >( rsource, source.n, rtarget, target.n, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, NodeSeq source, - int i_target_host, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + NodeSeq source, + int i_target_host, + std::vector< int > target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source.i0); - RemoteNode rtarget(i_target_host, target.data()); - return _RemoteConnect(rsource, source.n, rtarget, - target.size(), conn_spec, syn_spec); + RemoteNode< int > rsource( i_source_host, source.i0 ); + RemoteNode< int* > rtarget( i_target_host, target.data() ); + return _RemoteConnect< int, int* >( rsource, source.n, rtarget, target.size(), conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, std::vector source, - int i_target_host, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + std::vector< int > source, + int i_target_host, + NodeSeq target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source.data()); - RemoteNode rtarget(i_target_host, target.i0); - return _RemoteConnect(rsource, source.size(), rtarget, target.n, - conn_spec, syn_spec); + RemoteNode< int* > rsource( i_source_host, source.data() ); + RemoteNode< int > rtarget( i_target_host, target.i0 ); + return _RemoteConnect< int*, int >( rsource, source.size(), rtarget, target.n, conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::RemoteConnect(int i_source_host, std::vector source, - int i_target_host, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec) +int +NESTGPU::RemoteConnect( int i_source_host, + std::vector< int > source, + int i_target_host, + std::vector< int > target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { #ifdef HAVE_MPI - RemoteNode rsource(i_source_host, source.data()); - RemoteNode rtarget(i_target_host, target.data()); - return _RemoteConnect(rsource, source.size(), rtarget, - target.size(), conn_spec, syn_spec); + RemoteNode< int* > rsource( i_source_host, source.data() ); + RemoteNode< int* > rtarget( i_target_host, target.data() ); + return _RemoteConnect< int*, int* >( rsource, source.size(), rtarget, target.size(), conn_spec, syn_spec ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } diff --git a/src/connect_rules.h b/src/connect_rules.h index 9cb1f9b31..04b9e91c1 100644 --- a/src/connect_rules.h +++ b/src/connect_rules.h @@ -21,16 +21,15 @@ */ - - - #ifndef CONNECTRULES_H #define CONNECTRULES_H -#include -#include +#include #include + #include "nestgpu.h" +#include +#include #ifdef HAVE_MPI #include "connect_mpi.h" @@ -39,23 +38,25 @@ #define THREAD_MAXNUM 1 #define THREAD_IDX 0 -template<> -int RemoteNode::GetINode(int in) +template <> +int +RemoteNode< int >::GetINode( int in ) { return i_node_ + in; } -template<> -int RemoteNode::GetINode(int in) +template <> +int +RemoteNode< int* >::GetINode( int in ) { - return *(i_node_ + in); + return *( i_node_ + in ); } -template -int NESTGPU::_Connect(T1 source, int n_source, T2 target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_Connect( T1 source, int n_source, T2 target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ) { - CheckUncalibrated("Connections cannot be created after calibration"); + CheckUncalibrated( "Connections cannot be created after calibration" ); //////////////////////// // TO DO: // if (syn_spec.weight_distr_ != NULL) { @@ -64,370 +65,407 @@ int NESTGPU::_Connect(T1 source, int n_source, T2 target, int n_target, // if (syn_spec.delay_distr_ != NULL) { // syn_spec.delay_array_ = Distribution(syn_spec.delay_distr, n); // } - - switch (conn_spec.rule_) { + + switch ( conn_spec.rule_ ) + { case ONE_TO_ONE: - if (n_source != n_target) { - throw ngpu_exception("Number of source and target nodes must be equal " - "for the one-to-one connection rule"); + if ( n_source != n_target ) + { + throw ngpu_exception( + "Number of source and target nodes must be equal " + "for the one-to-one connection rule" ); } - return _ConnectOneToOne(source, target, n_source, syn_spec); + return _ConnectOneToOne< T1, T2 >( source, target, n_source, syn_spec ); break; case ALL_TO_ALL: - return _ConnectAllToAll(source, n_source, target, n_target, - syn_spec); + return _ConnectAllToAll< T1, T2 >( source, n_source, target, n_target, syn_spec ); break; case FIXED_TOTAL_NUMBER: - return _ConnectFixedTotalNumber(source, n_source, target, n_target, - conn_spec.total_num_, syn_spec); + return _ConnectFixedTotalNumber< T1, T2 >( source, n_source, target, n_target, conn_spec.total_num_, syn_spec ); break; case FIXED_INDEGREE: - return _ConnectFixedIndegree(source, n_source, target, n_target, - conn_spec.indegree_, syn_spec); + return _ConnectFixedIndegree< T1, T2 >( source, n_source, target, n_target, conn_spec.indegree_, syn_spec ); break; case FIXED_OUTDEGREE: - return _ConnectFixedOutdegree(source, n_source, target, n_target, - conn_spec.outdegree_, syn_spec); + return _ConnectFixedOutdegree< T1, T2 >( source, n_source, target, n_target, conn_spec.outdegree_, syn_spec ); break; default: - throw ngpu_exception("Unknown connection rule"); + throw ngpu_exception( "Unknown connection rule" ); } return 0; } -template -int NESTGPU::_SingleConnect(T1 source, int i_source, T2 target, int i_target, - int i_array, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_SingleConnect( T1 source, int i_source, T2 target, int i_target, int i_array, SynSpec& syn_spec ) { float weight; - if (syn_spec.weight_array_ != NULL) { - weight = syn_spec.weight_array_[i_array]; + if ( syn_spec.weight_array_ != NULL ) + { + weight = syn_spec.weight_array_[ i_array ]; } - else { + else + { weight = syn_spec.weight_; } float delay; - if (syn_spec.delay_array_ != NULL) { - delay = syn_spec.delay_array_[i_array]; + if ( syn_spec.delay_array_ != NULL ) + { + delay = syn_spec.delay_array_[ i_array ]; } - else { + else + { delay = syn_spec.delay_; } - return _SingleConnect(source, i_source, target, i_target, - weight, delay, i_array, syn_spec); + return _SingleConnect< T1, T2 >( source, i_source, target, i_target, weight, delay, i_array, syn_spec ); } -template -int NESTGPU::_SingleConnect(T1 source, int i_source, T2 target, int i_target, - float weight, float delay, int i_array, - SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_SingleConnect( T1 source, + int i_source, + T2 target, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) { - throw ngpu_exception("Unknown type for _SingleConnect template"); + throw ngpu_exception( "Unknown type for _SingleConnect template" ); } -template -int NESTGPU::_RemoteSingleConnect(int i_source, T target, int i_target, - int i_array, SynSpec &syn_spec) +template < class T > +int +NESTGPU::_RemoteSingleConnect( int i_source, T target, int i_target, int i_array, SynSpec& syn_spec ) { float weight; - if (syn_spec.weight_array_ != NULL) { - weight = syn_spec.weight_array_[i_array]; + if ( syn_spec.weight_array_ != NULL ) + { + weight = syn_spec.weight_array_[ i_array ]; } - else { + else + { weight = syn_spec.weight_; } float delay; - if (syn_spec.delay_array_ != NULL) { - delay = syn_spec.delay_array_[i_array]; + if ( syn_spec.delay_array_ != NULL ) + { + delay = syn_spec.delay_array_[ i_array ]; } - else { + else + { delay = syn_spec.delay_; } - return _RemoteSingleConnect(i_source, target, i_target, - weight, delay, i_array, syn_spec); + return _RemoteSingleConnect< T >( i_source, target, i_target, weight, delay, i_array, syn_spec ); } -template -int NESTGPU::_RemoteSingleConnect(int i_source, T target, int i_target, - float weight, float delay, int i_array, - SynSpec &syn_spec) +template < class T > +int +NESTGPU::_RemoteSingleConnect( int i_source, + T target, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ) { - throw ngpu_exception("Unknown type for _RemoteSingleConnect template"); + throw ngpu_exception( "Unknown type for _RemoteSingleConnect template" ); } - - -template -int NESTGPU::_ConnectOneToOne(T1 source, T2 target, int n_node, - SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_ConnectOneToOne( T1 source, T2 target, int n_node, SynSpec& syn_spec ) { - for (int in=0; in(source, in, target, in, in, syn_spec); + for ( int in = 0; in < n_node; in++ ) + { + _SingleConnect< T1, T2 >( source, in, target, in, in, syn_spec ); } return 0; } -template -int NESTGPU::_ConnectAllToAll -(T1 source, int n_source, T2 target, int n_target, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_ConnectAllToAll( T1 source, int n_source, T2 target, int n_target, SynSpec& syn_spec ) { - for (int itn=0; itn(source, isn, target, itn, i_array, syn_spec); + for ( int itn = 0; itn < n_target; itn++ ) + { + for ( int isn = 0; isn < n_source; isn++ ) + { + size_t i_array = ( size_t ) itn * n_source + isn; + _SingleConnect< T1, T2 >( source, isn, target, itn, i_array, syn_spec ); } } return 0; } -template -int NESTGPU::_ConnectFixedTotalNumber -(T1 source, int n_source, T2 target, int n_target, int n_conn, - SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_ConnectFixedTotalNumber( T1 source, int n_source, T2 target, int n_target, int n_conn, SynSpec& syn_spec ) { - unsigned int *rnd = RandomInt(2*n_conn); - for (int i_conn=0; i_conn(source, isn, target, itn, i_conn, syn_spec); + unsigned int* rnd = RandomInt( 2 * n_conn ); + for ( int i_conn = 0; i_conn < n_conn; i_conn++ ) + { + int isn = rnd[ 2 * i_conn ] % n_source; + int itn = rnd[ 2 * i_conn + 1 ] % n_target; + _SingleConnect< T1, T2 >( source, isn, target, itn, i_conn, syn_spec ); } delete[] rnd; - + return 0; } -template -int NESTGPU::_ConnectFixedIndegree -( - T1 source, int n_source, T2 target, int n_target, int indegree, - SynSpec &syn_spec - ) +template < class T1, class T2 > +int +NESTGPU::_ConnectFixedIndegree( T1 source, int n_source, T2 target, int n_target, int indegree, SynSpec& syn_spec ) { const int method_thresh = 5; - if (indegree>n_source) { - throw ngpu_exception("Indegree larger than number of source nodes"); + if ( indegree > n_source ) + { + throw ngpu_exception( "Indegree larger than number of source nodes" ); } - int n_rnd = indegree*THREAD_MAXNUM; - if (n_source>=method_thresh*indegree) { // nuovo metodo - n_rnd *= 5; - } - unsigned int *rnd = RandomInt(n_rnd); - - for (int k=0; k= method_thresh * indegree ) + { // nuovo metodo + n_rnd *= 5; + } + unsigned int* rnd = RandomInt( n_rnd ); + + for ( int k = 0; k < n_target; k += THREAD_MAXNUM ) + { + for ( int ith = 0; ith < THREAD_MAXNUM; ith++ ) + { int itn = k + ith; - if (itn < n_target) { - std::vector int_vect; - //int_vect.clear(); - if (n_source sorted_vect; - for (int i=0; i::iterator iter; - int j; - do { - j = rnd[(i1*indegree + i)*THREAD_MAXNUM + ith] - % n_source; - // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup - // check if j is in target_vect - iter = std::lower_bound(sorted_vect.begin(), - sorted_vect.end(), j); - i1++; - } while (iter != sorted_vect.end() && *iter == j); // we found j - sorted_vect.insert(iter, j); - int_vect.push_back(j); - } - } - for (int i=0; i(source, isn, target, itn, i_array, syn_spec); - } + if ( itn < n_target ) + { + std::vector< int > int_vect; + // int_vect.clear(); + if ( n_source < method_thresh * indegree ) + { // vecchio metodo + // https://stackoverflow.com/questions/18625223 + // v = sequence(0, n_source-1) + int_vect.resize( n_source ); + int start = 0; + std::iota( int_vect.begin(), int_vect.end(), start ); + for ( int i = 0; i < indegree; i++ ) + { + int j = i + rnd[ i * THREAD_MAXNUM + ith ] % ( n_source - i ); + if ( j != i ) + { + std::swap( int_vect[ i ], int_vect[ j ] ); + } + } + } + else + { // nuovo metodo + std::vector< int > sorted_vect; + for ( int i = 0; i < indegree; i++ ) + { + int i1 = 0; + std::vector< int >::iterator iter; + int j; + do + { + j = rnd[ ( i1 * indegree + i ) * THREAD_MAXNUM + ith ] % n_source; + // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup + // check if j is in target_vect + iter = std::lower_bound( sorted_vect.begin(), sorted_vect.end(), j ); + i1++; + } while ( iter != sorted_vect.end() && *iter == j ); // we found j + sorted_vect.insert( iter, j ); + int_vect.push_back( j ); + } + } + for ( int i = 0; i < indegree; i++ ) + { + int isn = int_vect[ i ]; + size_t i_array = ( size_t ) itn * indegree + i; + _SingleConnect< T1, T2 >( source, isn, target, itn, i_array, syn_spec ); + } } } } delete[] rnd; - + return 0; } -template -int NESTGPU::_ConnectFixedOutdegree -( - T1 source, int n_source, T2 target, int n_target, int outdegree, - SynSpec &syn_spec - ) +template < class T1, class T2 > +int +NESTGPU::_ConnectFixedOutdegree( T1 source, int n_source, T2 target, int n_target, int outdegree, SynSpec& syn_spec ) { const int method_thresh = 5; - if (outdegree>n_target) { - throw ngpu_exception("Outdegree larger than number of target nodes"); + if ( outdegree > n_target ) + { + throw ngpu_exception( "Outdegree larger than number of target nodes" ); + } + int n_rnd = outdegree * THREAD_MAXNUM; + if ( n_target >= method_thresh * outdegree ) + { // choose method + n_rnd *= 5; } - int n_rnd = outdegree*THREAD_MAXNUM; - if (n_target>=method_thresh*outdegree) { // choose method - n_rnd *= 5; - } - unsigned int *rnd = RandomInt(n_rnd); + unsigned int* rnd = RandomInt( n_rnd ); - for (int is0=0; is0 int_vect; - if (n_target sorted_vect; - for (int i=0; i::iterator iter; - int j; - do { - j = rnd[(i1*outdegree + i)*THREAD_MAXNUM + ith] - % n_target; - // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup - // check if j is in target_vect - iter = std::lower_bound(sorted_vect.begin(), - sorted_vect.end(), j); - i1++; - } while (iter != sorted_vect.end() && *iter == j); // we found j - sorted_vect.insert(iter, j); - int_vect.push_back(j); - } - } - for (int k=0; k(source, isn, target, itn, i_array, syn_spec); - } + if ( isn < n_source ) + { + std::vector< int > int_vect; + if ( n_target < method_thresh * outdegree ) + { // choose method + // https://stackoverflow.com/questions/18625223 + // v = sequence(0, n_target-1) + int_vect.resize( n_target ); + int start = 0; + std::iota( int_vect.begin(), int_vect.end(), start ); + for ( int i = 0; i < outdegree; i++ ) + { + int j = i + rnd[ i * THREAD_MAXNUM + ith ] % ( n_target - i ); + if ( j != i ) + { + std::swap( int_vect[ i ], int_vect[ j ] ); + } + } + } + else + { // other method + std::vector< int > sorted_vect; + for ( int i = 0; i < outdegree; i++ ) + { + int i1 = 0; + std::vector< int >::iterator iter; + int j; + do + { + j = rnd[ ( i1 * outdegree + i ) * THREAD_MAXNUM + ith ] % n_target; + // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup + // check if j is in target_vect + iter = std::lower_bound( sorted_vect.begin(), sorted_vect.end(), j ); + i1++; + } while ( iter != sorted_vect.end() && *iter == j ); // we found j + sorted_vect.insert( iter, j ); + int_vect.push_back( j ); + } + } + for ( int k = 0; k < outdegree; k++ ) + { + int itn = int_vect[ k ]; + size_t i_array = ( size_t ) isn * outdegree + k; + _SingleConnect< T1, T2 >( source, isn, target, itn, i_array, syn_spec ); + } } } } delete[] rnd; - + return 0; } #ifdef HAVE_MPI -template -int NESTGPU::_RemoteConnect(RemoteNode source, int n_source, - RemoteNode target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnect( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ) { - CheckUncalibrated("Connections cannot be created after calibration"); - switch (conn_spec.rule_) { + CheckUncalibrated( "Connections cannot be created after calibration" ); + switch ( conn_spec.rule_ ) + { case ONE_TO_ONE: - if (n_source != n_target) { - throw ngpu_exception("Number of source and target nodes must be equal " - "for the one-to-one connection rule"); + if ( n_source != n_target ) + { + throw ngpu_exception( + "Number of source and target nodes must be equal " + "for the one-to-one connection rule" ); } - return _RemoteConnectOneToOne(source, target, n_source, syn_spec); + return _RemoteConnectOneToOne< T1, T2 >( source, target, n_source, syn_spec ); break; case ALL_TO_ALL: - return _RemoteConnectAllToAll(source, n_source, target, n_target, - syn_spec); + return _RemoteConnectAllToAll< T1, T2 >( source, n_source, target, n_target, syn_spec ); break; case FIXED_TOTAL_NUMBER: - return _RemoteConnectFixedTotalNumber(source, n_source, target, - n_target, - conn_spec.total_num_, - syn_spec); + return _RemoteConnectFixedTotalNumber< T1, T2 >( + source, n_source, target, n_target, conn_spec.total_num_, syn_spec ); break; case FIXED_INDEGREE: - return _RemoteConnectFixedIndegree(source, n_source, target, - n_target, conn_spec.indegree_, - syn_spec); + return _RemoteConnectFixedIndegree< T1, T2 >( source, n_source, target, n_target, conn_spec.indegree_, syn_spec ); break; case FIXED_OUTDEGREE: - return _RemoteConnectFixedOutdegree(source, n_source, target, - n_target, conn_spec.outdegree_, - syn_spec); + return _RemoteConnectFixedOutdegree< T1, T2 >( source, n_source, target, n_target, conn_spec.outdegree_, syn_spec ); break; default: - throw ngpu_exception("Unknown connection rule"); + throw ngpu_exception( "Unknown connection rule" ); } return 0; } -template - int NESTGPU::_RemoteConnectOneToOne - (RemoteNode source, RemoteNode target, int n_node, - SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnectOneToOne( RemoteNode< T1 > source, RemoteNode< T2 > target, int n_node, SynSpec& syn_spec ) { - if (MpiId()==source.i_host_ && source.i_host_==target.i_host_) { - return _ConnectOneToOne(source.i_node_, target.i_node_, - n_node, syn_spec); + if ( MpiId() == source.i_host_ && source.i_host_ == target.i_host_ ) + { + return _ConnectOneToOne< T1, T2 >( source.i_node_, target.i_node_, n_node, syn_spec ); } - else if (MpiId()==source.i_host_ || MpiId()==target.i_host_) { - int *i_remote_node_arr = new int[n_node]; - if (MpiId() == target.i_host_) { - connect_mpi_->MPI_Send_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(i_remote_node_arr, n_node, source.i_host_); - - for (int in=0; in(i_remote_node, target.i_node_, in, - in, syn_spec); + else if ( MpiId() == source.i_host_ || MpiId() == target.i_host_ ) + { + int* i_remote_node_arr = new int[ n_node ]; + if ( MpiId() == target.i_host_ ) + { + connect_mpi_->MPI_Send_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( i_remote_node_arr, n_node, source.i_host_ ); + + for ( int in = 0; in < n_node; in++ ) + { + int i_remote_node = i_remote_node_arr[ in ]; + _RemoteSingleConnect< T2 >( i_remote_node, target.i_node_, in, in, syn_spec ); } } - else if (MpiId() == source.i_host_) { + else if ( MpiId() == source.i_host_ ) + { int i_new_remote_node; - connect_mpi_->MPI_Recv_int(&i_new_remote_node, 1, target.i_host_); - for (int in=0; in::iterator it = - connect_mpi_->extern_connection_[i_source_node].begin(); - it < connect_mpi_->extern_connection_[i_source_node].end(); - it++) { - if ((*it).target_host_id == target.i_host_) { - i_remote_node = (*it).remote_node_id; - break; - } - } - if (i_remote_node == -1) { - i_remote_node = i_new_remote_node; - i_new_remote_node++; - ExternalConnectionNode conn_node = {target.i_host_, i_remote_node}; - connect_mpi_->extern_connection_[i_source_node].push_back(conn_node); - } - i_remote_node_arr[in] = i_remote_node; + connect_mpi_->MPI_Recv_int( &i_new_remote_node, 1, target.i_host_ ); + for ( int in = 0; in < n_node; in++ ) + { + int i_source_node = source.GetINode( in ); + int i_remote_node = -1; + for ( std::vector< ExternalConnectionNode >::iterator it = + connect_mpi_->extern_connection_[ i_source_node ].begin(); + it < connect_mpi_->extern_connection_[ i_source_node ].end(); + it++ ) + { + if ( ( *it ).target_host_id == target.i_host_ ) + { + i_remote_node = ( *it ).remote_node_id; + break; + } + } + if ( i_remote_node == -1 ) + { + i_remote_node = i_new_remote_node; + i_new_remote_node++; + ExternalConnectionNode conn_node = { target.i_host_, i_remote_node }; + connect_mpi_->extern_connection_[ i_source_node ].push_back( conn_node ); + } + i_remote_node_arr[ in ] = i_remote_node; } - connect_mpi_->MPI_Send_int(&i_new_remote_node, 1, target.i_host_); - connect_mpi_->MPI_Send_int(i_remote_node_arr, n_node, target.i_host_); + connect_mpi_->MPI_Send_int( &i_new_remote_node, 1, target.i_host_ ); + connect_mpi_->MPI_Send_int( i_remote_node_arr, n_node, target.i_host_ ); } delete[] i_remote_node_arr; } @@ -437,59 +475,70 @@ template } -template - int NESTGPU::_RemoteConnectAllToAll - (RemoteNode source, int n_source, RemoteNode target, int n_target, - SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnectAllToAll( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + SynSpec& syn_spec ) { - if (MpiId()==source.i_host_ && source.i_host_==target.i_host_) { - return _ConnectAllToAll(source.i_node_, n_source, - target.i_node_, n_target, syn_spec); + if ( MpiId() == source.i_host_ && source.i_host_ == target.i_host_ ) + { + return _ConnectAllToAll< T1, T2 >( source.i_node_, n_source, target.i_node_, n_target, syn_spec ); } - else if (MpiId()==source.i_host_ || MpiId()==target.i_host_) { - int *i_remote_node_arr = new int[n_target*n_source]; - if (MpiId() == target.i_host_) { - connect_mpi_->MPI_Send_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(i_remote_node_arr, n_target*n_source, - source.i_host_); - - for (int k=0; k(i_remote_node, target.i_node_, k, - i_array, syn_spec); - } + else if ( MpiId() == source.i_host_ || MpiId() == target.i_host_ ) + { + int* i_remote_node_arr = new int[ n_target * n_source ]; + if ( MpiId() == target.i_host_ ) + { + connect_mpi_->MPI_Send_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( i_remote_node_arr, n_target * n_source, source.i_host_ ); + + for ( int k = 0; k < n_target; k++ ) + { + for ( int i = 0; i < n_source; i++ ) + { + int i_remote_node = i_remote_node_arr[ k * n_source + i ]; + size_t i_array = ( size_t ) k * n_source + i; + _RemoteSingleConnect< T2 >( i_remote_node, target.i_node_, k, i_array, syn_spec ); + } } } - else if (MpiId() == source.i_host_) { + else if ( MpiId() == source.i_host_ ) + { int i_new_remote_node; - connect_mpi_->MPI_Recv_int(&i_new_remote_node, 1, target.i_host_); - for (int k=0; k::iterator it = - connect_mpi_->extern_connection_[i_source_node].begin(); - it < connect_mpi_->extern_connection_[i_source_node].end(); it++) { - if ((*it).target_host_id == target.i_host_) { - i_remote_node = (*it).remote_node_id; - break; - } - } - if (i_remote_node == -1) { - i_remote_node = i_new_remote_node; - i_new_remote_node++; - ExternalConnectionNode conn_node = {target.i_host_, i_remote_node}; - connect_mpi_->extern_connection_[i_source_node].push_back(conn_node); - } - i_remote_node_arr[k*n_source+i] = i_remote_node; - } + connect_mpi_->MPI_Recv_int( &i_new_remote_node, 1, target.i_host_ ); + for ( int k = 0; k < n_target; k++ ) + { + for ( int i = 0; i < n_source; i++ ) + { + int i_source_node = source.GetINode( i ); + int i_remote_node = -1; + for ( std::vector< ExternalConnectionNode >::iterator it = + connect_mpi_->extern_connection_[ i_source_node ].begin(); + it < connect_mpi_->extern_connection_[ i_source_node ].end(); + it++ ) + { + if ( ( *it ).target_host_id == target.i_host_ ) + { + i_remote_node = ( *it ).remote_node_id; + break; + } + } + if ( i_remote_node == -1 ) + { + i_remote_node = i_new_remote_node; + i_new_remote_node++; + ExternalConnectionNode conn_node = { target.i_host_, i_remote_node }; + connect_mpi_->extern_connection_[ i_source_node ].push_back( conn_node ); + } + i_remote_node_arr[ k * n_source + i ] = i_remote_node; + } } - connect_mpi_->MPI_Send_int(&i_new_remote_node, 1, target.i_host_); - connect_mpi_->MPI_Send_int(i_remote_node_arr, n_target*n_source, - target.i_host_); + connect_mpi_->MPI_Send_int( &i_new_remote_node, 1, target.i_host_ ); + connect_mpi_->MPI_Send_int( i_remote_node_arr, n_target * n_source, target.i_host_ ); } delete[] i_remote_node_arr; } @@ -498,58 +547,67 @@ template return 0; } -template - int NESTGPU::_RemoteConnectFixedTotalNumber - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int n_conn, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnectFixedTotalNumber( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int n_conn, + SynSpec& syn_spec ) { - if (MpiId()==source.i_host_ && source.i_host_==target.i_host_) { - return _ConnectFixedTotalNumber(source.i_node_, n_source, - target.i_node_, n_target, - n_conn, syn_spec); + if ( MpiId() == source.i_host_ && source.i_host_ == target.i_host_ ) + { + return _ConnectFixedTotalNumber< T1, T2 >( source.i_node_, n_source, target.i_node_, n_target, n_conn, syn_spec ); } - unsigned int *rnd = RandomInt(2*n_conn); - if (MpiId()==source.i_host_ || MpiId()==target.i_host_) { - int *i_remote_node_arr = new int[n_conn]; - if (MpiId() == target.i_host_) { - connect_mpi_->MPI_Send_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(i_remote_node_arr, n_conn, source.i_host_); - - for (int i_conn=0; i_conn(i_remote_node, target.i_node_, itn, - i_conn, syn_spec); + unsigned int* rnd = RandomInt( 2 * n_conn ); + if ( MpiId() == source.i_host_ || MpiId() == target.i_host_ ) + { + int* i_remote_node_arr = new int[ n_conn ]; + if ( MpiId() == target.i_host_ ) + { + connect_mpi_->MPI_Send_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( i_remote_node_arr, n_conn, source.i_host_ ); + + for ( int i_conn = 0; i_conn < n_conn; i_conn++ ) + { + int i_remote_node = i_remote_node_arr[ i_conn ]; + int itn = rnd[ 2 * i_conn + 1 ] % n_target; + _RemoteSingleConnect< T2 >( i_remote_node, target.i_node_, itn, i_conn, syn_spec ); } } - else if (MpiId() == source.i_host_) { + else if ( MpiId() == source.i_host_ ) + { int i_new_remote_node; - connect_mpi_->MPI_Recv_int(&i_new_remote_node, 1, target.i_host_); - for (int i_conn=0; i_conn::iterator it = - connect_mpi_->extern_connection_[i_source_node].begin(); - it < connect_mpi_->extern_connection_[i_source_node].end(); - it++) { - if ((*it).target_host_id == target.i_host_) { - i_remote_node = (*it).remote_node_id; - break; - } - } - if (i_remote_node == -1) { - i_remote_node = i_new_remote_node; - i_new_remote_node++; - ExternalConnectionNode conn_node = {target.i_host_, i_remote_node}; - connect_mpi_->extern_connection_[i_source_node].push_back(conn_node); - } - i_remote_node_arr[i_conn] = i_remote_node; + connect_mpi_->MPI_Recv_int( &i_new_remote_node, 1, target.i_host_ ); + for ( int i_conn = 0; i_conn < n_conn; i_conn++ ) + { + int isn = rnd[ 2 * i_conn ] % n_source; + int i_source_node = source.GetINode( isn ); + int i_remote_node = -1; + for ( std::vector< ExternalConnectionNode >::iterator it = + connect_mpi_->extern_connection_[ i_source_node ].begin(); + it < connect_mpi_->extern_connection_[ i_source_node ].end(); + it++ ) + { + if ( ( *it ).target_host_id == target.i_host_ ) + { + i_remote_node = ( *it ).remote_node_id; + break; + } + } + if ( i_remote_node == -1 ) + { + i_remote_node = i_new_remote_node; + i_new_remote_node++; + ExternalConnectionNode conn_node = { target.i_host_, i_remote_node }; + connect_mpi_->extern_connection_[ i_source_node ].push_back( conn_node ); + } + i_remote_node_arr[ i_conn ] = i_remote_node; } - connect_mpi_->MPI_Send_int(&i_new_remote_node, 1, target.i_host_); - connect_mpi_->MPI_Send_int(i_remote_node_arr, n_conn, - target.i_host_); + connect_mpi_->MPI_Send_int( &i_new_remote_node, 1, target.i_host_ ); + connect_mpi_->MPI_Send_int( i_remote_node_arr, n_conn, target.i_host_ ); } delete[] i_remote_node_arr; } @@ -558,109 +616,124 @@ template return 0; } -template - int NESTGPU::_RemoteConnectFixedIndegree - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int indegree, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnectFixedIndegree( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int indegree, + SynSpec& syn_spec ) { const int method_thresh = 5; - if (indegree>n_source) { - throw ngpu_exception("Indegree larger than number of source nodes"); + if ( indegree > n_source ) + { + throw ngpu_exception( "Indegree larger than number of source nodes" ); } - if (MpiId()==source.i_host_ && source.i_host_==target.i_host_) { - return _ConnectFixedIndegree(source.i_node_, n_source, - target.i_node_, n_target, indegree, - syn_spec); + if ( MpiId() == source.i_host_ && source.i_host_ == target.i_host_ ) + { + return _ConnectFixedIndegree< T1, T2 >( source.i_node_, n_source, target.i_node_, n_target, indegree, syn_spec ); } - else if (MpiId()==source.i_host_ || MpiId()==target.i_host_) { - int *i_remote_node_arr = new int[n_target*indegree]; - if (MpiId() == target.i_host_) { - connect_mpi_->MPI_Send_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(i_remote_node_arr, n_target*indegree, - source.i_host_); - - for (int k=0; k(i_remote_node, target.i_node_, k, - i_array, syn_spec); - - } + else if ( MpiId() == source.i_host_ || MpiId() == target.i_host_ ) + { + int* i_remote_node_arr = new int[ n_target * indegree ]; + if ( MpiId() == target.i_host_ ) + { + connect_mpi_->MPI_Send_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( i_remote_node_arr, n_target * indegree, source.i_host_ ); + + for ( int k = 0; k < n_target; k++ ) + { + for ( int i = 0; i < indegree; i++ ) + { + int i_remote_node = i_remote_node_arr[ k * indegree + i ]; + size_t i_array = ( size_t ) k * indegree + i; + _RemoteSingleConnect< T2 >( i_remote_node, target.i_node_, k, i_array, syn_spec ); + } } } - else if (MpiId() == source.i_host_) { + else if ( MpiId() == source.i_host_ ) + { int i_new_remote_node; - connect_mpi_->MPI_Recv_int(&i_new_remote_node, 1, target.i_host_); + connect_mpi_->MPI_Recv_int( &i_new_remote_node, 1, target.i_host_ ); int n_rnd = indegree; - if (n_source>=method_thresh*indegree) { // choose method - n_rnd *= 5; - } - unsigned int *rnd = RandomInt(n_rnd); - - //std::vector input_array; - //for (int i=0; i int_vect; - if (n_source sorted_vect; - for (int i=0; i::iterator iter; - int j; - do { - j = rnd[i1*indegree + i] - % n_source; - // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup - // check if j is in target_vect - iter = std::lower_bound(sorted_vect.begin(), - sorted_vect.end(), j); - i1++; - } while (iter != sorted_vect.end() && *iter == j); // we found j - sorted_vect.insert(iter, j); - int_vect.push_back(j); - } - } - for (int i=0; i::iterator it = - connect_mpi_->extern_connection_[i_source_node].begin(); - it < connect_mpi_->extern_connection_[i_source_node].end(); - it++) { - if ((*it).target_host_id == target.i_host_) { - i_remote_node = (*it).remote_node_id; - break; - } - } - if (i_remote_node == -1) { - i_remote_node = i_new_remote_node; - i_new_remote_node++; - ExternalConnectionNode conn_node = {target.i_host_, i_remote_node}; - connect_mpi_->extern_connection_[i_source_node].push_back(conn_node); - } - i_remote_node_arr[k*indegree+i] = i_remote_node; - } + if ( n_source >= method_thresh * indegree ) + { // choose method + n_rnd *= 5; + } + unsigned int* rnd = RandomInt( n_rnd ); + + // std::vector input_array; + // for (int i=0; i int_vect; + if ( n_source < method_thresh * indegree ) + { // choose method + // https://stackoverflow.com/questions/18625223 + // v = sequence(0, n_source-1) + int_vect.resize( n_source ); + int start = 0; + std::iota( int_vect.begin(), int_vect.end(), start ); + for ( int i = 0; i < indegree; i++ ) + { + int j = i + rnd[ i ] % ( n_source - i ); + if ( j != i ) + { + std::swap( int_vect[ i ], int_vect[ j ] ); + } + } + } + else + { // nuovo metodo + std::vector< int > sorted_vect; + for ( int i = 0; i < indegree; i++ ) + { + int i1 = 0; + std::vector< int >::iterator iter; + int j; + do + { + j = rnd[ i1 * indegree + i ] % n_source; + // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup + // check if j is in target_vect + iter = std::lower_bound( sorted_vect.begin(), sorted_vect.end(), j ); + i1++; + } while ( iter != sorted_vect.end() && *iter == j ); // we found j + sorted_vect.insert( iter, j ); + int_vect.push_back( j ); + } + } + for ( int i = 0; i < indegree; i++ ) + { + int i_source_node = source.GetINode( int_vect[ i ] ); + int i_remote_node = -1; + for ( std::vector< ExternalConnectionNode >::iterator it = + connect_mpi_->extern_connection_[ i_source_node ].begin(); + it < connect_mpi_->extern_connection_[ i_source_node ].end(); + it++ ) + { + if ( ( *it ).target_host_id == target.i_host_ ) + { + i_remote_node = ( *it ).remote_node_id; + break; + } + } + if ( i_remote_node == -1 ) + { + i_remote_node = i_new_remote_node; + i_new_remote_node++; + ExternalConnectionNode conn_node = { target.i_host_, i_remote_node }; + connect_mpi_->extern_connection_[ i_source_node ].push_back( conn_node ); + } + i_remote_node_arr[ k * indegree + i ] = i_remote_node; + } } - connect_mpi_->MPI_Send_int(&i_new_remote_node, 1, target.i_host_); - connect_mpi_->MPI_Send_int(i_remote_node_arr, n_target*indegree, - target.i_host_); + connect_mpi_->MPI_Send_int( &i_new_remote_node, 1, target.i_host_ ); + connect_mpi_->MPI_Send_int( i_remote_node_arr, n_target * indegree, target.i_host_ ); delete[] rnd; } delete[] i_remote_node_arr; @@ -671,102 +744,119 @@ template } -template - int NESTGPU::_RemoteConnectFixedOutdegree - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int outdegree, SynSpec &syn_spec) +template < class T1, class T2 > +int +NESTGPU::_RemoteConnectFixedOutdegree( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int outdegree, + SynSpec& syn_spec ) { const int method_thresh = 5; - if (outdegree>n_target) { - throw ngpu_exception("Outdegree larger than number of target nodes"); + if ( outdegree > n_target ) + { + throw ngpu_exception( "Outdegree larger than number of target nodes" ); } - if (MpiId()==source.i_host_ && source.i_host_==target.i_host_) { - return _ConnectFixedOutdegree(source.i_node_, n_source, - target.i_node_, n_target, outdegree, - syn_spec); + if ( MpiId() == source.i_host_ && source.i_host_ == target.i_host_ ) + { + return _ConnectFixedOutdegree< T1, T2 >( source.i_node_, n_source, target.i_node_, n_target, outdegree, syn_spec ); } - else if (MpiId()==source.i_host_ || MpiId()==target.i_host_) { - int *i_remote_node_arr = new int[n_source]; - if (MpiId() == target.i_host_) { - connect_mpi_->MPI_Send_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(&n_remote_node_, 1, source.i_host_); - connect_mpi_->MPI_Recv_int(i_remote_node_arr, n_source, - source.i_host_); + else if ( MpiId() == source.i_host_ || MpiId() == target.i_host_ ) + { + int* i_remote_node_arr = new int[ n_source ]; + if ( MpiId() == target.i_host_ ) + { + connect_mpi_->MPI_Send_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( &n_remote_node_, 1, source.i_host_ ); + connect_mpi_->MPI_Recv_int( i_remote_node_arr, n_source, source.i_host_ ); int n_rnd = outdegree; - if (n_target>=method_thresh*outdegree) { // choose method - n_rnd *= 5; + if ( n_target >= method_thresh * outdegree ) + { // choose method + n_rnd *= 5; } - unsigned int *rnd = RandomInt(n_rnd); - - for (int isn=0; isn int_vect; - if (n_target sorted_vect; - for (int i=0; i::iterator iter; - int j; - do { - j = rnd[i1*outdegree + i] % n_target; - // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup - // check if j is in target_vect - iter = std::lower_bound(sorted_vect.begin(), - sorted_vect.end(), j); - i1++; - } while (iter != sorted_vect.end() && *iter == j); // we found j - sorted_vect.insert(iter, j); - int_vect.push_back(j); - } - } - for (int k=0; k(i_remote_node, target.i_node_, itn, - i_array, syn_spec); - } + unsigned int* rnd = RandomInt( n_rnd ); + + for ( int isn = 0; isn < n_source; isn++ ) + { + std::vector< int > int_vect; + if ( n_target < method_thresh * outdegree ) + { // choose method + // https://stackoverflow.com/questions/18625223 + // v = sequence(0, n_target-1) + int_vect.resize( n_target ); + int start = 0; + std::iota( int_vect.begin(), int_vect.end(), start ); + for ( int i = 0; i < outdegree; i++ ) + { + int j = i + rnd[ i ] % ( n_target - i ); + if ( j != i ) + { + std::swap( int_vect[ i ], int_vect[ j ] ); + } + } + } + else + { // other method + std::vector< int > sorted_vect; + for ( int i = 0; i < outdegree; i++ ) + { + int i1 = 0; + std::vector< int >::iterator iter; + int j; + do + { + j = rnd[ i1 * outdegree + i ] % n_target; + // https://riptutorial.com/cplusplus/example/7270/using-a-sorted-vector-for-fast-element-lookup + // check if j is in target_vect + iter = std::lower_bound( sorted_vect.begin(), sorted_vect.end(), j ); + i1++; + } while ( iter != sorted_vect.end() && *iter == j ); // we found j + sorted_vect.insert( iter, j ); + int_vect.push_back( j ); + } + } + for ( int k = 0; k < outdegree; k++ ) + { + int i_remote_node = i_remote_node_arr[ isn ]; + int itn = int_vect[ k ]; + size_t i_array = ( size_t ) isn * outdegree + k; + _RemoteSingleConnect< T2 >( i_remote_node, target.i_node_, itn, i_array, syn_spec ); + } } delete[] rnd; } - else if (MpiId() == source.i_host_) { + else if ( MpiId() == source.i_host_ ) + { int i_new_remote_node; - connect_mpi_->MPI_Recv_int(&i_new_remote_node, 1, target.i_host_); - for (int isn=0; isn::iterator it = - connect_mpi_->extern_connection_[i_source_node].begin(); - it < connect_mpi_->extern_connection_[i_source_node].end(); - it++) { - if ((*it).target_host_id == target.i_host_) { - i_remote_node = (*it).remote_node_id; - break; - } - } - if (i_remote_node == -1) { - i_remote_node = i_new_remote_node; - i_new_remote_node++; - ExternalConnectionNode conn_node = {target.i_host_, i_remote_node}; - connect_mpi_->extern_connection_[i_source_node].push_back(conn_node); - } - i_remote_node_arr[isn] = i_remote_node; + connect_mpi_->MPI_Recv_int( &i_new_remote_node, 1, target.i_host_ ); + for ( int isn = 0; isn < n_source; isn++ ) + { + int i_source_node = source.GetINode( isn ); + int i_remote_node = -1; + for ( std::vector< ExternalConnectionNode >::iterator it = + connect_mpi_->extern_connection_[ i_source_node ].begin(); + it < connect_mpi_->extern_connection_[ i_source_node ].end(); + it++ ) + { + if ( ( *it ).target_host_id == target.i_host_ ) + { + i_remote_node = ( *it ).remote_node_id; + break; + } + } + if ( i_remote_node == -1 ) + { + i_remote_node = i_new_remote_node; + i_new_remote_node++; + ExternalConnectionNode conn_node = { target.i_host_, i_remote_node }; + connect_mpi_->extern_connection_[ i_source_node ].push_back( conn_node ); + } + i_remote_node_arr[ isn ] = i_remote_node; } - connect_mpi_->MPI_Send_int(&i_new_remote_node, 1, target.i_host_); - connect_mpi_->MPI_Send_int(i_remote_node_arr, n_source, target.i_host_); + connect_mpi_->MPI_Send_int( &i_new_remote_node, 1, target.i_host_ ); + connect_mpi_->MPI_Send_int( i_remote_node_arr, n_source, target.i_host_ ); } delete[] i_remote_node_arr; } diff --git a/src/connect_spec.h b/src/connect_spec.h index c62827b93..efd7d6593 100644 --- a/src/connect_spec.h +++ b/src/connect_spec.h @@ -21,9 +21,6 @@ */ - - - #ifndef CONNECTSPEC_H #define CONNECTSPEC_H @@ -33,42 +30,51 @@ class NESTGPU; -template +template < class T > class RemoteNode { - public: +public: int i_host_; T i_node_; - RemoteNode(int i_host, T node): i_host_(i_host), i_node_(node) {} - int GetINode(int in); + RemoteNode( int i_host, T node ) + : i_host_( i_host ) + , i_node_( node ) + { + } + int GetINode( int in ); }; enum ConnectionRules - { - ONE_TO_ONE=0, ALL_TO_ALL, FIXED_TOTAL_NUMBER, FIXED_INDEGREE, - FIXED_OUTDEGREE, N_CONN_RULE - }; - -const std::string conn_rule_name[N_CONN_RULE] = - { - "one_to_one", "all_to_all", "fixed_total_number", "fixed_indegree", - "fixed_outdegree" +{ + ONE_TO_ONE = 0, + ALL_TO_ALL, + FIXED_TOTAL_NUMBER, + FIXED_INDEGREE, + FIXED_OUTDEGREE, + N_CONN_RULE }; +const std::string conn_rule_name[ N_CONN_RULE ] = { "one_to_one", + "all_to_all", + "fixed_total_number", + "fixed_indegree", + "fixed_outdegree" }; + class ConnSpec { int rule_; int total_num_; int indegree_; int outdegree_; + public: ConnSpec(); - ConnSpec(int rule, int degree=0); + ConnSpec( int rule, int degree = 0 ); int Init(); - int Init(int rule, int degree=0); - int SetParam(std::string param_name, int value); - int GetParam(std::string param_name); - static bool IsParam(std::string param_name); + int Init( int rule, int degree = 0 ); + int SetParam( std::string param_name, int value ); + int GetParam( std::string param_name ); + static bool IsParam( std::string param_name ); friend class NESTGPU; }; @@ -78,27 +84,29 @@ class SynSpec { unsigned char syn_group_; unsigned char port_; - public: + +public: int weight_distr_; - float *weight_array_; + float* weight_array_; float weight_; int delay_distr_; - float *delay_array_; + float* delay_array_; float delay_; - public: + +public: SynSpec(); - SynSpec(float weight, float delay); - SynSpec(int syn_group, float weight, float delay, int port=0); + SynSpec( float weight, float delay ); + SynSpec( int syn_group, float weight, float delay, int port = 0 ); int Init(); - int Init(float weight, float delay); - int Init(int syn_group, float weight, float delay, int port=0); - int SetParam(std::string param_name, int value); - int SetParam(std::string param_name, float value); - int SetParam(std::string param_name, float *array_pt); - float GetParam(std::string param_name); - static bool IsIntParam(std::string param_name); - static bool IsFloatParam(std::string param_name); - static bool IsFloatPtParam(std::string param_name); + int Init( float weight, float delay ); + int Init( int syn_group, float weight, float delay, int port = 0 ); + int SetParam( std::string param_name, int value ); + int SetParam( std::string param_name, float value ); + int SetParam( std::string param_name, float* array_pt ); + float GetParam( std::string param_name ); + static bool IsIntParam( std::string param_name ); + static bool IsFloatParam( std::string param_name ); + static bool IsFloatPtParam( std::string param_name ); friend class NESTGPU; }; diff --git a/src/cuda_error.h b/src/cuda_error.h index dfe0be6de..34e7737de 100644 --- a/src/cuda_error.h +++ b/src/cuda_error.h @@ -21,29 +21,45 @@ */ - - - #ifndef CUDAERROR_H #define CUDAERROR_H -#include #include "ngpu_exception.h" +#include -#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } -inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) +#define gpuErrchk( ans ) \ + { \ + gpuAssert( ( ans ), __FILE__, __LINE__ ); \ + } +inline void +gpuAssert( cudaError_t code, const char* file, int line, bool abort = true ) { - if (code != cudaSuccess) - { - fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); - if (abort) throw ngpu_exception("CUDA error"); - } + if ( code != cudaSuccess ) + { + fprintf( stderr, "GPUassert: %s %s %d\n", cudaGetErrorString( code ), file, line ); + if ( abort ) + { + throw ngpu_exception( "CUDA error" ); + } + } } -#define CUDA_CALL(x) do { if((x) != cudaSuccess) { \ - printf("Error at %s:%d\n",__FILE__,__LINE__); \ - throw ngpu_exception("CUDA error");}} while(0) -#define CURAND_CALL(x) do { if((x) != CURAND_STATUS_SUCCESS) { \ - printf("Error at %s:%d\n",__FILE__,__LINE__); \ - throw ngpu_exception("CUDA error");}} while(0) +#define CUDA_CALL( x ) \ + do \ + { \ + if ( ( x ) != cudaSuccess ) \ + { \ + printf( "Error at %s:%d\n", __FILE__, __LINE__ ); \ + throw ngpu_exception( "CUDA error" ); \ + } \ + } while ( 0 ) +#define CURAND_CALL( x ) \ + do \ + { \ + if ( ( x ) != CURAND_STATUS_SUCCESS ) \ + { \ + printf( "Error at %s:%d\n", __FILE__, __LINE__ ); \ + throw ngpu_exception( "CUDA error" ); \ + } \ + } while ( 0 ) #endif diff --git a/src/dir_connect.h b/src/dir_connect.h index 9831114e2..a8d59c797 100644 --- a/src/dir_connect.h +++ b/src/dir_connect.h @@ -21,9 +21,6 @@ */ - - - #ifndef DIRCONNECT_H #define DIRCONNECT_H diff --git a/src/dummyfile.cpp b/src/dummyfile.cpp index bc98828c0..6ad3bca41 100644 --- a/src/dummyfile.cpp +++ b/src/dummyfile.cpp @@ -1,5 +1,6 @@ #include -int dummy_function_for_nestgpu() +int +dummy_function_for_nestgpu() #include { #include diff --git a/src/ext_neuron.cu b/src/ext_neuron.cu index fcb98d426..710ea5ada 100644 --- a/src/ext_neuron.cu +++ b/src/ext_neuron.cu @@ -21,29 +21,25 @@ */ - - - -#include +#include "ext_neuron.h" #include +#include #include -#include "ext_neuron.h" using namespace ext_neuron_ns; -__global__ void UpdateExtNeuron(float *port_input_pt, float *port_value_pt, - int n_node, int n_var, int n_port_var, - int n_port) +__global__ void +UpdateExtNeuron( float* port_input_pt, float* port_value_pt, int n_node, int n_var, int n_port_var, int n_port ) { int i_thread = threadIdx.x + blockIdx.x * blockDim.x; - if (i_thread>> - (port_input_pt, port_value_pt, n_node_, n_var_, n_port_var_, n_port_); - //gpuErrchk( cudaDeviceSynchronize() ); - + float* port_input_pt = GetVarPt( 0, "port_input", 0 ); + float* port_value_pt = GetVarPt( 0, "port_value", 0 ); + + UpdateExtNeuron<<< ( n_node_ * n_port_ + 1023 ) / 1024, 1024 >>>( + port_input_pt, port_value_pt, n_node_, n_var_, n_port_var_, n_port_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int ext_neuron::Free() +int +ext_neuron::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } -float *ext_neuron::GetExtNeuronInputSpikes(int *n_node, int *n_port) +float* +ext_neuron::GetExtNeuronInputSpikes( int* n_node, int* n_port ) { - if ((int)ext_neuron_input_spikes_.size() -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace ext_neuron_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ N_SCAL_VAR = 0 }; -enum PortVarIndexes { +enum PortVarIndexes +{ i_port_input = 0, i_port_value, N_PORT_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_den_delay = 0, N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_port_weight = 0, N_PORT_PARAM }; -//const std::string *ext_neuron_scal_var_name[N_SCAL_VAR] = {}; +// const std::string *ext_neuron_scal_var_name[N_SCAL_VAR] = {}; -const std::string ext_neuron_port_var_name[N_PORT_VAR] = { - "port_input", "port_value" -}; +const std::string ext_neuron_port_var_name[ N_PORT_VAR ] = { "port_input", "port_value" }; -const std::string ext_neuron_scal_param_name[N_SCAL_PARAM] = { - "den_delay" -}; +const std::string ext_neuron_scal_param_name[ N_SCAL_PARAM ] = { "den_delay" }; -const std::string ext_neuron_port_param_name[N_PORT_PARAM] = { - "port_weight" -}; +const std::string ext_neuron_port_param_name[ N_PORT_PARAM ] = { "port_weight" }; } class ext_neuron : public BaseNeuron { - public: +public: ~ext_neuron(); - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + + // int Calibrate(double time_min, float time_resolution); - //int Calibrate(double time_min, float time_resolution); - - int Update(long long it, double t1); + int Update( long long it, double t1 ); int Free(); - float *GetExtNeuronInputSpikes(int *n_node, int *n_port); - + float* GetExtNeuronInputSpikes( int* n_node, int* n_port ); }; diff --git a/src/getRealTime.cu b/src/getRealTime.cu index ec1a6b60a..4ed0df496 100644 --- a/src/getRealTime.cu +++ b/src/getRealTime.cu @@ -21,9 +21,6 @@ */ - - - /* * Author: David Robert Nadeau * Site: http://NadeauSoftware.com/ @@ -31,16 +28,16 @@ * http://creativecommons.org/licenses/by/3.0/deed.en_US */ -#if defined(_WIN32) -#include +#if defined( _WIN32 ) #include +#include -#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) -#include /* POSIX flags */ -#include /* clock_gettime(), time() */ -#include /* gethrtime(), gettimeofday() */ +#elif defined( __unix__ ) || defined( __unix ) || defined( unix ) || ( defined( __APPLE__ ) && defined( __MACH__ ) ) +#include /* gethrtime(), gettimeofday() */ +#include /* clock_gettime(), time() */ +#include /* POSIX flags */ -#if defined(__MACH__) && defined(__APPLE__) +#if defined( __MACH__ ) && defined( __APPLE__ ) #include #include #endif @@ -50,9 +47,6 @@ #endif - - - /** * Returns the real time, in seconds, or -1.0 if an error occurred. * @@ -60,73 +54,74 @@ * The returned real time is only useful for computing an elapsed time * between two calls to this function. */ -double getRealTime( ) +double +getRealTime() { -#if defined(_WIN32) - FILETIME tm; - ULONGLONG t; -#if defined(NTDDI_WIN8) && NTDDI_VERSION >= NTDDI_WIN8 - /* Windows 8, Windows Server 2012 and later. ---------------- */ - GetSystemTimePreciseAsFileTime( &tm ); +#if defined( _WIN32 ) + FILETIME tm; + ULONGLONG t; +#if defined( NTDDI_WIN8 ) && NTDDI_VERSION >= NTDDI_WIN8 + /* Windows 8, Windows Server 2012 and later. ---------------- */ + GetSystemTimePreciseAsFileTime( &tm ); #else - /* Windows 2000 and later. ---------------------------------- */ - GetSystemTimeAsFileTime( &tm ); + /* Windows 2000 and later. ---------------------------------- */ + GetSystemTimeAsFileTime( &tm ); #endif - t = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime; - return (double)t / 10000000.0; - -#elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))) - /* HP-UX, Solaris. ------------------------------------------ */ - return (double)gethrtime( ) / 1000000000.0; - -#elif defined(__MACH__) && defined(__APPLE__) - /* OSX. ----------------------------------------------------- */ - static double timeConvert = 0.0; - if ( timeConvert == 0.0 ) - { - mach_timebase_info_data_t timeBase; - (void)mach_timebase_info( &timeBase ); - timeConvert = (double)timeBase.numer / - (double)timeBase.denom / - 1000000000.0; - } - return (double)mach_absolute_time( ) * timeConvert; - -#elif defined(_POSIX_VERSION) - /* POSIX. --------------------------------------------------- */ -#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) - { - struct timespec ts; -#if defined(CLOCK_MONOTONIC_PRECISE) - /* BSD. --------------------------------------------- */ - const clockid_t id = CLOCK_MONOTONIC_PRECISE; -#elif defined(CLOCK_MONOTONIC_RAW) - /* Linux. ------------------------------------------- */ - const clockid_t id = CLOCK_MONOTONIC_RAW; -#elif defined(CLOCK_HIGHRES) - /* Solaris. ----------------------------------------- */ - const clockid_t id = CLOCK_HIGHRES; -#elif defined(CLOCK_MONOTONIC) - /* AIX, BSD, Linux, POSIX, Solaris. ----------------- */ - const clockid_t id = CLOCK_MONOTONIC; -#elif defined(CLOCK_REALTIME) - /* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */ - const clockid_t id = CLOCK_REALTIME; + t = ( ( ULONGLONG ) tm.dwHighDateTime << 32 ) | ( ULONGLONG ) tm.dwLowDateTime; + return ( double ) t / 10000000.0; + +#elif ( defined( __hpux ) || defined( hpux ) ) \ + || ( ( defined( __sun__ ) || defined( __sun ) || defined( sun ) ) && ( defined( __SVR4 ) || defined( __svr4__ ) ) ) + /* HP-UX, Solaris. ------------------------------------------ */ + return ( double ) gethrtime() / 1000000000.0; + +#elif defined( __MACH__ ) && defined( __APPLE__ ) + /* OSX. ----------------------------------------------------- */ + static double timeConvert = 0.0; + if ( timeConvert == 0.0 ) + { + mach_timebase_info_data_t timeBase; + ( void ) mach_timebase_info( &timeBase ); + timeConvert = ( double ) timeBase.numer / ( double ) timeBase.denom / 1000000000.0; + } + return ( double ) mach_absolute_time() * timeConvert; + +#elif defined( _POSIX_VERSION ) + /* POSIX. --------------------------------------------------- */ +#if defined( _POSIX_TIMERS ) && ( _POSIX_TIMERS > 0 ) + { + struct timespec ts; +#if defined( CLOCK_MONOTONIC_PRECISE ) + /* BSD. --------------------------------------------- */ + const clockid_t id = CLOCK_MONOTONIC_PRECISE; +#elif defined( CLOCK_MONOTONIC_RAW ) + /* Linux. ------------------------------------------- */ + const clockid_t id = CLOCK_MONOTONIC_RAW; +#elif defined( CLOCK_HIGHRES ) + /* Solaris. ----------------------------------------- */ + const clockid_t id = CLOCK_HIGHRES; +#elif defined( CLOCK_MONOTONIC ) + /* AIX, BSD, Linux, POSIX, Solaris. ----------------- */ + const clockid_t id = CLOCK_MONOTONIC; +#elif defined( CLOCK_REALTIME ) + /* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */ + const clockid_t id = CLOCK_REALTIME; #else - const clockid_t id = (clockid_t)-1; /* Unknown. */ + const clockid_t id = ( clockid_t ) -1; /* Unknown. */ #endif /* CLOCK_* */ - if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) - return (double)ts.tv_sec + - (double)ts.tv_nsec / 1000000000.0; - /* Fall thru. */ - } + if ( id != ( clockid_t ) -1 && clock_gettime( id, &ts ) != -1 ) + { + return ( double ) ts.tv_sec + ( double ) ts.tv_nsec / 1000000000.0; + } + /* Fall thru. */ + } #endif /* _POSIX_TIMERS */ - /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ - struct timeval tm; - gettimeofday( &tm, NULL ); - return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0; + /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ + struct timeval tm; + gettimeofday( &tm, NULL ); + return ( double ) tm.tv_sec + ( double ) tm.tv_usec / 1000000.0; #else - return -1.0; /* Failed. */ + return -1.0; /* Failed. */ #endif } diff --git a/src/getRealTime.h b/src/getRealTime.h index 5dff62f2b..8f68b4946 100644 --- a/src/getRealTime.h +++ b/src/getRealTime.h @@ -21,9 +21,6 @@ */ - - - #ifndef GETREALTIME_H #define GETREALTIME_H diff --git a/src/get_spike.cu b/src/get_spike.cu index 7acc5050c..578a0a0a6 100644 --- a/src/get_spike.cu +++ b/src/get_spike.cu @@ -21,106 +21,103 @@ */ - - - #include #include +#include "cuda_error.h" #include "nestgpu.h" #include "node_group.h" #include "send_spike.h" #include "spike_buffer.h" -#include "cuda_error.h" extern __constant__ long long NESTGPUTimeIdx; extern __constant__ float NESTGPUTimeResolution; extern __constant__ NodeGroupStruct NodeGroupArray[]; -extern __device__ signed char *NodeGroupMap; +extern __device__ signed char* NodeGroupMap; -extern __device__ void SynapseUpdate(int syn_group, float *w, float Dt); +extern __device__ void SynapseUpdate( int syn_group, float* w, float Dt ); -__device__ double atomicAddDouble(double* address, double val) +__device__ double +atomicAddDouble( double* address, double val ) { - unsigned long long int* address_as_ull = - (unsigned long long int*)address; - unsigned long long int old = *address_as_ull, assumed; - do { - assumed = old; - old = atomicCAS(address_as_ull, assumed, - __double_as_longlong(val + - __longlong_as_double(assumed))); - } while (assumed != old); - return __longlong_as_double(old); + unsigned long long int* address_as_ull = ( unsigned long long int* ) address; + unsigned long long int old = *address_as_ull, assumed; + do + { + assumed = old; + old = atomicCAS( address_as_ull, assumed, __double_as_longlong( val + __longlong_as_double( assumed ) ) ); + } while ( assumed != old ); + return __longlong_as_double( old ); } ////////////////////////////////////////////////////////////////////// // This is the function called by the nested loop // that collects the spikes -__device__ void CollectSpikeFunction(int i_spike, int i_syn) +__device__ void +CollectSpikeFunction( int i_spike, int i_syn ) { - int i_source = SpikeSourceIdx[i_spike]; - int i_conn = SpikeConnIdx[i_spike]; - float height = SpikeHeight[i_spike]; - unsigned int target_port - = ConnectionGroupTargetNode[i_conn*NSpikeBuffer + i_source][i_syn]; + int i_source = SpikeSourceIdx[ i_spike ]; + int i_conn = SpikeConnIdx[ i_spike ]; + float height = SpikeHeight[ i_spike ]; + unsigned int target_port = ConnectionGroupTargetNode[ i_conn * NSpikeBuffer + i_source ][ i_syn ]; int i_target = target_port & PORT_MASK; - unsigned char port = (unsigned char)(target_port >> (PORT_N_SHIFT + 24)); - unsigned char syn_group - = ConnectionGroupTargetSynGroup[i_conn*NSpikeBuffer + i_source][i_syn]; - float weight = ConnectionGroupTargetWeight[i_conn*NSpikeBuffer+i_source] - [i_syn]; - //printf("handles spike %d src %d conn %d syn %d target %d" + unsigned char port = ( unsigned char ) ( target_port >> ( PORT_N_SHIFT + 24 ) ); + unsigned char syn_group = ConnectionGroupTargetSynGroup[ i_conn * NSpikeBuffer + i_source ][ i_syn ]; + float weight = ConnectionGroupTargetWeight[ i_conn * NSpikeBuffer + i_source ][ i_syn ]; + // printf("handles spike %d src %d conn %d syn %d target %d" //" port %d weight %f\n", - //i_spike, i_source, i_conn, i_syn, i_target, - //port, weight); - + // i_spike, i_source, i_conn, i_syn, i_target, + // port, weight); + ///////////////////////////////////////////////////////////////// - int i_group=NodeGroupMap[i_target]; - int i = port*NodeGroupArray[i_group].n_node_ + i_target - - NodeGroupArray[i_group].i_node_0_; - double d_val = (double)(height*weight); - - atomicAddDouble(&NodeGroupArray[i_group].get_spike_array_[i], d_val); - if (syn_group>0) { - ConnectionGroupTargetSpikeTime[i_conn*NSpikeBuffer+i_source][i_syn] - = (unsigned short)(NESTGPUTimeIdx & 0xffff); - - long long Dt_int = NESTGPUTimeIdx - LastRevSpikeTimeIdx[i_target]; - if (Dt_int>0 && Dt_int 0 ) + { + ConnectionGroupTargetSpikeTime[ i_conn * NSpikeBuffer + i_source ][ i_syn ] = + ( unsigned short ) ( NESTGPUTimeIdx & 0xffff ); + + long long Dt_int = NESTGPUTimeIdx - LastRevSpikeTimeIdx[ i_target ]; + if ( Dt_int > 0 && Dt_int < MAX_SYN_DT ) + { + SynapseUpdate( syn_group, + &ConnectionGroupTargetWeight[ i_conn * NSpikeBuffer + i_source ][ i_syn ], + -NESTGPUTimeResolution * Dt_int ); } } //////////////////////////////////////////////////////////////// } -__global__ void CollectSpikeKernel(int n_spikes, int *SpikeTargetNum) +__global__ void +CollectSpikeKernel( int n_spikes, int* SpikeTargetNum ) { const int i_spike = blockIdx.x; - if (i_spikeget_spike_array_ != NULL) { - gpuErrchk(cudaMemsetAsync(bn->get_spike_array_, 0, bn->n_node_*bn->n_port_ - *sizeof(double))); + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + BaseNeuron* bn = node_vect_[ i ]; + if ( bn->get_spike_array_ != NULL ) + { + gpuErrchk( cudaMemsetAsync( bn->get_spike_array_, 0, bn->n_node_ * bn->n_port_ * sizeof( double ) ) ); } } - + return 0; } -int NESTGPU::FreeGetSpikeArrays() +int +NESTGPU::FreeGetSpikeArrays() { - for (unsigned int i=0; iget_spike_array_ != NULL) { - gpuErrchk(cudaFree(bn->get_spike_array_)); + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + BaseNeuron* bn = node_vect_[ i ]; + if ( bn->get_spike_array_ != NULL ) + { + gpuErrchk( cudaFree( bn->get_spike_array_ ) ); } } - + return 0; } diff --git a/src/get_spike.h b/src/get_spike.h index b3ca3d78c..5bbf304db 100644 --- a/src/get_spike.h +++ b/src/get_spike.h @@ -21,22 +21,21 @@ */ - - - #ifndef GETSPIKE_H #define GETSPIKE_H -__global__ void GetSpikes(double *spike_array, int array_size, int n_port, - int n_var, - float *port_weight_arr, - int port_weight_arr_step, - int port_weight_port_step, //float *y_arr); - float *port_input_arr, - int port_input_arr_step, - int port_input_port_step); +__global__ void GetSpikes( double* spike_array, + int array_size, + int n_port, + int n_var, + float* port_weight_arr, + int port_weight_arr_step, + int port_weight_port_step, // float *y_arr); + float* port_input_arr, + int port_input_arr_step, + int port_input_port_step ); -__global__ void CollectSpikeKernel(int n_spikes, int *SpikeTargetNum); +__global__ void CollectSpikeKernel( int n_spikes, int* SpikeTargetNum ); #endif diff --git a/src/iaf_psc_alpha.cu b/src/iaf_psc_alpha.cu index 5e2036716..8718c128f 100644 --- a/src/iaf_psc_alpha.cu +++ b/src/iaf_psc_alpha.cu @@ -21,67 +21,65 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_alpha.cpp -#include -#include -#include #include "iaf_psc_alpha.h" #include "propagator_stability.h" #include "spike_buffer.h" +#include +#include +#include using namespace iaf_psc_alpha_ns; extern __constant__ float NESTGPUTimeResolution; -extern __device__ double propagator_31(double, double, double, double); -extern __device__ double propagator_32(double, double, double, double); - -#define I_ex var[i_I_ex] -#define I_in var[i_I_in] -#define dI_ex var[i_dI_ex] -#define dI_in var[i_dI_in] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] - -#define tau_m param[i_tau_m] -#define C_m param[i_C_m] -#define E_L param[i_E_L] -#define I_e param[i_I_e] -#define Theta_rel param[i_Theta_rel] -#define V_reset_rel param[i_V_reset_rel] -#define tau_ex param[i_tau_ex] -#define tau_in param[i_tau_in] -#define t_ref param[i_t_ref] -#define den_delay param[i_den_delay] - -#define P11ex param[i_P11ex] -#define P11in param[i_P11in] -#define P21ex param[i_P21ex] -#define P21in param[i_P21in] -#define P22ex param[i_P22ex] -#define P22in param[i_P22in] -#define P31ex param[i_P31ex] -#define P31in param[i_P31in] -#define P32ex param[i_P32ex] -#define P32in param[i_P32in] -#define P30 param[i_P30] -#define P33 param[i_P33] -#define expm1_tau_m param[i_expm1_tau_m] -#define EPSCInitialValue param[i_EPSCInitialValue] -#define IPSCInitialValue param[i_IPSCInitialValue] - - -__global__ void iaf_psc_alpha_Calibrate(int n_node, float *param_arr, - int n_param, float h) +extern __device__ double propagator_31( double, double, double, double ); +extern __device__ double propagator_32( double, double, double, double ); + +#define I_ex var[ i_I_ex ] +#define I_in var[ i_I_in ] +#define dI_ex var[ i_dI_ex ] +#define dI_in var[ i_dI_in ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] + +#define tau_m param[ i_tau_m ] +#define C_m param[ i_C_m ] +#define E_L param[ i_E_L ] +#define I_e param[ i_I_e ] +#define Theta_rel param[ i_Theta_rel ] +#define V_reset_rel param[ i_V_reset_rel ] +#define tau_ex param[ i_tau_ex ] +#define tau_in param[ i_tau_in ] +#define t_ref param[ i_t_ref ] +#define den_delay param[ i_den_delay ] + +#define P11ex param[ i_P11ex ] +#define P11in param[ i_P11in ] +#define P21ex param[ i_P21ex ] +#define P21in param[ i_P21in ] +#define P22ex param[ i_P22ex ] +#define P22in param[ i_P22in ] +#define P31ex param[ i_P31ex ] +#define P31in param[ i_P31in ] +#define P32ex param[ i_P32ex ] +#define P32in param[ i_P32in ] +#define P30 param[ i_P30 ] +#define P33 param[ i_P33 ] +#define expm1_tau_m param[ i_expm1_tau_m ] +#define EPSCInitialValue param[ i_EPSCInitialValue ] +#define IPSCInitialValue param[ i_IPSCInitialValue ] + + +__global__ void +iaf_psc_alpha_Calibrate( int n_node, float* param_arr, int n_param, float h ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V - V_m_rel = P30 * I_e + P31ex * dI_ex + P32ex * I_ex - + P31in * dI_in + P32in * I_in + expm1_tau_m * V_m_rel + V_m_rel; + else + { // neuron is not refractory, so evolve V + V_m_rel = + P30 * I_e + P31ex * dI_ex + P32ex * I_ex + P31in * dI_in + P32in * I_in + expm1_tau_m * V_m_rel + V_m_rel; } - + // alpha shape PSCs I_ex = P21ex * dI_ex + P22ex * I_ex; dI_ex *= P11ex; @@ -127,10 +127,11 @@ __global__ void iaf_psc_alpha_Update(int n_node, int i_node_0, float *var_arr, I_in = P21in * dI_in + P22in * I_in; dI_in *= P11in; - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; - refractory_step = (int)round(t_ref/NESTGPUTimeResolution); + refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution ); } } } @@ -141,90 +142,92 @@ iaf_psc_alpha::~iaf_psc_alpha() FreeParamArr(); } -int iaf_psc_alpha::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +iaf_psc_alpha::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_iaf_psc_alpha_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = iaf_psc_alpha_scal_var_name; scal_param_name_ = iaf_psc_alpha_scal_param_name; - SetScalParam(0, n_node, "tau_m", 10.0 ); // in ms - SetScalParam(0, n_node, "C_m", 250.0 ); // in pF - SetScalParam(0, n_node, "E_L", -70.0 ); // in mV - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "Theta_rel", -55.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "V_reset_rel", -70.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "tau_syn_ex", 2.0 ); // in ms - SetScalParam(0, n_node, "tau_syn_in", 2.0 ); // in ms - SetScalParam(0, n_node, "t_ref", 2.0 ); // in ms - SetScalParam(0, n_node, "den_delay", 0.0); // in ms - SetScalParam(0, n_node, "P11ex", 0.0); - SetScalParam(0, n_node, "P11in", 0.0); - SetScalParam(0, n_node, "P21ex", 0.0); - SetScalParam(0, n_node, "P21in", 0.0); - SetScalParam(0, n_node, "P22ex", 0.0); - SetScalParam(0, n_node, "P22in", 0.0); - SetScalParam(0, n_node, "P31ex", 0.0); - SetScalParam(0, n_node, "P31in", 0.0); - SetScalParam(0, n_node, "P32ex", 0.0); - SetScalParam(0, n_node, "P32in", 0.0); - SetScalParam(0, n_node, "P30", 0.0); - SetScalParam(0, n_node, "P33", 0.0); - SetScalParam(0, n_node, "EPSCInitialValue", 0.0); - SetScalParam(0, n_node, "IPSCInitialValue", 0.0); - - SetScalVar(0, n_node, "I_syn_ex", 0.0 ); - SetScalVar(0, n_node, "dI_ex", 0.0 ); - SetScalVar(0, n_node, "I_syn_in", 0.0 ); - SetScalVar(0, n_node, "dI_in", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", -70.0 - (-70.0) ); // in mV, relative to E_L - SetScalVar(0, n_node, "refractory_step", 0 ); - - port_weight_arr_ = GetParamArr() + GetScalParamIdx("EPSCInitialValue"); + SetScalParam( 0, n_node, "tau_m", 10.0 ); // in ms + SetScalParam( 0, n_node, "C_m", 250.0 ); // in pF + SetScalParam( 0, n_node, "E_L", -70.0 ); // in mV + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "Theta_rel", -55.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "V_reset_rel", -70.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "tau_syn_ex", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_syn_in", 2.0 ); // in ms + SetScalParam( 0, n_node, "t_ref", 2.0 ); // in ms + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + SetScalParam( 0, n_node, "P11ex", 0.0 ); + SetScalParam( 0, n_node, "P11in", 0.0 ); + SetScalParam( 0, n_node, "P21ex", 0.0 ); + SetScalParam( 0, n_node, "P21in", 0.0 ); + SetScalParam( 0, n_node, "P22ex", 0.0 ); + SetScalParam( 0, n_node, "P22in", 0.0 ); + SetScalParam( 0, n_node, "P31ex", 0.0 ); + SetScalParam( 0, n_node, "P31in", 0.0 ); + SetScalParam( 0, n_node, "P32ex", 0.0 ); + SetScalParam( 0, n_node, "P32in", 0.0 ); + SetScalParam( 0, n_node, "P30", 0.0 ); + SetScalParam( 0, n_node, "P33", 0.0 ); + SetScalParam( 0, n_node, "EPSCInitialValue", 0.0 ); + SetScalParam( 0, n_node, "IPSCInitialValue", 0.0 ); + + SetScalVar( 0, n_node, "I_syn_ex", 0.0 ); + SetScalVar( 0, n_node, "dI_ex", 0.0 ); + SetScalVar( 0, n_node, "I_syn_in", 0.0 ); + SetScalVar( 0, n_node, "dI_in", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", -70.0 - ( -70.0 ) ); // in mV, relative to E_L + SetScalVar( 0, n_node, "refractory_step", 0 ); + + port_weight_arr_ = GetParamArr() + GetScalParamIdx( "EPSCInitialValue" ); port_weight_arr_step_ = n_param_; port_weight_port_step_ = 1; - port_input_arr_ = GetVarArr() + GetScalVarIdx("dI_ex"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "dI_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 iaf_psc_alpha::Update(long long it, double t1) +int +iaf_psc_alpha::Update( long long it, double t1 ) { // std::cout << "iaf_psc_alpha neuron update\n"; - iaf_psc_alpha_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); + iaf_psc_alpha_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); // gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -int iaf_psc_alpha::Free() +int +iaf_psc_alpha::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } -int iaf_psc_alpha::Calibrate(double, float time_resolution) +int +iaf_psc_alpha::Calibrate( double, float time_resolution ) { - iaf_psc_alpha_Calibrate<<<(n_node_+1023)/1024, 1024>>> - (n_node_, param_arr_, n_param_, time_resolution); + iaf_psc_alpha_Calibrate<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, param_arr_, n_param_, time_resolution ); return 0; } diff --git a/src/iaf_psc_alpha.h b/src/iaf_psc_alpha.h index e49393c2e..8456f3f15 100644 --- a/src/iaf_psc_alpha.h +++ b/src/iaf_psc_alpha.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_alpha.h @@ -31,12 +28,12 @@ #ifndef IAFPSCALPHA_H #define IAFPSCALPHA_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include /* BeginUserDocs: neuron, integrate-and-fire, current-based @@ -106,7 +103,7 @@ References DOI: https://doi.org/10.1007/s004220050570 .. [2] Potjans TC. and Diesmann M. 2014. The cell-type specific cortical microcircuit: relating structure and activity in a full-scale spiking - network model. Cerebral Cortex. 24(3):785–806. + network model. Cerebral Cortex. 24(3):785–806. DOI: https://doi.org/10.1093/cercor/bhs358. See also @@ -119,29 +116,31 @@ EndUserDocs */ namespace iaf_psc_alpha_ns { -enum ScalVarIndexes { - i_I_ex = 0, // postsynaptic current for exc. inputs - i_I_in, // postsynaptic current for inh. inputs +enum ScalVarIndexes +{ + i_I_ex = 0, // postsynaptic current for exc. inputs + i_I_in, // postsynaptic current for inh. inputs i_dI_ex, i_dI_in, - i_V_m_rel, // membrane potential - i_refractory_step, // refractory step counter + i_V_m_rel, // membrane potential + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_I_e, // External current in pA - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_ex, // Time constant of excitatory synaptic current in ms - i_tau_in, // Time constant of inhibitory synaptic current in ms +enum ScalParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_I_e, // External current in pA + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_ex, // Time constant of excitatory synaptic current in ms + i_tau_in, // Time constant of inhibitory synaptic current in ms // i_rho, // Stochastic firing intensity at threshold in 1/s // i_delta, // Width of threshold region in mV - i_t_ref, // Refractory period in ms + i_t_ref, // Refractory period in ms i_den_delay, // dendritic backpropagation delay // time evolution operator i_P11ex, @@ -162,19 +161,16 @@ enum ScalParamIndexes { N_SCAL_PARAM }; - -const std::string iaf_psc_alpha_scal_var_name[N_SCAL_VAR] = { - "I_syn_ex", + +const std::string iaf_psc_alpha_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex", "I_syn_in", "dI_ex", "dI_in", "V_m_rel", - "refractory_step" -}; + "refractory_step" }; -const std::string iaf_psc_alpha_scal_param_name[N_SCAL_PARAM] = { - "tau_m", +const std::string iaf_psc_alpha_scal_param_name[ N_SCAL_PARAM ] = { "tau_m", "C_m", "E_L", "I_e", @@ -198,25 +194,22 @@ const std::string iaf_psc_alpha_scal_param_name[N_SCAL_PARAM] = { "P33", "expm1_tau_m", "EPSCInitialValue", - "IPSCInitialValue" -}; + "IPSCInitialValue" }; } // namespace - + class iaf_psc_alpha : public BaseNeuron { - public: +public: ~iaf_psc_alpha(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double, float time_resolution); - - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Calibrate( double, float time_resolution ); + int Update( long long it, double t1 ); + + int Free(); }; diff --git a/src/iaf_psc_exp.cu b/src/iaf_psc_exp.cu index 38028184f..77df17b81 100644 --- a/src/iaf_psc_exp.cu +++ b/src/iaf_psc_exp.cu @@ -21,91 +21,93 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.cpp -#include -#include -#include #include "iaf_psc_exp.h" -#include "spike_buffer.h" #include "propagator_stability.h" +#include "spike_buffer.h" +#include +#include +#include using namespace iaf_psc_exp_ns; extern __constant__ float NESTGPUTimeResolution; -extern __device__ double propagator_32(double, double, double, double); - -#define I_syn_ex var[i_I_syn_ex] -#define I_syn_in var[i_I_syn_in] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] - -#define tau_m param[i_tau_m] -#define C_m param[i_C_m] -#define E_L param[i_E_L] -#define I_e param[i_I_e] -#define Theta_rel param[i_Theta_rel] -#define V_reset_rel param[i_V_reset_rel] -#define tau_ex param[i_tau_ex] -#define tau_in param[i_tau_in] -//#define rho param[i_rho] -//#define delta param[i_delta] -#define t_ref param[i_t_ref] -#define den_delay param[i_den_delay] - -#define P20 param[i_P20] -#define P11ex param[i_P11ex] -#define P11in param[i_P11in] -#define P21ex param[i_P21ex] -#define P21in param[i_P21in] -#define P22 param[i_P22] - - -__global__ void iaf_psc_exp_Calibrate(int n_node, float *param_arr, - int n_param, float h) +extern __device__ double propagator_32( double, double, double, double ); + +#define I_syn_ex var[ i_I_syn_ex ] +#define I_syn_in var[ i_I_syn_in ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] + +#define tau_m param[ i_tau_m ] +#define C_m param[ i_C_m ] +#define E_L param[ i_E_L ] +#define I_e param[ i_I_e ] +#define Theta_rel param[ i_Theta_rel ] +#define V_reset_rel param[ i_V_reset_rel ] +#define tau_ex param[ i_tau_ex ] +#define tau_in param[ i_tau_in ] +// #define rho param[i_rho] +// #define delta param[i_delta] +#define t_ref param[ i_t_ref ] +#define den_delay param[ i_den_delay ] + +#define P20 param[ i_P20 ] +#define P11ex param[ i_P11ex ] +#define P11in param[ i_P11in ] +#define P21ex param[ i_P21ex ] +#define P21in param[ i_P21in ] +#define P22 param[ i_P22 ] + + +__global__ void +iaf_psc_exp_Calibrate( int n_node, float* param_arr, int n_param, float h ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn_ex * P21ex + I_syn_in * P21in + I_e * P20; } // exponential decaying PSCs I_syn_ex *= P11ex; I_syn_in *= P11in; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; - refractory_step = (int)round(t_ref/NESTGPUTimeResolution); - } + refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution ); + } } } @@ -115,87 +117,88 @@ iaf_psc_exp::~iaf_psc_exp() FreeParamArr(); } -int iaf_psc_exp::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +iaf_psc_exp::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_iaf_psc_exp_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = iaf_psc_exp_scal_var_name; scal_param_name_ = iaf_psc_exp_scal_param_name; - SetScalParam(0, n_node, "tau_m", 10.0 ); // in ms - SetScalParam(0, n_node, "C_m", 250.0 ); // in pF - SetScalParam(0, n_node, "E_L", -70.0 ); // in mV - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "Theta_rel", -55.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "V_reset_rel", -70.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "tau_ex", 2.0 ); // in ms - SetScalParam(0, n_node, "tau_in", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_m", 10.0 ); // in ms + SetScalParam( 0, n_node, "C_m", 250.0 ); // in pF + SetScalParam( 0, n_node, "E_L", -70.0 ); // in mV + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "Theta_rel", -55.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "V_reset_rel", -70.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "tau_ex", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_in", 2.0 ); // in ms // SetScalParam(0, n_node, "rho", 0.01 ); // in 1/s // SetScalParam(0, n_node, "delta", 0.0 ); // in mV - SetScalParam(0, n_node, "t_ref", 2.0 ); // in ms - SetScalParam(0, n_node, "den_delay", 0.0); // in ms - SetScalParam(0, n_node, "P20", 0.0); - SetScalParam(0, n_node, "P11ex", 0.0); - SetScalParam(0, n_node, "P11in", 0.0); - SetScalParam(0, n_node, "P21ex", 0.0); - SetScalParam(0, n_node, "P21in", 0.0); - SetScalParam(0, n_node, "P22", 0.0); - - SetScalVar(0, n_node, "I_syn_ex", 0.0 ); - SetScalVar(0, n_node, "I_syn_in", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", -70.0 - (-70.0) ); // in mV, relative to E_L - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalParam( 0, n_node, "t_ref", 2.0 ); // in ms + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + SetScalParam( 0, n_node, "P20", 0.0 ); + SetScalParam( 0, n_node, "P11ex", 0.0 ); + SetScalParam( 0, n_node, "P11in", 0.0 ); + SetScalParam( 0, n_node, "P21ex", 0.0 ); + SetScalParam( 0, n_node, "P21in", 0.0 ); + SetScalParam( 0, n_node, "P22", 0.0 ); + + SetScalVar( 0, n_node, "I_syn_ex", 0.0 ); + SetScalVar( 0, n_node, "I_syn_in", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", -70.0 - ( -70.0 ) ); // in mV, relative to E_L + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn_ex, I_syn_in - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn_ex"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_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 iaf_psc_exp::Update(long long it, double t1) +int +iaf_psc_exp::Update( long long it, double t1 ) { // std::cout << "iaf_psc_exp neuron update\n"; - iaf_psc_exp_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); + iaf_psc_exp_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); // gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -int iaf_psc_exp::Free() +int +iaf_psc_exp::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } -int iaf_psc_exp::Calibrate(double, float time_resolution) +int +iaf_psc_exp::Calibrate( double, float time_resolution ) { - iaf_psc_exp_Calibrate<<<(n_node_+1023)/1024, 1024>>> - (n_node_, param_arr_, n_param_, time_resolution); + iaf_psc_exp_Calibrate<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, param_arr_, n_param_, time_resolution ); return 0; } diff --git a/src/iaf_psc_exp.h b/src/iaf_psc_exp.h index 15ee5a769..d8ef9da1a 100644 --- a/src/iaf_psc_exp.h +++ b/src/iaf_psc_exp.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,12 +28,12 @@ #ifndef IAFPSCEXP_H #define IAFPSCEXP_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include /* BeginUserDocs: neuron, integrate-and-fire, current-based @@ -50,7 +47,7 @@ Description +++++++++++ iaf_psc_exp is an implementation of a leaky integrate-and-fire model -with exponential shaped postsynaptic currents (PSCs) according to +with exponential shaped postsynaptic currents (PSCs) according to equations 1, 2, 4 and 5 of [1]_ and equation 3 of [2]_. Thus, postsynaptic currents have an infinitely short rise time. @@ -109,7 +106,7 @@ References DOI: https://doi.org/10.1007/s004220050570 .. [4] Potjans TC. and Diesmann M. 2014. The cell-type specific cortical microcircuit: relating structure and activity in a full-scale spiking - network model. Cerebral Cortex. 24(3):785–806. + network model. Cerebral Cortex. 24(3):785–806. DOI: https://doi.org/10.1093/cercor/bhs358. See also @@ -122,27 +119,29 @@ EndUserDocs */ namespace iaf_psc_exp_ns { -enum ScalVarIndexes { - i_I_syn_ex = 0, // postsynaptic current for exc. inputs - i_I_syn_in, // postsynaptic current for inh. inputs - i_V_m_rel, // membrane potential - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn_ex = 0, // postsynaptic current for exc. inputs + i_I_syn_in, // postsynaptic current for inh. inputs + i_V_m_rel, // membrane potential + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_I_e, // External current in pA - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_ex, // Time constant of excitatory synaptic current in ms - i_tau_in, // Time constant of inhibitory synaptic current in ms +enum ScalParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_I_e, // External current in pA + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_ex, // Time constant of excitatory synaptic current in ms + i_tau_in, // Time constant of inhibitory synaptic current in ms // i_rho, // Stochastic firing intensity at threshold in 1/s // i_delta, // Width of threshold region in mV - i_t_ref, // Refractory period in ms + i_t_ref, // Refractory period in ms i_den_delay, // dendritic backpropagation delay // time evolution operator i_P20, @@ -154,17 +153,11 @@ enum ScalParamIndexes { N_SCAL_PARAM }; - -const std::string iaf_psc_exp_scal_var_name[N_SCAL_VAR] = { - "I_syn_ex", - "I_syn_in", - "V_m_rel", - "refractory_step" -}; + +const std::string iaf_psc_exp_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex", "I_syn_in", "V_m_rel", "refractory_step" }; -const std::string iaf_psc_exp_scal_param_name[N_SCAL_PARAM] = { - "tau_m", +const std::string iaf_psc_exp_scal_param_name[ N_SCAL_PARAM ] = { "tau_m", "C_m", "E_L", "I_e", @@ -181,25 +174,22 @@ const std::string iaf_psc_exp_scal_param_name[N_SCAL_PARAM] = { "P11in", "P21ex", "P21in", - "P22" -}; + "P22" }; } // namespace - + class iaf_psc_exp : public BaseNeuron { - public: +public: ~iaf_psc_exp(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double, float time_resolution); - - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Calibrate( double, float time_resolution ); + int Update( long long it, double t1 ); + + int Free(); }; diff --git a/src/iaf_psc_exp_g.cu b/src/iaf_psc_exp_g.cu index 598f188b9..76a273d11 100644 --- a/src/iaf_psc_exp_g.cu +++ b/src/iaf_psc_exp_g.cu @@ -21,73 +21,82 @@ */ - - - -#include -#include -#include #include "iaf_psc_exp_g.h" #include "spike_buffer.h" +#include +#include +#include using namespace iaf_psc_exp_g_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] - -#define tau_m_ group_param_[i_tau_m] -#define C_m_ group_param_[i_C_m] -#define E_L_ group_param_[i_E_L] -#define Theta_rel_ group_param_[i_Theta_rel] -#define V_reset_rel_ group_param_[i_V_reset_rel] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void iaf_psc_exp_g_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float Theta_rel, float V_reset_rel, int n_refractory_steps, - float P11, float P22, float P21, float P20 ) +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] + +#define tau_m_ group_param_[ i_tau_m ] +#define C_m_ group_param_[ i_C_m ] +#define E_L_ group_param_[ i_E_L ] +#define Theta_rel_ group_param_[ i_Theta_rel ] +#define V_reset_rel_ group_param_[ i_V_reset_rel ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +iaf_psc_exp_g_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float Theta_rel, + float V_reset_rel, + int n_refractory_steps, + float P11, + float P22, + float P21, + float P20 ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } -double h_propagator_32( double tau_syn, double tau, double C, double h ) +double +h_propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -103,10 +112,10 @@ iaf_psc_exp_g::~iaf_psc_exp_g() FreeParamArr(); } -int iaf_psc_exp_g::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +iaf_psc_exp_g::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_iaf_psc_exp_g_model; n_scal_var_ = N_SCAL_VAR; @@ -114,46 +123,46 @@ int iaf_psc_exp_g::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = iaf_psc_exp_g_scal_var_name; scal_param_name_ = iaf_psc_exp_g_scal_param_name; group_param_name_ = iaf_psc_exp_g_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); - SetGroupParam("tau_m", 10.0); - SetGroupParam("C_m", 250.0); - SetGroupParam("E_L", -65.0); - SetGroupParam("Theta_rel", 15.0); - SetGroupParam("V_reset_rel", 0.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 2.0); + SetGroupParam( "tau_m", 10.0 ); + SetGroupParam( "C_m", 250.0 ); + SetGroupParam( "E_L", -65.0 ); + SetGroupParam( "Theta_rel", 15.0 ); + SetGroupParam( "V_reset_rel", 0.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 2.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int iaf_psc_exp_g::Update(long long it, double t1) +int +iaf_psc_exp_g::Update( long long it, double t1 ) { // std::cout << "iaf_psc_exp_g neuron update\n"; float h = time_resolution_; @@ -161,21 +170,32 @@ int iaf_psc_exp_g::Update(long long it, double t1) float P22 = exp( -h / tau_m_ ); float P21 = h_propagator_32( tau_syn_, tau_m_, C_m_, h ); float P20 = tau_m_ / C_m_ * ( 1.0 - P22 ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + iaf_psc_exp_g_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, + i_node_0_, + var_arr_, + param_arr_, + n_var_, + n_param_, + Theta_rel_, + V_reset_rel_, + n_refractory_steps, + P11, + P22, + P21, + P20 ); + // gpuErrchk( cudaDeviceSynchronize() ); - iaf_psc_exp_g_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - Theta_rel_, V_reset_rel_, n_refractory_steps, P11, P22, P21, P20 ); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int iaf_psc_exp_g::Free() +int +iaf_psc_exp_g::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/iaf_psc_exp_g.h b/src/iaf_psc_exp_g.h index 37c290f3e..a2c6f378c 100644 --- a/src/iaf_psc_exp_g.h +++ b/src/iaf_psc_exp_g.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,12 +28,12 @@ #ifndef IAFPSCEXPG_H #define IAFPSCEXPG_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include /* BeginUserDocs: neuron, integrate-and-fire, current-based @@ -50,7 +47,7 @@ Description +++++++++++ iaf_psc_exp_g is an implementation of a leaky integrate-and-fire model -with exponential shaped postsynaptic currents (PSCs) according to +with exponential shaped postsynaptic currents (PSCs) according to equations 1, 2, 4 and 5 of [1]_ and equation 3 of [2]_. Thus, postsynaptic currents have an infinitely short rise time. @@ -116,7 +113,7 @@ References DOI: https://doi.org/10.1007/s004220050570 .. [4] Potjans TC. and Diesmann M. 2014. The cell-type specific cortical microcircuit: relating structure and activity in a full-scale spiking - network model. Cerebral Cortex. 24(3):785–806. + network model. Cerebral Cortex. 24(3):785–806. DOI: https://doi.org/10.1093/cercor/bhs358. See also @@ -129,75 +126,67 @@ EndUserDocs */ namespace iaf_psc_exp_g_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; -enum GroupParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms +enum GroupParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string iaf_psc_exp_g_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string iaf_psc_exp_g_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string iaf_psc_exp_g_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string iaf_psc_exp_g_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; -const std::string iaf_psc_exp_g_group_param_name[N_GROUP_PARAM] = { - "tau_m", +const std::string iaf_psc_exp_g_group_param_name[ N_GROUP_PARAM ] = { "tau_m", "C_m", "E_L", "Theta_rel", "V_reset_rel", "tau_syn", - "t_ref" -}; - -} // namespace - + "t_ref" }; +} // namespace class iaf_psc_exp_g : public BaseNeuron { float time_resolution_; - public: +public: ~iaf_psc_exp_g(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/iaf_psc_exp_hc.cu b/src/iaf_psc_exp_hc.cu index dbabfcbdd..63ea8b200 100644 --- a/src/iaf_psc_exp_hc.cu +++ b/src/iaf_psc_exp_hc.cu @@ -21,50 +21,50 @@ */ - - - -#include -#include -#include #include "iaf_psc_exp_hc.h" #include "spike_buffer.h" +#include +#include +#include using namespace iaf_psc_exp_hc_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] #include "iaf_psc_exp_hc_params.h" -__global__ void iaf_psc_exp_hc_Update(int n_node, int i_node_0, - float *var_arr, float *param_arr, - int n_var, int n_param) +__global__ void +iaf_psc_exp_hc_Update( int n_node, int i_node_0, float* var_arr, float* param_arr, int n_var, int n_param ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } @@ -74,59 +74,60 @@ iaf_psc_exp_hc::~iaf_psc_exp_hc() FreeParamArr(); } -int iaf_psc_exp_hc::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +iaf_psc_exp_hc::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_iaf_psc_exp_hc_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = iaf_psc_exp_hc_scal_var_name; scal_param_name_ = iaf_psc_exp_hc_scal_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int iaf_psc_exp_hc::Update(long long it, double t1) +int +iaf_psc_exp_hc::Update( long long it, double t1 ) { // std::cout << "iaf_psc_exp_hc neuron update\n"; - iaf_psc_exp_hc_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaDeviceSynchronize() ); - + iaf_psc_exp_hc_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int iaf_psc_exp_hc::Free() +int +iaf_psc_exp_hc::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } diff --git a/src/iaf_psc_exp_hc.h b/src/iaf_psc_exp_hc.h index 75899907b..f71de220a 100644 --- a/src/iaf_psc_exp_hc.h +++ b/src/iaf_psc_exp_hc.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,53 +28,47 @@ #ifndef IAFPSCEXPHC_H #define IAFPSCEXPHC_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace iaf_psc_exp_hc_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; - const std::string iaf_psc_exp_hc_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string iaf_psc_exp_hc_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string iaf_psc_exp_hc_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string iaf_psc_exp_hc_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; } // namespace - + class iaf_psc_exp_hc : public BaseNeuron { - public: +public: ~iaf_psc_exp_hc(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/izhikevich.cu b/src/izhikevich.cu index e7ace088d..638efaf1a 100644 --- a/src/izhikevich.cu +++ b/src/izhikevich.cu @@ -21,64 +21,75 @@ */ - - - -#include -#include -#include #include "izhikevich.h" #include "spike_buffer.h" +#include +#include +#include using namespace izhikevich_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m var[i_V_m] -#define u var[i_u] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] -#define den_delay param[i_den_delay] - -#define V_th_ group_param_[i_V_th] -#define a_ group_param_[i_a] -#define b_ group_param_[i_b] -#define c_ group_param_[i_c] -#define d_ group_param_[i_d] -#define t_ref_ group_param_[i_t_ref] - -__global__ void izhikevich_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float V_th, float a, float b, float c, float d, - int n_refractory_steps, float h) +#define I_syn var[ i_I_syn ] +#define V_m var[ i_V_m ] +#define u var[ i_u ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] +#define den_delay param[ i_den_delay ] + +#define V_th_ group_param_[ i_V_th ] +#define a_ group_param_[ i_a ] +#define b_ group_param_[ i_b ] +#define c_ group_param_[ i_c ] +#define d_ group_param_[ i_d ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +izhikevich_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float V_th, + float a, + float b, + float c, + float d, + int n_refractory_steps, + float h ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V and u + else + { // neuron is not refractory, so evolve V and u float v_old = V_m; float u_old = u; - V_m += h*(0.04 * v_old * v_old + 5.0 * v_old + 140.0 - u_old - + I_e) + I_syn; - u += h*a*(b*v_old - u_old); + V_m += h * ( 0.04 * v_old * v_old + 5.0 * v_old + 140.0 - u_old + I_e ) + I_syn; + u += h * a * ( b * v_old - u_old ); } I_syn = 0; - - if ( V_m >= V_th ) { // send spike - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m >= V_th ) + { // send spike + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m = c; u += d; // spike-driven adaptation refractory_step = n_refractory_steps; - if (refractory_step<0) { - refractory_step = 0; + if ( refractory_step < 0 ) + { + refractory_step = 0; } } } @@ -91,10 +102,10 @@ izhikevich::~izhikevich() FreeParamArr(); } -int izhikevich::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +izhikevich::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_izhikevich_model; n_scal_var_ = N_SCAL_VAR; @@ -102,65 +113,65 @@ int izhikevich::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = izhikevich_scal_var_name; scal_param_name_ = izhikevich_scal_param_name; group_param_name_ = izhikevich_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "den_delay", 0.0 ); // in ms - - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m", -70.0 ); // in mV - SetScalVar(0, n_node, "u", -70.0*0.2 ); - SetScalVar(0, n_node, "refractory_step", 0 ); - - SetGroupParam("V_th", 30.0); - SetGroupParam("a", 0.02); - SetGroupParam("b", 0.2); - SetGroupParam("c", -65.0); - SetGroupParam("d", 8.0); - SetGroupParam("t_ref", 0.0); + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m", -70.0 ); // in mV + SetScalVar( 0, n_node, "u", -70.0 * 0.2 ); + SetScalVar( 0, n_node, "refractory_step", 0 ); + + SetGroupParam( "V_th", 30.0 ); + SetGroupParam( "a", 0.02 ); + SetGroupParam( "b", 0.2 ); + SetGroupParam( "c", -65.0 ); + SetGroupParam( "d", 8.0 ); + SetGroupParam( "t_ref", 0.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int izhikevich::Update(long long it, double t1) +int +izhikevich::Update( long long it, double t1 ) { // std::cout << "izhikevich neuron update\n"; float h = time_resolution_; - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + izhikevich_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, V_th_, a_, b_, c_, d_, n_refractory_steps, h ); + // gpuErrchk( cudaDeviceSynchronize() ); - izhikevich_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - V_th_, a_, b_, c_, d_, n_refractory_steps, h); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int izhikevich::Free() +int +izhikevich::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/izhikevich.h b/src/izhikevich.h index b2017813d..6e1c2991f 100644 --- a/src/izhikevich.h +++ b/src/izhikevich.h @@ -21,18 +21,15 @@ */ - - - #ifndef IZHIKEVICH_H #define IZHIKEVICH_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include /* BeginUserDocs: neuron, integrate-and-fire @@ -94,76 +91,61 @@ EndUserDocs */ namespace izhikevich_ns { -enum ScalVarIndexes { - i_I_syn = 0, // input current - i_V_m, // membrane potential +enum ScalVarIndexes +{ + i_I_syn = 0, // input current + i_V_m, // membrane potential i_u, - i_refractory_step, // refractory step counter + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA i_den_delay, N_SCAL_PARAM }; -enum GroupParamIndexes { +enum GroupParamIndexes +{ i_V_th = 0, i_a, i_b, i_c, i_d, - i_t_ref, // Refractory period in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string izhikevich_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m", - "u", - "refractory_step" -}; +const std::string izhikevich_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m", "u", "refractory_step" }; -const std::string izhikevich_scal_param_name[N_SCAL_PARAM] = { - "I_e", - "den_delay" -}; +const std::string izhikevich_scal_param_name[ N_SCAL_PARAM ] = { "I_e", "den_delay" }; -const std::string izhikevich_group_param_name[N_GROUP_PARAM] = { - "V_th", - "a", - "b", - "c", - "d", - "t_ref" -}; - -} // namespace - +const std::string izhikevich_group_param_name[ N_GROUP_PARAM ] = { "V_th", "a", "b", "c", "d", "t_ref" }; +} // namespace class izhikevich : public BaseNeuron { float time_resolution_; - public: +public: ~izhikevich(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/izhikevich_cond_beta.cu b/src/izhikevich_cond_beta.cu index f0ec6e389..5d6806bb8 100644 --- a/src/izhikevich_cond_beta.cu +++ b/src/izhikevich_cond_beta.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include +#include "izhikevich_cond_beta.h" #include "izhikevich_cond_beta_kernel.h" #include "rk5.h" -#include "izhikevich_cond_beta.h" +#include +#include +#include namespace izhikevich_cond_beta_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - izhikevich_cond_beta_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, izhikevich_cond_beta_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 = 30.0; a = 0.02; @@ -49,133 +45,135 @@ void NodeInit(int n_var, int n_param, double x, float *y, float *param, I_e = 0.0; t_ref = 0.0; den_delay = 0.0; - + V_m = -70.0; - u = b*V_m; + u = b * V_m; refractory_step = 0; - for (int i = 0; i -int izhikevich_cond_beta::UpdateNR<0>(long long it, double t1) +int +izhikevich_cond_beta::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int izhikevich_cond_beta::Update(long long it, double t1) { - UpdateNR(it, t1); +int +izhikevich_cond_beta::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/izhikevich_cond_beta.h b/src/izhikevich_cond_beta.h index d3d27f8d5..2b9cf60ff 100644 --- a/src/izhikevich_cond_beta.h +++ b/src/izhikevich_cond_beta.h @@ -21,19 +21,16 @@ */ - - - #ifndef IZHIKEVICHCONDBETA_H #define IZHIKEVICHCONDBETA_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 @@ -64,9 +61,9 @@ The dynamics are given by: &v \text{ jumps on each spike arrival by the weight of the spike} This implementation uses the standard technique for forward Euler integration. -This model is multisynapse, so it allows an arbitrary number of synaptic -rise time and decay time constants. The number of receptor ports must be specified -at neuron creation (default value is 1) and the receptor index starts from 0 +This model is multisynapse, so it allows an arbitrary number of synaptic +rise time and decay time constants. 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 @@ -95,7 +92,7 @@ The following parameters can be set in the status dictionary. tau_decay ms Decay time constant of synaptic conductance h_min_rel real Starting step in ODE integration relative to time resolution - h0_rel real Minimum step in ODE integration relative to + h0_rel real Minimum step in ODE integration relative to time resolution ======================= ======= ============================================== @@ -126,30 +123,32 @@ struct izhikevich_cond_beta_rk5 class izhikevich_cond_beta : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< izhikevich_cond_beta_rk5 > rk5_; float h_min_; float h_; izhikevich_cond_beta_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - - 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, unsigned long long* seed ); + + 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/izhikevich_cond_beta_kernel.h b/src/izhikevich_cond_beta_kernel.h index 3b5f22650..7dd3b9507 100644 --- a/src/izhikevich_cond_beta_kernel.h +++ b/src/izhikevich_cond_beta_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef IZHIKEVICHCONDBETAKERNEL_H #define IZHIKEVICHCONDBETAKERNEL_H -#include -#include -#include "spike_buffer.h" -#include "node_group.h" #include "izhikevich_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 izhikevich_cond_beta_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_u, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ i_g = 0, i_g1, N_PORT_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_a, i_b, @@ -64,7 +64,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -72,25 +73,19 @@ 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 izhikevich_cond_beta_scal_var_name[N_SCAL_VAR] = { - "V_m", - "u" -}; -const std::string izhikevich_cond_beta_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string izhikevich_cond_beta_scal_var_name[ N_SCAL_VAR ] = { "V_m", "u" }; -const std::string izhikevich_cond_beta_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string izhikevich_cond_beta_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; + +const std::string izhikevich_cond_beta_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "a", "b", "c", @@ -98,115 +93,114 @@ const std::string izhikevich_cond_beta_scal_param_name[N_SCAL_PARAM] = { "I_e", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string izhikevich_cond_beta_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_rise", - "tau_decay", - "g0" -}; +const std::string izhikevich_cond_beta_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_rise", "tau_decay", "g0" }; -const std::string izhikevich_cond_beta_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string izhikevich_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 V_m y[i_V_m] -#define u y[i_u] -#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 dudt dydx[i_u] -#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 a param[i_a] -#define b param[i_b] -#define c param[i_c] -#define d param[i_d] -#define I_e param[i_I_e] -#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, - izhikevich_cond_beta_rk5 data_struct) +#define V_m y[ i_V_m ] +#define u y[ i_u ] +#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 dudt dydx[ i_u ] +#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 a param[ i_a ] +#define b param[ i_b ] +#define c param[ i_c ] +#define d param[ i_d ] +#define I_e param[ i_I_e ] +#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, izhikevich_cond_beta_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 ) ? c : V_m; - for (int i = 0; i 0 ) ? c : V_m; + for ( int i = 0; i < n_port; i++ ) + { + I_syn += g( i ) * ( E_rev( i ) - V ); } - dVdt = ( refractory_step > 0 ) ? 0 : - 0.04 * V * V + 5.0 * V + 140.0 - u + I_syn + I_e; - - dudt = a*(b*V - u); + dVdt = ( refractory_step > 0 ) ? 0 : 0.04 * V * V + 5.0 * V + 140.0 - u + I_syn + I_e; + + dudt = a * ( b * V - u ); - for (int i=0; i //, class DataStruct> -__device__ - void ExternalUpdate - (double x, float *y, float *param, bool end_time_step, - izhikevich_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, izhikevich_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 = c; - u=0; + u = 0; return; } - if ( u < -1.0e6 || u > 1.0e6) { // numerical instability - printf("u out of bound\n"); + if ( u < -1.0e6 || u > 1.0e6 ) + { // numerical instability + printf( "u out of bound\n" ); V_m = c; - u=0; + u = 0; return; } - if (refractory_step > 0.0) { + if ( refractory_step > 0.0 ) + { V_m = c; - if (end_time_step) { + if ( end_time_step ) + { refractory_step -= 1.0; } } - else { - if ( V_m >= V_th ) { // send spike + else + { + if ( V_m >= V_th ) + { // 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 = c; u += d; // 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; } } } @@ -216,43 +210,39 @@ __device__ }; template <> -int izhikevich_cond_beta::UpdateNR<0>(long long it, double t1); +int izhikevich_cond_beta::UpdateNR< 0 >( long long it, double t1 ); -template -int izhikevich_cond_beta::UpdateNR(long long it, double t1) +template < int N_PORT > +int +izhikevich_cond_beta::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = izhikevich_cond_beta_ns::N_SCAL_VAR - + izhikevich_cond_beta_ns::N_PORT_VAR*N_PORT; - const int NPARAM = izhikevich_cond_beta_ns::N_SCAL_PARAM - + izhikevich_cond_beta_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = izhikevich_cond_beta_ns::N_SCAL_VAR + izhikevich_cond_beta_ns::N_PORT_VAR * N_PORT; + const int NPARAM = izhikevich_cond_beta_ns::N_SCAL_PARAM + izhikevich_cond_beta_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, - izhikevich_cond_beta_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, izhikevich_cond_beta_rk5 data_struct ) { - izhikevich_cond_beta_ns::Derivatives(x, y, dydx, param, - data_struct); + izhikevich_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, - izhikevich_cond_beta_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, izhikevich_cond_beta_rk5 data_struct ) { - izhikevich_cond_beta_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + izhikevich_cond_beta_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/izhikevich_cond_beta_rk5.h b/src/izhikevich_cond_beta_rk5.h index c00f137e9..9aeec9215 100644 --- a/src/izhikevich_cond_beta_rk5.h +++ b/src/izhikevich_cond_beta_rk5.h @@ -21,31 +21,23 @@ */ - - - #ifndef IZHIKEVICHCONDBETARK5_H #define IZHIKEVICHCONDBETARK5_H struct izhikevich_cond_beta_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - izhikevich_cond_beta_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, izhikevich_cond_beta_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - izhikevich_cond_beta_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, izhikevich_cond_beta_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, izhikevich_cond_beta_rk5 data_struct); +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, izhikevich_cond_beta_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, izhikevich_cond_beta_rk5 data_struct); +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, izhikevich_cond_beta_rk5 data_struct ); #endif diff --git a/src/izhikevich_psc_exp.cu b/src/izhikevich_psc_exp.cu index 03c29404a..171965b07 100644 --- a/src/izhikevich_psc_exp.cu +++ b/src/izhikevich_psc_exp.cu @@ -21,66 +21,78 @@ */ - - - -#include -#include -#include #include "izhikevich_psc_exp.h" #include "spike_buffer.h" +#include +#include +#include using namespace izhikevich_psc_exp_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m var[i_V_m] -#define u var[i_u] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] -#define den_delay param[i_den_delay] - -#define V_th_ group_param_[i_V_th] -#define a_ group_param_[i_a] -#define b_ group_param_[i_b] -#define c_ group_param_[i_c] -#define d_ group_param_[i_d] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void izhikevich_psc_exp_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float V_th, float a, float b, float c, float d, - int n_refractory_steps, float h, float C_syn) +#define I_syn var[ i_I_syn ] +#define V_m var[ i_V_m ] +#define u var[ i_u ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] +#define den_delay param[ i_den_delay ] + +#define V_th_ group_param_[ i_V_th ] +#define a_ group_param_[ i_a ] +#define b_ group_param_[ i_b ] +#define c_ group_param_[ i_c ] +#define d_ group_param_[ i_d ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +izhikevich_psc_exp_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float V_th, + float a, + float b, + float c, + float d, + int n_refractory_steps, + float h, + float C_syn ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V and u + else + { // neuron is not refractory, so evolve V and u float v_old = V_m; float u_old = u; - V_m += h*(0.04 * v_old * v_old + 5.0 * v_old + 140.0 - u_old - + I_syn + I_e); - u += h*a*(b*v_old - u_old); + V_m += h * ( 0.04 * v_old * v_old + 5.0 * v_old + 140.0 - u_old + I_syn + I_e ); + u += h * a * ( b * v_old - u_old ); } // exponential decaying PSC I_syn *= C_syn; - - if ( V_m >= V_th ) { // send spike - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m >= V_th ) + { // send spike + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m = c; u += d; // spike-driven adaptation refractory_step = n_refractory_steps; - if (refractory_step<0) { - refractory_step = 0; + if ( refractory_step < 0 ) + { + refractory_step = 0; } } } @@ -93,10 +105,10 @@ izhikevich_psc_exp::~izhikevich_psc_exp() FreeParamArr(); } -int izhikevich_psc_exp::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +izhikevich_psc_exp::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_izhikevich_psc_exp_model; n_scal_var_ = N_SCAL_VAR; @@ -104,67 +116,67 @@ int izhikevich_psc_exp::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = izhikevich_psc_exp_scal_var_name; scal_param_name_ = izhikevich_psc_exp_scal_param_name; group_param_name_ = izhikevich_psc_exp_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "den_delay", 0.0 ); // in ms - - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m", -70.0 ); // in mV - SetScalVar(0, n_node, "u", -70.0*0.2 ); - SetScalVar(0, n_node, "refractory_step", 0 ); - - SetGroupParam("V_th", 30.0); - SetGroupParam("a", 0.02); - SetGroupParam("b", 0.2); - SetGroupParam("c", -65.0); - SetGroupParam("d", 8.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 0.0); + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m", -70.0 ); // in mV + SetScalVar( 0, n_node, "u", -70.0 * 0.2 ); + SetScalVar( 0, n_node, "refractory_step", 0 ); + + SetGroupParam( "V_th", 30.0 ); + SetGroupParam( "a", 0.02 ); + SetGroupParam( "b", 0.2 ); + SetGroupParam( "c", -65.0 ); + SetGroupParam( "d", 8.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 0.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int izhikevich_psc_exp::Update(long long it, double t1) +int +izhikevich_psc_exp::Update( long long it, double t1 ) { // std::cout << "izhikevich_psc_exp neuron update\n"; float h = time_resolution_; float C_syn = exp( -h / tau_syn_ ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + izhikevich_psc_exp_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn ); + // gpuErrchk( cudaDeviceSynchronize() ); - izhikevich_psc_exp_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int izhikevich_psc_exp::Free() +int +izhikevich_psc_exp::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/izhikevich_psc_exp.h b/src/izhikevich_psc_exp.h index a6bb98542..aa51472a5 100644 --- a/src/izhikevich_psc_exp.h +++ b/src/izhikevich_psc_exp.h @@ -21,19 +21,15 @@ */ - - - - #ifndef IZHIKEVICHPSCEXP_H #define IZHIKEVICHPSCEXP_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include /* BeginUserDocs: neuron, integrate-and-fire @@ -98,78 +94,63 @@ EndUserDocs */ namespace izhikevich_psc_exp_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m, // membrane potential +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m, // membrane potential i_u, - i_refractory_step, // refractory step counter + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA i_den_delay, N_SCAL_PARAM }; -enum GroupParamIndexes { +enum GroupParamIndexes +{ i_V_th = 0, i_a, i_b, i_c, i_d, - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string izhikevich_psc_exp_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m", - "u", - "refractory_step" -}; +const std::string izhikevich_psc_exp_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m", "u", "refractory_step" }; -const std::string izhikevich_psc_exp_scal_param_name[N_SCAL_PARAM] = { - "I_e", - "den_delay" -}; +const std::string izhikevich_psc_exp_scal_param_name[ N_SCAL_PARAM ] = { "I_e", "den_delay" }; -const std::string izhikevich_psc_exp_group_param_name[N_GROUP_PARAM] = { - "V_th", - "a", - "b", - "c", - "d", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + izhikevich_psc_exp_group_param_name[ N_GROUP_PARAM ] = { "V_th", "a", "b", "c", "d", "tau_syn", "t_ref" }; +} // namespace class izhikevich_psc_exp : public BaseNeuron { float time_resolution_; - public: +public: ~izhikevich_psc_exp(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/izhikevich_psc_exp_2s.cu b/src/izhikevich_psc_exp_2s.cu index 85f5ef49c..dc238bc28 100644 --- a/src/izhikevich_psc_exp_2s.cu +++ b/src/izhikevich_psc_exp_2s.cu @@ -21,73 +21,87 @@ */ - - - -#include -#include -#include #include "izhikevich_psc_exp_2s.h" #include "spike_buffer.h" +#include +#include +#include using namespace izhikevich_psc_exp_2s_ns; extern __constant__ float NESTGPUTimeResolution; #define INTEGR_STEPS 2 -#define I_syn var[i_I_syn] -#define V_m var[i_V_m] -#define u var[i_u] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] -#define den_delay param[i_den_delay] - -#define V_th_ group_param_[i_V_th] -#define a_ group_param_[i_a] -#define b_ group_param_[i_b] -#define c_ group_param_[i_c] -#define d_ group_param_[i_d] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void izhikevich_psc_exp_2s_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float V_th, float a, float b, float c, float d, - int n_refractory_steps, float h, float C_syn) +#define I_syn var[ i_I_syn ] +#define V_m var[ i_V_m ] +#define u var[ i_u ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] +#define den_delay param[ i_den_delay ] + +#define V_th_ group_param_[ i_V_th ] +#define a_ group_param_[ i_a ] +#define b_ group_param_[ i_b ] +#define c_ group_param_[ i_c ] +#define d_ group_param_[ i_d ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +izhikevich_psc_exp_2s_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float V_th, + float a, + float b, + float c, + float d, + int n_refractory_steps, + float h, + float C_syn ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; - - for (int i=0; i= V_th ) { // send spike - PushSpike(i_node_0 + i_neuron, 1.0); + if ( V_m >= V_th ) + { // send spike + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m = c; u += d; // spike-driven adaptation refractory_step = n_refractory_steps; - if (refractory_step<0) { - refractory_step = 0; + if ( refractory_step < 0 ) + { + refractory_step = 0; } } } @@ -100,10 +114,10 @@ izhikevich_psc_exp_2s::~izhikevich_psc_exp_2s() FreeParamArr(); } -int izhikevich_psc_exp_2s::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +izhikevich_psc_exp_2s::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_izhikevich_psc_exp_2s_model; n_scal_var_ = N_SCAL_VAR; @@ -111,67 +125,67 @@ int izhikevich_psc_exp_2s::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = izhikevich_psc_exp_2s_scal_var_name; scal_param_name_ = izhikevich_psc_exp_2s_scal_param_name; group_param_name_ = izhikevich_psc_exp_2s_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "den_delay", 0.0 ); // in ms - - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m", -70.0 ); // in mV - SetScalVar(0, n_node, "u", -70.0*0.2 ); - SetScalVar(0, n_node, "refractory_step", 0 ); - - SetGroupParam("V_th", 30.0); - SetGroupParam("a", 0.02); - SetGroupParam("b", 0.2); - SetGroupParam("c", -65.0); - SetGroupParam("d", 8.0); - SetGroupParam("tau_syn", 2.0); - SetGroupParam("t_ref", 0.0); + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m", -70.0 ); // in mV + SetScalVar( 0, n_node, "u", -70.0 * 0.2 ); + SetScalVar( 0, n_node, "refractory_step", 0 ); + + SetGroupParam( "V_th", 30.0 ); + SetGroupParam( "a", 0.02 ); + SetGroupParam( "b", 0.2 ); + SetGroupParam( "c", -65.0 ); + SetGroupParam( "d", 8.0 ); + SetGroupParam( "tau_syn", 2.0 ); + SetGroupParam( "t_ref", 0.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int izhikevich_psc_exp_2s::Update(long long it, double t1) +int +izhikevich_psc_exp_2s::Update( long long it, double t1 ) { // std::cout << "izhikevich_psc_exp_2s neuron update\n"; - float h = time_resolution_/INTEGR_STEPS; + float h = time_resolution_ / INTEGR_STEPS; float C_syn = exp( -h / tau_syn_ ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + izhikevich_psc_exp_2s_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn ); + // gpuErrchk( cudaDeviceSynchronize() ); - izhikevich_psc_exp_2s_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int izhikevich_psc_exp_2s::Free() +int +izhikevich_psc_exp_2s::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/izhikevich_psc_exp_2s.h b/src/izhikevich_psc_exp_2s.h index 75b3c5d06..f5f240837 100644 --- a/src/izhikevich_psc_exp_2s.h +++ b/src/izhikevich_psc_exp_2s.h @@ -21,95 +21,76 @@ */ - - - - #ifndef IZHIKEVICHPSCEXP2S_H #define IZHIKEVICHPSCEXP2S_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace izhikevich_psc_exp_2s_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m, // membrane potential +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m, // membrane potential i_u, - i_refractory_step, // refractory step counter + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA i_den_delay, N_SCAL_PARAM }; -enum GroupParamIndexes { +enum GroupParamIndexes +{ i_V_th = 0, i_a, i_b, i_c, i_d, - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string izhikevich_psc_exp_2s_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m", - "u", - "refractory_step" -}; +const std::string izhikevich_psc_exp_2s_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m", "u", "refractory_step" }; -const std::string izhikevich_psc_exp_2s_scal_param_name[N_SCAL_PARAM] = { - "I_e", - "den_delay" -}; +const std::string izhikevich_psc_exp_2s_scal_param_name[ N_SCAL_PARAM ] = { "I_e", "den_delay" }; -const std::string izhikevich_psc_exp_2s_group_param_name[N_GROUP_PARAM] = { - "V_th", - "a", - "b", - "c", - "d", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + izhikevich_psc_exp_2s_group_param_name[ N_GROUP_PARAM ] = { "V_th", "a", "b", "c", "d", "tau_syn", "t_ref" }; +} // namespace class izhikevich_psc_exp_2s : public BaseNeuron { float time_resolution_; - public: +public: ~izhikevich_psc_exp_2s(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/izhikevich_psc_exp_5s.cu b/src/izhikevich_psc_exp_5s.cu index c59827a84..431e5e0c2 100644 --- a/src/izhikevich_psc_exp_5s.cu +++ b/src/izhikevich_psc_exp_5s.cu @@ -21,73 +21,87 @@ */ - - - -#include -#include -#include #include "izhikevich_psc_exp_5s.h" #include "spike_buffer.h" +#include +#include +#include using namespace izhikevich_psc_exp_5s_ns; extern __constant__ float NESTGPUTimeResolution; #define INTEGR_STEPS 5 -#define I_syn var[i_I_syn] -#define V_m var[i_V_m] -#define u var[i_u] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] -#define den_delay param[i_den_delay] - -#define V_th_ group_param_[i_V_th] -#define a_ group_param_[i_a] -#define b_ group_param_[i_b] -#define c_ group_param_[i_c] -#define d_ group_param_[i_d] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void izhikevich_psc_exp_5s_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float V_th, float a, float b, float c, float d, - int n_refractory_steps, float h, float C_syn) +#define I_syn var[ i_I_syn ] +#define V_m var[ i_V_m ] +#define u var[ i_u ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] +#define den_delay param[ i_den_delay ] + +#define V_th_ group_param_[ i_V_th ] +#define a_ group_param_[ i_a ] +#define b_ group_param_[ i_b ] +#define c_ group_param_[ i_c ] +#define d_ group_param_[ i_d ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +izhikevich_psc_exp_5s_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float V_th, + float a, + float b, + float c, + float d, + int n_refractory_steps, + float h, + float C_syn ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; - - for (int i=0; i= V_th ) { // send spike - PushSpike(i_node_0 + i_neuron, 1.0); + if ( V_m >= V_th ) + { // send spike + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m = c; u += d; // spike-driven adaptation refractory_step = n_refractory_steps; - if (refractory_step<0) { - refractory_step = 0; + if ( refractory_step < 0 ) + { + refractory_step = 0; } } } @@ -100,10 +114,10 @@ izhikevich_psc_exp_5s::~izhikevich_psc_exp_5s() FreeParamArr(); } -int izhikevich_psc_exp_5s::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +izhikevich_psc_exp_5s::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_izhikevich_psc_exp_5s_model; n_scal_var_ = N_SCAL_VAR; @@ -111,67 +125,67 @@ int izhikevich_psc_exp_5s::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = izhikevich_psc_exp_5s_scal_var_name; scal_param_name_ = izhikevich_psc_exp_5s_scal_param_name; group_param_name_ = izhikevich_psc_exp_5s_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "den_delay", 0.0 ); // in ms - - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m", -70.0 ); // in mV - SetScalVar(0, n_node, "u", -70.0*0.2 ); - SetScalVar(0, n_node, "refractory_step", 0 ); - - SetGroupParam("V_th", 30.0); - SetGroupParam("a", 0.02); - SetGroupParam("b", 0.2); - SetGroupParam("c", -65.0); - SetGroupParam("d", 8.0); - SetGroupParam("tau_syn", 2.0); - SetGroupParam("t_ref", 0.0); + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m", -70.0 ); // in mV + SetScalVar( 0, n_node, "u", -70.0 * 0.2 ); + SetScalVar( 0, n_node, "refractory_step", 0 ); + + SetGroupParam( "V_th", 30.0 ); + SetGroupParam( "a", 0.02 ); + SetGroupParam( "b", 0.2 ); + SetGroupParam( "c", -65.0 ); + SetGroupParam( "d", 8.0 ); + SetGroupParam( "tau_syn", 2.0 ); + SetGroupParam( "t_ref", 0.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int izhikevich_psc_exp_5s::Update(long long it, double t1) +int +izhikevich_psc_exp_5s::Update( long long it, double t1 ) { // std::cout << "izhikevich_psc_exp_5s neuron update\n"; - float h = time_resolution_/INTEGR_STEPS; + float h = time_resolution_ / INTEGR_STEPS; float C_syn = exp( -h / tau_syn_ ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + izhikevich_psc_exp_5s_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn ); + // gpuErrchk( cudaDeviceSynchronize() ); - izhikevich_psc_exp_5s_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - V_th_, a_, b_, c_, d_, n_refractory_steps, h, C_syn); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int izhikevich_psc_exp_5s::Free() +int +izhikevich_psc_exp_5s::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/izhikevich_psc_exp_5s.h b/src/izhikevich_psc_exp_5s.h index 43957dcf1..862c8eaf4 100644 --- a/src/izhikevich_psc_exp_5s.h +++ b/src/izhikevich_psc_exp_5s.h @@ -21,95 +21,76 @@ */ - - - - #ifndef IZHIKEVICHPSCEXP5S_H #define IZHIKEVICHPSCEXP5S_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace izhikevich_psc_exp_5s_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m, // membrane potential +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m, // membrane potential i_u, - i_refractory_step, // refractory step counter + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA i_den_delay, N_SCAL_PARAM }; -enum GroupParamIndexes { +enum GroupParamIndexes +{ i_V_th = 0, i_a, i_b, i_c, i_d, - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string izhikevich_psc_exp_5s_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m", - "u", - "refractory_step" -}; +const std::string izhikevich_psc_exp_5s_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m", "u", "refractory_step" }; -const std::string izhikevich_psc_exp_5s_scal_param_name[N_SCAL_PARAM] = { - "I_e", - "den_delay" -}; +const std::string izhikevich_psc_exp_5s_scal_param_name[ N_SCAL_PARAM ] = { "I_e", "den_delay" }; -const std::string izhikevich_psc_exp_5s_group_param_name[N_GROUP_PARAM] = { - "V_th", - "a", - "b", - "c", - "d", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + izhikevich_psc_exp_5s_group_param_name[ N_GROUP_PARAM ] = { "V_th", "a", "b", "c", "d", "tau_syn", "t_ref" }; +} // namespace class izhikevich_psc_exp_5s : public BaseNeuron { float time_resolution_; - public: +public: ~izhikevich_psc_exp_5s(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/locate.cu b/src/locate.cu index 0528955e5..fa4a27e3f 100644 --- a/src/locate.cu +++ b/src/locate.cu @@ -1,15 +1,26 @@ #include "locate.h" -__device__ int locate(int val, int *data, int n) +__device__ int +locate( int val, int* data, int n ) { int i_left = 0; - int i_right = n-1; - int i = (i_left+i_right)/2; - while(i_right-i_left>1) { - if (data[i] > val) i_right = i; - else if (data[i] 1 ) + { + if ( data[ i ] > val ) + { + i_right = i; + } + else if ( data[ i ] < val ) + { + i_left = i; + } + else + { + break; + } + i = ( i_left + i_right ) / 2; } return i; diff --git a/src/locate.h b/src/locate.h index 15160189b..b73423e47 100644 --- a/src/locate.h +++ b/src/locate.h @@ -1,3 +1,3 @@ #pragma once -__device__ int locate(int val, int *data, int n); +__device__ int locate( int val, int* data, int n ); diff --git a/src/multimeter.cu b/src/multimeter.cu index 6989f8130..c683d2f2f 100644 --- a/src/multimeter.cu +++ b/src/multimeter.cu @@ -21,143 +21,169 @@ */ - - - +#include "cuda_error.h" +#include "multimeter.h" #include #include #include -#include "multimeter.h" -#include "cuda_error.h" -const std::string SpikeVarName = "spike"; - -Record::Record(std::vector neur_vect, std::string file_name, - std::vector var_name_vect, - std::vector i_neur_vect, std::vector port_vect): - neuron_vect_(neur_vect), file_name_(file_name), - var_name_vect_(var_name_vect), - i_neuron_vect_(i_neur_vect), - port_vect_(port_vect) +const std::string SpikeVarName = "spike"; + +Record::Record( std::vector< BaseNeuron* > neur_vect, + std::string file_name, + std::vector< std::string > var_name_vect, + std::vector< int > i_neur_vect, + std::vector< int > port_vect ) + : neuron_vect_( neur_vect ) + , file_name_( file_name ) + , var_name_vect_( var_name_vect ) + , i_neuron_vect_( i_neur_vect ) + , port_vect_( port_vect ) { data_vect_flag_ = true; - if (file_name=="") { + if ( file_name == "" ) + { out_file_flag_ = false; - } else { + } + else + { out_file_flag_ = true; } var_pt_vect_.clear(); - for (unsigned int i=0; iGetVarPt(i_neur_vect[i], var_name_vect[i], - port_vect[i]); - var_pt_vect_.push_back(var_pt); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + if ( var_name_vect[ i ] != SpikeVarName ) + { + float* var_pt = neur_vect[ i ]->GetVarPt( i_neur_vect[ i ], var_name_vect[ i ], port_vect[ i ] ); + var_pt_vect_.push_back( var_pt ); } - else { - var_pt_vect_.push_back(NULL); + else + { + var_pt_vect_.push_back( NULL ); } } } -int Record::OpenFile() +int +Record::OpenFile() { - fp_=fopen(file_name_.c_str(), "w"); - + fp_ = fopen( file_name_.c_str(), "w" ); + return 0; } -int Record::CloseFile() +int +Record::CloseFile() { - fclose(fp_); - + fclose( fp_ ); + return 0; } -int Record::WriteRecord(float t) +int +Record::WriteRecord( float t ) { float var; - std::vector vect; - - if (out_file_flag_) { - fprintf(fp_,"%f", t); + std::vector< float > vect; + + if ( out_file_flag_ ) + { + fprintf( fp_, "%f", t ); } - if (data_vect_flag_) { - vect.push_back(t); + if ( data_vect_flag_ ) + { + vect.push_back( t ); } - for (unsigned int i=0; iGetSpikeActivity(i_neuron_vect_[i]); + else + { + var = neuron_vect_[ i ]->GetSpikeActivity( i_neuron_vect_[ i ] ); } - if (out_file_flag_) { - fprintf(fp_,"\t%f", var); + if ( out_file_flag_ ) + { + fprintf( fp_, "\t%f", var ); } - if (data_vect_flag_) { - vect.push_back(var); + if ( data_vect_flag_ ) + { + vect.push_back( var ); } } - if (out_file_flag_) { - fprintf(fp_,"\n"); + if ( out_file_flag_ ) + { + fprintf( fp_, "\n" ); } - if (data_vect_flag_) { - data_vect_.push_back(vect); + if ( data_vect_flag_ ) + { + data_vect_.push_back( vect ); } return 0; } -int Multimeter::CreateRecord(std::vector neur_vect, - std::string file_name, - std::vector var_name_vect, - std::vector i_neur_vect, - std::vector port_vect) +int +Multimeter::CreateRecord( std::vector< BaseNeuron* > neur_vect, + std::string file_name, + std::vector< std::string > var_name_vect, + std::vector< int > i_neur_vect, + std::vector< int > port_vect ) { - Record record(neur_vect, file_name, var_name_vect, i_neur_vect, - port_vect); - record_vect_.push_back(record); + Record record( neur_vect, file_name, var_name_vect, i_neur_vect, port_vect ); + record_vect_.push_back( record ); - return (record_vect_.size() - 1); + return ( record_vect_.size() - 1 ); } -int Multimeter::OpenFiles() +int +Multimeter::OpenFiles() { - for (unsigned int i=0; i > *Multimeter::GetRecordData(int i_record) +std::vector< std::vector< float > >* +Multimeter::GetRecordData( int i_record ) { - if (i_record<0 || i_record>=(int)record_vect_.size()) { - throw ngpu_exception("Record does not exist."); + if ( i_record < 0 || i_record >= ( int ) record_vect_.size() ) + { + throw ngpu_exception( "Record does not exist." ); } - - return &record_vect_[i_record].data_vect_; + + return &record_vect_[ i_record ].data_vect_; } diff --git a/src/multimeter.h b/src/multimeter.h index eabc060e1..fa01d6dc2 100644 --- a/src/multimeter.h +++ b/src/multimeter.h @@ -21,15 +21,12 @@ */ - - - #ifndef MULTIMETER_H #define MULTIMETER_H +#include "base_neuron.h" #include #include #include -#include "base_neuron.h" /* BeginUserDocs: device, recorder @@ -84,7 +81,7 @@ can also be retreived through the commands ``GetRecordDataRows`` and print("recorder has {} rows and {} columns".format(rows, columns)) recorded_data = nestgpu.GetRecordData(record) - + time = [row[0] for row in recorded_data] variable = [row[1] for row in recorded_data] @@ -95,51 +92,50 @@ See also EndUserDocs */ - class Record { - public: +public: bool data_vect_flag_; bool out_file_flag_; - std::vector > data_vect_; - std::vector neuron_vect_; + std::vector< std::vector< float > > data_vect_; + std::vector< BaseNeuron* > neuron_vect_; std::string file_name_; - std::vector var_name_vect_; - std::vector i_neuron_vect_; - std::vector port_vect_; - std::vector var_pt_vect_; - FILE *fp_; - - Record(std::vector neur_vect, std::string file_name, - std::vector var_name_vect, - std::vector i_neur_vect, std::vector port_vect); + std::vector< std::string > var_name_vect_; + std::vector< int > i_neuron_vect_; + std::vector< int > port_vect_; + std::vector< float* > var_pt_vect_; + FILE* fp_; + + Record( std::vector< BaseNeuron* > neur_vect, + std::string file_name, + std::vector< std::string > var_name_vect, + std::vector< int > i_neur_vect, + std::vector< int > port_vect ); int OpenFile(); - + int CloseFile(); - - int WriteRecord(float t); + int WriteRecord( float t ); }; - + class Multimeter { - public: - std::vector record_vect_; - - int CreateRecord(std::vector neur_vect, - std::string file_name, - std::vector var_name_vect, - std::vector i_neur_vect, - std::vector port_vect); +public: + std::vector< Record > record_vect_; + + int CreateRecord( std::vector< BaseNeuron* > neur_vect, + std::string file_name, + std::vector< std::string > var_name_vect, + std::vector< int > i_neur_vect, + std::vector< int > port_vect ); int OpenFiles(); int CloseFiles(); - int WriteRecords(float t); + int WriteRecords( float t ); - std::vector > *GetRecordData(int i_record); - + std::vector< std::vector< float > >* GetRecordData( int i_record ); }; #endif diff --git a/src/nestgpu.cu b/src/nestgpu.cu index 8124a912f..97eb6ce3b 100644 --- a/src/nestgpu.cu +++ b/src/nestgpu.cu @@ -21,31 +21,28 @@ */ - - - -#include -#include -#include +#include "cuda_error.h" +#include "get_spike.h" +#include "send_spike.h" +#include "spike_buffer.h" +#include #include +#include +#include #include +#include +#include #include -#include -#include -#include "spike_buffer.h" -#include "cuda_error.h" -#include "send_spike.h" -#include "get_spike.h" -#include "connect_mpi.h" -#include "spike_generator.h" +#include "connect_mpi.h" +#include "dir_connect.h" +#include "getRealTime.h" #include "multimeter.h" +#include "nestgpu.h" #include "poisson.h" -#include "getRealTime.h" #include "random.h" -#include "nestgpu.h" -#include "dir_connect.h" #include "rev_spike.h" +#include "spike_generator.h" #include "spike_mpi.h" #ifdef HAVE_MPI @@ -55,20 +52,22 @@ #define THREAD_MAXNUM 1 #define THREAD_IDX 0 - //#define VERBOSE_TIME +// #define VERBOSE_TIME __constant__ double NESTGPUTime; __constant__ long long NESTGPUTimeIdx; __constant__ float NESTGPUTimeResolution; -enum KernelFloatParamIndexes { +enum KernelFloatParamIndexes +{ i_time_resolution = 0, i_max_spike_num_fact, i_max_spike_per_host_fact, N_KERNEL_FLOAT_PARAM }; -enum KernelIntParamIndexes { +enum KernelIntParamIndexes +{ i_rnd_seed = 0, i_verbosity_level, i_max_spike_buffer_size, @@ -76,67 +75,61 @@ enum KernelIntParamIndexes { N_KERNEL_INT_PARAM }; -enum KernelBoolParamIndexes { +enum KernelBoolParamIndexes +{ i_print_time, N_KERNEL_BOOL_PARAM }; -const std::string kernel_float_param_name[N_KERNEL_FLOAT_PARAM] = { - "time_resolution", +const std::string kernel_float_param_name[ N_KERNEL_FLOAT_PARAM ] = { "time_resolution", "max_spike_num_fact", - "max_spike_per_host_fact" -}; + "max_spike_per_host_fact" }; -const std::string kernel_int_param_name[N_KERNEL_INT_PARAM] = { - "rnd_seed", +const std::string kernel_int_param_name[ N_KERNEL_INT_PARAM ] = { "rnd_seed", "verbosity_level", "max_spike_buffer_size", - "remote_spike_height_flag" -}; + "remote_spike_height_flag" }; -const std::string kernel_bool_param_name[N_KERNEL_BOOL_PARAM] = { - "print_time" -}; +const std::string kernel_bool_param_name[ N_KERNEL_BOOL_PARAM ] = { "print_time" }; NESTGPU::NESTGPU() { random_generator_ = new curandGenerator_t; - CURAND_CALL(curandCreateGenerator(random_generator_, - CURAND_RNG_PSEUDO_DEFAULT)); + CURAND_CALL( curandCreateGenerator( random_generator_, CURAND_RNG_PSEUDO_DEFAULT ) ); poiss_generator_ = new PoissonGenerator; multimeter_ = new Multimeter; net_connection_ = new NetConnection; - - + + calibrate_flag_ = false; start_real_time_ = getRealTime(); max_spike_buffer_size_ = 20; t_min_ = 0.0; - sim_time_ = 1000.0; //Simulation time in ms + sim_time_ = 1000.0; // Simulation time in ms n_poiss_node_ = 0; n_remote_node_ = 0; - SetTimeResolution(0.1); // time resolution in ms + SetTimeResolution( 0.1 ); // time resolution in ms max_spike_num_fact_ = 1.0; max_spike_per_host_fact_ = 1.0; - + error_flag_ = false; error_message_ = ""; error_code_ = 0; - + on_exception_ = ON_EXCEPTION_EXIT; verbosity_level_ = 4; print_time_ = false; - + mpi_flag_ = false; #ifdef HAVE_MPI connect_mpi_ = new ConnectMpi; connect_mpi_->net_connection_ = net_connection_; connect_mpi_->remote_spike_height_ = false; #endif - - SetRandomSeed(54321ULL); + + SetRandomSeed( 54321ULL ); SpikeBufferUpdate_time_ = 0; poisson_generator_time_ = 0; @@ -159,13 +152,15 @@ NESTGPU::~NESTGPU() gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - if (calibrate_flag_) { + if ( calibrate_flag_ ) + { FreeNodeGroupMap(); FreeGetSpikeArrays(); } - for (unsigned int i=0; impi_id_; - #endif - CURAND_CALL(curandDestroyGenerator(*random_generator_)); +#endif + CURAND_CALL( curandDestroyGenerator( *random_generator_ ) ); random_generator_ = new curandGenerator_t; - CURAND_CALL(curandCreateGenerator(random_generator_, - CURAND_RNG_PSEUDO_DEFAULT)); - CURAND_CALL(curandSetPseudoRandomGeneratorSeed(*random_generator_, seed)); + CURAND_CALL( curandCreateGenerator( random_generator_, CURAND_RNG_PSEUDO_DEFAULT ) ); + CURAND_CALL( curandSetPseudoRandomGeneratorSeed( *random_generator_, seed ) ); poiss_generator_->random_generator_ = random_generator_; return 0; } -int NESTGPU::SetTimeResolution(float time_res) +int +NESTGPU::SetTimeResolution( float time_res ) { time_resolution_ = time_res; net_connection_->time_resolution_ = time_res; - + return 0; } -int NESTGPU::SetMaxSpikeBufferSize(int max_size) +int +NESTGPU::SetMaxSpikeBufferSize( int max_size ) { max_spike_buffer_size_ = max_size; - + return 0; } -int NESTGPU::GetMaxSpikeBufferSize() +int +NESTGPU::GetMaxSpikeBufferSize() { return max_spike_buffer_size_; } -int NESTGPU::CreateNodeGroup(int n_node, int n_port) +int +NESTGPU::CreateNodeGroup( int n_node, int n_port ) { int i_node_0 = node_group_map_.size(); #ifdef HAVE_MPI - if ((int)connect_mpi_->extern_connection_.size() != i_node_0) { - throw ngpu_exception("Error: connect_mpi_.extern_connection_ and " - "node_group_map_ must have the same size!"); + if ( ( int ) connect_mpi_->extern_connection_.size() != i_node_0 ) + { + throw ngpu_exception( + "Error: connect_mpi_.extern_connection_ and " + "node_group_map_ must have the same size!" ); } #endif - if ((int)net_connection_->connection_.size() != i_node_0) { - throw ngpu_exception("Error: net_connection_.connection_ and " - "node_group_map_ must have the same size!"); + if ( ( int ) net_connection_->connection_.size() != i_node_0 ) + { + throw ngpu_exception( + "Error: net_connection_.connection_ and " + "node_group_map_ must have the same size!" ); } - if ((net_connection_->connection_.size() + n_node) > MAX_N_NEURON) { - throw ngpu_exception(std::string("Maximum number of neurons ") - + std::to_string(MAX_N_NEURON) + " exceeded"); + if ( ( net_connection_->connection_.size() + n_node ) > MAX_N_NEURON ) + { + throw ngpu_exception( std::string( "Maximum number of neurons " ) + std::to_string( MAX_N_NEURON ) + " exceeded" ); } - if (n_port > MAX_N_PORT) { - throw ngpu_exception(std::string("Maximum number of ports ") - + std::to_string(MAX_N_PORT) + " exceeded"); + if ( n_port > MAX_N_PORT ) + { + throw ngpu_exception( std::string( "Maximum number of ports " ) + std::to_string( MAX_N_PORT ) + " exceeded" ); } int i_group = node_vect_.size() - 1; - node_group_map_.insert(node_group_map_.end(), n_node, i_group); - - std::vector conn; - std::vector >::iterator it - = net_connection_->connection_.end(); - net_connection_->connection_.insert(it, n_node, conn); + node_group_map_.insert( node_group_map_.end(), n_node, i_group ); + + std::vector< ConnGroup > conn; + std::vector< std::vector< ConnGroup > >::iterator it = net_connection_->connection_.end(); + net_connection_->connection_.insert( it, n_node, conn ); #ifdef HAVE_MPI - std::vector conn_node; - std::vector >::iterator it1 - = connect_mpi_->extern_connection_.end(); - connect_mpi_->extern_connection_.insert(it1, n_node, conn_node); + std::vector< ExternalConnectionNode > conn_node; + std::vector< std::vector< ExternalConnectionNode > >::iterator it1 = connect_mpi_->extern_connection_.end(); + connect_mpi_->extern_connection_.insert( it1, n_node, conn_node ); #endif - - node_vect_[i_group]->Init(i_node_0, n_node, n_port, i_group, &kernel_seed_); - node_vect_[i_group]->get_spike_array_ = InitGetSpikeArray(n_node, n_port); - + + node_vect_[ i_group ]->Init( i_node_0, n_node, n_port, i_group, &kernel_seed_ ); + node_vect_[ i_group ]->get_spike_array_ = InitGetSpikeArray( n_node, n_port ); + return i_node_0; } -NodeSeq NESTGPU::CreatePoissonGenerator(int n_node, float rate) +NodeSeq +NESTGPU::CreatePoissonGenerator( int n_node, float rate ) { - CheckUncalibrated("Poisson generator cannot be created after calibration"); - if (n_poiss_node_ != 0) { - throw ngpu_exception("Number of poisson generators cannot be modified."); + CheckUncalibrated( "Poisson generator cannot be created after calibration" ); + if ( n_poiss_node_ != 0 ) + { + throw ngpu_exception( "Number of poisson generators cannot be modified." ); } - else if (n_node <= 0) { - throw ngpu_exception("Number of nodes must be greater than zero."); + else if ( n_node <= 0 ) + { + throw ngpu_exception( "Number of nodes must be greater than zero." ); } - - n_poiss_node_ = n_node; - - BaseNeuron *bn = new BaseNeuron; - node_vect_.push_back(bn); - int i_node_0 = CreateNodeGroup( n_node, 0); - - float lambda = rate*time_resolution_ / 1000.0; // rate is in Hz, time in ms - poiss_generator_->Create(random_generator_, i_node_0, n_node, lambda); - - return NodeSeq(i_node_0, n_node); + + n_poiss_node_ = n_node; + + BaseNeuron* bn = new BaseNeuron; + node_vect_.push_back( bn ); + int i_node_0 = CreateNodeGroup( n_node, 0 ); + + float lambda = rate * time_resolution_ / 1000.0; // rate is in Hz, time in ms + poiss_generator_->Create( random_generator_, i_node_0, n_node, lambda ); + + return NodeSeq( i_node_0, n_node ); } -int NESTGPU::CheckUncalibrated(std::string message) +int +NESTGPU::CheckUncalibrated( std::string message ) { - if (calibrate_flag_ == true) { - throw ngpu_exception(message); + if ( calibrate_flag_ == true ) + { + throw ngpu_exception( message ); } - + return 0; } -int NESTGPU::Calibrate() +int +NESTGPU::Calibrate() { - CheckUncalibrated("Calibration can be made only once"); + CheckUncalibrated( "Calibration can be made only once" ); ConnectRemoteNodes(); calibrate_flag_ = true; BuildDirectConnections(); #ifdef HAVE_MPI - gpuErrchk(cudaMemcpyToSymbolAsync(NESTGPUMpiFlag, &mpi_flag_, sizeof(bool))); + gpuErrchk( cudaMemcpyToSymbolAsync( NESTGPUMpiFlag, &mpi_flag_, sizeof( bool ) ) ); #endif - if (verbosity_level_>=1) { + if ( verbosity_level_ >= 1 ) + { std::cout << MpiRankStr() << "Calibrating ...\n"; } - + neural_time_ = t_min_; - + NodeGroupArrayInit(); - - max_spike_num_ = (int)round(max_spike_num_fact_ - * net_connection_->connection_.size() - * net_connection_->MaxDelayNum()); - max_spike_num_ = (max_spike_num_>1) ? max_spike_num_ : 1; - - max_spike_per_host_ = (int)round(max_spike_per_host_fact_ - * net_connection_->connection_.size() - * net_connection_->MaxDelayNum()); - max_spike_per_host_ = (max_spike_per_host_>1) ? max_spike_per_host_ : 1; - - SpikeInit(max_spike_num_); - SpikeBufferInit(net_connection_, max_spike_buffer_size_); + + max_spike_num_ = + ( int ) round( max_spike_num_fact_ * net_connection_->connection_.size() * net_connection_->MaxDelayNum() ); + max_spike_num_ = ( max_spike_num_ > 1 ) ? max_spike_num_ : 1; + + max_spike_per_host_ = + ( int ) round( max_spike_per_host_fact_ * net_connection_->connection_.size() * net_connection_->MaxDelayNum() ); + max_spike_per_host_ = ( max_spike_per_host_ > 1 ) ? max_spike_per_host_ : 1; + + SpikeInit( max_spike_num_ ); + SpikeBufferInit( net_connection_, max_spike_buffer_size_ ); #ifdef HAVE_MPI - if (mpi_flag_) { + if ( mpi_flag_ ) + { // remove superfluous argument mpi_np - connect_mpi_->ExternalSpikeInit(connect_mpi_->extern_connection_.size(), - connect_mpi_->mpi_np_, - max_spike_per_host_); + connect_mpi_->ExternalSpikeInit( + connect_mpi_->extern_connection_.size(), connect_mpi_->mpi_np_, max_spike_per_host_ ); } #endif - - if (net_connection_->NRevConnections()>0) { - RevSpikeInit(net_connection_); + + if ( net_connection_->NRevConnections() > 0 ) + { + RevSpikeInit( net_connection_ ); } - + multimeter_->OpenFiles(); - - for (unsigned int i=0; iCalibrate(t_min_, time_resolution_); + + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + node_vect_[ i ]->Calibrate( t_min_, time_resolution_ ); } - + SynGroupCalibrate(); - - gpuErrchk(cudaMemcpyToSymbolAsync(NESTGPUTimeResolution, &time_resolution_, - sizeof(float))); -/////////////////////////////////// + + gpuErrchk( cudaMemcpyToSymbolAsync( NESTGPUTimeResolution, &time_resolution_, sizeof( float ) ) ); + /////////////////////////////////// return 0; } -int NESTGPU::Simulate(float sim_time) { +int +NESTGPU::Simulate( float sim_time ) +{ sim_time_ = sim_time; return Simulate(); } -int NESTGPU::Simulate() +int +NESTGPU::Simulate() { StartSimulation(); - - for (long long it=0; it=2 && print_time_==true) { - printf("\r[%.2lf %%] Model time: %.3lf ms", 100.0*(neural_time_-neur_t0_)/sim_time_, neural_time_); + + for ( long long it = 0; it < Nt_; it++ ) + { + if ( it % 100 == 0 && verbosity_level_ >= 2 && print_time_ == true ) + { + printf( "\r[%.2lf %%] Model time: %.3lf ms", 100.0 * ( neural_time_ - neur_t0_ ) / sim_time_, neural_time_ ); } SimulationStep(); } @@ -371,760 +383,804 @@ int NESTGPU::Simulate() return 0; } -int NESTGPU::StartSimulation() +int +NESTGPU::StartSimulation() { - if (!calibrate_flag_) { + if ( !calibrate_flag_ ) + { Calibrate(); } -#ifdef HAVE_MPI - if (mpi_flag_) { - MPI_Barrier(MPI_COMM_WORLD); +#ifdef HAVE_MPI + if ( mpi_flag_ ) + { + MPI_Barrier( MPI_COMM_WORLD ); } #endif - if (first_simulation_flag_) { - gpuErrchk(cudaMemcpyToSymbolAsync(NESTGPUTime, &neural_time_, sizeof(double))); - multimeter_->WriteRecords(neural_time_); + if ( first_simulation_flag_ ) + { + gpuErrchk( cudaMemcpyToSymbolAsync( NESTGPUTime, &neural_time_, sizeof( double ) ) ); + multimeter_->WriteRecords( neural_time_ ); build_real_time_ = getRealTime(); first_simulation_flag_ = false; } - if (verbosity_level_>=1) { + if ( verbosity_level_ >= 1 ) + { std::cout << MpiRankStr() << "Simulating ...\n"; - printf("Neural activity simulation time: %.3lf ms\n", sim_time_); + printf( "Neural activity simulation time: %.3lf ms\n", sim_time_ ); } - + neur_t0_ = neural_time_; it_ = 0; - Nt_ = (long long)round(sim_time_/time_resolution_); - + Nt_ = ( long long ) round( sim_time_ / time_resolution_ ); + return 0; } -int NESTGPU::EndSimulation() +int +NESTGPU::EndSimulation() { - if (verbosity_level_>=2 && print_time_==true) { - printf("\r[%.2lf %%] Model time: %.3lf ms", 100.0*(neural_time_-neur_t0_)/sim_time_, neural_time_); + if ( verbosity_level_ >= 2 && print_time_ == true ) + { + printf( "\r[%.2lf %%] Model time: %.3lf ms", 100.0 * ( neural_time_ - neur_t0_ ) / sim_time_, neural_time_ ); } -#ifdef HAVE_MPI - if (mpi_flag_) { - MPI_Barrier(MPI_COMM_WORLD); +#ifdef HAVE_MPI + if ( mpi_flag_ ) + { + MPI_Barrier( MPI_COMM_WORLD ); } #endif end_real_time_ = getRealTime(); - //multimeter_->CloseFiles(); - //neuron.rk5.Free(); + // multimeter_->CloseFiles(); + // neuron.rk5.Free(); - if (verbosity_level_>=3) { + if ( verbosity_level_ >= 3 ) + { std::cout << "\n"; - std::cout << MpiRankStr() << " SpikeBufferUpdate_time: " << - SpikeBufferUpdate_time_ << "\n"; - std::cout << MpiRankStr() << " poisson_generator_time: " << - poisson_generator_time_ << "\n"; - std::cout << MpiRankStr() << " neuron_Update_time: " << - neuron_Update_time_ << "\n"; - std::cout << MpiRankStr() << " copy_ext_spike_time: " << - copy_ext_spike_time_ << "\n"; - std::cout << MpiRankStr() << " SendExternalSpike_time: " << - SendExternalSpike_time_ << "\n"; - std::cout << MpiRankStr() << " SendSpikeToRemote_time: " << - SendSpikeToRemote_time_ << "\n"; - std::cout << MpiRankStr() << " RecvSpikeFromRemote_time: " << - RecvSpikeFromRemote_time_ << "\n"; - std::cout << MpiRankStr() << " NestedLoop_time: " << - NestedLoop_time_ << "\n"; - std::cout << MpiRankStr() << " GetSpike_time: " << - GetSpike_time_ << "\n"; - std::cout << MpiRankStr() << " SpikeReset_time: " << - SpikeReset_time_ << "\n"; - std::cout << MpiRankStr() << " ExternalSpikeReset_time: " << - ExternalSpikeReset_time_ << "\n"; + std::cout << MpiRankStr() << " SpikeBufferUpdate_time: " << SpikeBufferUpdate_time_ << "\n"; + std::cout << MpiRankStr() << " poisson_generator_time: " << poisson_generator_time_ << "\n"; + std::cout << MpiRankStr() << " neuron_Update_time: " << neuron_Update_time_ << "\n"; + std::cout << MpiRankStr() << " copy_ext_spike_time: " << copy_ext_spike_time_ << "\n"; + std::cout << MpiRankStr() << " SendExternalSpike_time: " << SendExternalSpike_time_ << "\n"; + std::cout << MpiRankStr() << " SendSpikeToRemote_time: " << SendSpikeToRemote_time_ << "\n"; + std::cout << MpiRankStr() << " RecvSpikeFromRemote_time: " << RecvSpikeFromRemote_time_ << "\n"; + std::cout << MpiRankStr() << " NestedLoop_time: " << NestedLoop_time_ << "\n"; + std::cout << MpiRankStr() << " GetSpike_time: " << GetSpike_time_ << "\n"; + std::cout << MpiRankStr() << " SpikeReset_time: " << SpikeReset_time_ << "\n"; + std::cout << MpiRankStr() << " ExternalSpikeReset_time: " << ExternalSpikeReset_time_ << "\n"; } #ifdef HAVE_MPI - if (mpi_flag_ && verbosity_level_>=4) { - std::cout << MpiRankStr() << " SendSpikeToRemote_MPI_time: " << - connect_mpi_->SendSpikeToRemote_MPI_time_ << "\n"; - std::cout << MpiRankStr() << " RecvSpikeFromRemote_MPI_time: " << - connect_mpi_->RecvSpikeFromRemote_MPI_time_ << "\n"; - std::cout << MpiRankStr() << " SendSpikeToRemote_CUDAcp_time: " << - connect_mpi_->SendSpikeToRemote_CUDAcp_time_ << "\n"; - std::cout << MpiRankStr() << " RecvSpikeFromRemote_CUDAcp_time: " << - connect_mpi_->RecvSpikeFromRemote_CUDAcp_time_ << "\n"; - std::cout << MpiRankStr() << " JoinSpike_time: " << - connect_mpi_->JoinSpike_time_ << "\n"; + if ( mpi_flag_ && verbosity_level_ >= 4 ) + { + std::cout << MpiRankStr() << " SendSpikeToRemote_MPI_time: " << connect_mpi_->SendSpikeToRemote_MPI_time_ << "\n"; + std::cout << MpiRankStr() << " RecvSpikeFromRemote_MPI_time: " << connect_mpi_->RecvSpikeFromRemote_MPI_time_ + << "\n"; + std::cout << MpiRankStr() << " SendSpikeToRemote_CUDAcp_time: " << connect_mpi_->SendSpikeToRemote_CUDAcp_time_ + << "\n"; + std::cout << MpiRankStr() << " RecvSpikeFromRemote_CUDAcp_time: " << connect_mpi_->RecvSpikeFromRemote_CUDAcp_time_ + << "\n"; + std::cout << MpiRankStr() << " JoinSpike_time: " << connect_mpi_->JoinSpike_time_ << "\n"; } #endif - - if (verbosity_level_>=1) { - std::cout << MpiRankStr() << "Building time: " << - (build_real_time_ - start_real_time_) << "\n"; - std::cout << MpiRankStr() << "Simulation time: " << - (end_real_time_ - build_real_time_) << "\n"; - } - + + if ( verbosity_level_ >= 1 ) + { + std::cout << MpiRankStr() << "Building time: " << ( build_real_time_ - start_real_time_ ) << "\n"; + std::cout << MpiRankStr() << "Simulation time: " << ( end_real_time_ - build_real_time_ ) << "\n"; + } + return 0; } -int NESTGPU::SimulationStep() +int +NESTGPU::SimulationStep() { - if (first_simulation_flag_) { + if ( first_simulation_flag_ ) + { StartSimulation(); } double time_mark; time_mark = getRealTime(); - SpikeBufferUpdate<<<(net_connection_->connection_.size()+1023)/1024, - 1024>>>(); + SpikeBufferUpdate<<< ( net_connection_->connection_.size() + 1023 ) / 1024, 1024 >>>(); gpuErrchk( cudaPeekAtLastError() ); - SpikeBufferUpdate_time_ += (getRealTime() - time_mark); + SpikeBufferUpdate_time_ += ( getRealTime() - time_mark ); time_mark = getRealTime(); - if (n_poiss_node_>0) { - poiss_generator_->Update(Nt_-it_); - poisson_generator_time_ += (getRealTime() - time_mark); + if ( n_poiss_node_ > 0 ) + { + poiss_generator_->Update( Nt_ - it_ ); + poisson_generator_time_ += ( getRealTime() - time_mark ); } time_mark = getRealTime(); - neural_time_ = neur_t0_ + (double)time_resolution_*(it_+1); - gpuErrchk(cudaMemcpyToSymbolAsync(NESTGPUTime, &neural_time_, sizeof(double))); - long long time_idx = (int)round(neur_t0_/time_resolution_) + it_ + 1; - gpuErrchk(cudaMemcpyToSymbolAsync(NESTGPUTimeIdx, &time_idx, sizeof(long long))); - - if (ConnectionSpikeTimeFlag) { - if ( (time_idx & 0xffff) == 0x8000) { - ResetConnectionSpikeTimeUp(net_connection_); + neural_time_ = neur_t0_ + ( double ) time_resolution_ * ( it_ + 1 ); + gpuErrchk( cudaMemcpyToSymbolAsync( NESTGPUTime, &neural_time_, sizeof( double ) ) ); + long long time_idx = ( int ) round( neur_t0_ / time_resolution_ ) + it_ + 1; + gpuErrchk( cudaMemcpyToSymbolAsync( NESTGPUTimeIdx, &time_idx, sizeof( long long ) ) ); + + if ( ConnectionSpikeTimeFlag ) + { + if ( ( time_idx & 0xffff ) == 0x8000 ) + { + ResetConnectionSpikeTimeUp( net_connection_ ); } - else if ( (time_idx & 0xffff) == 0) { - ResetConnectionSpikeTimeDown(net_connection_); + else if ( ( time_idx & 0xffff ) == 0 ) + { + ResetConnectionSpikeTimeDown( net_connection_ ); } } - - for (unsigned int i=0; iUpdate(it_, neural_time_); + + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + node_vect_[ i ]->Update( it_, neural_time_ ); } gpuErrchk( cudaPeekAtLastError() ); - - neuron_Update_time_ += (getRealTime() - time_mark); - multimeter_->WriteRecords(neural_time_); + + neuron_Update_time_ += ( getRealTime() - time_mark ); + multimeter_->WriteRecords( neural_time_ ); #ifdef HAVE_MPI - if (mpi_flag_) { + if ( mpi_flag_ ) + { int n_ext_spike; time_mark = getRealTime(); - gpuErrchk(cudaMemcpy(&n_ext_spike, d_ExternalSpikeNum, sizeof(int), - cudaMemcpyDeviceToHost)); - copy_ext_spike_time_ += (getRealTime() - time_mark); + gpuErrchk( cudaMemcpy( &n_ext_spike, d_ExternalSpikeNum, sizeof( int ), cudaMemcpyDeviceToHost ) ); + copy_ext_spike_time_ += ( getRealTime() - time_mark ); - if (n_ext_spike != 0) { + if ( n_ext_spike != 0 ) + { time_mark = getRealTime(); - SendExternalSpike<<<(n_ext_spike+1023)/1024, 1024>>>(); + SendExternalSpike<<< ( n_ext_spike + 1023 ) / 1024, 1024 >>>(); gpuErrchk( cudaPeekAtLastError() ); - SendExternalSpike_time_ += (getRealTime() - time_mark); + SendExternalSpike_time_ += ( getRealTime() - time_mark ); } - //for (int ih=0; ihmpi_np_; ih++) { - //if (ih == connect_mpi_->mpi_id_) { + // for (int ih=0; ihmpi_np_; ih++) { + // if (ih == connect_mpi_->mpi_id_) { time_mark = getRealTime(); - connect_mpi_->SendSpikeToRemote(connect_mpi_->mpi_np_, - max_spike_per_host_); - SendSpikeToRemote_time_ += (getRealTime() - time_mark); + connect_mpi_->SendSpikeToRemote( connect_mpi_->mpi_np_, max_spike_per_host_ ); + SendSpikeToRemote_time_ += ( getRealTime() - time_mark ); time_mark = getRealTime(); - connect_mpi_->RecvSpikeFromRemote(connect_mpi_->mpi_np_, - max_spike_per_host_); - - RecvSpikeFromRemote_time_ += (getRealTime() - time_mark); - connect_mpi_->CopySpikeFromRemote(connect_mpi_->mpi_np_, - max_spike_per_host_, - i_remote_node_0_); - MPI_Barrier(MPI_COMM_WORLD); + connect_mpi_->RecvSpikeFromRemote( connect_mpi_->mpi_np_, max_spike_per_host_ ); + + RecvSpikeFromRemote_time_ += ( getRealTime() - time_mark ); + connect_mpi_->CopySpikeFromRemote( connect_mpi_->mpi_np_, max_spike_per_host_, i_remote_node_0_ ); + MPI_Barrier( MPI_COMM_WORLD ); } #endif - + int n_spikes; - time_mark = getRealTime(); + // Call will get delayed until ClearGetSpikesArrays() // afterwards the value of n_spikes will be available - gpuErrchk(cudaMemcpyAsync(&n_spikes, d_SpikeNum, sizeof(int), - cudaMemcpyDeviceToHost)); + gpuErrchk( cudaMemcpyAsync( &n_spikes, d_SpikeNum, sizeof( int ), cudaMemcpyDeviceToHost ) ); - ClearGetSpikeArrays(); - gpuErrchk( cudaDeviceSynchronize() ); - if (n_spikes > 0) { + ClearGetSpikeArrays(); + gpuErrchk( cudaDeviceSynchronize() ); + if ( n_spikes > 0 ) + { time_mark = getRealTime(); - CollectSpikeKernel<<>>(n_spikes, d_SpikeTargetNum); - gpuErrchk(cudaPeekAtLastError()); + CollectSpikeKernel<<< n_spikes, 1024 >>>( n_spikes, d_SpikeTargetNum ); + gpuErrchk( cudaPeekAtLastError() ); - NestedLoop_time_ += (getRealTime() - time_mark); + NestedLoop_time_ += ( getRealTime() - time_mark ); } time_mark = getRealTime(); - for (unsigned int i=0; ihas_dir_conn_) { - node_vect_[i]->SendDirectSpikes(neural_time_, time_resolution_/1000.0); + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + if ( node_vect_[ i ]->has_dir_conn_ ) + { + node_vect_[ i ]->SendDirectSpikes( neural_time_, time_resolution_ / 1000.0 ); } } - poisson_generator_time_ += (getRealTime() - time_mark); + poisson_generator_time_ += ( getRealTime() - time_mark ); time_mark = getRealTime(); - for (unsigned int i=0; in_port_>0) { - - int grid_dim_x = (node_vect_[i]->n_node_+1023)/1024; - int grid_dim_y = node_vect_[i]->n_port_; - dim3 grid_dim(grid_dim_x, grid_dim_y); - //dim3 block_dim(1024,1); - - GetSpikes<<>> //block_dim>>> - (node_vect_[i]->get_spike_array_, node_vect_[i]->n_node_, - node_vect_[i]->n_port_, - node_vect_[i]->n_var_, - node_vect_[i]->port_weight_arr_, - node_vect_[i]->port_weight_arr_step_, - node_vect_[i]->port_weight_port_step_, - node_vect_[i]->port_input_arr_, - node_vect_[i]->port_input_arr_step_, - node_vect_[i]->port_input_port_step_); + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + if ( node_vect_[ i ]->n_port_ > 0 ) + { + + int grid_dim_x = ( node_vect_[ i ]->n_node_ + 1023 ) / 1024; + int grid_dim_y = node_vect_[ i ]->n_port_; + dim3 grid_dim( grid_dim_x, grid_dim_y ); + // dim3 block_dim(1024,1); + + GetSpikes<<< grid_dim, 1024 >>> // block_dim>>> + ( node_vect_[ i ]->get_spike_array_, + node_vect_[ i ]->n_node_, + node_vect_[ i ]->n_port_, + node_vect_[ i ]->n_var_, + node_vect_[ i ]->port_weight_arr_, + node_vect_[ i ]->port_weight_arr_step_, + node_vect_[ i ]->port_weight_port_step_, + node_vect_[ i ]->port_input_arr_, + node_vect_[ i ]->port_input_arr_step_, + node_vect_[ i ]->port_input_port_step_ ); } } gpuErrchk( cudaPeekAtLastError() ); - GetSpike_time_ += (getRealTime() - time_mark); + GetSpike_time_ += ( getRealTime() - time_mark ); time_mark = getRealTime(); - SpikeReset<<<1, 1>>>(); + SpikeReset<<< 1, 1 >>>(); gpuErrchk( cudaPeekAtLastError() ); - SpikeReset_time_ += (getRealTime() - time_mark); + SpikeReset_time_ += ( getRealTime() - time_mark ); #ifdef HAVE_MPI - if (mpi_flag_) { + if ( mpi_flag_ ) + { time_mark = getRealTime(); - ExternalSpikeReset<<<1, 1>>>(); + ExternalSpikeReset<<< 1, 1 >>>(); gpuErrchk( cudaPeekAtLastError() ); - ExternalSpikeReset_time_ += (getRealTime() - time_mark); + ExternalSpikeReset_time_ += ( getRealTime() - time_mark ); } #endif - if (net_connection_->NRevConnections()>0) { - //time_mark = getRealTime(); - RevSpikeReset<<<1, 1>>>(); + if ( net_connection_->NRevConnections() > 0 ) + { + // time_mark = getRealTime(); + RevSpikeReset<<< 1, 1 >>>(); gpuErrchk( cudaPeekAtLastError() ); - RevSpikeBufferUpdate<<<(net_connection_->connection_.size()+1023)/1024, - 1024>>>(net_connection_->connection_.size()); + RevSpikeBufferUpdate<<< ( net_connection_->connection_.size() + 1023 ) / 1024, 1024 >>>( + net_connection_->connection_.size() ); gpuErrchk( cudaPeekAtLastError() ); unsigned int n_rev_spikes; - gpuErrchk(cudaMemcpy(&n_rev_spikes, d_RevSpikeNum, sizeof(unsigned int), - cudaMemcpyDeviceToHost)); - if (n_rev_spikes > 0) { - SynapseUpdateKernel<<>>(n_rev_spikes, d_RevSpikeNConn); - gpuErrchk(cudaPeekAtLastError()); - } - //RevSpikeBufferUpdate_time_ += (getRealTime() - time_mark); + gpuErrchk( cudaMemcpy( &n_rev_spikes, d_RevSpikeNum, sizeof( unsigned int ), cudaMemcpyDeviceToHost ) ); + if ( n_rev_spikes > 0 ) + { + SynapseUpdateKernel<<< n_rev_spikes, 1024 >>>( n_rev_spikes, d_RevSpikeNConn ); + gpuErrchk( cudaPeekAtLastError() ); + } + // RevSpikeBufferUpdate_time_ += (getRealTime() - time_mark); } - for (unsigned int i=0; imax_n_rec_spike_times_>0) { + if ( node_vect_[ i ]->max_n_rec_spike_times_ > 0 ) + { // and if buffering is activated every n_step time steps... - int n_step = node_vect_[i]->rec_spike_times_step_; - if (n_step>0 && (time_idx%n_step == n_step-1)) { + int n_step = node_vect_[ i ]->rec_spike_times_step_; + if ( n_step > 0 && ( time_idx % n_step == n_step - 1 ) ) + { // extract recorded spike times and put them in buffers - node_vect_[i]->BufferRecSpikeTimes(); + node_vect_[ i ]->BufferRecSpikeTimes(); } } } it_++; - + return 0; } -int NESTGPU::CreateRecord(std::string file_name, std::string *var_name_arr, - int *i_node_arr, int *port_arr, - int n_node) +int +NESTGPU::CreateRecord( std::string file_name, std::string* var_name_arr, int* i_node_arr, int* port_arr, int n_node ) { - std::vector neur_vect; - std::vector i_neur_vect; - std::vector port_vect; - std::vector var_name_vect; - for (int i=0; ii_node_0_); - port_vect.push_back(port_arr[i]); - neur_vect.push_back(node_vect_[i_group]); + std::vector< BaseNeuron* > neur_vect; + std::vector< int > i_neur_vect; + std::vector< int > port_vect; + std::vector< std::string > var_name_vect; + for ( int i = 0; i < n_node; i++ ) + { + var_name_vect.push_back( var_name_arr[ i ] ); + int i_group = node_group_map_[ i_node_arr[ i ] ]; + i_neur_vect.push_back( i_node_arr[ i ] - node_vect_[ i_group ]->i_node_0_ ); + port_vect.push_back( port_arr[ i ] ); + neur_vect.push_back( node_vect_[ i_group ] ); } - return multimeter_->CreateRecord(neur_vect, file_name, var_name_vect, - i_neur_vect, port_vect); - + return multimeter_->CreateRecord( neur_vect, file_name, var_name_vect, i_neur_vect, port_vect ); } -int NESTGPU::CreateRecord(std::string file_name, std::string *var_name_arr, - int *i_node_arr, int n_node) +int +NESTGPU::CreateRecord( std::string file_name, std::string* var_name_arr, int* i_node_arr, int n_node ) { - std::vector port_vect(n_node, 0); - return CreateRecord(file_name, var_name_arr, i_node_arr, - port_vect.data(), n_node); + std::vector< int > port_vect( n_node, 0 ); + return CreateRecord( file_name, var_name_arr, i_node_arr, port_vect.data(), n_node ); } -std::vector > *NESTGPU::GetRecordData(int i_record) +std::vector< std::vector< float > >* +NESTGPU::GetRecordData( int i_record ) { - return multimeter_->GetRecordData(i_record); + return multimeter_->GetRecordData( i_record ); } -int NESTGPU::GetNodeSequenceOffset(int i_node, int n_node, int &i_group) +int +NESTGPU::GetNodeSequenceOffset( int i_node, int n_node, int& i_group ) { - if (i_node<0 || (i_node+n_node > (int)node_group_map_.size())) { - throw ngpu_exception("Unrecognized node in getting node sequence offset"); + if ( i_node < 0 || ( i_node + n_node > ( int ) node_group_map_.size() ) ) + { + throw ngpu_exception( "Unrecognized node in getting node sequence offset" ); } - i_group = node_group_map_[i_node]; - if (node_group_map_[i_node+n_node-1] != i_group) { - throw ngpu_exception("Nodes belong to different node groups " - "in setting parameter"); + i_group = node_group_map_[ i_node ]; + if ( node_group_map_[ i_node + n_node - 1 ] != i_group ) + { + throw ngpu_exception( + "Nodes belong to different node groups " + "in setting parameter" ); } - return node_vect_[i_group]->i_node_0_; + return node_vect_[ i_group ]->i_node_0_; } - -std::vector NESTGPU::GetNodeArrayWithOffset(int *i_node, int n_node, - int &i_group) + +std::vector< int > +NESTGPU::GetNodeArrayWithOffset( int* i_node, int n_node, int& i_group ) { - int in0 = i_node[0]; - if (in0<0 || in0>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in setting parameter"); + int in0 = i_node[ 0 ]; + if ( in0 < 0 || in0 > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in setting parameter" ); } - i_group = node_group_map_[in0]; - int i0 = node_vect_[i_group]->i_node_0_; - std::vector nodes; - nodes.assign(i_node, i_node+n_node); - for(int i=0; i=(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in setting parameter"); + i_group = node_group_map_[ in0 ]; + int i0 = node_vect_[ i_group ]->i_node_0_; + std::vector< int > nodes; + nodes.assign( i_node, i_node + n_node ); + for ( int i = 0; i < n_node; i++ ) + { + int in = nodes[ i ]; + if ( in < 0 || in >= ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in setting parameter" ); } - if (node_group_map_[in] != i_group) { - throw ngpu_exception("Nodes belong to different node groups " - "in setting parameter"); + if ( node_group_map_[ in ] != i_group ) + { + throw ngpu_exception( + "Nodes belong to different node groups " + "in setting parameter" ); } - nodes[i] -= i0; + nodes[ i ] -= i0; } return nodes; } -int NESTGPU::SetNeuronParam(int i_node, int n_node, - std::string param_name, float val) +int +NESTGPU::SetNeuronParam( int i_node, int n_node, std::string param_name, float val ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - - return node_vect_[i_group]->SetScalParam(i_neuron, n_node, param_name, val); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + + return node_vect_[ i_group ]->SetScalParam( i_neuron, n_node, param_name, val ); } -int NESTGPU::SetNeuronParam(int *i_node, int n_node, - std::string param_name, float val) +int +NESTGPU::SetNeuronParam( int* i_node, int n_node, std::string param_name, float val ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - return node_vect_[i_group]->SetScalParam(nodes.data(), n_node, - param_name, val); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + return node_vect_[ i_group ]->SetScalParam( nodes.data(), n_node, param_name, val ); } -int NESTGPU::SetNeuronParam(int i_node, int n_node, std::string param_name, - float *param, int array_size) +int +NESTGPU::SetNeuronParam( int i_node, int n_node, std::string param_name, float* param, int array_size ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - if (node_vect_[i_group]->IsPortParam(param_name)) { - return node_vect_[i_group]->SetPortParam(i_neuron, n_node, param_name, - param, array_size); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsPortParam( param_name ) ) + { + return node_vect_[ i_group ]->SetPortParam( i_neuron, n_node, param_name, param, array_size ); } - else { - return node_vect_[i_group]->SetArrayParam(i_neuron, n_node, param_name, - param, array_size); + else + { + return node_vect_[ i_group ]->SetArrayParam( i_neuron, n_node, param_name, param, array_size ); } } -int NESTGPU::SetNeuronParam( int *i_node, int n_node, - std::string param_name, float *param, - int array_size) +int +NESTGPU::SetNeuronParam( int* i_node, int n_node, std::string param_name, float* param, int array_size ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - if (node_vect_[i_group]->IsPortParam(param_name)) { - return node_vect_[i_group]->SetPortParam(nodes.data(), n_node, - param_name, param, array_size); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsPortParam( param_name ) ) + { + return node_vect_[ i_group ]->SetPortParam( nodes.data(), n_node, param_name, param, array_size ); + } + else + { + return node_vect_[ i_group ]->SetArrayParam( nodes.data(), n_node, param_name, param, array_size ); } - else { - return node_vect_[i_group]->SetArrayParam(nodes.data(), n_node, - param_name, param, array_size); - } } -int NESTGPU::IsNeuronScalParam(int i_node, std::string param_name) +int +NESTGPU::IsNeuronScalParam( int i_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsScalParam(param_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsScalParam( param_name ); } -int NESTGPU::IsNeuronPortParam(int i_node, std::string param_name) +int +NESTGPU::IsNeuronPortParam( int i_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsPortParam(param_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsPortParam( param_name ); } -int NESTGPU::IsNeuronArrayParam(int i_node, std::string param_name) +int +NESTGPU::IsNeuronArrayParam( int i_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsArrayParam(param_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsArrayParam( param_name ); } -int NESTGPU::SetNeuronIntVar(int i_node, int n_node, - std::string var_name, int val) +int +NESTGPU::SetNeuronIntVar( int i_node, int n_node, std::string var_name, int val ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - - return node_vect_[i_group]->SetIntVar(i_neuron, n_node, var_name, val); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + + return node_vect_[ i_group ]->SetIntVar( i_neuron, n_node, var_name, val ); } -int NESTGPU::SetNeuronIntVar(int *i_node, int n_node, - std::string var_name, int val) +int +NESTGPU::SetNeuronIntVar( int* i_node, int n_node, std::string var_name, int val ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - return node_vect_[i_group]->SetIntVar(nodes.data(), n_node, - var_name, val); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + return node_vect_[ i_group ]->SetIntVar( nodes.data(), n_node, var_name, val ); } -int NESTGPU::SetNeuronVar(int i_node, int n_node, - std::string var_name, float val) +int +NESTGPU::SetNeuronVar( int i_node, int n_node, std::string var_name, float val ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - - return node_vect_[i_group]->SetScalVar(i_neuron, n_node, var_name, val); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + + return node_vect_[ i_group ]->SetScalVar( i_neuron, n_node, var_name, val ); } -int NESTGPU::SetNeuronVar(int *i_node, int n_node, - std::string var_name, float val) +int +NESTGPU::SetNeuronVar( int* i_node, int n_node, std::string var_name, float val ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - return node_vect_[i_group]->SetScalVar(nodes.data(), n_node, - var_name, val); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + return node_vect_[ i_group ]->SetScalVar( nodes.data(), n_node, var_name, val ); } -int NESTGPU::SetNeuronVar(int i_node, int n_node, std::string var_name, - float *var, int array_size) +int +NESTGPU::SetNeuronVar( int i_node, int n_node, std::string var_name, float* var, int array_size ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - if (node_vect_[i_group]->IsPortVar(var_name)) { - return node_vect_[i_group]->SetPortVar(i_neuron, n_node, var_name, - var, array_size); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsPortVar( var_name ) ) + { + return node_vect_[ i_group ]->SetPortVar( i_neuron, n_node, var_name, var, array_size ); } - else { - return node_vect_[i_group]->SetArrayVar(i_neuron, n_node, var_name, - var, array_size); + else + { + return node_vect_[ i_group ]->SetArrayVar( i_neuron, n_node, var_name, var, array_size ); } } -int NESTGPU::SetNeuronVar( int *i_node, int n_node, - std::string var_name, float *var, - int array_size) +int +NESTGPU::SetNeuronVar( int* i_node, int n_node, std::string var_name, float* var, int array_size ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - if (node_vect_[i_group]->IsPortVar(var_name)) { - return node_vect_[i_group]->SetPortVar(nodes.data(), n_node, - var_name, var, array_size); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsPortVar( var_name ) ) + { + return node_vect_[ i_group ]->SetPortVar( nodes.data(), n_node, var_name, var, array_size ); + } + else + { + return node_vect_[ i_group ]->SetArrayVar( nodes.data(), n_node, var_name, var, array_size ); } - else { - return node_vect_[i_group]->SetArrayVar(nodes.data(), n_node, - var_name, var, array_size); - } } -int NESTGPU::IsNeuronIntVar(int i_node, std::string var_name) +int +NESTGPU::IsNeuronIntVar( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsIntVar(var_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsIntVar( var_name ); } -int NESTGPU::IsNeuronScalVar(int i_node, std::string var_name) +int +NESTGPU::IsNeuronScalVar( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsScalVar(var_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsScalVar( var_name ); } -int NESTGPU::IsNeuronPortVar(int i_node, std::string var_name) +int +NESTGPU::IsNeuronPortVar( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsPortVar(var_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsPortVar( var_name ); } -int NESTGPU::IsNeuronArrayVar(int i_node, std::string var_name) +int +NESTGPU::IsNeuronArrayVar( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - - return node_vect_[i_group]->IsArrayVar(var_name); + GetNodeSequenceOffset( i_node, 1, i_group ); + + return node_vect_[ i_group ]->IsArrayVar( var_name ); } -int NESTGPU::GetNeuronParamSize(int i_node, std::string param_name) +int +NESTGPU::GetNeuronParamSize( int i_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - if (node_vect_[i_group]->IsArrayParam(param_name)!=0) { - return node_vect_[i_group]->GetArrayParamSize(i_neuron, param_name); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, 1, i_group ); + if ( node_vect_[ i_group ]->IsArrayParam( param_name ) != 0 ) + { + return node_vect_[ i_group ]->GetArrayParamSize( i_neuron, param_name ); } - else { - return node_vect_[i_group]->GetParamSize(param_name); + else + { + return node_vect_[ i_group ]->GetParamSize( param_name ); } } -int NESTGPU::GetNeuronVarSize(int i_node, std::string var_name) +int +NESTGPU::GetNeuronVarSize( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - if (node_vect_[i_group]->IsArrayVar(var_name)!=0) { - return node_vect_[i_group]->GetArrayVarSize(i_neuron, var_name); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, 1, i_group ); + if ( node_vect_[ i_group ]->IsArrayVar( var_name ) != 0 ) + { + return node_vect_[ i_group ]->GetArrayVarSize( i_neuron, var_name ); } - else { - return node_vect_[i_group]->GetVarSize(var_name); + else + { + return node_vect_[ i_group ]->GetVarSize( var_name ); } } -float *NESTGPU::GetNeuronParam(int i_node, int n_node, - std::string param_name) +float* +NESTGPU::GetNeuronParam( int i_node, int n_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - if (node_vect_[i_group]->IsScalParam(param_name)) { - return node_vect_[i_group]->GetScalParam(i_neuron, n_node, param_name); - } - else if (node_vect_[i_group]->IsPortParam(param_name)) { - return node_vect_[i_group]->GetPortParam(i_neuron, n_node, param_name); - } - else if (node_vect_[i_group]->IsArrayParam(param_name)) { - if (n_node != 1) { - throw ngpu_exception("Cannot get array parameters for more than one node" - "at a time"); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsScalParam( param_name ) ) + { + return node_vect_[ i_group ]->GetScalParam( i_neuron, n_node, param_name ); + } + else if ( node_vect_[ i_group ]->IsPortParam( param_name ) ) + { + return node_vect_[ i_group ]->GetPortParam( i_neuron, n_node, param_name ); + } + else if ( node_vect_[ i_group ]->IsArrayParam( param_name ) ) + { + if ( n_node != 1 ) + { + throw ngpu_exception( + "Cannot get array parameters for more than one node" + "at a time" ); } - return node_vect_[i_group]->GetArrayParam(i_neuron, param_name); + return node_vect_[ i_group ]->GetArrayParam( i_neuron, param_name ); } - else { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } } -float *NESTGPU::GetNeuronParam( int *i_node, int n_node, - std::string param_name) +float* +NESTGPU::GetNeuronParam( int* i_node, int n_node, std::string param_name ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - if (node_vect_[i_group]->IsScalParam(param_name)) { - return node_vect_[i_group]->GetScalParam(nodes.data(), n_node, - param_name); - } - else if (node_vect_[i_group]->IsPortParam(param_name)) { - return node_vect_[i_group]->GetPortParam(nodes.data(), n_node, - param_name); - } - else if (node_vect_[i_group]->IsArrayParam(param_name)) { - if (n_node != 1) { - throw ngpu_exception("Cannot get array parameters for more than one node" - "at a time"); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsScalParam( param_name ) ) + { + return node_vect_[ i_group ]->GetScalParam( nodes.data(), n_node, param_name ); + } + else if ( node_vect_[ i_group ]->IsPortParam( param_name ) ) + { + return node_vect_[ i_group ]->GetPortParam( nodes.data(), n_node, param_name ); + } + else if ( node_vect_[ i_group ]->IsArrayParam( param_name ) ) + { + if ( n_node != 1 ) + { + throw ngpu_exception( + "Cannot get array parameters for more than one node" + "at a time" ); } - return node_vect_[i_group]->GetArrayParam(nodes[0], param_name); + return node_vect_[ i_group ]->GetArrayParam( nodes[ 0 ], param_name ); } - else { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } } -float *NESTGPU::GetArrayParam(int i_node, std::string param_name) +float* +NESTGPU::GetArrayParam( int i_node, std::string param_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, 1, i_group ); - return node_vect_[i_group]->GetArrayParam(i_neuron, param_name); + return node_vect_[ i_group ]->GetArrayParam( i_neuron, param_name ); } -int *NESTGPU::GetNeuronIntVar(int i_node, int n_node, - std::string var_name) +int* +NESTGPU::GetNeuronIntVar( int i_node, int n_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - if (node_vect_[i_group]->IsIntVar(var_name)) { - return node_vect_[i_group]->GetIntVar(i_neuron, n_node, var_name); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsIntVar( var_name ) ) + { + return node_vect_[ i_group ]->GetIntVar( i_neuron, n_node, var_name ); } - else { - throw ngpu_exception(std::string("Unrecognized integer variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized integer variable " ) + var_name ); } } -int *NESTGPU::GetNeuronIntVar(int *i_node, int n_node, - std::string var_name) +int* +NESTGPU::GetNeuronIntVar( int* i_node, int n_node, std::string var_name ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - if (node_vect_[i_group]->IsIntVar(var_name)) { - return node_vect_[i_group]->GetIntVar(nodes.data(), n_node, - var_name); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsIntVar( var_name ) ) + { + return node_vect_[ i_group ]->GetIntVar( nodes.data(), n_node, var_name ); } - else { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } } -float *NESTGPU::GetNeuronVar(int i_node, int n_node, - std::string var_name) +float* +NESTGPU::GetNeuronVar( int i_node, int n_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, n_node, i_group); - if (node_vect_[i_group]->IsScalVar(var_name)) { - return node_vect_[i_group]->GetScalVar(i_neuron, n_node, var_name); - } - else if (node_vect_[i_group]->IsPortVar(var_name)) { - return node_vect_[i_group]->GetPortVar(i_neuron, n_node, var_name); - } - else if (node_vect_[i_group]->IsArrayVar(var_name)) { - if (n_node != 1) { - throw ngpu_exception("Cannot get array variables for more than one node" - "at a time"); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsScalVar( var_name ) ) + { + return node_vect_[ i_group ]->GetScalVar( i_neuron, n_node, var_name ); + } + else if ( node_vect_[ i_group ]->IsPortVar( var_name ) ) + { + return node_vect_[ i_group ]->GetPortVar( i_neuron, n_node, var_name ); + } + else if ( node_vect_[ i_group ]->IsArrayVar( var_name ) ) + { + if ( n_node != 1 ) + { + throw ngpu_exception( + "Cannot get array variables for more than one node" + "at a time" ); } - return node_vect_[i_group]->GetArrayVar(i_neuron, var_name); + return node_vect_[ i_group ]->GetArrayVar( i_neuron, var_name ); } - else { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } } -float *NESTGPU::GetNeuronVar(int *i_node, int n_node, - std::string var_name) +float* +NESTGPU::GetNeuronVar( int* i_node, int n_node, std::string var_name ) { int i_group; - std::vector nodes = GetNodeArrayWithOffset(i_node, n_node, - i_group); - if (node_vect_[i_group]->IsScalVar(var_name)) { - return node_vect_[i_group]->GetScalVar(nodes.data(), n_node, - var_name); - } - else if (node_vect_[i_group]->IsPortVar(var_name)) { - return node_vect_[i_group]->GetPortVar(nodes.data(), n_node, - var_name); - } - else if (node_vect_[i_group]->IsArrayVar(var_name)) { - if (n_node != 1) { - throw ngpu_exception("Cannot get array variables for more than one node" - "at a time"); + std::vector< int > nodes = GetNodeArrayWithOffset( i_node, n_node, i_group ); + if ( node_vect_[ i_group ]->IsScalVar( var_name ) ) + { + return node_vect_[ i_group ]->GetScalVar( nodes.data(), n_node, var_name ); + } + else if ( node_vect_[ i_group ]->IsPortVar( var_name ) ) + { + return node_vect_[ i_group ]->GetPortVar( nodes.data(), n_node, var_name ); + } + else if ( node_vect_[ i_group ]->IsArrayVar( var_name ) ) + { + if ( n_node != 1 ) + { + throw ngpu_exception( + "Cannot get array variables for more than one node" + "at a time" ); } - return node_vect_[i_group]->GetArrayVar(nodes[0], var_name); + return node_vect_[ i_group ]->GetArrayVar( nodes[ 0 ], var_name ); } - else { - throw ngpu_exception(std::string("Unrecognized variable ") - + var_name); + else + { + throw ngpu_exception( std::string( "Unrecognized variable " ) + var_name ); } } -float *NESTGPU::GetArrayVar(int i_node, std::string var_name) +float* +NESTGPU::GetArrayVar( int i_node, std::string var_name ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, 1, i_group ); - return node_vect_[i_group]->GetArrayVar(i_neuron, var_name); + return node_vect_[ i_group ]->GetArrayVar( i_neuron, var_name ); } -int NESTGPU::ConnectMpiInit(int argc, char *argv[]) +int +NESTGPU::ConnectMpiInit( int argc, char* argv[] ) { #ifdef HAVE_MPI - CheckUncalibrated("MPI connections cannot be initialized after calibration"); - int err = connect_mpi_->MpiInit(argc, argv); - if (err==0) { + CheckUncalibrated( "MPI connections cannot be initialized after calibration" ); + int err = connect_mpi_->MpiInit( argc, argv ); + if ( err == 0 ) + { mpi_flag_ = true; } - + return err; #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::MpiId() +int +NESTGPU::MpiId() { #ifdef HAVE_MPI return connect_mpi_->mpi_id_; #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -int NESTGPU::MpiNp() +int +NESTGPU::MpiNp() { #ifdef HAVE_MPI return connect_mpi_->mpi_np_; #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif - } -int NESTGPU::ProcMaster() +int +NESTGPU::ProcMaster() { #ifdef HAVE_MPI return connect_mpi_->ProcMaster(); #else - throw ngpu_exception("MPI is not available in your build"); -#endif + throw ngpu_exception( "MPI is not available in your build" ); +#endif } -int NESTGPU::MpiFinalize() +int +NESTGPU::MpiFinalize() { #ifdef HAVE_MPI - if (mpi_flag_) { + if ( mpi_flag_ ) + { int finalized; - MPI_Finalized(&finalized); - if (!finalized) { + MPI_Finalized( &finalized ); + if ( !finalized ) + { MPI_Finalize(); } } - + return 0; #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } -std::string NESTGPU::MpiRankStr() +std::string +NESTGPU::MpiRankStr() { #ifdef HAVE_MPI - if (mpi_flag_) { - return std::string("MPI rank ") + std::to_string(connect_mpi_->mpi_id_) - + " : "; + if ( mpi_flag_ ) + { + return std::string( "MPI rank " ) + std::to_string( connect_mpi_->mpi_id_ ) + " : "; } - else { + else + { return ""; } #else @@ -1132,685 +1188,780 @@ std::string NESTGPU::MpiRankStr() #endif } -unsigned int *NESTGPU::RandomInt(size_t n) +unsigned int* +NESTGPU::RandomInt( size_t n ) { - return curand_int(*random_generator_, n); + return curand_int( *random_generator_, n ); } -float *NESTGPU::RandomUniform(size_t n) +float* +NESTGPU::RandomUniform( size_t n ) { - return curand_uniform(*random_generator_, n); + return curand_uniform( *random_generator_, n ); } -float *NESTGPU::RandomNormal(size_t n, float mean, float stddev) +float* +NESTGPU::RandomNormal( size_t n, float mean, float stddev ) { - return curand_normal(*random_generator_, n, mean, stddev); + return curand_normal( *random_generator_, n, mean, stddev ); } -float *NESTGPU::RandomNormalClipped(size_t n, float mean, float stddev, - float vmin, float vmax, float vstep) +float* +NESTGPU::RandomNormalClipped( size_t n, float mean, float stddev, float vmin, float vmax, float vstep ) { const float epsi = 1.0e-6; - - n = (n/4 + 1)*4; - int n_extra = n/10; - n_extra = (n_extra/4 + 1)*4; - if (n_extra<1024) { - n_extra=1024; + + n = ( n / 4 + 1 ) * 4; + int n_extra = n / 10; + n_extra = ( n_extra / 4 + 1 ) * 4; + if ( n_extra < 1024 ) + { + n_extra = 1024; } int i_extra = 0; - float *arr = curand_normal(*random_generator_, n, mean, stddev); - float *arr_extra = NULL; - for (size_t i=0; ivmax) { - if (i_extra==0) { - arr_extra = curand_normal(*random_generator_, n_extra, mean, stddev); + float* arr = curand_normal( *random_generator_, n, mean, stddev ); + float* arr_extra = NULL; + for ( size_t i = 0; i < n; i++ ) + { + while ( arr[ i ] < vmin || arr[ i ] > vmax ) + { + if ( i_extra == 0 ) + { + arr_extra = curand_normal( *random_generator_, n_extra, mean, stddev ); } - arr[i] = arr_extra[i_extra]; + arr[ i ] = arr_extra[ i_extra ]; i_extra++; - if (i_extra==n_extra) { - i_extra = 0; - delete[](arr_extra); - arr_extra = NULL; + if ( i_extra == n_extra ) + { + i_extra = 0; + delete[] ( arr_extra ); + arr_extra = NULL; } } } - if (arr_extra != NULL) { - delete[](arr_extra); + if ( arr_extra != NULL ) + { + delete[] ( arr_extra ); } - if (vstep>stddev*epsi) { - for (size_t i=0; i stddev * epsi ) + { + for ( size_t i = 0; i < n; i++ ) + { + arr[ i ] = vmin + vstep * round( ( arr[ i ] - vmin ) / vstep ); } } - return arr; -} - -int NESTGPU::BuildDirectConnections() -{ - for (unsigned int iv=0; ivhas_dir_conn_) { - std::vector dir_conn_vect; - int i0 = node_vect_[iv]->i_node_0_; - int n = node_vect_[iv]->n_node_; - for (int i_source=i0; i_source &conn = net_connection_->connection_[i_source]; - for (unsigned int id=0; id tv = conn[id].target_vect; - for (unsigned int i=0; ihas_dir_conn_ ) + { + std::vector< DirectConnection > dir_conn_vect; + int i0 = node_vect_[ iv ]->i_node_0_; + int n = node_vect_[ iv ]->n_node_; + for ( int i_source = i0; i_source < i0 + n; i_source++ ) + { + std::vector< ConnGroup >& conn = net_connection_->connection_[ i_source ]; + for ( unsigned int id = 0; id < conn.size(); id++ ) + { + std::vector< TargetSyn > tv = conn[ id ].target_vect; + for ( unsigned int i = 0; i < tv.size(); i++ ) + { + DirectConnection dir_conn; + dir_conn.irel_source_ = i_source - i0; + dir_conn.i_target_ = tv[ i ].node; + dir_conn.port_ = tv[ i ].port; + dir_conn.weight_ = tv[ i ].weight; + dir_conn.delay_ = time_resolution_ * ( conn[ id ].delay + 1 ); + dir_conn_vect.push_back( dir_conn ); + } + } } uint64_t n_dir_conn = dir_conn_vect.size(); - node_vect_[iv]->n_dir_conn_ = n_dir_conn; - - DirectConnection *d_dir_conn_array; - gpuErrchk(cudaMalloc(&d_dir_conn_array, - n_dir_conn*sizeof(DirectConnection ))); - gpuErrchk(cudaMemcpy(d_dir_conn_array, dir_conn_vect.data(), - n_dir_conn*sizeof(DirectConnection), - cudaMemcpyHostToDevice)); - node_vect_[iv]->d_dir_conn_array_ = d_dir_conn_array; + node_vect_[ iv ]->n_dir_conn_ = n_dir_conn; + + DirectConnection* d_dir_conn_array; + gpuErrchk( cudaMalloc( &d_dir_conn_array, n_dir_conn * sizeof( DirectConnection ) ) ); + gpuErrchk( cudaMemcpy( + d_dir_conn_array, dir_conn_vect.data(), n_dir_conn * sizeof( DirectConnection ), cudaMemcpyHostToDevice ) ); + node_vect_[ iv ]->d_dir_conn_array_ = d_dir_conn_array; } } return 0; } -std::vector NESTGPU::GetIntVarNames(int i_node) +std::vector< std::string > +NESTGPU::GetIntVarNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading variable names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading variable names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetIntVarNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetIntVarNames(); } -std::vector NESTGPU::GetScalVarNames(int i_node) +std::vector< std::string > +NESTGPU::GetScalVarNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading variable names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading variable names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetScalVarNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetScalVarNames(); } -int NESTGPU::GetNIntVar(int i_node) +int +NESTGPU::GetNIntVar( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "variables"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "variables" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNIntVar(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNIntVar(); } -int NESTGPU::GetNScalVar(int i_node) +int +NESTGPU::GetNScalVar( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "variables"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "variables" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNScalVar(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNScalVar(); } -std::vector NESTGPU::GetPortVarNames(int i_node) +std::vector< std::string > +NESTGPU::GetPortVarNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading variable names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading variable names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetPortVarNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetPortVarNames(); } -int NESTGPU::GetNPortVar(int i_node) +int +NESTGPU::GetNPortVar( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "variables"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "variables" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNPortVar(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNPortVar(); } -std::vector NESTGPU::GetScalParamNames(int i_node) +std::vector< std::string > +NESTGPU::GetScalParamNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading parameter names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading parameter names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetScalParamNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetScalParamNames(); } -int NESTGPU::GetNScalParam(int i_node) +int +NESTGPU::GetNScalParam( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "parameters"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "parameters" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNScalParam(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNScalParam(); } -std::vector NESTGPU::GetPortParamNames(int i_node) +std::vector< std::string > +NESTGPU::GetPortParamNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading parameter names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading parameter names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetPortParamNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetPortParamNames(); } -int NESTGPU::GetNPortParam(int i_node) +int +NESTGPU::GetNPortParam( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "parameters"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "parameters" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNPortParam(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNPortParam(); } -std::vector NESTGPU::GetArrayParamNames(int i_node) +std::vector< std::string > +NESTGPU::GetArrayParamNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading array parameter names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading array parameter names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetArrayParamNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetArrayParamNames(); } -int NESTGPU::GetNArrayParam(int i_node) +int +NESTGPU::GetNArrayParam( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of array " - "parameters"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of array " + "parameters" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNArrayParam(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNArrayParam(); } -std::vector NESTGPU::GetArrayVarNames(int i_node) +std::vector< std::string > +NESTGPU::GetArrayVarNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading array variable names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading array variable names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetArrayVarNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetArrayVarNames(); } -int NESTGPU::GetNArrayVar(int i_node) +int +NESTGPU::GetNArrayVar( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of array " - "variables"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of array " + "variables" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNArrayVar(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNArrayVar(); } -ConnectionStatus NESTGPU::GetConnectionStatus(ConnectionId conn_id) { - ConnectionStatus conn_stat = net_connection_->GetConnectionStatus(conn_id); - if (calibrate_flag_ == true) { +ConnectionStatus +NESTGPU::GetConnectionStatus( ConnectionId conn_id ) +{ + ConnectionStatus conn_stat = net_connection_->GetConnectionStatus( conn_id ); + if ( calibrate_flag_ == true ) + { int i_source = conn_id.i_source_; int i_group = conn_id.i_group_; int i_conn = conn_id.i_conn_; int n_spike_buffer = net_connection_->connection_.size(); conn_stat.weight = 0; - float *d_weight_pt - = h_ConnectionGroupTargetWeight[i_group*n_spike_buffer+i_source] + i_conn; - gpuErrchk(cudaMemcpy(&conn_stat.weight, d_weight_pt, sizeof(float), - cudaMemcpyDeviceToHost)); + float* d_weight_pt = h_ConnectionGroupTargetWeight[ i_group * n_spike_buffer + i_source ] + i_conn; + gpuErrchk( cudaMemcpy( &conn_stat.weight, d_weight_pt, sizeof( float ), cudaMemcpyDeviceToHost ) ); } return conn_stat; } -std::vector NESTGPU::GetConnectionStatus(std::vector - - &conn_id_vect) { - std::vector conn_stat_vect; - for (unsigned int i=0; i +NESTGPU::GetConnectionStatus( std::vector< ConnectionId >& conn_id_vect ) +{ + std::vector< ConnectionStatus > conn_stat_vect; + for ( unsigned int i = 0; i < conn_id_vect.size(); i++ ) + { + ConnectionStatus conn_stat = GetConnectionStatus( conn_id_vect[ i ] ); + conn_stat_vect.push_back( conn_stat ); } return conn_stat_vect; } - -std::vector NESTGPU::GetConnections(int i_source, int n_source, - int i_target, int n_target, - int syn_group) { - if (n_source<=0) { + +std::vector< ConnectionId > +NESTGPU::GetConnections( int i_source, int n_source, int i_target, int n_target, int syn_group ) +{ + if ( n_source <= 0 ) + { i_source = 0; n_source = net_connection_->connection_.size(); } - if (n_target<=0) { + if ( n_target <= 0 ) + { i_target = 0; n_target = net_connection_->connection_.size(); } - return net_connection_->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + return net_connection_->GetConnections< int >( i_source, n_source, i_target, n_target, syn_group ); } -std::vector NESTGPU::GetConnections(int *i_source, int n_source, - int i_target, int n_target, - int syn_group) { - if (n_target<=0) { +std::vector< ConnectionId > +NESTGPU::GetConnections( int* i_source, int n_source, int i_target, int n_target, int syn_group ) +{ + if ( n_target <= 0 ) + { i_target = 0; n_target = net_connection_->connection_.size(); } - - return net_connection_->GetConnections(i_source, n_source, i_target, - n_target, syn_group); - + + return net_connection_->GetConnections< int* >( i_source, n_source, i_target, n_target, syn_group ); } -std::vector NESTGPU::GetConnections(int i_source, int n_source, - int *i_target, int n_target, - int syn_group) { - if (n_source<=0) { +std::vector< ConnectionId > +NESTGPU::GetConnections( int i_source, int n_source, int* i_target, int n_target, int syn_group ) +{ + if ( n_source <= 0 ) + { i_source = 0; n_source = net_connection_->connection_.size(); } - - return net_connection_->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + + return net_connection_->GetConnections< int >( i_source, n_source, i_target, n_target, syn_group ); } -std::vector NESTGPU::GetConnections(int *i_source, int n_source, - int *i_target, int n_target, - int syn_group) { - - return net_connection_->GetConnections(i_source, n_source, i_target, - n_target, syn_group); - +std::vector< ConnectionId > +NESTGPU::GetConnections( int* i_source, int n_source, int* i_target, int n_target, int syn_group ) +{ + + return net_connection_->GetConnections< int* >( i_source, n_source, i_target, n_target, syn_group ); } -std::vector NESTGPU::GetConnections(NodeSeq source, - NodeSeq target, - int syn_group) { - return net_connection_->GetConnections(source.i0, source.n, target.i0, - target.n, syn_group); +std::vector< ConnectionId > +NESTGPU::GetConnections( NodeSeq source, NodeSeq target, int syn_group ) +{ + return net_connection_->GetConnections< int >( source.i0, source.n, target.i0, target.n, syn_group ); } -std::vector NESTGPU::GetConnections(std::vector source, - NodeSeq target, - int syn_group) { - return net_connection_->GetConnections(source.data(), source.size(), - target.i0, target.n, - syn_group); +std::vector< ConnectionId > +NESTGPU::GetConnections( std::vector< int > source, NodeSeq target, int syn_group ) +{ + return net_connection_->GetConnections< int* >( source.data(), source.size(), target.i0, target.n, syn_group ); } -std::vector NESTGPU::GetConnections(NodeSeq source, - std::vector target, - int syn_group) { - return net_connection_->GetConnections(source.i0, source.n, - target.data(), target.size(), - syn_group); +std::vector< ConnectionId > +NESTGPU::GetConnections( NodeSeq source, std::vector< int > target, int syn_group ) +{ + return net_connection_->GetConnections< int >( source.i0, source.n, target.data(), target.size(), syn_group ); } -std::vector NESTGPU::GetConnections(std::vector source, - std::vector target, - int syn_group) { - return net_connection_->GetConnections(source.data(), source.size(), - target.data(), target.size(), - syn_group); +std::vector< ConnectionId > +NESTGPU::GetConnections( std::vector< int > source, std::vector< int > target, int syn_group ) +{ + return net_connection_->GetConnections< int* >( + source.data(), source.size(), target.data(), target.size(), syn_group ); } -int NESTGPU::ActivateSpikeCount(int i_node, int n_node) +int +NESTGPU::ActivateSpikeCount( int i_node, int n_node ) { - CheckUncalibrated("Spike count must be activated before calibration"); + CheckUncalibrated( "Spike count must be activated before calibration" ); int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, n_node, i_group); - if (i_node_0!=i_node || node_vect_[i_group]->n_node_!=n_node) { - throw ngpu_exception("Spike count must be activated for all and only " - " the nodes of the same group"); + int i_node_0 = GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( i_node_0 != i_node || node_vect_[ i_group ]->n_node_ != n_node ) + { + throw ngpu_exception( + "Spike count must be activated for all and only " + " the nodes of the same group" ); } - node_vect_[i_group]->ActivateSpikeCount(); + node_vect_[ i_group ]->ActivateSpikeCount(); return 0; } -int NESTGPU::ActivateRecSpikeTimes(int i_node, int n_node, - int max_n_rec_spike_times) +int +NESTGPU::ActivateRecSpikeTimes( int i_node, int n_node, int max_n_rec_spike_times ) { - CheckUncalibrated("Spike time recording must be activated " - "before calibration"); + CheckUncalibrated( + "Spike time recording must be activated " + "before calibration" ); int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, n_node, i_group); - if (i_node_0!=i_node || node_vect_[i_group]->n_node_!=n_node) { - throw ngpu_exception("Spike count must be activated for all and only " - " the nodes of the same group"); + int i_node_0 = GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( i_node_0 != i_node || node_vect_[ i_group ]->n_node_ != n_node ) + { + throw ngpu_exception( + "Spike count must be activated for all and only " + " the nodes of the same group" ); } - node_vect_[i_group]->ActivateRecSpikeTimes(max_n_rec_spike_times); + node_vect_[ i_group ]->ActivateRecSpikeTimes( max_n_rec_spike_times ); return 0; } -int NESTGPU::SetRecSpikeTimesStep(int i_node, int n_node, - int rec_spike_times_step) +int +NESTGPU::SetRecSpikeTimesStep( int i_node, int n_node, int rec_spike_times_step ) { int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, n_node, i_group); - if (i_node_0!=i_node || node_vect_[i_group]->n_node_!=n_node) { - throw ngpu_exception("Time step for buffering spike time recording " - "must be set for all and only " - "the nodes of the same group"); + int i_node_0 = GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( i_node_0 != i_node || node_vect_[ i_group ]->n_node_ != n_node ) + { + throw ngpu_exception( + "Time step for buffering spike time recording " + "must be set for all and only " + "the nodes of the same group" ); } - node_vect_[i_group]->SetRecSpikeTimesStep(rec_spike_times_step); + node_vect_[ i_group ]->SetRecSpikeTimesStep( rec_spike_times_step ); return 0; } // get number of recorded spike times for a node -int NESTGPU::GetNRecSpikeTimes(int i_node) +int +NESTGPU::GetNRecSpikeTimes( int i_node ) { int i_group; - int i_neuron = i_node - GetNodeSequenceOffset(i_node, 1, i_group); - return node_vect_[i_group]->GetNRecSpikeTimes(i_neuron); + int i_neuron = i_node - GetNodeSequenceOffset( i_node, 1, i_group ); + return node_vect_[ i_group ]->GetNRecSpikeTimes( i_neuron ); } // get recorded spike times for node group -int NESTGPU::GetRecSpikeTimes(int i_node, int n_node, int **n_spike_times_pt, - float ***spike_times_pt) +int +NESTGPU::GetRecSpikeTimes( int i_node, int n_node, int** n_spike_times_pt, float*** spike_times_pt ) { int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, n_node, i_group); - if (i_node_0!=i_node || node_vect_[i_group]->n_node_!=n_node) { - throw ngpu_exception("Spike times must be extracted for all and only " - " the nodes of the same group"); + int i_node_0 = GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( i_node_0 != i_node || node_vect_[ i_group ]->n_node_ != n_node ) + { + throw ngpu_exception( + "Spike times must be extracted for all and only " + " the nodes of the same group" ); } - - return node_vect_[i_group]->GetRecSpikeTimes(n_spike_times_pt, - spike_times_pt); - + + return node_vect_[ i_group ]->GetRecSpikeTimes( n_spike_times_pt, spike_times_pt ); } -int NESTGPU::PushSpikesToNodes(int n_spikes, int *node_id, - float *spike_height) +int +NESTGPU::PushSpikesToNodes( int n_spikes, int* node_id, float* spike_height ) { - int *d_node_id; - float *d_spike_height; - gpuErrchk(cudaMalloc(&d_node_id, n_spikes*sizeof(int))); - gpuErrchk(cudaMalloc(&d_spike_height, n_spikes*sizeof(float))); + int* d_node_id; + float* d_spike_height; + gpuErrchk( cudaMalloc( &d_node_id, n_spikes * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_spike_height, n_spikes * sizeof( float ) ) ); // Memcpy are synchronized by PushSpikeFromRemote kernel - gpuErrchk(cudaMemcpyAsync(d_node_id, node_id, n_spikes*sizeof(int), - cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpyAsync(d_spike_height, spike_height, n_spikes*sizeof(float), - cudaMemcpyHostToDevice)); - PushSpikeFromRemote<<<(n_spikes+1023)/1024, 1024>>>(n_spikes, d_node_id, - d_spike_height); + gpuErrchk( cudaMemcpyAsync( d_node_id, node_id, n_spikes * sizeof( int ), cudaMemcpyHostToDevice ) ); + gpuErrchk( cudaMemcpyAsync( d_spike_height, spike_height, n_spikes * sizeof( float ), cudaMemcpyHostToDevice ) ); + PushSpikeFromRemote<<< ( n_spikes + 1023 ) / 1024, 1024 >>>( n_spikes, d_node_id, d_spike_height ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_node_id)); - gpuErrchk(cudaFree(d_spike_height)); + gpuErrchk( cudaFree( d_node_id ) ); + gpuErrchk( cudaFree( d_spike_height ) ); return 0; } -int NESTGPU::PushSpikesToNodes(int n_spikes, int *node_id) +int +NESTGPU::PushSpikesToNodes( int n_spikes, int* node_id ) { - //std::cout << "n_spikes: " << n_spikes << "\n"; - //for (int i=0; i>>(n_spikes, d_node_id); + gpuErrchk( cudaMemcpyAsync( d_node_id, node_id, n_spikes * sizeof( int ), cudaMemcpyHostToDevice ) ); + PushSpikeFromRemote<<< ( n_spikes + 1023 ) / 1024, 1024 >>>( n_spikes, d_node_id ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - gpuErrchk(cudaFree(d_node_id)); + gpuErrchk( cudaFree( d_node_id ) ); return 0; } -int NESTGPU::GetExtNeuronInputSpikes(int *n_spikes, int **node, int **port, - float **spike_height, bool include_zeros) +int +NESTGPU::GetExtNeuronInputSpikes( int* n_spikes, int** node, int** port, float** spike_height, bool include_zeros ) { ext_neuron_input_spike_node_.clear(); ext_neuron_input_spike_port_.clear(); ext_neuron_input_spike_height_.clear(); - - for (unsigned int i=0; iIsExtNeuron()) { + + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { + if ( node_vect_[ i ]->IsExtNeuron() ) + { int n_node; int n_port; - float *sh = node_vect_[i]->GetExtNeuronInputSpikes(&n_node, &n_port); - for (int i_neur=0; i_neuri_node_0_; - for (int i_port=0; i_portGetExtNeuronInputSpikes( &n_node, &n_port ); + for ( int i_neur = 0; i_neur < n_node; i_neur++ ) + { + int i_node = i_neur + node_vect_[ i ]->i_node_0_; + for ( int i_port = 0; i_port < n_port; i_port++ ) + { + int j = i_neur * n_port + i_port; + if ( sh[ j ] != 0.0 || include_zeros ) + { + ext_neuron_input_spike_node_.push_back( i_node ); + ext_neuron_input_spike_port_.push_back( i_port ); + ext_neuron_input_spike_height_.push_back( sh[ j ] ); + } + } + } } } *n_spikes = ext_neuron_input_spike_node_.size(); *node = ext_neuron_input_spike_node_.data(); *port = ext_neuron_input_spike_port_.data(); *spike_height = ext_neuron_input_spike_height_.data(); - + return 0; } -int NESTGPU::SetNeuronGroupParam(int i_node, int n_node, - std::string param_name, float val) +int +NESTGPU::SetNeuronGroupParam( int i_node, int n_node, std::string param_name, float val ) { int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, n_node, i_group); - if (i_node_0!=i_node || node_vect_[i_group]->n_node_!=n_node) { + int i_node_0 = GetNodeSequenceOffset( i_node, n_node, i_group ); + if ( i_node_0 != i_node || node_vect_[ i_group ]->n_node_ != n_node ) + { throw ngpu_exception(std::string("Group parameter ") + param_name + " can only be set for all and only " " the nodes of the same group"); } - return node_vect_[i_group]->SetGroupParam(param_name, val); + return node_vect_[ i_group ]->SetGroupParam( param_name, val ); } -int NESTGPU::IsNeuronGroupParam(int i_node, std::string param_name) +int +NESTGPU::IsNeuronGroupParam( int i_node, std::string param_name ) { int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, 1, i_group); + GetNodeSequenceOffset( i_node, 1, i_group ); - return node_vect_[i_group]->IsGroupParam(param_name); + return node_vect_[ i_group ]->IsGroupParam( param_name ); } -float NESTGPU::GetNeuronGroupParam(int i_node, std::string param_name) +float +NESTGPU::GetNeuronGroupParam( int i_node, std::string param_name ) { int i_group; - int i_node_0 = GetNodeSequenceOffset(i_node, 1, i_group); + GetNodeSequenceOffset( i_node, 1, i_group ); - return node_vect_[i_group]->GetGroupParam(param_name); + return node_vect_[ i_group ]->GetGroupParam( param_name ); } -std::vector NESTGPU::GetGroupParamNames(int i_node) +std::vector< std::string > +NESTGPU::GetGroupParamNames( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading group parameter names"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( "Unrecognized node in reading group parameter names" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetGroupParamNames(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetGroupParamNames(); } -int NESTGPU::GetNGroupParam(int i_node) +int +NESTGPU::GetNGroupParam( int i_node ) { - if (i_node<0 || i_node>(int)node_group_map_.size()) { - throw ngpu_exception("Unrecognized node in reading number of " - "group parameters"); + if ( i_node < 0 || i_node > ( int ) node_group_map_.size() ) + { + throw ngpu_exception( + "Unrecognized node in reading number of " + "group parameters" ); } - int i_group = node_group_map_[i_node]; - - return node_vect_[i_group]->GetNGroupParam(); + int i_group = node_group_map_[ i_node ]; + + return node_vect_[ i_group ]->GetNGroupParam(); } // Connect spike buffers of remote source nodes to local target nodes // Maybe move this in connect_rules.cpp ? And parallelize with OpenMP? -int NESTGPU::ConnectRemoteNodes() +int +NESTGPU::ConnectRemoteNodes() { - if (n_remote_node_>0) { + if ( n_remote_node_ > 0 ) + { i_remote_node_0_ = node_group_map_.size(); - BaseNeuron *bn = new BaseNeuron; - node_vect_.push_back(bn); - CreateNodeGroup(n_remote_node_, 0); - for (unsigned int i=0; iConnect(i_remote_node_0_ + rc.i_source_rel, rc.i_target, - rc.port, rc.syn_group, rc.weight, rc.delay); - + BaseNeuron* bn = new BaseNeuron; + node_vect_.push_back( bn ); + CreateNodeGroup( n_remote_node_, 0 ); + for ( unsigned int i = 0; i < remote_connection_vect_.size(); i++ ) + { + RemoteConnection rc = remote_connection_vect_[ i ]; + net_connection_->Connect( + i_remote_node_0_ + rc.i_source_rel, rc.i_target, rc.port, rc.syn_group, rc.weight, rc.delay ); } } - + return 0; } -int NESTGPU::GetNBoolParam() +int +NESTGPU::GetNBoolParam() { return N_KERNEL_BOOL_PARAM; } -std::vector NESTGPU::GetBoolParamNames() +std::vector< std::string > +NESTGPU::GetBoolParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < N_KERNEL_BOOL_PARAM; i++ ) + { + param_name_vect.push_back( kernel_bool_param_name[ i ] ); } - + return param_name_vect; } -bool NESTGPU::IsBoolParam(std::string param_name) +bool +NESTGPU::IsBoolParam( std::string param_name ) { int i_param; - for (i_param=0; i_param NESTGPU::GetFloatParamNames() +std::vector< std::string > +NESTGPU::GetFloatParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < N_KERNEL_FLOAT_PARAM; i++ ) + { + param_name_vect.push_back( kernel_float_param_name[ i ] ); } - + return param_name_vect; } -bool NESTGPU::IsFloatParam(std::string param_name) +bool +NESTGPU::IsFloatParam( std::string param_name ) { int i_param; - for (i_param=0; i_param NESTGPU::GetIntParamNames() +std::vector< std::string > +NESTGPU::GetIntParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < N_KERNEL_INT_PARAM; i++ ) + { + param_name_vect.push_back( kernel_int_param_name[ i ] ); } - + return param_name_vect; } -bool NESTGPU::IsIntParam(std::string param_name) +bool +NESTGPU::IsIntParam( std::string param_name ) { int i_param; - for (i_param=0; i_paramremote_spike_height_) { + if ( connect_mpi_->remote_spike_height_ ) + { return 1; } - else { + else + { return 0; } #else return 0; #endif default: - throw ngpu_exception(std::string("Unrecognized kernel int parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized kernel int parameter " ) + param_name ); } } -int NESTGPU::SetIntParam(std::string param_name, int val) +int +NESTGPU::SetIntParam( std::string param_name, int val ) { - int i_param = GetIntParamIdx(param_name); - switch (i_param) { + int i_param = GetIntParamIdx( param_name ); + switch ( i_param ) + { case i_rnd_seed: - SetRandomSeed(val); + SetRandomSeed( val ); break; case i_verbosity_level: - SetVerbosityLevel(val); + SetVerbosityLevel( val ); break; case i_max_spike_per_host_fact: - SetMaxSpikeBufferSize(val); + SetMaxSpikeBufferSize( val ); break; case i_remote_spike_height_flag: #ifdef HAVE_MPI - if (val==0) { + if ( val == 0 ) + { connect_mpi_->remote_spike_height_ = false; } - else if (val==1) { + else if ( val == 1 ) + { connect_mpi_->remote_spike_height_ = true; } - else { - throw ngpu_exception("Admissible values of remote_spike_height_flag are only 0 or 1"); + else + { + throw ngpu_exception( "Admissible values of remote_spike_height_flag are only 0 or 1" ); } break; #else - throw ngpu_exception("remote_spike_height_flag cannot be changed in an installation without MPI support"); + throw ngpu_exception( "remote_spike_height_flag cannot be changed in an installation without MPI support" ); #endif default: - throw ngpu_exception(std::string("Unrecognized kernel int parameter ") - + param_name); + throw ngpu_exception( std::string( "Unrecognized kernel int parameter " ) + param_name ); } - + return 0; } -RemoteNodeSeq NESTGPU::RemoteCreate(int i_host, std::string model_name, - int n_node /*=1*/, int n_port /*=1*/) +RemoteNodeSeq +NESTGPU::RemoteCreate( int i_host, std::string model_name, int n_node /*=1*/, int n_port /*=1*/ ) { #ifdef HAVE_MPI - if (i_host<0 || i_host>=MpiNp()) { - throw ngpu_exception("Invalid host index in RemoteCreate"); + if ( i_host < 0 || i_host >= MpiNp() ) + { + throw ngpu_exception( "Invalid host index in RemoteCreate" ); } NodeSeq node_seq; - if (i_host == MpiId()) { - node_seq = Create(model_name, n_node, n_port); + if ( i_host == MpiId() ) + { + node_seq = Create( model_name, n_node, n_port ); } - MPI_Bcast(&node_seq, sizeof(NodeSeq), MPI_BYTE, i_host, MPI_COMM_WORLD); - return RemoteNodeSeq(i_host, node_seq); + MPI_Bcast( &node_seq, sizeof( NodeSeq ), MPI_BYTE, i_host, MPI_COMM_WORLD ); + return RemoteNodeSeq( i_host, node_seq ); #else - throw ngpu_exception("MPI is not available in your build"); + throw ngpu_exception( "MPI is not available in your build" ); #endif } diff --git a/src/nestgpu.h b/src/nestgpu.h index 8b5fc3a78..87385cf87 100644 --- a/src/nestgpu.h +++ b/src/nestgpu.h @@ -21,23 +21,20 @@ */ - - - #ifndef NESTGPU_H #define NESTGPU_H -#include -#include -#include #include +#include #include +#include +#include -#include "ngpu_exception.h" -#include "node_group.h" #include "base_neuron.h" -#include "connect_spec.h" #include "connect.h" +#include "connect_spec.h" +#include "ngpu_exception.h" +#include "node_group.h" #include "syn_model.h" #ifdef HAVE_MPI @@ -54,37 +51,51 @@ class SynSpec; class Sequence { - public: +public: int i0; int n; - - Sequence(int i0=0, int n=0) : i0(i0), n(n) {} - - inline int operator[](int i) { - if (i<0) { - throw ngpu_exception("Sequence index cannot be negative"); + + Sequence( int i0 = 0, int n = 0 ) + : i0( i0 ) + , n( n ) + { + } + + inline int + operator[]( int i ) + { + if ( i < 0 ) + { + throw ngpu_exception( "Sequence index cannot be negative" ); } - if (i>=n) { - throw ngpu_exception("Sequence index out of range"); + if ( i >= n ) + { + throw ngpu_exception( "Sequence index out of range" ); } return i0 + i; } - inline Sequence Subseq(int first, int last) { - if (first<0 || first>last) { - throw ngpu_exception("Sequence subset range error"); + inline Sequence + Subseq( int first, int last ) + { + if ( first < 0 || first > last ) + { + throw ngpu_exception( "Sequence subset range error" ); } - if (last>=n) { - throw ngpu_exception("Sequence subset out of range"); + if ( last >= n ) + { + throw ngpu_exception( "Sequence subset out of range" ); } - return Sequence(i0 + first, last - first + 1); + return Sequence( i0 + first, last - first + 1 ); } // https://stackoverflow.com/questions/18625223 - inline std::vector ToVector() { + inline std::vector< int > + ToVector() + { int start = i0; - std::vector v(n); - std::iota(v.begin(), v.end(), start); + std::vector< int > v( n ); + std::iota( v.begin(), v.end(), start ); return v; } }; @@ -93,37 +104,44 @@ typedef Sequence NodeSeq; class RemoteNodeSeq { - public: +public: int i_host; NodeSeq node_seq; - - RemoteNodeSeq(int i_host=0, NodeSeq node_seq=NodeSeq(0,0)) : - i_host(i_host), node_seq(node_seq) {} + + RemoteNodeSeq( int i_host = 0, NodeSeq node_seq = NodeSeq( 0, 0 ) ) + : i_host( i_host ) + , node_seq( node_seq ) + { + } }; -enum {ON_EXCEPTION_EXIT=0, ON_EXCEPTION_HANDLE}; +enum +{ + ON_EXCEPTION_EXIT = 0, + ON_EXCEPTION_HANDLE +}; class NESTGPU { float time_resolution_; // time resolution in ms - curandGenerator_t *random_generator_; + curandGenerator_t* random_generator_; unsigned long long kernel_seed_; bool calibrate_flag_; // becomes true after calibration - PoissonGenerator *poiss_generator_; - Multimeter *multimeter_; - std::vector node_vect_; // -> node_group_vect - std::vector syn_group_vect_; - - NetConnection *net_connection_; + PoissonGenerator* poiss_generator_; + Multimeter* multimeter_; + std::vector< BaseNeuron* > node_vect_; // -> node_group_vect + std::vector< SynModel* > syn_group_vect_; + + NetConnection* net_connection_; bool mpi_flag_; // true if MPI is initialized #ifdef HAVE_MPI - ConnectMpi *connect_mpi_; + ConnectMpi* connect_mpi_; #endif - - std::vector node_group_map_; - signed char *d_node_group_map_; + + std::vector< signed char > node_group_map_; + signed char* d_node_group_map_; int max_spike_buffer_size_; @@ -135,10 +153,10 @@ class NESTGPU double t_min_; double neural_time_; // Neural activity time - double sim_time_; // Simulation time in ms - double neur_t0_; // Neural activity simulation time origin - long long it_; // simulation time index - long long Nt_; // number of simulation time steps + double sim_time_; // Simulation time in ms + double neur_t0_; // Neural activity simulation time origin + long long it_; // simulation time index + long long Nt_; // number of simulation time steps int n_poiss_node_; int n_remote_node_; int i_remote_node_0_; @@ -155,96 +173,103 @@ class NESTGPU int verbosity_level_; bool print_time_; - std::vector remote_connection_vect_; - std::vector ext_neuron_input_spike_node_; - std::vector ext_neuron_input_spike_port_; - std::vector ext_neuron_input_spike_height_; + std::vector< RemoteConnection > remote_connection_vect_; + std::vector< int > ext_neuron_input_spike_node_; + std::vector< int > ext_neuron_input_spike_port_; + std::vector< float > ext_neuron_input_spike_height_; - int CreateNodeGroup(int n_neuron, int n_port); - int CheckUncalibrated(std::string message); - double *InitGetSpikeArray(int n_node, int n_port); + int CreateNodeGroup( int n_neuron, int n_port ); + int CheckUncalibrated( std::string message ); + double* InitGetSpikeArray( int n_node, int n_port ); int NodeGroupArrayInit(); int ClearGetSpikeArrays(); int FreeGetSpikeArrays(); int FreeNodeGroupMap(); - template - int _Connect(T1 source, int n_source, T2 target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); - - template - int _SingleConnect(T1 source, int i_source, T2 target, int i_target, - int i_array, SynSpec &syn_spec); - template - int _SingleConnect(T1 source, int i_source, T2 target, int i_target, - float weight, float delay, int i_array, - SynSpec &syn_spec); - - template - int _RemoteSingleConnect(int i_source, T target, int i_target, - int i_array, SynSpec &syn_spec); - template - int _RemoteSingleConnect(int i_source, T target, int i_target, - float weight, float delay, int i_array, - SynSpec &syn_spec); - - template - int _ConnectOneToOne(T1 source, T2 target, int n_node, SynSpec &syn_spec); - - template - int _ConnectAllToAll - (T1 source, int n_source, T2 target, int n_target, SynSpec &syn_spec); - - template - int _ConnectFixedTotalNumber - (T1 source, int n_source, T2 target, int n_target, int n_conn, - SynSpec &syn_spec); - - template - int _ConnectFixedIndegree - ( - T1 source, int n_source, T2 target, int n_target, int indegree, - SynSpec &syn_spec - ); - - template - int _ConnectFixedOutdegree - ( - T1 source, int n_source, T2 target, int n_target, int outdegree, - SynSpec &syn_spec - ); + template < class T1, class T2 > + int _Connect( T1 source, int n_source, T2 target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _SingleConnect( T1 source, int i_source, T2 target, int i_target, int i_array, SynSpec& syn_spec ); + template < class T1, class T2 > + int _SingleConnect( T1 source, + int i_source, + T2 target, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ); + + template < class T > + int _RemoteSingleConnect( int i_source, T target, int i_target, int i_array, SynSpec& syn_spec ); + template < class T > + int _RemoteSingleConnect( int i_source, + T target, + int i_target, + float weight, + float delay, + int i_array, + SynSpec& syn_spec ); + + template < class T1, class T2 > + int _ConnectOneToOne( T1 source, T2 target, int n_node, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _ConnectAllToAll( T1 source, int n_source, T2 target, int n_target, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _ConnectFixedTotalNumber( T1 source, int n_source, T2 target, int n_target, int n_conn, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _ConnectFixedIndegree( T1 source, int n_source, T2 target, int n_target, int indegree, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _ConnectFixedOutdegree( T1 source, int n_source, T2 target, int n_target, int outdegree, SynSpec& syn_spec ); #ifdef HAVE_MPI - template - int _RemoteConnect(RemoteNode source, int n_source, - RemoteNode target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); - - template - int _RemoteConnectOneToOne - (RemoteNode source, RemoteNode target, int n_node, - SynSpec &syn_spec); - - template - int _RemoteConnectAllToAll - (RemoteNode source, int n_source, RemoteNode target, int n_target, - SynSpec &syn_spec); - - template - int _RemoteConnectFixedTotalNumber - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int n_conn, SynSpec &syn_spec); - - template - int _RemoteConnectFixedIndegree - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int indegree, SynSpec &syn_spec); - - template - int _RemoteConnectFixedOutdegree - (RemoteNode source, int n_source, RemoteNode target, int n_target, - int outdegree, SynSpec &syn_spec); + template < class T1, class T2 > + int _RemoteConnect( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + template < class T1, class T2 > + int _RemoteConnectOneToOne( RemoteNode< T1 > source, RemoteNode< T2 > target, int n_node, SynSpec& syn_spec ); + + template < class T1, class T2 > + int _RemoteConnectAllToAll( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + SynSpec& syn_spec ); + + template < class T1, class T2 > + int _RemoteConnectFixedTotalNumber( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int n_conn, + SynSpec& syn_spec ); + + template < class T1, class T2 > + int _RemoteConnectFixedIndegree( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int indegree, + SynSpec& syn_spec ); + + template < class T1, class T2 > + int _RemoteConnectFixedOutdegree( RemoteNode< T1 > source, + int n_source, + RemoteNode< T2 > target, + int n_target, + int outdegree, + SynSpec& syn_spec ); #endif int ConnectRemoteNodes(); @@ -262,232 +287,250 @@ class NESTGPU bool first_simulation_flag_; - public: +public: NESTGPU(); ~NESTGPU(); - int SetRandomSeed(unsigned long long seed); + int SetRandomSeed( unsigned long long seed ); + + int SetTimeResolution( float time_res ); - int SetTimeResolution(float time_res); - - inline float GetTimeResolution() { + inline float + GetTimeResolution() + { return time_resolution_; } - inline int SetSimTime(float sim_time) { + inline int + SetSimTime( float sim_time ) + { sim_time_ = sim_time; return 0; } - inline float GetSimTime() { + inline float + GetSimTime() + { return sim_time_; } - inline int SetVerbosityLevel(int verbosity_level) { + inline int + SetVerbosityLevel( int verbosity_level ) + { verbosity_level_ = verbosity_level; return 0; } - inline int SetPrintTime(bool print_time) { + inline int + SetPrintTime( bool print_time ) + { print_time_ = print_time; return 0; } - int SetMaxSpikeBufferSize(int max_size); + int SetMaxSpikeBufferSize( int max_size ); int GetMaxSpikeBufferSize(); int GetNBoolParam(); - std::vector GetBoolParamNames(); - bool IsBoolParam(std::string param_name); - int GetBoolParamIdx(std::string param_name); - bool GetBoolParam(std::string param_name); - int SetBoolParam(std::string param_name, bool val); + std::vector< std::string > GetBoolParamNames(); + bool IsBoolParam( std::string param_name ); + int GetBoolParamIdx( std::string param_name ); + bool GetBoolParam( std::string param_name ); + int SetBoolParam( std::string param_name, bool val ); int GetNFloatParam(); - std::vector GetFloatParamNames(); - bool IsFloatParam(std::string param_name); - int GetFloatParamIdx(std::string param_name); - float GetFloatParam(std::string param_name); - int SetFloatParam(std::string param_name, float val); + std::vector< std::string > GetFloatParamNames(); + bool IsFloatParam( std::string param_name ); + int GetFloatParamIdx( std::string param_name ); + float GetFloatParam( std::string param_name ); + int SetFloatParam( std::string param_name, float val ); int GetNIntParam(); - std::vector GetIntParamNames(); - bool IsIntParam(std::string param_name); - int GetIntParamIdx(std::string param_name); - int GetIntParam(std::string param_name); - int SetIntParam(std::string param_name, int val); + std::vector< std::string > GetIntParamNames(); + bool IsIntParam( std::string param_name ); + int GetIntParamIdx( std::string param_name ); + int GetIntParam( std::string param_name ); + int SetIntParam( std::string param_name, int val ); - NodeSeq Create(std::string model_name, int n_neuron=1, int n_port=1); - NodeSeq CreatePoissonGenerator(int n_node, float rate); - RemoteNodeSeq RemoteCreate(int i_host, std::string model_name, - int n_node=1, int n_port=1); + NodeSeq Create( std::string model_name, int n_neuron = 1, int n_port = 1 ); + NodeSeq CreatePoissonGenerator( int n_node, float rate ); + RemoteNodeSeq RemoteCreate( int i_host, std::string model_name, int n_node = 1, int n_port = 1 ); - int CreateRecord(std::string file_name, std::string *var_name_arr, - int *i_node_arr, int n_node); - int CreateRecord(std::string file_name, std::string *var_name_arr, - int *i_node_arr, int *port_arr, int n_node); - std::vector > *GetRecordData(int i_record); + int CreateRecord( std::string file_name, std::string* var_name_arr, int* i_node_arr, int n_node ); + int CreateRecord( std::string file_name, std::string* var_name_arr, int* i_node_arr, int* port_arr, int n_node ); + std::vector< std::vector< float > >* GetRecordData( int i_record ); - int SetNeuronParam(int i_node, int n_neuron, std::string param_name, - float val); + int SetNeuronParam( int i_node, int n_neuron, std::string param_name, float val ); - int SetNeuronParam(int *i_node, int n_neuron, std::string param_name, - float val); + int SetNeuronParam( int* i_node, int n_neuron, std::string param_name, float val ); - int SetNeuronParam(int i_node, int n_neuron, std::string param_name, - float *param, int array_size); + int SetNeuronParam( int i_node, int n_neuron, std::string param_name, float* param, int array_size ); - int SetNeuronParam(int *i_node, int n_neuron, std::string param_name, - float *param, int array_size); + int SetNeuronParam( int* i_node, int n_neuron, std::string param_name, float* param, int array_size ); - int SetNeuronParam(NodeSeq nodes, std::string param_name, float val) { - return SetNeuronParam(nodes.i0, nodes.n, param_name, val); + int + SetNeuronParam( NodeSeq nodes, std::string param_name, float val ) + { + return SetNeuronParam( nodes.i0, nodes.n, param_name, val ); } - int SetNeuronParam(NodeSeq nodes, std::string param_name, float *param, - int array_size) { - return SetNeuronParam(nodes.i0, nodes.n, param_name, param, array_size); + int + SetNeuronParam( NodeSeq nodes, std::string param_name, float* param, int array_size ) + { + return SetNeuronParam( nodes.i0, nodes.n, param_name, param, array_size ); } - - int SetNeuronParam(std::vector nodes, std::string param_name, - float val) { - return SetNeuronParam(nodes.data(), nodes.size(), param_name, val); + + int + SetNeuronParam( std::vector< int > nodes, std::string param_name, float val ) + { + return SetNeuronParam( nodes.data(), nodes.size(), param_name, val ); } - int SetNeuronParam(std::vector nodes, std::string param_name, - float *param, int array_size) { - return SetNeuronParam(nodes.data(), nodes.size(), param_name, param, - array_size); + int + SetNeuronParam( std::vector< int > nodes, std::string param_name, float* param, int array_size ) + { + return SetNeuronParam( nodes.data(), nodes.size(), param_name, param, array_size ); } - int SetNeuronIntVar(int i_node, int n_neuron, std::string var_name, - int val); + int SetNeuronIntVar( int i_node, int n_neuron, std::string var_name, int val ); - int SetNeuronIntVar(int *i_node, int n_neuron, std::string var_name, - int val); + int SetNeuronIntVar( int* i_node, int n_neuron, std::string var_name, int val ); - int SetNeuronIntVar(NodeSeq nodes, std::string var_name, int val) { - return SetNeuronIntVar(nodes.i0, nodes.n, var_name, val); + int + SetNeuronIntVar( NodeSeq nodes, std::string var_name, int val ) + { + return SetNeuronIntVar( nodes.i0, nodes.n, var_name, val ); } - int SetNeuronIntVar(std::vector nodes, std::string var_name, - int val) { - return SetNeuronIntVar(nodes.data(), nodes.size(), var_name, val); + int + SetNeuronIntVar( std::vector< int > nodes, std::string var_name, int val ) + { + return SetNeuronIntVar( nodes.data(), nodes.size(), var_name, val ); } - int SetNeuronVar(int i_node, int n_neuron, std::string var_name, - float val); + int SetNeuronVar( int i_node, int n_neuron, std::string var_name, float val ); - int SetNeuronVar(int *i_node, int n_neuron, std::string var_name, - float val); + int SetNeuronVar( int* i_node, int n_neuron, std::string var_name, float val ); - int SetNeuronVar(int i_node, int n_neuron, std::string var_name, - float *var, int array_size); + int SetNeuronVar( int i_node, int n_neuron, std::string var_name, float* var, int array_size ); - int SetNeuronVar(int *i_node, int n_neuron, std::string var_name, - float *var, int array_size); + int SetNeuronVar( int* i_node, int n_neuron, std::string var_name, float* var, int array_size ); - int SetNeuronVar(NodeSeq nodes, std::string var_name, float val) { - return SetNeuronVar(nodes.i0, nodes.n, var_name, val); + int + SetNeuronVar( NodeSeq nodes, std::string var_name, float val ) + { + return SetNeuronVar( nodes.i0, nodes.n, var_name, val ); } - int SetNeuronVar(NodeSeq nodes, std::string var_name, float *var, - int array_size) { - return SetNeuronVar(nodes.i0, nodes.n, var_name, var, array_size); + int + SetNeuronVar( NodeSeq nodes, std::string var_name, float* var, int array_size ) + { + return SetNeuronVar( nodes.i0, nodes.n, var_name, var, array_size ); } - - int SetNeuronVar(std::vector nodes, std::string var_name, - float val) { - return SetNeuronVar(nodes.data(), nodes.size(), var_name, val); + + int + SetNeuronVar( std::vector< int > nodes, std::string var_name, float val ) + { + return SetNeuronVar( nodes.data(), nodes.size(), var_name, val ); } - int SetNeuronVar(std::vector nodes, std::string var_name, - float *var, int array_size) { - return SetNeuronVar(nodes.data(), nodes.size(), var_name, var, - array_size); + int + SetNeuronVar( std::vector< int > nodes, std::string var_name, float* var, int array_size ) + { + return SetNeuronVar( nodes.data(), nodes.size(), var_name, var, array_size ); } - int GetNeuronParamSize(int i_node, std::string param_name); + int GetNeuronParamSize( int i_node, std::string param_name ); - int GetNeuronVarSize(int i_node, std::string var_name); + int GetNeuronVarSize( int i_node, std::string var_name ); - float *GetNeuronParam(int i_node, int n_neuron, std::string param_name); + float* GetNeuronParam( int i_node, int n_neuron, std::string param_name ); - float *GetNeuronParam(int *i_node, int n_neuron, std::string param_name); + float* GetNeuronParam( int* i_node, int n_neuron, std::string param_name ); - float *GetNeuronParam(NodeSeq nodes, std::string param_name) { - return GetNeuronParam(nodes.i0, nodes.n, param_name); + float* + GetNeuronParam( NodeSeq nodes, std::string param_name ) + { + return GetNeuronParam( nodes.i0, nodes.n, param_name ); } - - float *GetNeuronParam(std::vector nodes, std::string param_name) { - return GetNeuronParam(nodes.data(), nodes.size(), param_name); + + float* + GetNeuronParam( std::vector< int > nodes, std::string param_name ) + { + return GetNeuronParam( nodes.data(), nodes.size(), param_name ); } - float *GetArrayParam(int i_node, std::string param_name); - - int *GetNeuronIntVar(int i_node, int n_neuron, std::string var_name); + float* GetArrayParam( int i_node, std::string param_name ); + + int* GetNeuronIntVar( int i_node, int n_neuron, std::string var_name ); - int *GetNeuronIntVar(int *i_node, int n_neuron, std::string var_name); + int* GetNeuronIntVar( int* i_node, int n_neuron, std::string var_name ); - int *GetNeuronIntVar(NodeSeq nodes, std::string var_name) { - return GetNeuronIntVar(nodes.i0, nodes.n, var_name); + int* + GetNeuronIntVar( NodeSeq nodes, std::string var_name ) + { + return GetNeuronIntVar( nodes.i0, nodes.n, var_name ); } - - int *GetNeuronIntVar(std::vector nodes, std::string var_name) { - return GetNeuronIntVar(nodes.data(), nodes.size(), var_name); + + int* + GetNeuronIntVar( std::vector< int > nodes, std::string var_name ) + { + return GetNeuronIntVar( nodes.data(), nodes.size(), var_name ); } - - float *GetNeuronVar(int i_node, int n_neuron, std::string var_name); - float *GetNeuronVar(int *i_node, int n_neuron, std::string var_name); + float* GetNeuronVar( int i_node, int n_neuron, std::string var_name ); - float *GetNeuronVar(NodeSeq nodes, std::string var_name) { - return GetNeuronVar(nodes.i0, nodes.n, var_name); + float* GetNeuronVar( int* i_node, int n_neuron, std::string var_name ); + + float* + GetNeuronVar( NodeSeq nodes, std::string var_name ) + { + return GetNeuronVar( nodes.i0, nodes.n, var_name ); } - - float *GetNeuronVar(std::vector nodes, std::string var_name) { - return GetNeuronVar(nodes.data(), nodes.size(), var_name); + + float* + GetNeuronVar( std::vector< int > nodes, std::string var_name ) + { + return GetNeuronVar( nodes.data(), nodes.size(), var_name ); } - float *GetArrayVar(int i_node, std::string param_name); - - int GetNodeSequenceOffset(int i_node, int n_node, int &i_group); + float* GetArrayVar( int i_node, std::string param_name ); - std::vector GetNodeArrayWithOffset(int *i_node, int n_node, - int &i_group); + int GetNodeSequenceOffset( int i_node, int n_node, int& i_group ); - int IsNeuronScalParam(int i_node, std::string param_name); + std::vector< int > GetNodeArrayWithOffset( int* i_node, int n_node, int& i_group ); - int IsNeuronPortParam(int i_node, std::string param_name); + int IsNeuronScalParam( int i_node, std::string param_name ); - int IsNeuronArrayParam(int i_node, std::string param_name); + int IsNeuronPortParam( int i_node, std::string param_name ); - int IsNeuronIntVar(int i_node, std::string var_name); - - int IsNeuronScalVar(int i_node, std::string var_name); + int IsNeuronArrayParam( int i_node, std::string param_name ); - int IsNeuronPortVar(int i_node, std::string var_name); + int IsNeuronIntVar( int i_node, std::string var_name ); - int IsNeuronArrayVar(int i_node, std::string var_name); - - int SetSpikeGenerator(int i_node, int n_spikes, float *spike_time, - float *spike_height); + int IsNeuronScalVar( int i_node, std::string var_name ); + + int IsNeuronPortVar( int i_node, std::string var_name ); + + int IsNeuronArrayVar( int i_node, std::string var_name ); + + int SetSpikeGenerator( int i_node, int n_spikes, float* spike_time, float* spike_height ); int Calibrate(); - + int Simulate(); - int Simulate(float sim_time); + int Simulate( float sim_time ); int StartSimulation(); int SimulationStep(); int EndSimulation(); - - int ConnectMpiInit(int argc, char *argv[]); + + int ConnectMpiInit( int argc, char* argv[] ); int MpiId(); @@ -498,225 +541,271 @@ class NESTGPU int MpiFinalize(); std::string MpiRankStr(); - - void SetErrorFlag(bool error_flag) {error_flag_ = error_flag;} - - void SetErrorMessage(std::string error_message) { error_message_ - = error_message; } - - void SetErrorCode(unsigned char error_code) {error_code_ = error_code;} - - void SetOnException(int on_exception) {on_exception_ = on_exception;} - - bool GetErrorFlag() {return error_flag_;} - - char *GetErrorMessage() {return &error_message_[0];} - - unsigned char GetErrorCode() {return error_code_;} - - int OnException() {return on_exception_;} - - unsigned int *RandomInt(size_t n); - - float *RandomUniform(size_t n); - float *RandomNormal(size_t n, float mean, float stddev); - - float *RandomNormalClipped(size_t n, float mean, float stddev, float vmin, - float vmax, float vstep); - - int Connect - ( - int i_source_node, int i_target_node, unsigned char port, - unsigned char syn_group, float weight, float delay - ); + void + SetErrorFlag( bool error_flag ) + { + error_flag_ = error_flag; + } - int Connect(int i_source, int n_source, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + void + SetErrorMessage( std::string error_message ) + { + error_message_ = error_message; + } - int Connect(int i_source, int n_source, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + void + SetErrorCode( unsigned char error_code ) + { + error_code_ = error_code; + } - int Connect(int* source, int n_source, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + void + SetOnException( int on_exception ) + { + on_exception_ = on_exception; + } - int Connect(int* source, int n_source, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + bool + GetErrorFlag() + { + return error_flag_; + } - int Connect(NodeSeq source, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec); + char* + GetErrorMessage() + { + return &error_message_[ 0 ]; + } - int Connect(NodeSeq source, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec); + unsigned char + GetErrorCode() + { + return error_code_; + } - int Connect(std::vector source, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec); + int + OnException() + { + return on_exception_; + } - int Connect(std::vector source, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec); + unsigned int* RandomInt( size_t n ); + + float* RandomUniform( size_t n ); + + float* RandomNormal( size_t n, float mean, float stddev ); + + float* RandomNormalClipped( size_t n, float mean, float stddev, float vmin, float vmax, float vstep ); + + int Connect( int i_source_node, + int i_target_node, + unsigned char port, + unsigned char syn_group, + float weight, + float delay ); + + int Connect( int i_source, int n_source, int i_target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( int i_source, int n_source, int* target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( int* source, int n_source, int i_target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( int* source, int n_source, int* target, int n_target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( NodeSeq source, NodeSeq target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( NodeSeq source, std::vector< int > target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( std::vector< int > source, NodeSeq target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int Connect( std::vector< int > source, std::vector< int > target, ConnSpec& conn_spec, SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int i_target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int* target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + int* source, + int n_source, + int i_target_host, + int i_target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + int* source, + int n_source, + int i_target_host, + int* target, + int n_target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + NodeSeq source, + int i_target_host, + NodeSeq target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + NodeSeq source, + int i_target_host, + std::vector< int > target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + std::vector< int > source, + int i_target_host, + NodeSeq target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); + + int RemoteConnect( int i_source_host, + std::vector< int > source, + int i_target_host, + std::vector< int > target, + ConnSpec& conn_spec, + SynSpec& syn_spec ); - int RemoteConnect(int i_source_host, int i_source, int n_source, - int i_target_host, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + int BuildDirectConnections(); - int RemoteConnect(int i_source_host, int i_source, int n_source, - int i_target_host, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + std::vector< std::string > GetScalVarNames( int i_node ); - int RemoteConnect(int i_source_host, int* source, int n_source, - int i_target_host, int i_target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + int GetNIntVar( int i_node ); - int RemoteConnect(int i_source_host, int* source, int n_source, - int i_target_host, int* target, int n_target, - ConnSpec &conn_spec, SynSpec &syn_spec); + std::vector< std::string > GetIntVarNames( int i_node ); - int RemoteConnect(int i_source_host, NodeSeq source, - int i_target_host, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec); + int GetNScalVar( int i_node ); - int RemoteConnect(int i_source_host, NodeSeq source, - int i_target_host, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec); + std::vector< std::string > GetPortVarNames( int i_node ); - int RemoteConnect(int i_source_host, std::vector source, - int i_target_host, NodeSeq target, - ConnSpec &conn_spec, SynSpec &syn_spec); + int GetNPortVar( int i_node ); - int RemoteConnect(int i_source_host, std::vector source, - int i_target_host, std::vector target, - ConnSpec &conn_spec, SynSpec &syn_spec); + std::vector< std::string > GetScalParamNames( int i_node ); - int BuildDirectConnections(); + int GetNScalParam( int i_node ); - std::vector GetScalVarNames(int i_node); + std::vector< std::string > GetPortParamNames( int i_node ); - int GetNIntVar(int i_node); - - std::vector GetIntVarNames(int i_node); + int GetNPortParam( int i_node ); - int GetNScalVar(int i_node); - - std::vector GetPortVarNames(int i_node); + std::vector< std::string > GetArrayParamNames( int i_node ); - int GetNPortVar(int i_node); - - std::vector GetScalParamNames(int i_node); + int GetNArrayParam( int i_node ); - int GetNScalParam(int i_node); - - std::vector GetPortParamNames(int i_node); + std::vector< std::string > GetArrayVarNames( int i_node ); - int GetNPortParam(int i_node); - - std::vector GetArrayParamNames(int i_node); + std::vector< std::string > GetGroupParamNames( int i_node ); - int GetNArrayParam(int i_node); + int GetNGroupParam( int i_node ); - std::vector GetArrayVarNames(int i_node); + int GetNArrayVar( int i_node ); - std::vector GetGroupParamNames(int i_node); + ConnectionStatus GetConnectionStatus( ConnectionId conn_id ); - int GetNGroupParam(int i_node); - - int GetNArrayVar(int i_node); + std::vector< ConnectionStatus > GetConnectionStatus( std::vector< ConnectionId >& conn_id_vect ); - ConnectionStatus GetConnectionStatus(ConnectionId conn_id); - - std::vector GetConnectionStatus(std::vector - &conn_id_vect); + std::vector< ConnectionId > + GetConnections( int i_source, int n_source, int i_target, int n_target, int syn_group = -1 ); - std::vector GetConnections(int i_source, int n_source, - int i_target, int n_target, - int syn_group=-1); + std::vector< ConnectionId > + GetConnections( int* i_source, int n_source, int i_target, int n_target, int syn_group = -1 ); - std::vector GetConnections(int *i_source, int n_source, - int i_target, int n_target, - int syn_group=-1); + std::vector< ConnectionId > + GetConnections( int i_source, int n_source, int* i_target, int n_target, int syn_group = -1 ); - std::vector GetConnections(int i_source, int n_source, - int *i_target, int n_target, - int syn_group=-1); + std::vector< ConnectionId > + GetConnections( int* i_source, int n_source, int* i_target, int n_target, int syn_group = -1 ); - std::vector GetConnections(int *i_source, int n_source, - int *i_target, int n_target, - int syn_group=-1); - - std::vector GetConnections(NodeSeq source, NodeSeq target, - int syn_group=-1); + std::vector< ConnectionId > GetConnections( NodeSeq source, NodeSeq target, int syn_group = -1 ); - std::vector GetConnections(std::vector source, - NodeSeq target, int syn_group=-1); + std::vector< ConnectionId > GetConnections( std::vector< int > source, NodeSeq target, int syn_group = -1 ); - std::vector GetConnections(NodeSeq source, - std::vector target, - int syn_group=-1); + std::vector< ConnectionId > GetConnections( NodeSeq source, std::vector< int > target, int syn_group = -1 ); - std::vector GetConnections(std::vector source, - std::vector target, - int syn_group=-1); + std::vector< ConnectionId > + GetConnections( std::vector< int > source, std::vector< int > target, int syn_group = -1 ); - int CreateSynGroup(std::string model_name); + int CreateSynGroup( std::string model_name ); - int GetSynGroupNParam(int syn_group); + int GetSynGroupNParam( int syn_group ); - std::vector GetSynGroupParamNames(int syn_group); + std::vector< std::string > GetSynGroupParamNames( int syn_group ); - bool IsSynGroupParam(int syn_group, std::string param_name); + bool IsSynGroupParam( int syn_group, std::string param_name ); - int GetSynGroupParamIdx(int syn_group, std::string param_name); + int GetSynGroupParamIdx( int syn_group, std::string param_name ); - float GetSynGroupParam(int syn_group, std::string param_name); + float GetSynGroupParam( int syn_group, std::string param_name ); - int SetSynGroupParam(int syn_group, std::string param_name, float val); + int SetSynGroupParam( int syn_group, std::string param_name, float val ); int SynGroupCalibrate(); - int ActivateSpikeCount(int i_node, int n_node); - - int ActivateSpikeCount(NodeSeq nodes) { - return ActivateSpikeCount(nodes.i0, nodes.n); + int ActivateSpikeCount( int i_node, int n_node ); + + int + ActivateSpikeCount( NodeSeq nodes ) + { + return ActivateSpikeCount( nodes.i0, nodes.n ); } - int ActivateRecSpikeTimes(int i_node, int n_node, int max_n_rec_spike_times); - - int ActivateRecSpikeTimes(NodeSeq nodes, int max_n_rec_spike_times) { - return ActivateRecSpikeTimes(nodes.i0, nodes.n, max_n_rec_spike_times); + int ActivateRecSpikeTimes( int i_node, int n_node, int max_n_rec_spike_times ); + + int + ActivateRecSpikeTimes( NodeSeq nodes, int max_n_rec_spike_times ) + { + return ActivateRecSpikeTimes( nodes.i0, nodes.n, max_n_rec_spike_times ); } - int SetRecSpikeTimesStep(int i_node, int n_node, int rec_spike_times_step); + int SetRecSpikeTimesStep( int i_node, int n_node, int rec_spike_times_step ); - int SetRecSpikeTimesStep(NodeSeq nodes, int rec_spike_times_step) { - return SetRecSpikeTimesStep(nodes.i0, nodes.n, rec_spike_times_step); + int + SetRecSpikeTimesStep( NodeSeq nodes, int rec_spike_times_step ) + { + return SetRecSpikeTimesStep( nodes.i0, nodes.n, rec_spike_times_step ); } - int GetNRecSpikeTimes(int i_node); + int GetNRecSpikeTimes( int i_node ); - int GetRecSpikeTimes(int i_node, int n_node, int **n_spike_times_pt, - float ***spike_times_pt); + int GetRecSpikeTimes( int i_node, int n_node, int** n_spike_times_pt, float*** spike_times_pt ); - int GetRecSpikeTimes(NodeSeq nodes, int **n_spike_times_pt, - float ***spike_times_pt) { - return GetRecSpikeTimes(nodes.i0, nodes.n, n_spike_times_pt, - spike_times_pt); + int + GetRecSpikeTimes( NodeSeq nodes, int** n_spike_times_pt, float*** spike_times_pt ) + { + return GetRecSpikeTimes( nodes.i0, nodes.n, n_spike_times_pt, spike_times_pt ); } - int PushSpikesToNodes(int n_spikes, int *node_id, float *spike_height); - - int PushSpikesToNodes(int n_spikes, int *node_id); + int PushSpikesToNodes( int n_spikes, int* node_id, float* spike_height ); - int GetExtNeuronInputSpikes(int *n_spikes, int **node, int **port, - float **spike_height, bool include_zeros); + int PushSpikesToNodes( int n_spikes, int* node_id ); - int SetNeuronGroupParam(int i_node, int n_node, - std::string param_name, float val); - - int IsNeuronGroupParam(int i_node, std::string param_name); + int GetExtNeuronInputSpikes( int* n_spikes, int** node, int** port, float** spike_height, bool include_zeros ); - float GetNeuronGroupParam(int i_node, std::string param_name); + int SetNeuronGroupParam( int i_node, int n_node, std::string param_name, float val ); -}; + int IsNeuronGroupParam( int i_node, std::string param_name ); + float GetNeuronGroupParam( int i_node, std::string param_name ); +}; #endif diff --git a/src/nestgpu_C.cpp b/src/nestgpu_C.cpp index 23d8d67f0..e0a61f84a 100644 --- a/src/nestgpu_C.cpp +++ b/src/nestgpu_C.cpp @@ -21,1174 +21,1864 @@ */ +#include +#include +#include +#include +#include + +#include "nestgpu.h" +#include "nestgpu_C.h" +#include "propagate_error.h" + +extern "C" +{ + static NESTGPU* NESTGPU_instance = NULL; + ConnSpec ConnSpec_instance; + SynSpec SynSpec_instance; + + void + checkNESTGPUInstance() + { + if ( NESTGPU_instance == NULL ) + { + NESTGPU_instance = new NESTGPU(); + } + } + + char* + NESTGPU_GetErrorMessage() + { + checkNESTGPUInstance(); + char* cstr = NESTGPU_instance->GetErrorMessage(); + return cstr; + } + + unsigned char + NESTGPU_GetErrorCode() + { + checkNESTGPUInstance(); + return NESTGPU_instance->GetErrorCode(); + } + + void + NESTGPU_SetOnException( int on_exception ) + { + checkNESTGPUInstance(); + NESTGPU_instance->SetOnException( on_exception ); + } + + unsigned int* RandomInt( size_t n ); + + int + NESTGPU_SetRandomSeed( unsigned long long seed ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SetRandomSeed( seed ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetTimeResolution( float time_res ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SetTimeResolution( time_res ); + } + END_ERR_PROP return ret; + } + + float + NESTGPU_GetTimeResolution() + { + float ret = 0.0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetTimeResolution(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetMaxSpikeBufferSize( int max_size ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SetMaxSpikeBufferSize( max_size ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetMaxSpikeBufferSize() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetMaxSpikeBufferSize(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetSimTime( float sim_time ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SetSimTime( sim_time ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetVerbosityLevel( int verbosity_level ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SetVerbosityLevel( verbosity_level ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_Create( char* model_name, int n_neuron, int n_port ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string model_name_str = std::string( model_name ); + NodeSeq neur = NESTGPU_instance->Create( model_name_str, n_neuron, n_port ); + ret = neur[ 0 ]; + } + END_ERR_PROP return ret; + } + + int + NESTGPU_CreatePoissonGenerator( int n_node, float rate ) + { + int ret = 0; + BEGIN_ERR_PROP + { + NodeSeq pg = NESTGPU_instance->CreatePoissonGenerator( n_node, rate ); + + ret = pg[ 0 ]; + } + END_ERR_PROP return ret; + } + + int + NESTGPU_CreateRecord( char* file_name, char* var_name_arr[], int* i_node_arr, int* port_arr, int n_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string file_name_str = std::string( file_name ); + std::vector< std::string > var_name_vect; + for ( int i = 0; i < n_node; i++ ) + { + std::string var_name = std::string( var_name_arr[ i ] ); + var_name_vect.push_back( var_name ); + } + ret = NESTGPU_instance->CreateRecord( file_name_str, var_name_vect.data(), i_node_arr, port_arr, n_node ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetRecordDataRows( int i_record ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::vector< std::vector< float > >* data_vect_pt = NESTGPU_instance->GetRecordData( i_record ); + + ret = data_vect_pt->size(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetRecordDataColumns( int i_record ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::vector< std::vector< float > >* data_vect_pt = NESTGPU_instance->GetRecordData( i_record ); + + ret = data_vect_pt->at( 0 ).size(); + } + END_ERR_PROP return ret; + } + + float** + NESTGPU_GetRecordData( int i_record ) + { + float** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::vector< float > >* data_vect_pt = NESTGPU_instance->GetRecordData( i_record ); + int nr = data_vect_pt->size(); + ret = new float*[ nr ]; + for ( int i = 0; i < nr; i++ ) + { + ret[ i ] = data_vect_pt->at( i ).data(); + } + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronScalParam( int i_node, int n_neuron, char* param_name, float val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetNeuronParam( i_node, n_neuron, param_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronArrayParam( int i_node, int n_neuron, char* param_name, float* param, int array_size ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetNeuronParam( i_node, n_neuron, param_name_str, param, array_size ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronPtScalParam( int* i_node, int n_neuron, char* param_name, float val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetNeuronParam( i_node, n_neuron, param_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronPtArrayParam( int* i_node, int n_neuron, char* param_name, float* param, int array_size ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetNeuronParam( i_node, n_neuron, param_name_str, param, array_size ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronScalParam( int i_node, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsNeuronScalParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronPortParam( int i_node, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsNeuronPortParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronArrayParam( int i_node, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsNeuronArrayParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_SetNeuronIntVar( int i_node, int n_neuron, char* var_name, int val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronIntVar( i_node, n_neuron, var_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronScalVar( int i_node, int n_neuron, char* var_name, float val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronVar( i_node, n_neuron, var_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronArrayVar( int i_node, int n_neuron, char* var_name, float* var, int array_size ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronVar( i_node, n_neuron, var_name_str, var, array_size ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronPtIntVar( int* i_node, int n_neuron, char* var_name, int val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronIntVar( i_node, n_neuron, var_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronPtScalVar( int* i_node, int n_neuron, char* var_name, float val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronVar( i_node, n_neuron, var_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronPtArrayVar( int* i_node, int n_neuron, char* var_name, float* var, int array_size ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->SetNeuronVar( i_node, n_neuron, var_name_str, var, array_size ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronIntVar( int i_node, char* var_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + + ret = NESTGPU_instance->IsNeuronIntVar( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronScalVar( int i_node, char* var_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + + ret = NESTGPU_instance->IsNeuronScalVar( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronPortVar( int i_node, char* var_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + + ret = NESTGPU_instance->IsNeuronPortVar( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronArrayVar( int i_node, char* var_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + + ret = NESTGPU_instance->IsNeuronArrayVar( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNeuronParamSize( int i_node, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetNeuronParamSize( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNeuronVarSize( int i_node, char* var_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string var_name_str = std::string( var_name ); + + ret = NESTGPU_instance->GetNeuronVarSize( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + + float* + NESTGPU_GetNeuronParam( int i_node, int n_neuron, char* param_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronParam( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + + float* + NESTGPU_GetNeuronPtParam( int* i_node, int n_neuron, char* param_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronParam( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + + float* + NESTGPU_GetArrayParam( int i_node, char* param_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetArrayParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int* + NESTGPU_GetNeuronIntVar( int i_node, int n_neuron, char* param_name ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronIntVar( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int* + NESTGPU_GetNeuronPtIntVar( int* i_node, int n_neuron, char* param_name ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronIntVar( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + float* + NESTGPU_GetNeuronVar( int i_node, int n_neuron, char* param_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronVar( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + + float* + NESTGPU_GetNeuronPtVar( int* i_node, int n_neuron, char* param_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetNeuronVar( i_node, n_neuron, param_name_str ); + } + END_ERR_PROP return ret; + } + + float* + NESTGPU_GetArrayVar( int i_node, char* var_name ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + + std::string var_name_str = std::string( var_name ); + ret = NESTGPU_instance->GetArrayVar( i_node, var_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_Calibrate() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Calibrate(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_Simulate() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Simulate(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_StartSimulation() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->StartSimulation(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SimulationStep() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->SimulationStep(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_EndSimulation() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->EndSimulation(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnectMpiInit( int argc, char* argv[] ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->ConnectMpiInit( argc, argv ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_MpiId() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->MpiId(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_MpiNp() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->MpiNp(); + } + END_ERR_PROP return ret; + } + int + NESTGPU_ProcMaster() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->ProcMaster(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_MpiFinalize() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->MpiFinalize(); + } + END_ERR_PROP return ret; + } + + unsigned int* + NESTGPU_RandomInt( size_t n ) + { + unsigned int* ret = NULL; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RandomInt( n ); + } + END_ERR_PROP return ret; + } + + float* + NESTGPU_RandomUniform( size_t n ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RandomUniform( n ); + } + END_ERR_PROP return ret; + } + + float* + NESTGPU_RandomNormal( size_t n, float mean, float stddev ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RandomNormal( n, mean, stddev ); + } + END_ERR_PROP return ret; + } + + float* + NESTGPU_RandomNormalClipped( size_t n, float mean, float stddev, float vmin, float vmax, float vstep ) + { + float* ret = NULL; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RandomNormalClipped( n, mean, stddev, vmin, vmax, vstep ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_Connect( int i_source_node, + int i_target_node, + unsigned char port, + unsigned char syn_group, + float weight, + float delay ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Connect( i_source_node, i_target_node, port, syn_group, weight, delay ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnSpecInit() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = ConnSpec_instance.Init(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetConnSpecParam( char* param_name, int value ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = ConnSpec_instance.SetParam( param_name_str, value ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnSpecIsParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = ConnSpec::IsParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SynSpecInit() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = SynSpec_instance.Init(); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetSynSpecIntParam( char* param_name, int value ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.SetParam( param_name_str, value ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetSynSpecFloatParam( char* param_name, float value ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.SetParam( param_name_str, value ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetSynSpecFloatPtParam( char* param_name, float* array_pt ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.SetParam( param_name_str, array_pt ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SynSpecIsIntParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.IsIntParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SynSpecIsFloatParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.IsFloatParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SynSpecIsFloatPtParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + ret = SynSpec_instance.IsFloatPtParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnectSeqSeq( int i_source, int n_source, int i_target, int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Connect( i_source, n_source, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnectSeqGroup( int i_source, int n_source, int* i_target, int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Connect( i_source, n_source, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnectGroupSeq( int* i_source, int n_source, int i_target, int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Connect( i_source, n_source, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_ConnectGroupGroup( int* i_source, int n_source, int* i_target, int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->Connect( i_source, n_source, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_RemoteConnectSeqSeq( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int i_target, + int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RemoteConnect( + i_source_host, i_source, n_source, i_target_host, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_RemoteConnectSeqGroup( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int* i_target, + int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RemoteConnect( + i_source_host, i_source, n_source, i_target_host, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_RemoteConnectGroupSeq( int i_source_host, + int* i_source, + int n_source, + int i_target_host, + int i_target, + int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RemoteConnect( + i_source_host, i_source, n_source, i_target_host, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_RemoteConnectGroupGroup( int i_source_host, + int* i_source, + int n_source, + int i_target_host, + int* i_target, + int n_target ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->RemoteConnect( + i_source_host, i_source, n_source, i_target_host, i_target, n_target, ConnSpec_instance, SynSpec_instance ); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetIntVarNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetIntVarNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } + + char** + NESTGPU_GetScalVarNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetScalVarNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetNIntVar( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNIntVar( i_node ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetNScalVar( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNScalVar( i_node ); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetPortVarNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetPortVarNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNPortVar( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNPortVar( i_node ); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetScalParamNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetScalParamNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNScalParam( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNScalParam( i_node ); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetGroupParamNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetGroupParamNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetNGroupParam( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNGroupParam( i_node ); + } + END_ERR_PROP return ret; + } -#include -#include -#include -#include -#include + char** + NESTGPU_GetPortParamNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetPortParamNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; + } -#include "nestgpu.h" -#include "nestgpu_C.h" -#include "propagate_error.h" -extern "C" { - static NESTGPU *NESTGPU_instance = NULL; - ConnSpec ConnSpec_instance; - SynSpec SynSpec_instance; + int + NESTGPU_GetNPortParam( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNPortParam( i_node ); + } + END_ERR_PROP return ret; + } - void checkNESTGPUInstance() { - if (NESTGPU_instance == NULL) { - NESTGPU_instance = new NESTGPU(); + + char** + NESTGPU_GetArrayParamNames( int i_node ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetArrayParamNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; } + END_ERR_PROP return ret; } - - char *NESTGPU_GetErrorMessage() + + + int + NESTGPU_GetNArrayParam( int i_node ) { - checkNESTGPUInstance(); - char *cstr = NESTGPU_instance->GetErrorMessage(); - return cstr; + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNArrayParam( i_node ); + } + END_ERR_PROP return ret; } - unsigned char NESTGPU_GetErrorCode() + char** + NESTGPU_GetArrayVarNames( int i_node ) { - checkNESTGPUInstance(); - return NESTGPU_instance->GetErrorCode(); + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > var_name_vect = NESTGPU_instance->GetArrayVarNames( i_node ); + char** var_name_array = ( char** ) malloc( var_name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < var_name_vect.size(); i++ ) + { + uint vl = var_name_vect[ i ].length() + 1; + char* var_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( var_name, var_name_vect[ i ].c_str(), vl ); + var_name_array[ i ] = var_name; + } + ret = var_name_array; + } + END_ERR_PROP return ret; } - void NESTGPU_SetOnException(int on_exception) + int + NESTGPU_GetNArrayVar( int i_node ) { - checkNESTGPUInstance(); - NESTGPU_instance->SetOnException(on_exception); - } - - unsigned int *RandomInt(size_t n); - - int NESTGPU_SetRandomSeed(unsigned long long seed) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SetRandomSeed(seed); - } END_ERR_PROP return ret; } - - int NESTGPU_SetTimeResolution(float time_res) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SetTimeResolution(time_res); - } END_ERR_PROP return ret; } - - float NESTGPU_GetTimeResolution() - { float ret = 0.0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetTimeResolution(); - } END_ERR_PROP return ret; } - - int NESTGPU_SetMaxSpikeBufferSize(int max_size) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SetMaxSpikeBufferSize(max_size); - } END_ERR_PROP return ret; } - - int NESTGPU_GetMaxSpikeBufferSize() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetMaxSpikeBufferSize(); - } END_ERR_PROP return ret; } - - int NESTGPU_SetSimTime(float sim_time) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SetSimTime(sim_time); - } END_ERR_PROP return ret; } - - int NESTGPU_SetVerbosityLevel(int verbosity_level) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SetVerbosityLevel(verbosity_level); - } END_ERR_PROP return ret; } - - - int NESTGPU_Create(char *model_name, int n_neuron, int n_port) - { int ret = 0; BEGIN_ERR_PROP { - std::string model_name_str = std::string(model_name); - NodeSeq neur = NESTGPU_instance->Create(model_name_str, n_neuron, - n_port); - ret = neur[0]; - } END_ERR_PROP return ret; } - - int NESTGPU_CreatePoissonGenerator(int n_node, float rate) - { int ret = 0; BEGIN_ERR_PROP { - NodeSeq pg = NESTGPU_instance->CreatePoissonGenerator(n_node, rate); - - ret = pg[0]; - } END_ERR_PROP return ret; } - - int NESTGPU_CreateRecord(char *file_name, char *var_name_arr[], - int *i_node_arr, int *port_arr, - int n_node) - { int ret = 0; BEGIN_ERR_PROP { - std::string file_name_str = std::string(file_name); - std::vector var_name_vect; - for (int i=0; iCreateRecord - (file_name_str, var_name_vect.data(), i_node_arr, port_arr, - n_node); - } END_ERR_PROP return ret; } - - int NESTGPU_GetRecordDataRows(int i_record) - { int ret = 0; BEGIN_ERR_PROP { - std::vector > *data_vect_pt - = NESTGPU_instance->GetRecordData(i_record); - - ret = data_vect_pt->size(); - } END_ERR_PROP return ret; } - - int NESTGPU_GetRecordDataColumns(int i_record) - { int ret = 0; BEGIN_ERR_PROP { - std::vector > *data_vect_pt - = NESTGPU_instance->GetRecordData(i_record); - - ret = data_vect_pt->at(0).size(); - } END_ERR_PROP return ret; } - - float **NESTGPU_GetRecordData(int i_record) - { float **ret = NULL; BEGIN_ERR_PROP { - std::vector > *data_vect_pt - = NESTGPU_instance->GetRecordData(i_record); - int nr = data_vect_pt->size(); - ret = new float*[nr]; - for (int i=0; iat(i).data(); - } - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronScalParam(int i_node, int n_neuron, char *param_name, - float val) - { int ret = 0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetNeuronParam(i_node, n_neuron, - param_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronArrayParam(int i_node, int n_neuron, - char *param_name, float *param, - int array_size) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetNeuronParam(i_node, n_neuron, - param_name_str, param, - array_size); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronPtScalParam(int *i_node, int n_neuron, - char *param_name,float val) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetNeuronParam(i_node, n_neuron, - param_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronPtArrayParam(int *i_node, int n_neuron, - char *param_name, float *param, - int array_size) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetNeuronParam(i_node, n_neuron, - param_name_str, param, - array_size); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronScalParam(int i_node, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->IsNeuronScalParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronPortParam(int i_node, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->IsNeuronPortParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronArrayParam(int i_node, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->IsNeuronArrayParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_SetNeuronIntVar(int i_node, int n_neuron, char *var_name, - int val) - { int ret = 0; BEGIN_ERR_PROP { - - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronIntVar(i_node, n_neuron, - var_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronScalVar(int i_node, int n_neuron, char *var_name, - float val) - { int ret = 0; BEGIN_ERR_PROP { - - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronVar(i_node, n_neuron, - var_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronArrayVar(int i_node, int n_neuron, - char *var_name, float *var, - int array_size) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronVar(i_node, n_neuron, - var_name_str, var, - array_size); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronPtIntVar(int *i_node, int n_neuron, - char *var_name, int val) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronIntVar(i_node, n_neuron, - var_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronPtScalVar(int *i_node, int n_neuron, - char *var_name, float val) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronVar(i_node, n_neuron, - var_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronPtArrayVar(int *i_node, int n_neuron, - char *var_name, float *var, - int array_size) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->SetNeuronVar(i_node, n_neuron, - var_name_str, var, - array_size); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronIntVar(int i_node, char *var_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - - ret = NESTGPU_instance->IsNeuronIntVar(i_node, var_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronScalVar(int i_node, char *var_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - - ret = NESTGPU_instance->IsNeuronScalVar(i_node, var_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronPortVar(int i_node, char *var_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - - ret = NESTGPU_instance->IsNeuronPortVar(i_node, var_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronArrayVar(int i_node, char *var_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - - ret = NESTGPU_instance->IsNeuronArrayVar(i_node, var_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetNeuronParamSize(int i_node, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetNeuronParamSize(i_node, param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetNeuronVarSize(int i_node, char *var_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string var_name_str = std::string(var_name); - - ret = NESTGPU_instance->GetNeuronVarSize(i_node, var_name_str); - } END_ERR_PROP return ret; } - - - float *NESTGPU_GetNeuronParam(int i_node, int n_neuron, - char *param_name) - { float *ret = NULL; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronParam(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - - float *NESTGPU_GetNeuronPtParam(int *i_node, int n_neuron, - char *param_name) - { float *ret = NULL; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronParam(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - - float *NESTGPU_GetArrayParam(int i_node, char *param_name) - { float *ret = NULL; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetArrayParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - - int *NESTGPU_GetNeuronIntVar(int i_node, int n_neuron, - char *param_name) - { int *ret = NULL; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronIntVar(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - - int *NESTGPU_GetNeuronPtIntVar(int *i_node, int n_neuron, - char *param_name) - { int *ret = NULL; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronIntVar(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - float *NESTGPU_GetNeuronVar(int i_node, int n_neuron, - char *param_name) - { float *ret = NULL; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronVar(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - - float *NESTGPU_GetNeuronPtVar(int *i_node, int n_neuron, - char *param_name) - { float *ret = NULL; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetNeuronVar(i_node, n_neuron, - param_name_str); - } END_ERR_PROP return ret; } - - float *NESTGPU_GetArrayVar(int i_node, char *var_name) - { float *ret = NULL; BEGIN_ERR_PROP { - - std::string var_name_str = std::string(var_name); - ret = NESTGPU_instance->GetArrayVar(i_node, var_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_Calibrate() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Calibrate(); - } END_ERR_PROP return ret; } - - int NESTGPU_Simulate() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Simulate(); - } END_ERR_PROP return ret; } - - int NESTGPU_StartSimulation() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->StartSimulation(); - } END_ERR_PROP return ret; } - - int NESTGPU_SimulationStep() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->SimulationStep(); - } END_ERR_PROP return ret; } - - int NESTGPU_EndSimulation() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->EndSimulation(); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnectMpiInit(int argc, char *argv[]) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->ConnectMpiInit(argc, argv); - } END_ERR_PROP return ret; } - - int NESTGPU_MpiId() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->MpiId(); - } END_ERR_PROP return ret; } - - int NESTGPU_MpiNp() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->MpiNp(); - } END_ERR_PROP return ret; } - int NESTGPU_ProcMaster() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->ProcMaster(); - } END_ERR_PROP return ret; } - - int NESTGPU_MpiFinalize() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->MpiFinalize(); - } END_ERR_PROP return ret; } - - unsigned int *NESTGPU_RandomInt(size_t n) - { unsigned int *ret = NULL; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RandomInt(n); - } END_ERR_PROP return ret; } - - float *NESTGPU_RandomUniform(size_t n) - { float* ret = NULL; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RandomUniform(n); - } END_ERR_PROP return ret; } - - float *NESTGPU_RandomNormal(size_t n, float mean, float stddev) - { float *ret = NULL; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RandomNormal(n, mean, stddev); - } END_ERR_PROP return ret; } - - float *NESTGPU_RandomNormalClipped(size_t n, float mean, float stddev, - float vmin, float vmax, float vstep) - { float *ret = NULL; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RandomNormalClipped(n, mean, stddev, vmin, - vmax, vstep); - } END_ERR_PROP return ret; } - - int NESTGPU_Connect(int i_source_node, int i_target_node, - unsigned char port, unsigned char syn_group, - float weight, float delay) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Connect(i_source_node, i_target_node, - port, syn_group, weight, delay); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnSpecInit() - { int ret = 0; BEGIN_ERR_PROP { - ret = ConnSpec_instance.Init(); - } END_ERR_PROP return ret; } - - int NESTGPU_SetConnSpecParam(char *param_name, int value) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = ConnSpec_instance.SetParam(param_name_str, value); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnSpecIsParam(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = ConnSpec::IsParam(param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_SynSpecInit() - { int ret = 0; BEGIN_ERR_PROP { - ret = SynSpec_instance.Init(); - } END_ERR_PROP return ret; } - - int NESTGPU_SetSynSpecIntParam(char *param_name, int value) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.SetParam(param_name_str, value); - } END_ERR_PROP return ret; } - - int NESTGPU_SetSynSpecFloatParam(char *param_name, float value) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.SetParam(param_name_str, value); - } END_ERR_PROP return ret; } - - int NESTGPU_SetSynSpecFloatPtParam(char *param_name, float *array_pt) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.SetParam(param_name_str, array_pt); - } END_ERR_PROP return ret; } - - int NESTGPU_SynSpecIsIntParam(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.IsIntParam(param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_SynSpecIsFloatParam(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.IsFloatParam(param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_SynSpecIsFloatPtParam(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - ret = SynSpec_instance.IsFloatPtParam(param_name_str); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnectSeqSeq(int i_source, int n_source, int i_target, - int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Connect(i_source, n_source, i_target, n_target, - ConnSpec_instance, SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnectSeqGroup(int i_source, int n_source, int *i_target, - int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Connect(i_source, n_source, i_target, n_target, - ConnSpec_instance, SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnectGroupSeq(int *i_source, int n_source, int i_target, - int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Connect(i_source, n_source, i_target, n_target, - ConnSpec_instance, SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_ConnectGroupGroup(int *i_source, int n_source, int *i_target, - int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->Connect(i_source, n_source, i_target, n_target, - ConnSpec_instance, SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_RemoteConnectSeqSeq(int i_source_host, int i_source, - int n_source, int i_target_host, - int i_target, int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RemoteConnect(i_source_host, i_source, n_source, - i_target_host, i_target, n_target, - ConnSpec_instance, - SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_RemoteConnectSeqGroup(int i_source_host, int i_source, - int n_source, int i_target_host, - int *i_target, int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RemoteConnect(i_source_host, i_source, n_source, - i_target_host, i_target, n_target, - ConnSpec_instance, - SynSpec_instance); - } END_ERR_PROP return ret; } - - int NESTGPU_RemoteConnectGroupSeq(int i_source_host, int *i_source, - int n_source, int i_target_host, - int i_target, int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RemoteConnect(i_source_host, i_source, n_source, - i_target_host, i_target, n_target, - ConnSpec_instance, - SynSpec_instance); - } END_ERR_PROP return ret; } - - - int NESTGPU_RemoteConnectGroupGroup(int i_source_host, int *i_source, - int n_source, int i_target_host, - int *i_target, int n_target) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->RemoteConnect(i_source_host, i_source, n_source, - i_target_host, i_target, n_target, - ConnSpec_instance, - SynSpec_instance); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetIntVarNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetIntVarNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; i var_name_vect = - NESTGPU_instance->GetScalVarNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNIntVar(i_node); - } END_ERR_PROP return ret; } - - int NESTGPU_GetNScalVar(int i_node) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetNScalVar(i_node); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetPortVarNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetPortVarNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNPortVar(i_node); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetScalParamNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetScalParamNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNScalParam(i_node); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetGroupParamNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetGroupParamNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNGroupParam(i_node); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetPortParamNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetPortParamNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNPortParam(i_node); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetArrayParamNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetArrayParamNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNArrayParam(i_node); - } END_ERR_PROP return ret; } - - char **NESTGPU_GetArrayVarNames(int i_node) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector var_name_vect = - NESTGPU_instance->GetArrayVarNames(i_node); - char **var_name_array = (char**)malloc(var_name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iGetNArrayVar(i_node); - } END_ERR_PROP return ret; } - - - int *NESTGPU_GetSeqSeqConnections(int i_source, int n_source, int i_target, - int n_target, int syn_group, int *n_conn) - { int *ret = NULL; BEGIN_ERR_PROP { - std::vector conn_id_vect = - NESTGPU_instance->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNArrayVar( i_node ); + } + END_ERR_PROP return ret; + } + + + int* + NESTGPU_GetSeqSeqConnections( int i_source, int n_source, int i_target, int n_target, int syn_group, int* n_conn ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + std::vector< ConnectionId > conn_id_vect = + NESTGPU_instance->GetConnections( i_source, n_source, i_target, n_target, syn_group ); *n_conn = conn_id_vect.size(); - int *conn_id_array = (int*)malloc((*n_conn)*3*sizeof(int)); - for (int i=0; i<(*n_conn); i++) { - conn_id_array[i*3] = conn_id_vect[i].i_source_; - conn_id_array[i*3 + 1] = conn_id_vect[i].i_group_; - conn_id_array[i*3 + 2] = conn_id_vect[i].i_conn_; + int* conn_id_array = ( int* ) malloc( ( *n_conn ) * 3 * sizeof( int ) ); + for ( int i = 0; i < ( *n_conn ); i++ ) + { + conn_id_array[ i * 3 ] = conn_id_vect[ i ].i_source_; + conn_id_array[ i * 3 + 1 ] = conn_id_vect[ i ].i_group_; + conn_id_array[ i * 3 + 2 ] = conn_id_vect[ i ].i_conn_; } ret = conn_id_array; - } END_ERR_PROP return ret; } - - int *NESTGPU_GetSeqGroupConnections(int i_source, int n_source, - int *i_target, int n_target, - int syn_group, int *n_conn) - { int *ret = NULL; BEGIN_ERR_PROP { - std::vector conn_id_vect = - NESTGPU_instance->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + } + END_ERR_PROP return ret; + } + + int* + NESTGPU_GetSeqGroupConnections( int i_source, int n_source, int* i_target, int n_target, int syn_group, int* n_conn ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + std::vector< ConnectionId > conn_id_vect = + NESTGPU_instance->GetConnections( i_source, n_source, i_target, n_target, syn_group ); *n_conn = conn_id_vect.size(); - int *conn_id_array = (int*)malloc((*n_conn)*3*sizeof(int)); - for (int i=0; i<(*n_conn); i++) { - conn_id_array[i*3] = conn_id_vect[i].i_source_; - conn_id_array[i*3 + 1] = conn_id_vect[i].i_group_; - conn_id_array[i*3 + 2] = conn_id_vect[i].i_conn_; + int* conn_id_array = ( int* ) malloc( ( *n_conn ) * 3 * sizeof( int ) ); + for ( int i = 0; i < ( *n_conn ); i++ ) + { + conn_id_array[ i * 3 ] = conn_id_vect[ i ].i_source_; + conn_id_array[ i * 3 + 1 ] = conn_id_vect[ i ].i_group_; + conn_id_array[ i * 3 + 2 ] = conn_id_vect[ i ].i_conn_; } ret = conn_id_array; - } END_ERR_PROP return ret; } - - int *NESTGPU_GetGroupSeqConnections(int *i_source, int n_source, - int i_target, int n_target, - int syn_group, int *n_conn) - { int *ret = NULL; BEGIN_ERR_PROP { - std::vector conn_id_vect = - NESTGPU_instance->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + } + END_ERR_PROP return ret; + } + + int* + NESTGPU_GetGroupSeqConnections( int* i_source, int n_source, int i_target, int n_target, int syn_group, int* n_conn ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + std::vector< ConnectionId > conn_id_vect = + NESTGPU_instance->GetConnections( i_source, n_source, i_target, n_target, syn_group ); *n_conn = conn_id_vect.size(); - int *conn_id_array = (int*)malloc((*n_conn)*3*sizeof(int)); - for (int i=0; i<(*n_conn); i++) { - conn_id_array[i*3] = conn_id_vect[i].i_source_; - conn_id_array[i*3 + 1] = conn_id_vect[i].i_group_; - conn_id_array[i*3 + 2] = conn_id_vect[i].i_conn_; + int* conn_id_array = ( int* ) malloc( ( *n_conn ) * 3 * sizeof( int ) ); + for ( int i = 0; i < ( *n_conn ); i++ ) + { + conn_id_array[ i * 3 ] = conn_id_vect[ i ].i_source_; + conn_id_array[ i * 3 + 1 ] = conn_id_vect[ i ].i_group_; + conn_id_array[ i * 3 + 2 ] = conn_id_vect[ i ].i_conn_; } ret = conn_id_array; - } END_ERR_PROP return ret; } - - int *NESTGPU_GetGroupGroupConnections(int *i_source, int n_source, - int *i_target, int n_target, - int syn_group, int *n_conn) - { int *ret = NULL; BEGIN_ERR_PROP { - std::vector conn_id_vect = - NESTGPU_instance->GetConnections(i_source, n_source, i_target, - n_target, syn_group); + } + END_ERR_PROP return ret; + } + + int* + NESTGPU_GetGroupGroupConnections( int* i_source, + int n_source, + int* i_target, + int n_target, + int syn_group, + int* n_conn ) + { + int* ret = NULL; + BEGIN_ERR_PROP + { + std::vector< ConnectionId > conn_id_vect = + NESTGPU_instance->GetConnections( i_source, n_source, i_target, n_target, syn_group ); *n_conn = conn_id_vect.size(); - int *conn_id_array = (int*)malloc((*n_conn)*3*sizeof(int)); - for (int i=0; i<(*n_conn); i++) { - conn_id_array[i*3] = conn_id_vect[i].i_source_; - conn_id_array[i*3 + 1] = conn_id_vect[i].i_group_; - conn_id_array[i*3 + 2] = conn_id_vect[i].i_conn_; + int* conn_id_array = ( int* ) malloc( ( *n_conn ) * 3 * sizeof( int ) ); + for ( int i = 0; i < ( *n_conn ); i++ ) + { + conn_id_array[ i * 3 ] = conn_id_vect[ i ].i_source_; + conn_id_array[ i * 3 + 1 ] = conn_id_vect[ i ].i_group_; + conn_id_array[ i * 3 + 2 ] = conn_id_vect[ i ].i_conn_; } ret = conn_id_array; - } END_ERR_PROP return ret; } + } + END_ERR_PROP return ret; + } - int NESTGPU_GetConnectionStatus(int i_source, int i_group, int i_conn, - int *i_target, unsigned char *port, - unsigned char *syn_group, float *delay, - float *weight) - { int ret = 0; BEGIN_ERR_PROP { + int + NESTGPU_GetConnectionStatus( int i_source, + int i_group, + int i_conn, + int* i_target, + unsigned char* port, + unsigned char* syn_group, + float* delay, + float* weight ) + { + int ret = 0; + BEGIN_ERR_PROP + { ConnectionId conn_id; conn_id.i_source_ = i_source; conn_id.i_group_ = i_group; conn_id.i_conn_ = i_conn; - ConnectionStatus conn_stat - = NESTGPU_instance->GetConnectionStatus(conn_id); + ConnectionStatus conn_stat = NESTGPU_instance->GetConnectionStatus( conn_id ); *i_target = conn_stat.i_target; *port = conn_stat.port; *syn_group = conn_stat.syn_group; *delay = conn_stat.delay; *weight = conn_stat.weight; - + ret = 0; - } END_ERR_PROP return ret; } - - - - int NESTGPU_CreateSynGroup(char *model_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string model_name_str = std::string(model_name); - ret = NESTGPU_instance->CreateSynGroup(model_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetSynGroupNParam(int i_syn_group) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetSynGroupNParam(i_syn_group); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetSynGroupParamNames(int i_syn_group) - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector name_vect = - NESTGPU_instance->GetSynGroupParamNames(i_syn_group); - char **name_array = (char**)malloc(name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iIsSynGroupParam(i_syn_group, param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetSynGroupParamIdx(int i_syn_group, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetSynGroupParamIdx(i_syn_group, param_name_str); - } END_ERR_PROP return ret; } - - - float NESTGPU_GetSynGroupParam(int i_syn_group, char *param_name) - { float ret = 0.0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetSynGroupParam(i_syn_group, param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_SetSynGroupParam(int i_syn_group, char *param_name, float val) - { float ret = 0.0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetSynGroupParam(i_syn_group, param_name_str, - val); - } END_ERR_PROP return ret; } - - - int NESTGPU_ActivateSpikeCount(int i_node, int n_node) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->ActivateSpikeCount(i_node, n_node); - } END_ERR_PROP return ret; } - - - int NESTGPU_ActivateRecSpikeTimes(int i_node, int n_node, - int max_n_rec_spike_times) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->ActivateRecSpikeTimes(i_node, n_node, - max_n_rec_spike_times); - } END_ERR_PROP return ret; } - - int NESTGPU_SetRecSpikeTimesStep(int i_node, int n_node, - int rec_spike_times_step) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->SetRecSpikeTimesStep(i_node, n_node, - rec_spike_times_step); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetNRecSpikeTimes(int i_node) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->GetNRecSpikeTimes(i_node); - } END_ERR_PROP return ret; } - - int NESTGPU_GetRecSpikeTimes(int i_node, int n_node, - int **n_spike_times_pt, - float ***spike_times_pt) - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetRecSpikeTimes(i_node, n_node, n_spike_times_pt, - spike_times_pt); - - } END_ERR_PROP return ret; } - - int NESTGPU_PushSpikesToNodes(int n_spikes, int *node_id) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->PushSpikesToNodes(n_spikes, node_id); - } END_ERR_PROP return ret; } - - int NESTGPU_GetExtNeuronInputSpikes(int *n_spikes, int **node, int **port, - float **spike_height, int include_zeros) - { int ret = 0; BEGIN_ERR_PROP { - - ret = NESTGPU_instance->GetExtNeuronInputSpikes(n_spikes, node, port, - spike_height, - include_zeros>0); - } END_ERR_PROP return ret; } - - int NESTGPU_SetNeuronGroupParam(int i_node, int n_node, char *param_name, - float val) - { float ret = 0.0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetNeuronGroupParam(i_node, n_node, - param_name_str, - val); - } END_ERR_PROP return ret; } - - int NESTGPU_IsNeuronGroupParam(int i_node, char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->IsNeuronGroupParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - float NESTGPU_GetNeuronGroupParam(int i_node, char *param_name) - { float ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetNeuronGroupParam(i_node, param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetNBoolParam() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetNBoolParam(); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetBoolParamNames() - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector name_vect = - NESTGPU_instance->GetBoolParamNames(); - char **name_array = (char**)malloc(name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iIsBoolParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetBoolParamIdx(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetBoolParamIdx(param_name_str); - } END_ERR_PROP return ret; } - - - bool NESTGPU_GetBoolParam(char *param_name) - { bool ret = true; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetBoolParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_SetBoolParam(char *param_name, bool val) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->SetBoolParam(param_name_str, val); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetNFloatParam() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetNFloatParam(); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetFloatParamNames() - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector name_vect = - NESTGPU_instance->GetFloatParamNames(); - char **name_array = (char**)malloc(name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iIsFloatParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetFloatParamIdx(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetFloatParamIdx(param_name_str); - } END_ERR_PROP return ret; } - - - float NESTGPU_GetFloatParam(char *param_name) - { float ret = 0.0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetFloatParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_SetFloatParam(char *param_name, float val) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->SetFloatParam(param_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_GetNIntParam() - { int ret = 0; BEGIN_ERR_PROP { - ret = NESTGPU_instance->GetNIntParam(); - } END_ERR_PROP return ret; } - - - char **NESTGPU_GetIntParamNames() - { char **ret = NULL; BEGIN_ERR_PROP { - std::vector name_vect = - NESTGPU_instance->GetIntParamNames(); - char **name_array = (char**)malloc(name_vect.size() - *sizeof(char*)); - for (unsigned int i=0; iIsIntParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetIntParamIdx(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - std::string param_name_str = std::string(param_name); - - ret = NESTGPU_instance->GetIntParamIdx(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_GetIntParam(char *param_name) - { int ret = 0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->GetIntParam(param_name_str); - } END_ERR_PROP return ret; } - - - int NESTGPU_SetIntParam(char *param_name, int val) - { int ret = 0; BEGIN_ERR_PROP { - - std::string param_name_str = std::string(param_name); - ret = NESTGPU_instance->SetIntParam(param_name_str, val); - } END_ERR_PROP return ret; } - - int NESTGPU_RemoteCreate(int i_host, char *model_name, int n_neuron, - int n_port) - { int ret = 0; BEGIN_ERR_PROP { - std::string model_name_str = std::string(model_name); - RemoteNodeSeq rneur = NESTGPU_instance->RemoteCreate(i_host, - model_name_str, - n_neuron, - n_port); - ret = rneur.node_seq[0]; - } END_ERR_PROP return ret; } + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_CreateSynGroup( char* model_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string model_name_str = std::string( model_name ); + ret = NESTGPU_instance->CreateSynGroup( model_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetSynGroupNParam( int i_syn_group ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetSynGroupNParam( i_syn_group ); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetSynGroupParamNames( int i_syn_group ) + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > name_vect = NESTGPU_instance->GetSynGroupParamNames( i_syn_group ); + char** name_array = ( char** ) malloc( name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < name_vect.size(); i++ ) + { + uint vl = name_vect[ i ].length() + 1; + char* param_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( param_name, name_vect[ i ].c_str(), vl ); + name_array[ i ] = param_name; + } + ret = name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_IsSynGroupParam( int i_syn_group, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsSynGroupParam( i_syn_group, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetSynGroupParamIdx( int i_syn_group, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetSynGroupParamIdx( i_syn_group, param_name_str ); + } + END_ERR_PROP return ret; + } + + + float + NESTGPU_GetSynGroupParam( int i_syn_group, char* param_name ) + { + float ret = 0.0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetSynGroupParam( i_syn_group, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_SetSynGroupParam( int i_syn_group, char* param_name, float val ) + { + float ret = 0.0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetSynGroupParam( i_syn_group, param_name_str, val ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_ActivateSpikeCount( int i_node, int n_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->ActivateSpikeCount( i_node, n_node ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_ActivateRecSpikeTimes( int i_node, int n_node, int max_n_rec_spike_times ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->ActivateRecSpikeTimes( i_node, n_node, max_n_rec_spike_times ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetRecSpikeTimesStep( int i_node, int n_node, int rec_spike_times_step ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->SetRecSpikeTimesStep( i_node, n_node, rec_spike_times_step ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNRecSpikeTimes( int i_node ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->GetNRecSpikeTimes( i_node ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetRecSpikeTimes( int i_node, int n_node, int** n_spike_times_pt, float*** spike_times_pt ) + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetRecSpikeTimes( i_node, n_node, n_spike_times_pt, spike_times_pt ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_PushSpikesToNodes( int n_spikes, int* node_id ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->PushSpikesToNodes( n_spikes, node_id ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetExtNeuronInputSpikes( int* n_spikes, int** node, int** port, float** spike_height, int include_zeros ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + ret = NESTGPU_instance->GetExtNeuronInputSpikes( n_spikes, node, port, spike_height, include_zeros > 0 ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_SetNeuronGroupParam( int i_node, int n_node, char* param_name, float val ) + { + float ret = 0.0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetNeuronGroupParam( i_node, n_node, param_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_IsNeuronGroupParam( int i_node, char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsNeuronGroupParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + float + NESTGPU_GetNeuronGroupParam( int i_node, char* param_name ) + { + float ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetNeuronGroupParam( i_node, param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNBoolParam() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNBoolParam(); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetBoolParamNames() + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > name_vect = NESTGPU_instance->GetBoolParamNames(); + char** name_array = ( char** ) malloc( name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < name_vect.size(); i++ ) + { + uint vl = name_vect[ i ].length() + 1; + char* param_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( param_name, name_vect[ i ].c_str(), vl ); + name_array[ i ] = param_name; + } + ret = name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_IsBoolParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsBoolParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetBoolParamIdx( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetBoolParamIdx( param_name_str ); + } + END_ERR_PROP return ret; + } + + + bool + NESTGPU_GetBoolParam( char* param_name ) + { + bool ret = true; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetBoolParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_SetBoolParam( char* param_name, bool val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->SetBoolParam( param_name_str, val ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetNFloatParam() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNFloatParam(); + } + END_ERR_PROP return ret; + } + + + char** + NESTGPU_GetFloatParamNames() + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > name_vect = NESTGPU_instance->GetFloatParamNames(); + char** name_array = ( char** ) malloc( name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < name_vect.size(); i++ ) + { + uint vl = name_vect[ i ].length() + 1; + char* param_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( param_name, name_vect[ i ].c_str(), vl ); + name_array[ i ] = param_name; + } + ret = name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_IsFloatParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsFloatParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetFloatParamIdx( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetFloatParamIdx( param_name_str ); + } + END_ERR_PROP return ret; + } + + + float + NESTGPU_GetFloatParam( char* param_name ) + { + float ret = 0.0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetFloatParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_SetFloatParam( char* param_name, float val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->SetFloatParam( param_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_GetNIntParam() + { + int ret = 0; + BEGIN_ERR_PROP + { + ret = NESTGPU_instance->GetNIntParam(); + } + END_ERR_PROP return ret; + } + + char** + NESTGPU_GetIntParamNames() + { + char** ret = NULL; + BEGIN_ERR_PROP + { + std::vector< std::string > name_vect = NESTGPU_instance->GetIntParamNames(); + char** name_array = ( char** ) malloc( name_vect.size() * sizeof( char* ) ); + for ( unsigned int i = 0; i < name_vect.size(); i++ ) + { + uint vl = name_vect[ i ].length() + 1; + char* param_name = ( char* ) malloc( vl * sizeof( char ) ); + + std::strncpy( param_name, name_vect[ i ].c_str(), vl ); + name_array[ i ] = param_name; + } + ret = name_array; + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_IsIntParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->IsIntParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetIntParamIdx( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string param_name_str = std::string( param_name ); + + ret = NESTGPU_instance->GetIntParamIdx( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_GetIntParam( char* param_name ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->GetIntParam( param_name_str ); + } + END_ERR_PROP return ret; + } + + + int + NESTGPU_SetIntParam( char* param_name, int val ) + { + int ret = 0; + BEGIN_ERR_PROP + { + + std::string param_name_str = std::string( param_name ); + ret = NESTGPU_instance->SetIntParam( param_name_str, val ); + } + END_ERR_PROP return ret; + } + + int + NESTGPU_RemoteCreate( int i_host, char* model_name, int n_neuron, int n_port ) + { + int ret = 0; + BEGIN_ERR_PROP + { + std::string model_name_str = std::string( model_name ); + RemoteNodeSeq rneur = NESTGPU_instance->RemoteCreate( i_host, model_name_str, n_neuron, n_port ); + ret = rneur.node_seq[ 0 ]; + } + END_ERR_PROP return ret; + } } diff --git a/src/nestgpu_C.h b/src/nestgpu_C.h index fe642dddc..5398b4808 100644 --- a/src/nestgpu_C.h +++ b/src/nestgpu_C.h @@ -21,125 +21,101 @@ */ - - - #ifndef NESTGPUC_H #define NESTGPUC_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - char *NESTGPU_GetErrorMessage(); + + char* NESTGPU_GetErrorMessage(); unsigned char NESTGPU_GetErrorCode(); - - void NESTGPU_SetOnException(int on_exception); - int NESTGPU_SetRandomSeed(unsigned long long seed); + void NESTGPU_SetOnException( int on_exception ); + + int NESTGPU_SetRandomSeed( unsigned long long seed ); - int NESTGPU_SetTimeResolution(float time_res); + int NESTGPU_SetTimeResolution( float time_res ); float NESTGPU_GetTimeResolution(); - int NESTGPU_SetMaxSpikeBufferSize(int max_size); + int NESTGPU_SetMaxSpikeBufferSize( int max_size ); int NESTGPU_GetMaxSpikeBufferSize(); - int NESTGPU_SetSimTime(float sim_time); + int NESTGPU_SetSimTime( float sim_time ); + + int NESTGPU_SetVerbosityLevel( int verbosity_level ); + + int NESTGPU_Create( char* model_name, int n_neuron, int n_port ); + + int NESTGPU_CreatePoissonGenerator( int n_node, float rate ); + + int NESTGPU_CreateRecord( char* file_name, char* var_name_arr[], int* i_node_arr, int* port_arr, int n_node ); - int NESTGPU_SetVerbosityLevel(int verbosity_level); + int NESTGPU_GetRecordDataRows( int i_record ); - int NESTGPU_Create(char *model_name, int n_neuron, int n_port); + int NESTGPU_GetRecordDataColumns( int i_record ); - int NESTGPU_CreatePoissonGenerator(int n_node, float rate); - - int NESTGPU_CreateRecord(char *file_name, char *var_name_arr[], - int *i_node_arr, int *port_arr, - int n_node); - - int NESTGPU_GetRecordDataRows(int i_record); - - int NESTGPU_GetRecordDataColumns(int i_record); + float** NESTGPU_GetRecordData( int i_record ); - float **NESTGPU_GetRecordData(int i_record); + int NESTGPU_SetNeuronScalParam( int i_node, int n_neuron, char* param_name, float val ); - int NESTGPU_SetNeuronScalParam(int i_node, int n_neuron, char *param_name, - float val); + int NESTGPU_SetNeuronArrayParam( int i_node, int n_neuron, char* param_name, float* param, int array_size ); - int NESTGPU_SetNeuronArrayParam(int i_node, int n_neuron, - char *param_name, float *param, - int array_size); + int NESTGPU_SetNeuronPtScalParam( int* i_node, int n_neuron, char* param_name, float val ); - int NESTGPU_SetNeuronPtScalParam(int *i_node, int n_neuron, - char *param_name, float val); + int NESTGPU_SetNeuronPtArrayParam( int* i_node, int n_neuron, char* param_name, float* param, int array_size ); - int NESTGPU_SetNeuronPtArrayParam(int *i_node, int n_neuron, - char *param_name, float *param, - int array_size); - - int NESTGPU_IsNeuronScalParam(int i_node, char *param_name); - - int NESTGPU_IsNeuronPortParam(int i_node, char *param_name); + int NESTGPU_IsNeuronScalParam( int i_node, char* param_name ); - int NESTGPU_IsNeuronArrayParam(int i_node, char *param_name); - + int NESTGPU_IsNeuronPortParam( int i_node, char* param_name ); - int NESTGPU_SetNeuronIntVar(int i_node, int n_neuron, char *var_name, - int val); + int NESTGPU_IsNeuronArrayParam( int i_node, char* param_name ); - int NESTGPU_SetNeuronScalVar(int i_node, int n_neuron, char *var_name, - float val); - int NESTGPU_SetNeuronArrayVar(int i_node, int n_neuron, - char *var_name, float *var, - int array_size); + int NESTGPU_SetNeuronIntVar( int i_node, int n_neuron, char* var_name, int val ); - int NESTGPU_SetNeuronPtIntVar(int *i_node, int n_neuron, - char *var_name, int val); + int NESTGPU_SetNeuronScalVar( int i_node, int n_neuron, char* var_name, float val ); - int NESTGPU_SetNeuronPtScalVar(int *i_node, int n_neuron, - char *var_name, float val); + int NESTGPU_SetNeuronArrayVar( int i_node, int n_neuron, char* var_name, float* var, int array_size ); - int NESTGPU_SetNeuronPtArrayVar(int *i_node, int n_neuron, - char *var_name, float *var, - int array_size); - - int NESTGPU_IsNeuronIntVar(int i_node, char *var_name); + int NESTGPU_SetNeuronPtIntVar( int* i_node, int n_neuron, char* var_name, int val ); - int NESTGPU_IsNeuronScalVar(int i_node, char *var_name); - - int NESTGPU_IsNeuronPortVar(int i_node, char *var_name); + int NESTGPU_SetNeuronPtScalVar( int* i_node, int n_neuron, char* var_name, float val ); - int NESTGPU_IsNeuronArrayVar(int i_node, char *var_name); + int NESTGPU_SetNeuronPtArrayVar( int* i_node, int n_neuron, char* var_name, float* var, int array_size ); - int NESTGPU_GetNeuronParamSize(int i_node, char *param_name); + int NESTGPU_IsNeuronIntVar( int i_node, char* var_name ); - int NESTGPU_GetNeuronVarSize(int i_node, char *var_name); - - float *NESTGPU_GetNeuronParam(int i_node, int n_neuron, - char *param_name); + int NESTGPU_IsNeuronScalVar( int i_node, char* var_name ); - float *NESTGPU_GetNeuronPtParam(int *i_node, int n_neuron, - char *param_name); + int NESTGPU_IsNeuronPortVar( int i_node, char* var_name ); - float *NESTGPU_GetArrayParam(int i_node, char *param_name); + int NESTGPU_IsNeuronArrayVar( int i_node, char* var_name ); - int *NESTGPU_GetNeuronIntVar(int i_node, int n_neuron, - char *param_name); + int NESTGPU_GetNeuronParamSize( int i_node, char* param_name ); - int *NESTGPU_GetNeuronPtIntVar(int *i_node, int n_neuron, - char *param_name); - - float *NESTGPU_GetNeuronVar(int i_node, int n_neuron, - char *param_name); + int NESTGPU_GetNeuronVarSize( int i_node, char* var_name ); + + float* NESTGPU_GetNeuronParam( int i_node, int n_neuron, char* param_name ); + + float* NESTGPU_GetNeuronPtParam( int* i_node, int n_neuron, char* param_name ); + + float* NESTGPU_GetArrayParam( int i_node, char* param_name ); + + int* NESTGPU_GetNeuronIntVar( int i_node, int n_neuron, char* param_name ); + + int* NESTGPU_GetNeuronPtIntVar( int* i_node, int n_neuron, char* param_name ); + + float* NESTGPU_GetNeuronVar( int i_node, int n_neuron, char* param_name ); + + float* NESTGPU_GetNeuronPtVar( int* i_node, int n_neuron, char* param_name ); + + float* NESTGPU_GetArrayVar( int i_node, char* var_name ); - float *NESTGPU_GetNeuronPtVar(int *i_node, int n_neuron, - char *param_name); - - float *NESTGPU_GetArrayVar(int i_node, char *var_name); - int NESTGPU_Calibrate(); int NESTGPU_Simulate(); @@ -150,7 +126,7 @@ extern "C" { int NESTGPU_EndSimulation(); - int NESTGPU_ConnectMpiInit(int argc, char *argv[]); + int NESTGPU_ConnectMpiInit( int argc, char* argv[] ); int NESTGPU_MpiId(); @@ -160,197 +136,204 @@ extern "C" { int NESTGPU_MpiFinalize(); - unsigned int *NESTGPU_RandomInt(size_t n); - - float *NESTGPU_RandomUniform(size_t n); - - float *NESTGPU_RandomNormal(size_t n, float mean, float stddev); - - float *NESTGPU_RandomNormalClipped(size_t n, float mean, float stddev, - float vmin, float vmax, float vstep); - - int NESTGPU_Connect(int i_source_node, int i_target_node, - unsigned char port, unsigned char syn_group, - float weight, float delay); + unsigned int* NESTGPU_RandomInt( size_t n ); + + float* NESTGPU_RandomUniform( size_t n ); + + float* NESTGPU_RandomNormal( size_t n, float mean, float stddev ); + + float* NESTGPU_RandomNormalClipped( size_t n, float mean, float stddev, float vmin, float vmax, float vstep ); + + int NESTGPU_Connect( int i_source_node, + int i_target_node, + unsigned char port, + unsigned char syn_group, + float weight, + float delay ); int NESTGPU_ConnSpecInit(); - int NESTGPU_SetConnSpecParam(char *param_name, int value); + int NESTGPU_SetConnSpecParam( char* param_name, int value ); - int NESTGPU_ConnSpecIsParam(char *param_name); + int NESTGPU_ConnSpecIsParam( char* param_name ); int NESTGPU_SynSpecInit(); - int NESTGPU_SetSynSpecIntParam(char *param_name, int value); + int NESTGPU_SetSynSpecIntParam( char* param_name, int value ); + + int NESTGPU_SetSynSpecFloatParam( char* param_name, float value ); + + int NESTGPU_SetSynSpecFloatPtParam( char* param_name, float* array_pt ); + + int NESTGPU_SynSpecIsIntParam( char* param_name ); + + int NESTGPU_SynSpecIsFloatParam( char* param_name ); + + int NESTGPU_SynSpecIsFloatPtParam( char* param_name ); + + int NESTGPU_ConnectSeqSeq( int i_source, int n_source, int i_target, int n_target ); + + int NESTGPU_ConnectSeqGroup( int i_source, int n_source, int* i_target, int n_target ); + + int NESTGPU_ConnectGroupSeq( int* i_source, int n_source, int i_target, int n_target ); + + int NESTGPU_ConnectGroupGroup( int* i_source, int n_source, int* i_target, int n_target ); + + int NESTGPU_RemoteConnectSeqSeq( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int i_target, + int n_target ); + + int NESTGPU_RemoteConnectSeqGroup( int i_source_host, + int i_source, + int n_source, + int i_target_host, + int* i_target, + int n_target ); + + int NESTGPU_RemoteConnectGroupSeq( int i_source_host, + int* i_source, + int n_source, + int i_target_host, + int i_target, + int n_target ); + + int NESTGPU_RemoteConnectGroupGroup( int i_source_host, + int* i_source, + int n_source, + int i_target_host, + int* i_target, + int n_target ); + + char** NESTGPU_GetIntVarNames( int i_node ); - int NESTGPU_SetSynSpecFloatParam(char *param_name, float value); - - int NESTGPU_SetSynSpecFloatPtParam(char *param_name, float *array_pt); + char** NESTGPU_GetScalVarNames( int i_node ); - int NESTGPU_SynSpecIsIntParam(char *param_name); + int NESTGPU_GetNIntVar( int i_node ); - int NESTGPU_SynSpecIsFloatParam(char *param_name); + int NESTGPU_GetNScalVar( int i_node ); - int NESTGPU_SynSpecIsFloatPtParam(char *param_name); - - int NESTGPU_ConnectSeqSeq(int i_source, int n_source, int i_target, - int n_target); - - int NESTGPU_ConnectSeqGroup(int i_source, int n_source, int *i_target, - int n_target); - - int NESTGPU_ConnectGroupSeq(int *i_source, int n_source, int i_target, - int n_target); - - int NESTGPU_ConnectGroupGroup(int *i_source, int n_source, int *i_target, - int n_target); - - int NESTGPU_RemoteConnectSeqSeq(int i_source_host, int i_source, - int n_source, int i_target_host, - int i_target, int n_target); - - int NESTGPU_RemoteConnectSeqGroup(int i_source_host, int i_source, - int n_source, int i_target_host, - int *i_target, int n_target); + char** NESTGPU_GetPortVarNames( int i_node ); - int NESTGPU_RemoteConnectGroupSeq(int i_source_host, int *i_source, - int n_source, int i_target_host, - int i_target, int n_target); + int NESTGPU_GetNPortVar( int i_node ); - int NESTGPU_RemoteConnectGroupGroup(int i_source_host, int *i_source, - int n_source, int i_target_host, - int *i_target, int n_target); + char** NESTGPU_GetScalParamNames( int i_node ); - char **NESTGPU_GetIntVarNames(int i_node); + int NESTGPU_GetNScalParam( int i_node ); - char **NESTGPU_GetScalVarNames(int i_node); - - int NESTGPU_GetNIntVar(int i_node); + char** NESTGPU_GetPortParamNames( int i_node ); - int NESTGPU_GetNScalVar(int i_node); - - char **NESTGPU_GetPortVarNames(int i_node); - - int NESTGPU_GetNPortVar(int i_node); - - char **NESTGPU_GetScalParamNames(int i_node); - - int NESTGPU_GetNScalParam(int i_node); - - char **NESTGPU_GetPortParamNames(int i_node); + int NESTGPU_GetNGroupParam( int i_node ); - int NESTGPU_GetNGroupParam(int i_node); - - char **NESTGPU_GetGroupParamNames(int i_node); + char** NESTGPU_GetGroupParamNames( int i_node ); - int NESTGPU_GetNPortParam(int i_node); + int NESTGPU_GetNPortParam( int i_node ); - char **NESTGPU_GetArrayParamNames(int i_node); - - int NESTGPU_GetNArrayParam(int i_node); + char** NESTGPU_GetArrayParamNames( int i_node ); - char **NESTGPU_GetArrayVarNames(int i_node); - - int NESTGPU_GetNArrayVar(int i_node); - - int *NESTGPU_GetSeqSeqConnections(int i_source, int n_source, int i_target, - int n_target, int syn_group, int *n_conn); + int NESTGPU_GetNArrayParam( int i_node ); - int *NESTGPU_GetSeqGroupConnections(int i_source, int n_source, - int *i_target, int n_target, - int syn_group, int *n_conn); + char** NESTGPU_GetArrayVarNames( int i_node ); - int *NESTGPU_GetGroupSeqConnections(int *i_source, int n_source, - int i_target, int n_target, - int syn_group, int *n_conn); + int NESTGPU_GetNArrayVar( int i_node ); - int *NESTGPU_GetGroupGroupConnections(int *i_source, int n_source, - int *i_target, int n_target, - int syn_group, int *n_conn); - int NESTGPU_GetConnectionStatus(int i_source, int i_group, int i_conn, - int *i_target, unsigned char *port, - unsigned char *syn_group, float *delay, - float *weight); + int* + NESTGPU_GetSeqSeqConnections( int i_source, int n_source, int i_target, int n_target, int syn_group, int* n_conn ); - int NESTGPU_CreateSynGroup(char *model_name); - - int NESTGPU_GetSynGroupNParam(int i_syn_group); - - char **NESTGPU_GetSynGroupParamNames(int i_syn_group); - - int NESTGPU_IsSynGroupParam(int i_syn_group, char *param_name); - - int NESTGPU_GetSynGroupParamIdx(int i_syn_group, char *param_name); - - float NESTGPU_GetSynGroupParam(int i_syn_group, char *param_name); - - int NESTGPU_SetSynGroupParam(int i_syn_group, char *param_name, float val); - - int NESTGPU_ActivateSpikeCount(int i_node, int n_node); - - int NESTGPU_ActivateRecSpikeTimes(int i_node, int n_node, - int max_n_rec_spike_times); - - int NESTGPU_SetRecSpikeTimesStep(int i_node, int n_node, - int rec_spike_times_step); - - int NESTGPU_GetNRecSpikeTimes(int i_node); - - int NESTGPU_GetRecSpikeTimes(int i_node, int n_node, - int **n_spike_times_pt, - float ***spike_times_pt); - - int NESTGPU_PushSpikesToNodes(int n_spikes, int *node_id); - - int NESTGPU_GetExtNeuronInputSpikes(int *n_spikes, int **node, int **port, - float **spike_height, - int include_zeros); - - int NESTGPU_SetNeuronGroupParam(int i_node, int n_node, char *param_name, - float val); - - int NESTGPU_IsNeuronGroupParam(int i_node, char *param_name); - - float NESTGPU_GetNeuronGroupParam(int i_node, char *param_name); + int* + NESTGPU_GetSeqGroupConnections( int i_source, int n_source, int* i_target, int n_target, int syn_group, int* n_conn ); + + int* + NESTGPU_GetGroupSeqConnections( int* i_source, int n_source, int i_target, int n_target, int syn_group, int* n_conn ); + + int* NESTGPU_GetGroupGroupConnections( int* i_source, + int n_source, + int* i_target, + int n_target, + int syn_group, + int* n_conn ); + int NESTGPU_GetConnectionStatus( int i_source, + int i_group, + int i_conn, + int* i_target, + unsigned char* port, + unsigned char* syn_group, + float* delay, + float* weight ); + + int NESTGPU_CreateSynGroup( char* model_name ); + + int NESTGPU_GetSynGroupNParam( int i_syn_group ); + + char** NESTGPU_GetSynGroupParamNames( int i_syn_group ); + + int NESTGPU_IsSynGroupParam( int i_syn_group, char* param_name ); + + int NESTGPU_GetSynGroupParamIdx( int i_syn_group, char* param_name ); + + float NESTGPU_GetSynGroupParam( int i_syn_group, char* param_name ); + + int NESTGPU_SetSynGroupParam( int i_syn_group, char* param_name, float val ); + + int NESTGPU_ActivateSpikeCount( int i_node, int n_node ); + + int NESTGPU_ActivateRecSpikeTimes( int i_node, int n_node, int max_n_rec_spike_times ); + + int NESTGPU_SetRecSpikeTimesStep( int i_node, int n_node, int rec_spike_times_step ); + + int NESTGPU_GetNRecSpikeTimes( int i_node ); + + int NESTGPU_GetRecSpikeTimes( int i_node, int n_node, int** n_spike_times_pt, float*** spike_times_pt ); + + int NESTGPU_PushSpikesToNodes( int n_spikes, int* node_id ); + + int NESTGPU_GetExtNeuronInputSpikes( int* n_spikes, int** node, int** port, float** spike_height, int include_zeros ); + + int NESTGPU_SetNeuronGroupParam( int i_node, int n_node, char* param_name, float val ); + + int NESTGPU_IsNeuronGroupParam( int i_node, char* param_name ); + + float NESTGPU_GetNeuronGroupParam( int i_node, char* param_name ); int NESTGPU_GetNBoolParam(); - - char **NESTGPU_GetBoolParamNames(); - - int NESTGPU_IsBoolParam(char *param_name); - - int NESTGPU_GetBoolParamIdx(char *param_name); - - bool NESTGPU_GetBoolParam(char *param_name); - - int NESTGPU_SetBoolParam(char *param_name, bool val); + + char** NESTGPU_GetBoolParamNames(); + + int NESTGPU_IsBoolParam( char* param_name ); + + int NESTGPU_GetBoolParamIdx( char* param_name ); + + bool NESTGPU_GetBoolParam( char* param_name ); + + int NESTGPU_SetBoolParam( char* param_name, bool val ); int NESTGPU_GetNFloatParam(); - - char **NESTGPU_GetFloatParamNames(); - - int NESTGPU_IsFloatParam(char *param_name); - - int NESTGPU_GetFloatParamIdx(char *param_name); - - float NESTGPU_GetFloatParam(char *param_name); - - int NESTGPU_SetFloatParam(char *param_name, float val); + + char** NESTGPU_GetFloatParamNames(); + + int NESTGPU_IsFloatParam( char* param_name ); + + int NESTGPU_GetFloatParamIdx( char* param_name ); + + float NESTGPU_GetFloatParam( char* param_name ); + + int NESTGPU_SetFloatParam( char* param_name, float val ); int NESTGPU_GetNIntParam(); - - char **NESTGPU_GetIntParamNames(); - - int NESTGPU_IsIntParam(char *param_name); - - int NESTGPU_GetIntParamIdx(char *param_name); - - int NESTGPU_GetIntParam(char *param_name); - - int NESTGPU_SetIntParam(char *param_name, int val); - - int NESTGPU_RemoteCreate(int i_host, char *model_name, int n_neuron, - int n_port); + + char** NESTGPU_GetIntParamNames(); + + int NESTGPU_IsIntParam( char* param_name ); + + int NESTGPU_GetIntParamIdx( char* param_name ); + + int NESTGPU_GetIntParam( char* param_name ); + + int NESTGPU_SetIntParam( char* param_name, int val ); + + int NESTGPU_RemoteCreate( int i_host, char* model_name, int n_neuron, int n_port ); #ifdef __cplusplus } diff --git a/src/neuron_models.cu b/src/neuron_models.cu index dc8c02bd4..a54f15383 100644 --- a/src/neuron_models.cu +++ b/src/neuron_models.cu @@ -21,171 +21,193 @@ */ - - - #include #include #include -#include "ngpu_exception.h" -#include "cuda_error.h" -#include "neuron_models.h" -#include "nestgpu.h" -#include "iaf_psc_exp.h" -#include "iaf_psc_exp_hc.h" -#include "iaf_psc_exp_g.h" -#include "iaf_psc_alpha.h" -#include "ext_neuron.h" #include "aeif_cond_alpha.h" +#include "aeif_cond_alpha_multisynapse.h" #include "aeif_cond_beta.h" +#include "aeif_cond_beta_multisynapse.h" #include "aeif_psc_alpha.h" +#include "aeif_psc_alpha_multisynapse.h" #include "aeif_psc_delta.h" #include "aeif_psc_exp.h" -#include "aeif_cond_beta_multisynapse.h" -#include "aeif_cond_alpha_multisynapse.h" -#include "aeif_psc_alpha_multisynapse.h" #include "aeif_psc_exp_multisynapse.h" -#include "poiss_gen.h" -#include "spike_generator.h" -#include "parrot_neuron.h" -#include "spike_detector.h" -#include "izhikevich_cond_beta.h" +#include "cuda_error.h" +#include "ext_neuron.h" +#include "iaf_psc_alpha.h" +#include "iaf_psc_exp.h" +#include "iaf_psc_exp_g.h" +#include "iaf_psc_exp_hc.h" #include "izhikevich.h" -#include "izhikevich_psc_exp_5s.h" -#include "izhikevich_psc_exp_2s.h" +#include "izhikevich_cond_beta.h" #include "izhikevich_psc_exp.h" +#include "izhikevich_psc_exp_2s.h" +#include "izhikevich_psc_exp_5s.h" +#include "nestgpu.h" +#include "neuron_models.h" +#include "ngpu_exception.h" +#include "parrot_neuron.h" +#include "poiss_gen.h" +#include "spike_detector.h" +#include "spike_generator.h" #include "user_m1.h" #include "user_m2.h" -NodeSeq NESTGPU::Create(std::string model_name, int n_node /*=1*/, - int n_port /*=1*/) +NodeSeq +NESTGPU::Create( std::string model_name, int n_node /*=1*/, int n_port /*=1*/ ) { - CheckUncalibrated("Nodes cannot be created after calibration"); - if (n_node <= 0) { - throw ngpu_exception("Number of nodes must be greater than zero."); + CheckUncalibrated( "Nodes cannot be created after calibration" ); + if ( n_node <= 0 ) + { + throw ngpu_exception( "Number of nodes must be greater than zero." ); } - else if (n_port < 0) { - throw ngpu_exception("Number of ports must be >= zero."); + else if ( n_port < 0 ) + { + throw ngpu_exception( "Number of ports must be >= zero." ); } - if (model_name == neuron_model_name[i_iaf_psc_exp_g_model]) { + if ( model_name == neuron_model_name[ i_iaf_psc_exp_g_model ] ) + { n_port = 1; - iaf_psc_exp_g *iaf_psc_exp_g_group = new iaf_psc_exp_g; - node_vect_.push_back(iaf_psc_exp_g_group); + iaf_psc_exp_g* iaf_psc_exp_g_group = new iaf_psc_exp_g; + node_vect_.push_back( iaf_psc_exp_g_group ); } - else if (model_name == neuron_model_name[i_iaf_psc_exp_hc_model]) { + else if ( model_name == neuron_model_name[ i_iaf_psc_exp_hc_model ] ) + { n_port = 1; - iaf_psc_exp_hc *iaf_psc_exp_hc_group = new iaf_psc_exp_hc; - node_vect_.push_back(iaf_psc_exp_hc_group); + iaf_psc_exp_hc* iaf_psc_exp_hc_group = new iaf_psc_exp_hc; + node_vect_.push_back( iaf_psc_exp_hc_group ); } - else if (model_name == neuron_model_name[i_iaf_psc_exp_model]) { + else if ( model_name == neuron_model_name[ i_iaf_psc_exp_model ] ) + { n_port = 2; - iaf_psc_exp *iaf_psc_exp_group = new iaf_psc_exp; - node_vect_.push_back(iaf_psc_exp_group); + iaf_psc_exp* iaf_psc_exp_group = new iaf_psc_exp; + node_vect_.push_back( iaf_psc_exp_group ); } - else if (model_name == neuron_model_name[i_iaf_psc_alpha_model]) { + else if ( model_name == neuron_model_name[ i_iaf_psc_alpha_model ] ) + { n_port = 2; - iaf_psc_alpha *iaf_psc_alpha_group = new iaf_psc_alpha; - node_vect_.push_back(iaf_psc_alpha_group); + iaf_psc_alpha* iaf_psc_alpha_group = new iaf_psc_alpha; + node_vect_.push_back( iaf_psc_alpha_group ); } - else if (model_name == neuron_model_name[i_ext_neuron_model]) { - ext_neuron *ext_neuron_group = new ext_neuron; - node_vect_.push_back(ext_neuron_group); + else if ( model_name == neuron_model_name[ i_ext_neuron_model ] ) + { + ext_neuron* ext_neuron_group = new ext_neuron; + node_vect_.push_back( ext_neuron_group ); } - else if (model_name == neuron_model_name[i_aeif_cond_alpha_model]) { + else if ( model_name == neuron_model_name[ i_aeif_cond_alpha_model ] ) + { n_port = 2; - aeif_cond_alpha *aeif_cond_alpha_group = new aeif_cond_alpha; - node_vect_.push_back(aeif_cond_alpha_group); + aeif_cond_alpha* aeif_cond_alpha_group = new aeif_cond_alpha; + node_vect_.push_back( aeif_cond_alpha_group ); } - else if (model_name == neuron_model_name[i_aeif_cond_beta_model]) { + else if ( model_name == neuron_model_name[ i_aeif_cond_beta_model ] ) + { n_port = 2; - aeif_cond_beta *aeif_cond_beta_group = new aeif_cond_beta; - node_vect_.push_back(aeif_cond_beta_group); + aeif_cond_beta* aeif_cond_beta_group = new aeif_cond_beta; + node_vect_.push_back( aeif_cond_beta_group ); } - else if (model_name == neuron_model_name[i_aeif_psc_alpha_model]) { + else if ( model_name == neuron_model_name[ i_aeif_psc_alpha_model ] ) + { n_port = 2; - aeif_psc_alpha *aeif_psc_alpha_group = new aeif_psc_alpha; - node_vect_.push_back(aeif_psc_alpha_group); + aeif_psc_alpha* aeif_psc_alpha_group = new aeif_psc_alpha; + node_vect_.push_back( aeif_psc_alpha_group ); } - else if (model_name == neuron_model_name[i_aeif_psc_delta_model]) { + else if ( model_name == neuron_model_name[ i_aeif_psc_delta_model ] ) + { n_port = 1; - aeif_psc_delta *aeif_psc_delta_group = new aeif_psc_delta; - node_vect_.push_back(aeif_psc_delta_group); + aeif_psc_delta* aeif_psc_delta_group = new aeif_psc_delta; + node_vect_.push_back( aeif_psc_delta_group ); } - else if (model_name == neuron_model_name[i_aeif_psc_exp_model]) { + else if ( model_name == neuron_model_name[ i_aeif_psc_exp_model ] ) + { n_port = 2; - aeif_psc_exp *aeif_psc_exp_group = new aeif_psc_exp; - node_vect_.push_back(aeif_psc_exp_group); - } - else if (model_name == neuron_model_name[i_aeif_cond_beta_multisynapse_model]) { - aeif_cond_beta_multisynapse *aeif_cond_beta_multisynapse_group = new aeif_cond_beta_multisynapse; - node_vect_.push_back(aeif_cond_beta_multisynapse_group); - } - else if (model_name == neuron_model_name[i_aeif_cond_alpha_multisynapse_model]) { - aeif_cond_alpha_multisynapse *aeif_cond_alpha_multisynapse_group = new aeif_cond_alpha_multisynapse; - node_vect_.push_back(aeif_cond_alpha_multisynapse_group); - } - else if (model_name == neuron_model_name[i_aeif_psc_exp_multisynapse_model]) { - aeif_psc_exp_multisynapse *aeif_psc_exp_multisynapse_group = new aeif_psc_exp_multisynapse; - node_vect_.push_back(aeif_psc_exp_multisynapse_group); - } - else if (model_name == neuron_model_name[i_aeif_psc_alpha_multisynapse_model]) { - aeif_psc_alpha_multisynapse *aeif_psc_alpha_multisynapse_group = new aeif_psc_alpha_multisynapse; - node_vect_.push_back(aeif_psc_alpha_multisynapse_group); - } - else if (model_name == neuron_model_name[i_user_m1_model]) { - user_m1 *user_m1_group = new user_m1; - node_vect_.push_back(user_m1_group); - } - else if (model_name == neuron_model_name[i_user_m2_model]) { - user_m2 *user_m2_group = new user_m2; - node_vect_.push_back(user_m2_group); - } - else if (model_name == neuron_model_name[i_poisson_generator_model]) { + aeif_psc_exp* aeif_psc_exp_group = new aeif_psc_exp; + node_vect_.push_back( aeif_psc_exp_group ); + } + else if ( model_name == neuron_model_name[ i_aeif_cond_beta_multisynapse_model ] ) + { + aeif_cond_beta_multisynapse* aeif_cond_beta_multisynapse_group = new aeif_cond_beta_multisynapse; + node_vect_.push_back( aeif_cond_beta_multisynapse_group ); + } + else if ( model_name == neuron_model_name[ i_aeif_cond_alpha_multisynapse_model ] ) + { + aeif_cond_alpha_multisynapse* aeif_cond_alpha_multisynapse_group = new aeif_cond_alpha_multisynapse; + node_vect_.push_back( aeif_cond_alpha_multisynapse_group ); + } + else if ( model_name == neuron_model_name[ i_aeif_psc_exp_multisynapse_model ] ) + { + aeif_psc_exp_multisynapse* aeif_psc_exp_multisynapse_group = new aeif_psc_exp_multisynapse; + node_vect_.push_back( aeif_psc_exp_multisynapse_group ); + } + else if ( model_name == neuron_model_name[ i_aeif_psc_alpha_multisynapse_model ] ) + { + aeif_psc_alpha_multisynapse* aeif_psc_alpha_multisynapse_group = new aeif_psc_alpha_multisynapse; + node_vect_.push_back( aeif_psc_alpha_multisynapse_group ); + } + else if ( model_name == neuron_model_name[ i_user_m1_model ] ) + { + user_m1* user_m1_group = new user_m1; + node_vect_.push_back( user_m1_group ); + } + else if ( model_name == neuron_model_name[ i_user_m2_model ] ) + { + user_m2* user_m2_group = new user_m2; + node_vect_.push_back( user_m2_group ); + } + else if ( model_name == neuron_model_name[ i_poisson_generator_model ] ) + { n_port = 0; - poiss_gen *poiss_gen_group = new poiss_gen; - node_vect_.push_back(poiss_gen_group); + poiss_gen* poiss_gen_group = new poiss_gen; + node_vect_.push_back( poiss_gen_group ); } - else if (model_name == neuron_model_name[i_spike_generator_model]) { + else if ( model_name == neuron_model_name[ i_spike_generator_model ] ) + { n_port = 0; - spike_generator *spike_generator_group = new spike_generator; - node_vect_.push_back(spike_generator_group); + spike_generator* spike_generator_group = new spike_generator; + node_vect_.push_back( spike_generator_group ); } - else if (model_name == neuron_model_name[i_parrot_neuron_model]) { + else if ( model_name == neuron_model_name[ i_parrot_neuron_model ] ) + { n_port = 2; - parrot_neuron *parrot_neuron_group = new parrot_neuron; - node_vect_.push_back(parrot_neuron_group); + parrot_neuron* parrot_neuron_group = new parrot_neuron; + node_vect_.push_back( parrot_neuron_group ); } - else if (model_name == neuron_model_name[i_spike_detector_model]) { + else if ( model_name == neuron_model_name[ i_spike_detector_model ] ) + { n_port = 1; - spike_detector *spike_detector_group = new spike_detector; - node_vect_.push_back(spike_detector_group); - } - else if (model_name == neuron_model_name[i_izhikevich_model]) { - izhikevich *izhikevich_group = new izhikevich; - node_vect_.push_back(izhikevich_group); - } - else if (model_name == neuron_model_name[i_izhikevich_cond_beta_model]) { - izhikevich_cond_beta *izhikevich_cond_beta_group = new izhikevich_cond_beta; - node_vect_.push_back(izhikevich_cond_beta_group); - } - else if (model_name == neuron_model_name[i_izhikevich_psc_exp_5s_model]) { - izhikevich_psc_exp_5s *izhikevich_psc_exp_5s_group = - new izhikevich_psc_exp_5s; - node_vect_.push_back(izhikevich_psc_exp_5s_group); - } - else if (model_name == neuron_model_name[i_izhikevich_psc_exp_2s_model]) { - izhikevich_psc_exp_2s *izhikevich_psc_exp_2s_group = - new izhikevich_psc_exp_2s; - node_vect_.push_back(izhikevich_psc_exp_2s_group); - } - else if (model_name == neuron_model_name[i_izhikevich_psc_exp_model]) { - izhikevich_psc_exp *izhikevich_psc_exp_group = new izhikevich_psc_exp; - node_vect_.push_back(izhikevich_psc_exp_group); - } - else { - throw ngpu_exception(std::string("Unknown neuron model name: ") - + model_name); - } - return NodeSeq(CreateNodeGroup(n_node, n_port), n_node); + spike_detector* spike_detector_group = new spike_detector; + node_vect_.push_back( spike_detector_group ); + } + else if ( model_name == neuron_model_name[ i_izhikevich_model ] ) + { + izhikevich* izhikevich_group = new izhikevich; + node_vect_.push_back( izhikevich_group ); + } + else if ( model_name == neuron_model_name[ i_izhikevich_cond_beta_model ] ) + { + izhikevich_cond_beta* izhikevich_cond_beta_group = new izhikevich_cond_beta; + node_vect_.push_back( izhikevich_cond_beta_group ); + } + else if ( model_name == neuron_model_name[ i_izhikevich_psc_exp_5s_model ] ) + { + izhikevich_psc_exp_5s* izhikevich_psc_exp_5s_group = new izhikevich_psc_exp_5s; + node_vect_.push_back( izhikevich_psc_exp_5s_group ); + } + else if ( model_name == neuron_model_name[ i_izhikevich_psc_exp_2s_model ] ) + { + izhikevich_psc_exp_2s* izhikevich_psc_exp_2s_group = new izhikevich_psc_exp_2s; + node_vect_.push_back( izhikevich_psc_exp_2s_group ); + } + else if ( model_name == neuron_model_name[ i_izhikevich_psc_exp_model ] ) + { + izhikevich_psc_exp* izhikevich_psc_exp_group = new izhikevich_psc_exp; + node_vect_.push_back( izhikevich_psc_exp_group ); + } + else + { + throw ngpu_exception( std::string( "Unknown neuron model name: " ) + model_name ); + } + return NodeSeq( CreateNodeGroup( n_node, n_port ), n_node ); } diff --git a/src/neuron_models.h b/src/neuron_models.h index 16206b7f9..67aa67157 100644 --- a/src/neuron_models.h +++ b/src/neuron_models.h @@ -21,15 +21,13 @@ */ - - - #ifndef NEURONMODELS_H #define NEURONMODELS_H -enum NeuronModels { +enum NeuronModels +{ i_null_model = 0, - i_iaf_psc_exp_g_model, + i_iaf_psc_exp_g_model, i_iaf_psc_exp_hc_model, i_iaf_psc_exp_model, i_iaf_psc_alpha_model, @@ -57,8 +55,7 @@ enum NeuronModels { N_NEURON_MODELS }; -const std::string neuron_model_name[N_NEURON_MODELS] = { - "", +const std::string neuron_model_name[ N_NEURON_MODELS ] = { "", "iaf_psc_exp_g", "iaf_psc_exp_hc", "iaf_psc_exp", @@ -83,7 +80,6 @@ const std::string neuron_model_name[N_NEURON_MODELS] = { "izhikevich_psc_exp_2s", "izhikevich_psc_exp", "user_m1", - "user_m2" -}; + "user_m2" }; #endif diff --git a/src/ngpu_exception.h b/src/ngpu_exception.h index 69573b61a..9cfaaf479 100644 --- a/src/ngpu_exception.h +++ b/src/ngpu_exception.h @@ -27,34 +27,51 @@ #ifndef NGPUEXCEPTION_H #define NGPUEXCEPTION_H -#include #include #include +#include /////////////////////////////////// // ngpu_exception class definition // in case of errors displays a message and stop the execution ////////////////////////////////// -class ngpu_exception: public std::exception +class ngpu_exception : public std::exception { - const char *Message; // error message - - public: + const char* Message; // error message + +public: // constructors - ngpu_exception(const char *ch) {Message=strdup(ch);} - ngpu_exception(std::string s) {Message=strdup(s.c_str());} + ngpu_exception( const char* ch ) + { + Message = strdup( ch ); + } + ngpu_exception( std::string s ) + { + Message = strdup( s.c_str() ); + } // throw method - virtual const char* what() const throw() + virtual const char* + what() const throw() { return Message; } }; #define BEGIN_TRY try -#define END_TRY catch (ngpu_exception &e){ \ - std::cerr << "Error: " << e.what() << "\n"; } \ - catch (bad_alloc&) { std::cerr << "Error allocating memory." << "\n"; } \ - catch (...) { std::cerr << "Unrecognized error\n"; } +#define END_TRY \ + catch ( ngpu_exception & e ) \ + { \ + std::cerr << "Error: " << e.what() << "\n"; \ + } \ + catch ( bad_alloc& ) \ + { \ + std::cerr << "Error allocating memory." \ + << "\n"; \ + } \ + catch ( ... ) \ + { \ + std::cerr << "Unrecognized error\n"; \ + } #endif diff --git a/src/node_group.cu b/src/node_group.cu index 86d6edcbb..fd7c030c1 100644 --- a/src/node_group.cu +++ b/src/node_group.cu @@ -21,75 +21,75 @@ */ - - - #include #include #include "cuda_error.h" -#include "node_group.h" #include "nestgpu.h" +#include "node_group.h" -__constant__ NodeGroupStruct NodeGroupArray[MAX_N_NODE_GROUPS]; -__device__ signed char *NodeGroupMap; +__constant__ NodeGroupStruct NodeGroupArray[ MAX_N_NODE_GROUPS ]; +__device__ signed char* NodeGroupMap; -__global__ -void NodeGroupMapInit(signed char *node_group_map) +__global__ void +NodeGroupMapInit( signed char* node_group_map ) { NodeGroupMap = node_group_map; } -int NESTGPU::NodeGroupArrayInit() +int +NESTGPU::NodeGroupArrayInit() { - gpuErrchk(cudaMalloc(&d_node_group_map_, - node_group_map_.size()*sizeof(signed char))); + gpuErrchk( cudaMalloc( &d_node_group_map_, node_group_map_.size() * sizeof( signed char ) ) ); - std::vector ngs_vect; - for (unsigned int i=0; i ngs_vect; + for ( unsigned int i = 0; i < node_vect_.size(); i++ ) + { NodeGroupStruct ngs; - ngs.node_type_ = node_vect_[i]->node_type_; - ngs.i_node_0_ = node_vect_[i]->i_node_0_; - ngs.n_node_ = node_vect_[i]->n_node_; - ngs.n_port_ = node_vect_[i]->n_port_; - ngs.n_param_ = node_vect_[i]->n_param_; - ngs.get_spike_array_ = node_vect_[i]->get_spike_array_; + ngs.node_type_ = node_vect_[ i ]->node_type_; + ngs.i_node_0_ = node_vect_[ i ]->i_node_0_; + ngs.n_node_ = node_vect_[ i ]->n_node_; + ngs.n_port_ = node_vect_[ i ]->n_port_; + ngs.n_param_ = node_vect_[ i ]->n_param_; + ngs.get_spike_array_ = node_vect_[ i ]->get_spike_array_; + + ngs.spike_count_ = node_vect_[ i ]->spike_count_; + ngs.rec_spike_times_ = node_vect_[ i ]->rec_spike_times_; + ngs.n_rec_spike_times_ = node_vect_[ i ]->n_rec_spike_times_; + ngs.max_n_rec_spike_times_ = node_vect_[ i ]->max_n_rec_spike_times_; + ngs.den_delay_arr_ = node_vect_[ i ]->den_delay_arr_; - ngs.spike_count_ = node_vect_[i]->spike_count_; - ngs.rec_spike_times_ = node_vect_[i]->rec_spike_times_; - ngs.n_rec_spike_times_ = node_vect_[i]->n_rec_spike_times_; - ngs.max_n_rec_spike_times_ = node_vect_[i]->max_n_rec_spike_times_; - ngs.den_delay_arr_ = node_vect_[i]->den_delay_arr_; - - ngs_vect.push_back(ngs); + ngs_vect.push_back( ngs ); } - gpuErrchk(cudaMemcpyToSymbolAsync(NodeGroupArray, ngs_vect.data(), - ngs_vect.size()*sizeof(NodeGroupStruct))); + gpuErrchk( cudaMemcpyToSymbolAsync( NodeGroupArray, ngs_vect.data(), ngs_vect.size() * sizeof( NodeGroupStruct ) ) ); // Memcopy will be synchronized with NodeGroupMapInit kernel - gpuErrchk(cudaMemcpyAsync(d_node_group_map_, node_group_map_.data(), - node_group_map_.size()*sizeof(signed char), - cudaMemcpyHostToDevice)); - NodeGroupMapInit<<<1, 1>>>(d_node_group_map_); + gpuErrchk( cudaMemcpyAsync( d_node_group_map_, + node_group_map_.data(), + node_group_map_.size() * sizeof( signed char ), + cudaMemcpyHostToDevice ) ); + NodeGroupMapInit<<< 1, 1 >>>( d_node_group_map_ ); gpuErrchk( cudaPeekAtLastError() ); return 0; } -double *NESTGPU::InitGetSpikeArray (int n_node, int n_port) +double* +NESTGPU::InitGetSpikeArray( int n_node, int n_port ) { - double *d_get_spike_array = NULL; - if (n_node*n_port > 0) { - gpuErrchk(cudaMalloc(&d_get_spike_array, n_node*n_port - *sizeof(double))); + double* d_get_spike_array = NULL; + if ( n_node * n_port > 0 ) + { + gpuErrchk( cudaMalloc( &d_get_spike_array, n_node * n_port * sizeof( double ) ) ); } - + return d_get_spike_array; } -int NESTGPU::FreeNodeGroupMap() +int +NESTGPU::FreeNodeGroupMap() { - gpuErrchk(cudaFree(d_node_group_map_)); - + gpuErrchk( cudaFree( d_node_group_map_ ) ); + return 0; } diff --git a/src/node_group.h b/src/node_group.h index fce18ee0b..490cf60c4 100644 --- a/src/node_group.h +++ b/src/node_group.h @@ -21,9 +21,6 @@ */ - - - #ifndef NODEGROUP_H #define NODEGROUP_H @@ -36,12 +33,12 @@ struct NodeGroupStruct int n_node_; int n_port_; int n_param_; - double *get_spike_array_; - int *spike_count_; - float *rec_spike_times_; - int *n_rec_spike_times_; + double* get_spike_array_; + int* spike_count_; + float* rec_spike_times_; + int* n_rec_spike_times_; int max_n_rec_spike_times_; - float *den_delay_arr_; + float* den_delay_arr_; }; #endif diff --git a/src/parrot_neuron.cu b/src/parrot_neuron.cu index 39ec0d452..294ccbdcd 100644 --- a/src/parrot_neuron.cu +++ b/src/parrot_neuron.cu @@ -21,134 +21,135 @@ */ - - - -#include #include +#include #include #include -//#include +// #include #include "cuda_error.h" #include "nestgpu.h" #include "neuron_models.h" #include "parrot_neuron.h" #include "spike_buffer.h" -//#include "parrot_neuron_variables.h" +// #include "parrot_neuron_variables.h" -enum { - i_parrot_neuron_hold_spike_height=0, +enum +{ + i_parrot_neuron_hold_spike_height = 0, i_parrot_neuron_den_delay, N_PARROT_NEURON_SCAL_PARAM }; -const std::string parrot_neuron_scal_param_name[N_PARROT_NEURON_SCAL_PARAM] -= {"hold_spike_height", "den_delay"}; +const std::string parrot_neuron_scal_param_name[ N_PARROT_NEURON_SCAL_PARAM ] = { "hold_spike_height", "den_delay" }; -enum { - i_parrot_neuron_input_spike_height=0, +enum +{ + i_parrot_neuron_input_spike_height = 0, i_parrot_neuron_dummy_input, i_parrot_neuron_V, N_PARROT_NEURON_SCAL_VAR }; -const std::string parrot_neuron_scal_var_name[N_PARROT_NEURON_SCAL_VAR] -= {"input_spike_height", "dummy_input", "V"}; +const std::string parrot_neuron_scal_var_name[ N_PARROT_NEURON_SCAL_VAR ] = { "input_spike_height", + "dummy_input", + "V" }; -__global__ -void parrot_neuron_UpdateKernel(int i_node_0, int n_node, float *var_arr, - float *param_arr, int n_var, int n_param) +__global__ void +parrot_neuron_UpdateKernel( int i_node_0, int n_node, float* var_arr, float* param_arr, int n_var, int n_param ) { int irel_node = threadIdx.x + blockIdx.x * blockDim.x; - if (irel_node < n_node) { - float *input_spike_height_pt = var_arr + irel_node*n_var - + i_parrot_neuron_input_spike_height; - float *V_pt = var_arr + irel_node*n_var + i_parrot_neuron_V; - float *hold_spike_height_pt = param_arr + irel_node*n_param + - i_parrot_neuron_hold_spike_height; + if ( irel_node < n_node ) + { + float* input_spike_height_pt = var_arr + irel_node * n_var + i_parrot_neuron_input_spike_height; + float* V_pt = var_arr + irel_node * n_var + i_parrot_neuron_V; + float* hold_spike_height_pt = param_arr + irel_node * n_param + i_parrot_neuron_hold_spike_height; int i_node = i_node_0 + irel_node; float spike_height = *input_spike_height_pt; *V_pt = spike_height; - if (spike_height != 0.0) { - if (*hold_spike_height_pt==0.0) { - spike_height = 1.0; + if ( spike_height != 0.0 ) + { + if ( *hold_spike_height_pt == 0.0 ) + { + spike_height = 1.0; } *input_spike_height_pt = 0; - PushSpike(i_node, spike_height); + PushSpike( i_node, spike_height ); } } } -int parrot_neuron::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +parrot_neuron::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_parrot_neuron_model; n_scal_var_ = N_PARROT_NEURON_SCAL_VAR; n_var_ = n_scal_var_; scal_var_name_ = parrot_neuron_scal_var_name; - + n_scal_param_ = N_PARROT_NEURON_SCAL_PARAM; n_param_ = n_scal_param_; scal_param_name_ = parrot_neuron_scal_param_name; - gpuErrchk(cudaMalloc(&var_arr_, n_node_*n_var_*sizeof(float))); + gpuErrchk( cudaMalloc( &var_arr_, n_node_ * n_var_ * sizeof( float ) ) ); - gpuErrchk(cudaMalloc(¶m_arr_, n_node_*n_param_*sizeof(float))); + gpuErrchk( cudaMalloc( ¶m_arr_, n_node_ * n_param_ * sizeof( float ) ) ); - SetScalParam(0, n_node, "hold_spike_height", 0.0); + SetScalParam( 0, n_node, "hold_spike_height", 0.0 ); - SetScalParam(0, n_node, "den_delay", 0.0); + SetScalParam( 0, n_node, "den_delay", 0.0 ); - SetScalVar(0, n_node, "input_spike_height", 0.0); + SetScalVar( 0, n_node, "input_spike_height", 0.0 ); - SetScalVar(0, n_node, "dummy_input", 0.0); + SetScalVar( 0, n_node, "dummy_input", 0.0 ); - SetScalVar(0, n_node, "V", 0.0); + SetScalVar( 0, n_node, "V", 0.0 ); // multiplication factor of input signal is always 1 for all nodes - float input_weight[] = {1.0, 0.0}; - gpuErrchk(cudaMalloc(&port_weight_arr_, 2*sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, input_weight, - 2*sizeof(float), cudaMemcpyHostToDevice)); + float input_weight[] = { 1.0, 0.0 }; + gpuErrchk( cudaMalloc( &port_weight_arr_, 2 * sizeof( float ) ) ); + gpuErrchk( cudaMemcpy( port_weight_arr_, input_weight, 2 * sizeof( float ), cudaMemcpyHostToDevice ) ); port_weight_arr_step_ = 0; port_weight_port_step_ = 1; - + // input signal is stored in input_spike_height - port_input_arr_ = GetVarArr() + GetScalVarIdx("input_spike_height"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "input_spike_height" ); 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 parrot_neuron::Update(long long /*i_time*/, double /*t1*/) +int +parrot_neuron::Update( long long /*i_time*/, double /*t1*/ ) { - parrot_neuron_UpdateKernel<<<(n_node_+1023)/1024, 1024>>> - (i_node_0_, n_node_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaPeekAtLastError() ); - //gpuErrchk( cudaDeviceSynchronize() ); + parrot_neuron_UpdateKernel<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + i_node_0_, n_node_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaPeekAtLastError() ); + // gpuErrchk( cudaDeviceSynchronize() ); return 0; } -int parrot_neuron::Free() +int +parrot_neuron::Free() { - gpuErrchk(cudaFree(var_arr_)); - gpuErrchk(cudaFree(param_arr_)); + gpuErrchk( cudaFree( var_arr_ ) ); + gpuErrchk( cudaFree( param_arr_ ) ); return 0; } parrot_neuron::~parrot_neuron() { - if (n_node_>0) { + if ( n_node_ > 0 ) + { Free(); } } diff --git a/src/parrot_neuron.h b/src/parrot_neuron.h index 55aa0ce74..a3dc73fb4 100644 --- a/src/parrot_neuron.h +++ b/src/parrot_neuron.h @@ -21,17 +21,14 @@ */ - - - #ifndef PARROTNEURON_H #define PARROTNEURON_H #include #include -//#include "node_group.h" +// #include "node_group.h" #include "base_neuron.h" -//#include "neuron_models.h" +// #include "neuron_models.h" /* BeginUserDocs: neuron, parrot @@ -59,10 +56,10 @@ Remarks - Weights on connections *from* the ``parrot_neuron`` are handled as usual. - Delays are honored on incoming and outgoing connections. -Only spikes arriving on connections to port (``receptor``) 0 will +Only spikes arriving on connections to port (``receptor``) 0 will be repeated. Connections onto port 1 will be accepted, but spikes incoming through port 1 will be ignored. This allows setting -exact pre- and postsynaptic spike times for STDP protocols by +exact pre- and postsynaptic spike times for STDP protocols by connecting two parrot neurons spiking at desired times by, e.g., a `stdp` onto port 1 on the postsynaptic parrot neuron. @@ -72,16 +69,14 @@ EndUserDocs */ class parrot_neuron : public BaseNeuron { - public: +public: ~parrot_neuron(); - int Init(int i_node_0, int n_node, int n_port, int i_group, - unsigned long long *seed); + int Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ); int Free(); - - int Update(long long it, double t1); + int Update( long long it, double t1 ); }; diff --git a/src/poiss_gen.cu b/src/poiss_gen.cu index 755715aaa..2e97630a2 100644 --- a/src/poiss_gen.cu +++ b/src/poiss_gen.cu @@ -21,16 +21,13 @@ */ - - - -#include #include +#include #include -//#include -#include +// #include #include #include +#include #include "nestgpu.h" #include "neuron_models.h" @@ -38,131 +35,141 @@ #include "poiss_gen_variables.h" extern __constant__ NodeGroupStruct NodeGroupArray[]; -extern __device__ signed char *NodeGroupMap; +extern __device__ signed char* NodeGroupMap; -extern __device__ double atomicAddDouble(double* address, double val); +extern __device__ double atomicAddDouble( double* address, double val ); -__global__ void SetupPoissKernel(curandState *curand_state, uint64_t n_dir_conn, - unsigned long long seed) +__global__ void +SetupPoissKernel( curandState* curand_state, uint64_t n_dir_conn, unsigned long long seed ) { - uint64_t blockId = (uint64_t)blockIdx.y * gridDim.x + blockIdx.x; + uint64_t blockId = ( uint64_t ) blockIdx.y * gridDim.x + blockIdx.x; uint64_t i_conn = blockId * blockDim.x + threadIdx.x; - if (i_conn=start) && (t_rel<=stop)){ - int n = curand_poisson(curand_state+i_conn, time_step*rate); - if (n>0) { // //Send direct spike (i_target, port, weight*n); - ///////////////////////////////////////////////////////////////// - int i_group=NodeGroupMap[i_target]; - int i = port*NodeGroupArray[i_group].n_node_ + i_target - - NodeGroupArray[i_group].i_node_0_; - double d_val = (double)(weight*n); - atomicAddDouble(&NodeGroupArray[i_group].get_spike_array_[i], d_val); - //////////////////////////////////////////////////////////////// + if ( ( t_rel >= start ) && ( t_rel <= stop ) ) + { + int n = curand_poisson( curand_state + i_conn, time_step * rate ); + if ( n > 0 ) + { // //Send direct spike (i_target, port, weight*n); + ///////////////////////////////////////////////////////////////// + int i_group = NodeGroupMap[ i_target ]; + int i = port * NodeGroupArray[ i_group ].n_node_ + i_target - NodeGroupArray[ i_group ].i_node_0_; + double d_val = ( double ) ( weight * n ); + atomicAddDouble( &NodeGroupArray[ i_group ].get_spike_array_[ i ], d_val ); + //////////////////////////////////////////////////////////////// } } } } -int poiss_gen::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +poiss_gen::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 0 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 0 /*n_port*/, i_group, seed ); node_type_ = i_poisson_generator_model; n_scal_param_ = N_POISS_GEN_SCAL_PARAM; n_param_ = n_scal_param_; scal_param_name_ = poiss_gen_scal_param_name; has_dir_conn_ = true; - - gpuErrchk(cudaMalloc(¶m_arr_, n_node_*n_param_*sizeof(float))); - - SetScalParam(0, n_node, "rate", 0.0); - SetScalParam(0, n_node, "origin", 0.0); - SetScalParam(0, n_node, "start", 0.0); - SetScalParam(0, n_node, "stop", 1.0e30); - + + gpuErrchk( cudaMalloc( ¶m_arr_, n_node_ * n_param_ * sizeof( float ) ) ); + + SetScalParam( 0, n_node, "rate", 0.0 ); + SetScalParam( 0, n_node, "origin", 0.0 ); + SetScalParam( 0, n_node, "start", 0.0 ); + SetScalParam( 0, n_node, "stop", 1.0e30 ); + return 0; } -int poiss_gen::Calibrate(double, float) +int +poiss_gen::Calibrate( double, float ) { - gpuErrchk(cudaMalloc(&d_curand_state_, n_dir_conn_*sizeof(curandState))); + gpuErrchk( cudaMalloc( &d_curand_state_, n_dir_conn_ * sizeof( curandState ) ) ); unsigned int grid_dim_x, grid_dim_y; - if (n_dir_conn_<65536*1024) { // max grid dim * max block dim - grid_dim_x = (n_dir_conn_+1023)/1024; + if ( n_dir_conn_ < 65536 * 1024 ) + { // max grid dim * max block dim + grid_dim_x = ( n_dir_conn_ + 1023 ) / 1024; grid_dim_y = 1; } - else { + else + { grid_dim_x = 64; // I think it's not necessary to increase it - if (n_dir_conn_>grid_dim_x*1024*65535) { - throw ngpu_exception(std::string("Number of direct connections ") - + std::to_string(n_dir_conn_) + - " larger than threshold " - + std::to_string(grid_dim_x*1024*65535)); + if ( n_dir_conn_ > grid_dim_x * 1024 * 65535 ) + { + throw ngpu_exception( std::string( "Number of direct connections " ) + std::to_string( n_dir_conn_ ) + + " larger than threshold " + std::to_string( grid_dim_x * 1024 * 65535 ) ); } - grid_dim_y = (n_dir_conn_ + grid_dim_x*1024 -1) / (grid_dim_x*1024); + grid_dim_y = ( n_dir_conn_ + grid_dim_x * 1024 - 1 ) / ( grid_dim_x * 1024 ); } - dim3 numBlocks(grid_dim_x, grid_dim_y); - SetupPoissKernel<<>>(d_curand_state_, n_dir_conn_, *seed_); + dim3 numBlocks( grid_dim_x, grid_dim_y ); + SetupPoissKernel<<< numBlocks, 1024 >>>( d_curand_state_, n_dir_conn_, *seed_ ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -int poiss_gen::Update(long long it, double t1) +int +poiss_gen::Update( long long it, double t1 ) { return 0; } -int poiss_gen::SendDirectSpikes(double t, float time_step) +int +poiss_gen::SendDirectSpikes( double t, float time_step ) { unsigned int grid_dim_x, grid_dim_y; - - if (n_dir_conn_<65536*1024) { // max grid dim * max block dim - grid_dim_x = (n_dir_conn_+1023)/1024; + + if ( n_dir_conn_ < 65536 * 1024 ) + { // max grid dim * max block dim + grid_dim_x = ( n_dir_conn_ + 1023 ) / 1024; grid_dim_y = 1; } - else { + else + { grid_dim_x = 64; // I think it's not necessary to increase it - if (n_dir_conn_>grid_dim_x*1024*65535) { - throw ngpu_exception(std::string("Number of direct connections ") - + std::to_string(n_dir_conn_) + - " larger than threshold " - + std::to_string(grid_dim_x*1024*65535)); + if ( n_dir_conn_ > grid_dim_x * 1024 * 65535 ) + { + throw ngpu_exception( std::string( "Number of direct connections " ) + std::to_string( n_dir_conn_ ) + + " larger than threshold " + std::to_string( grid_dim_x * 1024 * 65535 ) ); } - grid_dim_y = (n_dir_conn_ + grid_dim_x*1024 -1) / (grid_dim_x*1024); + grid_dim_y = ( n_dir_conn_ + grid_dim_x * 1024 - 1 ) / ( grid_dim_x * 1024 ); } - dim3 numBlocks(grid_dim_x, grid_dim_y); - PoissGenSendSpikeKernel<<>>(d_curand_state_, t, time_step, - param_arr_, n_param_, - d_dir_conn_array_, n_dir_conn_); - + dim3 numBlocks( grid_dim_x, grid_dim_y ); + PoissGenSendSpikeKernel<<< numBlocks, 1024 >>>( + d_curand_state_, t, time_step, param_arr_, n_param_, d_dir_conn_array_, n_dir_conn_ ); + gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); diff --git a/src/poiss_gen.h b/src/poiss_gen.h index aae48549a..8200d75b7 100644 --- a/src/poiss_gen.h +++ b/src/poiss_gen.h @@ -21,20 +21,17 @@ */ - - - #ifndef POISSGEN_H #define POISSGEN_H -#include -#include -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include +#include +#include /* const int N_POISS_GEN_SCAL_PARAM = 4; @@ -79,17 +76,15 @@ EndUserDocs */ class poiss_gen : public BaseNeuron { - curandState *d_curand_state_; - public: - - int Init(int i_node_0, int n_node, int n_port, int i_group, - unsigned long long *seed); + curandState* d_curand_state_; + +public: + int Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ); - int Calibrate(double, float); - - int Update(long long it, double t1); - int SendDirectSpikes(double t, float time_step); + int Calibrate( double, float ); + int Update( long long it, double t1 ); + int SendDirectSpikes( double t, float time_step ); }; diff --git a/src/poiss_gen_variables.h b/src/poiss_gen_variables.h index c85b5dddc..04dd8a234 100644 --- a/src/poiss_gen_variables.h +++ b/src/poiss_gen_variables.h @@ -21,15 +21,13 @@ */ - - - #ifndef POISSGENVARIABLES_H #define POISSGENVARIABLES_H #include -enum { +enum +{ i_rate = 0, i_origin, i_start, @@ -37,16 +35,16 @@ enum { N_POISS_GEN_SCAL_PARAM }; -const std::string poiss_gen_scal_param_name[N_POISS_GEN_SCAL_PARAM] = { +const std::string poiss_gen_scal_param_name[ N_POISS_GEN_SCAL_PARAM ] = { "rate", "origin", "start", "stop", }; -#define rate param[i_rate] -#define origin param[i_origin] -#define start param[i_start] -#define stop param[i_stop] +#define rate param[ i_rate ] +#define origin param[ i_origin ] +#define start param[ i_start ] +#define stop param[ i_stop ] #endif diff --git a/src/poisson.cu b/src/poisson.cu index eaea630cb..25ab20774 100644 --- a/src/poisson.cu +++ b/src/poisson.cu @@ -21,92 +21,99 @@ */ - - - +#include "cuda_error.h" +#include "poisson.h" +#include "spike_buffer.h" +#include #include -#include -#include #include #include -#include "poisson.h" -#include "spike_buffer.h" -#include "cuda_error.h" +#include +#include -__device__ unsigned int *PoissonData; +__device__ unsigned int* PoissonData; -__global__ void PoissonUpdate(unsigned int *poisson_data) +__global__ void +PoissonUpdate( unsigned int* poisson_data ) { PoissonData = poisson_data; } -__global__ -void PoissonSendSpikes(int i_node_0, int n_node) +__global__ void +PoissonSendSpikes( int i_node_0, int n_node ) { int i_node = threadIdx.x + blockIdx.x * blockDim.x; - if (i_node < n_node) { + if ( i_node < n_node ) + { int i_node_abs = i_node_0 + i_node; - unsigned int height = PoissonData[i_node]; - if (height>0) { - PushSpike(i_node_abs, (float)height); + unsigned int height = PoissonData[ i_node ]; + if ( height > 0 ) + { + PushSpike( i_node_abs, ( float ) height ); } } } -__global__ -void FixPoissonGenerator(unsigned int *poisson_data, int n, float mean) +__global__ void +FixPoissonGenerator( unsigned int* poisson_data, int n, float mean ) { int i = threadIdx.x + blockIdx.x * blockDim.x; - if (i < n) { - unsigned int val = poisson_data[i]; - if (val>mean*5) { - poisson_data[i] =0; + if ( i < n ) + { + unsigned int val = poisson_data[ i ]; + if ( val > mean * 5 ) + { + poisson_data[ i ] = 0; } } } -int PoissonGenerator::Init(curandGenerator_t *random_generator, unsigned int n) +int +PoissonGenerator::Init( curandGenerator_t* random_generator, unsigned int n ) { poisson_data_size_ = n; // Allocate n integers on device - CUDA_CALL(cudaMalloc((void **)&dev_poisson_data_, n * sizeof(unsigned int))); + CUDA_CALL( cudaMalloc( ( void** ) &dev_poisson_data_, n * sizeof( unsigned int ) ) ); random_generator_ = random_generator; return 0; } -int PoissonGenerator::Generate() +int +PoissonGenerator::Generate() { - return Generate(n_steps_); + return Generate( n_steps_ ); } -int PoissonGenerator::Generate(int max_n_steps) +int +PoissonGenerator::Generate( int max_n_steps ) { - if (max_n_steps <= 0) { + if ( max_n_steps <= 0 ) + { more_steps_ = n_steps_; } - else { - more_steps_ = min(n_steps_, max_n_steps); + else + { + more_steps_ = std::min( n_steps_, max_n_steps ); } // Generate N floats on device - CURAND_CALL(curandGeneratePoisson(*random_generator_, dev_poisson_data_, - n_node_*more_steps_, lambda_)); - FixPoissonGenerator<<<(n_node_+1023)/1024, 1024>>> - (dev_poisson_data_,n_node_*more_steps_, lambda_); + CURAND_CALL( curandGeneratePoisson( *random_generator_, dev_poisson_data_, n_node_ * more_steps_, lambda_ ) ); + FixPoissonGenerator<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( dev_poisson_data_, n_node_ * more_steps_, lambda_ ); return 0; } -int PoissonGenerator::Free() +int +PoissonGenerator::Free() { - CUDA_CALL(cudaFree(dev_poisson_data_)); + CUDA_CALL( cudaFree( dev_poisson_data_ ) ); return 0; } PoissonGenerator::~PoissonGenerator() { - //Free(); + // Free(); } PoissonGenerator::PoissonGenerator() @@ -115,41 +122,48 @@ PoissonGenerator::PoissonGenerator() n_node_ = 0; } -int PoissonGenerator::Create(curandGenerator_t *random_generator, - int i_node_0, int n_node, float lambda) +int +PoissonGenerator::Create( curandGenerator_t* random_generator, int i_node_0, int n_node, float lambda ) { i_node_0_ = i_node_0; n_node_ = n_node; lambda_ = lambda; - - n_steps_ = (buffer_size_ - 1)/n_node + 1; + + n_steps_ = ( buffer_size_ - 1 ) / n_node + 1; // with the above formula: // buffer_size <= n_node*n_steps <= buffer_size + n_node - 1 - Init(random_generator, n_node_*n_steps_); + Init( random_generator, n_node_ * n_steps_ ); i_step_ = 0; - + return 0; } -int PoissonGenerator::Update(int max_n_steps) +int +PoissonGenerator::Update( int max_n_steps ) { - if (i_step_ == 0) { - Generate(max_n_steps); + if ( i_step_ == 0 ) + { + Generate( max_n_steps ); } - if (i_step_ == more_steps_) { - throw ngpu_exception("Step index larger than maximum number of steps " - "in poisson generator"); + if ( i_step_ == more_steps_ ) + { + throw ngpu_exception( + "Step index larger than maximum number of steps " + "in poisson generator" ); } - - PoissonUpdate<<<1, 1>>>(&dev_poisson_data_[i_step_*n_node_]); + + PoissonUpdate<<< 1, 1 >>>( &dev_poisson_data_[ i_step_ * n_node_ ] ); gpuErrchk( cudaPeekAtLastError() ); - PoissonSendSpikes<<<(n_node_+1023)/1024, 1024>>>(i_node_0_, n_node_); + PoissonSendSpikes<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( i_node_0_, n_node_ ); gpuErrchk( cudaPeekAtLastError() ); i_step_++; - if (i_step_ == n_steps_) i_step_ = 0; + if ( i_step_ == n_steps_ ) + { + i_step_ = 0; + } return 0; } diff --git a/src/poisson.h b/src/poisson.h index f1ad0205f..818463861 100644 --- a/src/poisson.h +++ b/src/poisson.h @@ -21,19 +21,16 @@ */ - - - #ifndef POISSON_H #define POISSON_H #include #include -extern __device__ unsigned int *PoissonData; +extern __device__ unsigned int* PoissonData; class PoissonGenerator { - unsigned int *dev_poisson_data_; + unsigned int* dev_poisson_data_; int poisson_data_size_; int buffer_size_; @@ -43,28 +40,26 @@ class PoissonGenerator int more_steps_; int i_node_0_; - - int Init(curandGenerator_t *random_generator, unsigned int n); - public: - curandGenerator_t *random_generator_; + int Init( curandGenerator_t* random_generator, unsigned int n ); + +public: + curandGenerator_t* random_generator_; int n_node_; - + PoissonGenerator(); ~PoissonGenerator(); int Free(); - - int Create(curandGenerator_t *random_generator, - int i_node_0, int n_node, float lambda); - - int Generate(); - int Generate(int max_n_steps); + int Create( curandGenerator_t* random_generator, int i_node_0, int n_node, float lambda ); + + int Generate(); - int Update(int max_n_steps); + int Generate( int max_n_steps ); + int Update( int max_n_steps ); }; #endif diff --git a/src/prefix_scan.cu b/src/prefix_scan.cu index 541e9aa3d..ed959b082 100644 --- a/src/prefix_scan.cu +++ b/src/prefix_scan.cu @@ -21,36 +21,36 @@ */ - - - -#include -#include #include "prefix_scan.h" #include "scan.h" +#include +#include const unsigned int PrefixScan::AllocSize = 13 * 1048576 / 2; -int PrefixScan::Init() +int +PrefixScan::Init() { - //printf("Initializing CUDA-C scan...\n\n"); - //initScan(); - + // printf("Initializing CUDA-C scan...\n\n"); + // initScan(); + return 0; } -int PrefixScan::Scan(int *d_Output, int *d_Input, int n) +int +PrefixScan::Scan( int* d_Output, int* d_Input, int n ) { - prefix_scan(d_Output, d_Input, n, true); + prefix_scan( d_Output, d_Input, n, true ); return 0; } -int PrefixScan::Free() +int +PrefixScan::Free() { - //closeScan(); - //gpuErrchk(cudaFree(d_Output)); - //gpuErrchk(cudaFree(d_Input)); - + // closeScan(); + // gpuErrchk(cudaFree(d_Output)); + // gpuErrchk(cudaFree(d_Input)); + return 0; } diff --git a/src/prefix_scan.h b/src/prefix_scan.h index 5caf9c721..4f87bba3d 100644 --- a/src/prefix_scan.h +++ b/src/prefix_scan.h @@ -21,15 +21,12 @@ */ - - - #ifndef PREFIXSCAN_H #define PREFIXSCAN_H class PrefixScan { - public: +public: static const unsigned int AllocSize; /* @@ -43,10 +40,10 @@ class PrefixScan uint *h_OutputGPU; */ - + int Init(); - int Scan(int *d_Output, int *d_Input, int n); + int Scan( int* d_Output, int* d_Input, int n ); int Free(); }; diff --git a/src/propagate_error.h b/src/propagate_error.h index 694e95bfd..4456b3a1e 100644 --- a/src/propagate_error.h +++ b/src/propagate_error.h @@ -1,32 +1,36 @@ #ifndef PROPAGATEERROR_H #define PROPAGATEERROR_H -#define BEGIN_ERR_PROP \ - checkNESTGPUInstance(); \ - NESTGPU_instance->SetErrorFlag(false); \ - NESTGPU_instance->SetErrorMessage(""); \ - NESTGPU_instance->SetErrorCode(0); \ +#define BEGIN_ERR_PROP \ + checkNESTGPUInstance(); \ + NESTGPU_instance->SetErrorFlag( false ); \ + NESTGPU_instance->SetErrorMessage( "" ); \ + NESTGPU_instance->SetErrorCode( 0 ); \ try -#define END_ERR_PROP \ - catch (ngpu_exception &e){ \ - NESTGPU_instance->SetErrorFlag(true); \ - NESTGPU_instance->SetErrorMessage(e.what()); \ - NESTGPU_instance->SetErrorCode(2); \ - } \ - catch (std::bad_alloc&) { \ - NESTGPU_instance->SetErrorFlag(true); \ - NESTGPU_instance->SetErrorMessage("Memory allocation error."); \ - NESTGPU_instance->SetErrorCode(1); \ - } \ - catch (...) { \ - NESTGPU_instance->SetErrorFlag(true); \ - NESTGPU_instance->SetErrorMessage("Error in NESTGPU function."); \ - NESTGPU_instance->SetErrorCode(255); \ - } \ - if (NESTGPU_instance->OnException() == ON_EXCEPTION_EXIT) { \ +#define END_ERR_PROP \ + catch ( ngpu_exception & e ) \ + { \ + NESTGPU_instance->SetErrorFlag( true ); \ + NESTGPU_instance->SetErrorMessage( e.what() ); \ + NESTGPU_instance->SetErrorCode( 2 ); \ + } \ + catch ( std::bad_alloc& ) \ + { \ + NESTGPU_instance->SetErrorFlag( true ); \ + NESTGPU_instance->SetErrorMessage( "Memory allocation error." ); \ + NESTGPU_instance->SetErrorCode( 1 ); \ + } \ + catch ( ... ) \ + { \ + NESTGPU_instance->SetErrorFlag( true ); \ + NESTGPU_instance->SetErrorMessage( "Error in NESTGPU function." ); \ + NESTGPU_instance->SetErrorCode( 255 ); \ + } \ + if ( NESTGPU_instance->OnException() == ON_EXCEPTION_EXIT ) \ + { \ std::cerr << NESTGPU_instance->GetErrorMessage(); \ - exit(NESTGPU_instance->GetErrorCode()); \ + exit( NESTGPU_instance->GetErrorCode() ); \ } #endif diff --git a/src/propagator_stability.cu b/src/propagator_stability.cu index c12a3966c..5f5404707 100644 --- a/src/propagator_stability.cu +++ b/src/propagator_stability.cu @@ -26,22 +26,19 @@ #include // Includes from libnestutil: -//#include "numerics.h" +// #include "numerics.h" -__device__ -double propagator_32( double tau_syn, double tau, double C, double h ) +__device__ double +propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -51,13 +48,14 @@ double propagator_32( double tau_syn, double tau, double C, double h ) } } -__device__ -double propagator_31( double tau_syn, double tau, double C, double h ) +__device__ double +propagator_31( double tau_syn, double tau, double C, double h ) { const double P31_linear = 1.0 / ( 3.0 * C * tau * tau ) * h * h * h * ( tau_syn - tau ) * exp( -h / tau ); - const double P31 = - 1.0 / C * ( exp( -h / tau_syn ) * expm1( -h / tau + h / tau_syn ) / ( tau / tau_syn - 1.0 ) * tau - - h * exp( -h / tau_syn ) ) / ( -1.0 - -tau / tau_syn ) * tau; + const double P31 = 1.0 / C + * ( exp( -h / tau_syn ) * expm1( -h / tau + h / tau_syn ) / ( tau / tau_syn - 1.0 ) * tau + - h * exp( -h / tau_syn ) ) + / ( -1.0 - -tau / tau_syn ) * tau; const double P31_singular = h * h / 2.0 / C * exp( -h / tau ); const double dev_P31 = fabs( P31 - P31_singular ); diff --git a/src/propagator_stability.h b/src/propagator_stability.h index bb5e2422f..640c2c745 100644 --- a/src/propagator_stability.h +++ b/src/propagator_stability.h @@ -24,9 +24,7 @@ #define PROPAGATOR_STABILITY_H // Propagators to handle similar tau_m and tau_syn_* time constants. -__device__ -double propagator_31( double tau_syn, double tau, double C, double h ); -__device__ -double propagator_32( double tau_syn, double tau, double C, double h ); +__device__ double propagator_31( double tau_syn, double tau, double C, double h ); +__device__ double propagator_32( double tau_syn, double tau, double C, double h ); #endif diff --git a/src/random.cu b/src/random.cu index aac64b44f..37ce5f119 100644 --- a/src/random.cu +++ b/src/random.cu @@ -1,77 +1,75 @@ +#include "cuda_error.h" #include -#include -#include #include #include -#include "cuda_error.h" +#include +#include -unsigned int *curand_int(curandGenerator_t &gen, size_t n) +unsigned int* +curand_int( curandGenerator_t& gen, size_t n ) { - unsigned int *dev_data; + unsigned int* dev_data; // Allocate n integers on host - unsigned int *host_data = new unsigned int[n]; - + unsigned int* host_data = new unsigned int[ n ]; + // Allocate n integers on device - CUDA_CALL(cudaMalloc((void **)&dev_data, n*sizeof(unsigned int))); + CUDA_CALL( cudaMalloc( ( void** ) &dev_data, n * sizeof( unsigned int ) ) ); // Create pseudo-random number generator // Generate n integers on device - CURAND_CALL(curandGenerate(gen, dev_data, n)); + CURAND_CALL( curandGenerate( gen, dev_data, n ) ); cudaDeviceSynchronize(); // Copy device memory to host - CUDA_CALL(cudaMemcpy(host_data, dev_data, n*sizeof(unsigned int), - cudaMemcpyDeviceToHost)); + CUDA_CALL( cudaMemcpy( host_data, dev_data, n * sizeof( unsigned int ), cudaMemcpyDeviceToHost ) ); // Cleanup - CUDA_CALL(cudaFree(dev_data)); - + CUDA_CALL( cudaFree( dev_data ) ); + return host_data; } -float *curand_uniform(curandGenerator_t &gen, size_t n) +float* +curand_uniform( curandGenerator_t& gen, size_t n ) { - float *dev_data; + float* dev_data; // Allocate n floats on host - float *host_data = new float[n]; - + float* host_data = new float[ n ]; + // Allocate n floats on device - CUDA_CALL(cudaMalloc((void **)&dev_data, n*sizeof(float))); + CUDA_CALL( cudaMalloc( ( void** ) &dev_data, n * sizeof( float ) ) ); // Create pseudo-random number generator // Generate n integers on device - CURAND_CALL(curandGenerateUniform(gen, dev_data, n)); + CURAND_CALL( curandGenerateUniform( gen, dev_data, n ) ); cudaDeviceSynchronize(); // Copy device memory to host - CUDA_CALL(cudaMemcpy(host_data, dev_data, n*sizeof(float), - cudaMemcpyDeviceToHost)); + CUDA_CALL( cudaMemcpy( host_data, dev_data, n * sizeof( float ), cudaMemcpyDeviceToHost ) ); // Cleanup - CUDA_CALL(cudaFree(dev_data)); - + CUDA_CALL( cudaFree( dev_data ) ); + return host_data; } -float *curand_normal(curandGenerator_t &gen, size_t n, float mean, - float stddev) +float* +curand_normal( curandGenerator_t& gen, size_t n, float mean, float stddev ) { - size_t n1 = ( (n % 2) == 0 ) ? n : n + 1; // round up to multiple of 2 - float *dev_data; + size_t n1 = ( ( n % 2 ) == 0 ) ? n : n + 1; // round up to multiple of 2 + float* dev_data; // Allocate n floats on host - float *host_data = new float[n]; - + float* host_data = new float[ n ]; + // Allocate n1 floats on device - CUDA_CALL(cudaMalloc((void **)&dev_data, n1*sizeof(float))); + CUDA_CALL( cudaMalloc( ( void** ) &dev_data, n1 * sizeof( float ) ) ); // Create pseudo-random number generator // Generate n1 integers on device - //printf("curandGenerateNormal n1: %d\tmean: %f\tstd: %f\n", (int)n1, mean, + // printf("curandGenerateNormal n1: %d\tmean: %f\tstd: %f\n", (int)n1, mean, // stddev); - CURAND_CALL(curandGenerateNormal(gen, dev_data, n1, mean, stddev)); + CURAND_CALL( curandGenerateNormal( gen, dev_data, n1, mean, stddev ) ); cudaDeviceSynchronize(); // Copy device memory to host - CUDA_CALL(cudaMemcpy(host_data, dev_data, n*sizeof(float), - cudaMemcpyDeviceToHost)); + CUDA_CALL( cudaMemcpy( host_data, dev_data, n * sizeof( float ), cudaMemcpyDeviceToHost ) ); // Cleanup - CUDA_CALL(cudaFree(dev_data)); - + CUDA_CALL( cudaFree( dev_data ) ); + return host_data; } - diff --git a/src/random.h b/src/random.h index 38407daec..53ad4bf74 100644 --- a/src/random.h +++ b/src/random.h @@ -2,11 +2,10 @@ #define RANDOM_H #include -unsigned int *curand_int(curandGenerator_t &gen, size_t n); +unsigned int* curand_int( curandGenerator_t& gen, size_t n ); -float *curand_uniform(curandGenerator_t &gen, size_t n); +float* curand_uniform( curandGenerator_t& gen, size_t n ); -float *curand_normal(curandGenerator_t &gen, size_t n, float mean, - float stddev); +float* curand_normal( curandGenerator_t& gen, size_t n, float mean, float stddev ); #endif diff --git a/src/rev_spike.cu b/src/rev_spike.cu index 86ff99eee..def5b8446 100644 --- a/src/rev_spike.cu +++ b/src/rev_spike.cu @@ -21,119 +21,132 @@ */ - - - -#include -#include -#include "spike_buffer.h" #include "cuda_error.h" +#include "spike_buffer.h" #include "syn_model.h" +#include +#include #define SPIKE_TIME_DIFF_GUARD 15000 // must be less than 16384 -#define SPIKE_TIME_DIFF_THR 10000 // must be less than GUARD +#define SPIKE_TIME_DIFF_THR 10000 // must be less than GUARD extern __constant__ long long NESTGPUTimeIdx; extern __constant__ float NESTGPUTimeResolution; -unsigned int *d_RevSpikeNum; -unsigned int *d_RevSpikeTarget; -int *d_RevSpikeNConn; +unsigned int* d_RevSpikeNum; +unsigned int* d_RevSpikeTarget; +int* d_RevSpikeNConn; -extern __device__ void SynapseUpdate(int syn_group, float *w, float Dt); +extern __device__ void SynapseUpdate( int syn_group, float* w, float Dt ); -__device__ unsigned int *RevSpikeNum; -__device__ unsigned int *RevSpikeTarget; -__device__ int *RevSpikeNConn; +__device__ unsigned int* RevSpikeNum; +__device__ unsigned int* RevSpikeTarget; +__device__ int* RevSpikeNConn; ////////////////////////////////////////////////////////////////////// // This is the function called by the nested loop // that makes use of positive post-pre spike time difference -__device__ void SynapseUpdateFunction(int i_spike, int i_target_rev_conn) +__device__ void +SynapseUpdateFunction( int i_spike, int i_target_rev_conn ) { - unsigned int target = RevSpikeTarget[i_spike]; - unsigned int i_conn = TargetRevConnection[target][i_target_rev_conn]; - unsigned char syn_group = ConnectionSynGroup[i_conn]; - if (syn_group>0) { - float *weight = &ConnectionWeight[i_conn]; - unsigned short spike_time_idx = ConnectionSpikeTime[i_conn]; - unsigned short time_idx = (unsigned short)(NESTGPUTimeIdx & 0xffff); + unsigned int target = RevSpikeTarget[ i_spike ]; + unsigned int i_conn = TargetRevConnection[ target ][ i_target_rev_conn ]; + unsigned char syn_group = ConnectionSynGroup[ i_conn ]; + if ( syn_group > 0 ) + { + float* weight = &ConnectionWeight[ i_conn ]; + unsigned short spike_time_idx = ConnectionSpikeTime[ i_conn ]; + unsigned short time_idx = ( unsigned short ) ( NESTGPUTimeIdx & 0xffff ); unsigned short Dt_int = time_idx - spike_time_idx; - if (Dt_int= n_node) { + if ( i_node >= n_node ) + { return; } - long long target_spike_time_idx = LastRevSpikeTimeIdx[i_node]; + long long target_spike_time_idx = LastRevSpikeTimeIdx[ i_node ]; // Check if a spike reached the input synapses now - if (target_spike_time_idx!=NESTGPUTimeIdx) { + if ( target_spike_time_idx != NESTGPUTimeIdx ) + { return; } - int n_conn = TargetRevConnectionSize[i_node]; - if (n_conn>0) { - unsigned int pos = atomicAdd(RevSpikeNum, 1); - RevSpikeTarget[pos] = i_node; - RevSpikeNConn[pos] = n_conn; + int n_conn = TargetRevConnectionSize[ i_node ]; + if ( n_conn > 0 ) + { + unsigned int pos = atomicAdd( RevSpikeNum, 1 ); + RevSpikeTarget[ pos ] = i_node; + RevSpikeNConn[ pos ] = n_conn; } } -__global__ void SetConnectionSpikeTime(unsigned int n_conn, - unsigned short time_idx) +__global__ void +SetConnectionSpikeTime( unsigned int n_conn, unsigned short time_idx ) { unsigned int i_conn = threadIdx.x + blockIdx.x * blockDim.x; - if (i_conn>=n_conn) { + if ( i_conn >= n_conn ) + { return; } - ConnectionSpikeTime[i_conn] = time_idx; + ConnectionSpikeTime[ i_conn ] = time_idx; } -__global__ void ResetConnectionSpikeTimeUpKernel(unsigned int n_conn) +__global__ void +ResetConnectionSpikeTimeUpKernel( unsigned int n_conn ) { unsigned int i_conn = threadIdx.x + blockIdx.x * blockDim.x; - if (i_conn>=n_conn) { + if ( i_conn >= n_conn ) + { return; } - unsigned short spike_time = ConnectionSpikeTime[i_conn]; - if (spike_time >= 0x8000) { - ConnectionSpikeTime[i_conn] = 0; + unsigned short spike_time = ConnectionSpikeTime[ i_conn ]; + if ( spike_time >= 0x8000 ) + { + ConnectionSpikeTime[ i_conn ] = 0; } } -__global__ void ResetConnectionSpikeTimeDownKernel(unsigned int n_conn) +__global__ void +ResetConnectionSpikeTimeDownKernel( unsigned int n_conn ) { unsigned int i_conn = threadIdx.x + blockIdx.x * blockDim.x; - if (i_conn>=n_conn) { + if ( i_conn >= n_conn ) + { return; } - unsigned short spike_time = ConnectionSpikeTime[i_conn]; - if (spike_time < 0x8000) { - ConnectionSpikeTime[i_conn] = 0x8000; + unsigned short spike_time = ConnectionSpikeTime[ i_conn ]; + if ( spike_time < 0x8000 ) + { + ConnectionSpikeTime[ i_conn ] = 0x8000; } } -__global__ void DeviceRevSpikeInit(unsigned int *rev_spike_num, - unsigned int *rev_spike_target, - int *rev_spike_n_conn) +__global__ void +DeviceRevSpikeInit( unsigned int* rev_spike_num, unsigned int* rev_spike_target, int* rev_spike_n_conn ) { RevSpikeNum = rev_spike_num; RevSpikeTarget = rev_spike_target; @@ -141,61 +154,60 @@ __global__ void DeviceRevSpikeInit(unsigned int *rev_spike_num, *RevSpikeNum = 0; } -__global__ void RevSpikeReset() +__global__ void +RevSpikeReset() { *RevSpikeNum = 0; } - -int ResetConnectionSpikeTimeUp(NetConnection *net_connection) -{ - ResetConnectionSpikeTimeUpKernel - <<<(net_connection->StoredNConnections()+1023)/1024, 1024>>> - (net_connection->StoredNConnections()); + +int +ResetConnectionSpikeTimeUp( NetConnection* net_connection ) +{ + ResetConnectionSpikeTimeUpKernel <<< ( net_connection->StoredNConnections() + 1023 ) / 1024, 1024 >>>( + net_connection->StoredNConnections() ); gpuErrchk( cudaPeekAtLastError() ); return 0; } -int ResetConnectionSpikeTimeDown(NetConnection *net_connection) -{ - ResetConnectionSpikeTimeDownKernel - <<<(net_connection->StoredNConnections()+1023)/1024, 1024>>> - (net_connection->StoredNConnections()); +int +ResetConnectionSpikeTimeDown( NetConnection* net_connection ) +{ + ResetConnectionSpikeTimeDownKernel <<< ( net_connection->StoredNConnections() + 1023 ) / 1024, 1024 >>>( + net_connection->StoredNConnections() ); gpuErrchk( cudaPeekAtLastError() ); return 0; } -int RevSpikeInit(NetConnection *net_connection) +int +RevSpikeInit( NetConnection* net_connection ) { int n_spike_buffers = net_connection->connection_.size(); - - SetConnectionSpikeTime - <<<(net_connection->StoredNConnections()+1023)/1024, 1024>>> - (net_connection->StoredNConnections(), 0x8000); + + SetConnectionSpikeTime <<< ( net_connection->StoredNConnections() + 1023 ) / 1024, 1024 >>>( + net_connection->StoredNConnections(), 0x8000 ); gpuErrchk( cudaPeekAtLastError() ); - gpuErrchk(cudaMalloc(&d_RevSpikeNum, sizeof(unsigned int))); - - gpuErrchk(cudaMalloc(&d_RevSpikeTarget, - n_spike_buffers*sizeof(unsigned int))); - gpuErrchk(cudaMalloc(&d_RevSpikeNConn, - n_spike_buffers*sizeof(int))); + gpuErrchk( cudaMalloc( &d_RevSpikeNum, sizeof( unsigned int ) ) ); + + gpuErrchk( cudaMalloc( &d_RevSpikeTarget, n_spike_buffers * sizeof( unsigned int ) ) ); + gpuErrchk( cudaMalloc( &d_RevSpikeNConn, n_spike_buffers * sizeof( int ) ) ); - DeviceRevSpikeInit<<<1,1>>>(d_RevSpikeNum, d_RevSpikeTarget, - d_RevSpikeNConn); + DeviceRevSpikeInit<<< 1, 1 >>>( d_RevSpikeNum, d_RevSpikeTarget, d_RevSpikeNConn ); gpuErrchk( cudaPeekAtLastError() ); return 0; } -int RevSpikeFree() +int +RevSpikeFree() { - gpuErrchk(cudaFree(&d_RevSpikeNum)); - gpuErrchk(cudaFree(&d_RevSpikeTarget)); - gpuErrchk(cudaFree(&d_RevSpikeNConn)); + gpuErrchk( cudaFree( &d_RevSpikeNum ) ); + gpuErrchk( cudaFree( &d_RevSpikeTarget ) ); + gpuErrchk( cudaFree( &d_RevSpikeNConn ) ); return 0; } diff --git a/src/rev_spike.h b/src/rev_spike.h index 7179890f4..d1e79c2ec 100644 --- a/src/rev_spike.h +++ b/src/rev_spike.h @@ -21,28 +21,25 @@ */ - - - #ifndef REVSPIKE_H #define REVSPIKE_H -extern unsigned int *d_RevSpikeNum; -extern unsigned int *d_RevSpikeTarget; -extern int *d_RevSpikeNConn; +extern unsigned int* d_RevSpikeNum; +extern unsigned int* d_RevSpikeTarget; +extern int* d_RevSpikeNConn; __global__ void RevSpikeReset(); -__global__ void RevSpikeBufferUpdate(unsigned int n_node); +__global__ void RevSpikeBufferUpdate( unsigned int n_node ); -__global__ void SynapseUpdateKernel(int n_rev_spikes, int *RevSpikeNConn); +__global__ void SynapseUpdateKernel( int n_rev_spikes, int* RevSpikeNConn ); -int RevSpikeInit(NetConnection *net_connection); +int RevSpikeInit( NetConnection* net_connection ); int RevSpikeFree(); -int ResetConnectionSpikeTimeDown(NetConnection *net_connection); +int ResetConnectionSpikeTimeDown( NetConnection* net_connection ); -int ResetConnectionSpikeTimeUp(NetConnection *net_connection); +int ResetConnectionSpikeTimeUp( NetConnection* net_connection ); #endif diff --git a/src/rk5.cu b/src/rk5.cu index b08c29bda..1f8135b2b 100644 --- a/src/rk5.cu +++ b/src/rk5.cu @@ -21,16 +21,13 @@ */ - - - -#include -#include -#include +#include "rk5.h" #include +#include #include #include -#include "rk5.h" +#include +#include __constant__ float c2 = 0.2; __constant__ float c3 = 0.3; @@ -38,31 +35,31 @@ __constant__ float c4 = 0.6; __constant__ float c5 = 1.0; __constant__ float c6 = 0.875; __constant__ float a21 = 0.2; -__constant__ float a31 = 3.0/40.0; -__constant__ float a32 = 9.0/40.0; +__constant__ float a31 = 3.0 / 40.0; +__constant__ float a32 = 9.0 / 40.0; __constant__ float a41 = 0.3; __constant__ float a42 = -0.9; __constant__ float a43 = 1.2; -__constant__ float a51 = -11.0/54.0; +__constant__ float a51 = -11.0 / 54.0; __constant__ float a52 = 2.5; -__constant__ float a53 = -70.0/27.0; -__constant__ float a54 = 35.0/27.0; -__constant__ float a61 = 1631.0/55296.0; -__constant__ float a62 = 175.0/512.0; -__constant__ float a63 = 575.0/13824.0; -__constant__ float a64 = 44275.0/110592.0; -__constant__ float a65 = 253.0/4096.0; +__constant__ float a53 = -70.0 / 27.0; +__constant__ float a54 = 35.0 / 27.0; +__constant__ float a61 = 1631.0 / 55296.0; +__constant__ float a62 = 175.0 / 512.0; +__constant__ float a63 = 575.0 / 13824.0; +__constant__ float a64 = 44275.0 / 110592.0; +__constant__ float a65 = 253.0 / 4096.0; -__constant__ float a71 = 37.0/378.0; -__constant__ float a73 = 250.0/621.0; -__constant__ float a74 = 125.0/594.0; -__constant__ float a76 = 512.0/1771.0; +__constant__ float a71 = 37.0 / 378.0; +__constant__ float a73 = 250.0 / 621.0; +__constant__ float a74 = 125.0 / 594.0; +__constant__ float a76 = 512.0 / 1771.0; -__constant__ float e1 = 37.0/378.0 - 2825.0/27648.0; -__constant__ float e3 = 250.0/621.0 - 18575.0/48384.0; -__constant__ float e4 = 125.0/594.0 - 13525.0/55296.0; -__constant__ float e5 = -277.00/14336.0; -__constant__ float e6 = 512.0/1771.0 - 0.25; +__constant__ float e1 = 37.0 / 378.0 - 2825.0 / 27648.0; +__constant__ float e3 = 250.0 / 621.0 - 18575.0 / 48384.0; +__constant__ float e4 = 125.0 / 594.0 - 13525.0 / 55296.0; +__constant__ float e5 = -277.00 / 14336.0; +__constant__ float e6 = 512.0 / 1771.0 - 0.25; __constant__ float eps = 1.0e-6; __constant__ float coeff = 0.9; @@ -71,10 +68,12 @@ __constant__ float exp_dec = -0.25; __constant__ float err_min = 1.889568e-4; //(5/coeff)^(1/exp_inc) __constant__ float scal_min = 1.0e-1; -__global__ void SetFloatArray(float *arr, int n_elem, int step, float val) +__global__ void +SetFloatArray( float* arr, int n_elem, int step, float val ) { int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx(b))?(a):(b)) - -__global__ void SetFloatArray(float *arr, int n_elem, int step, float val); - -template -__global__ -void ArrayInit(int array_size, int n_var, int n_param, double *x_arr, - float *h_arr, float *y_arr, float *par_arr, double x_min, - float h, DataStruct data_struct) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) + +__global__ void SetFloatArray( float* arr, int n_elem, int step, float val ); + +template < class DataStruct > +__global__ void +ArrayInit( int array_size, + int n_var, + int n_param, + double* x_arr, + float* h_arr, + float* y_arr, + float* par_arr, + double x_min, + float h, + DataStruct data_struct ) { int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx -__global__ -void ArrayCalibrate(int array_size, int n_var, int n_param, double *x_arr, - float *h_arr, float *y_arr, float *par_arr, double x_min, - float h, DataStruct data_struct) +template < class DataStruct > +__global__ void +ArrayCalibrate( int array_size, + int n_var, + int n_param, + double* x_arr, + float* h_arr, + float* y_arr, + float* par_arr, + double x_min, + float h, + DataStruct data_struct ) { int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx -__device__ -void RK5Step(double &x, float *y, float &h, float h_min, float h_max, - float *param, DataStruct data_struct) +template < int NVAR, int NPARAM, class DataStruct > +__device__ void +RK5Step( double& x, float* y, float& h, float h_min, float h_max, float* param, DataStruct data_struct ) { - float y_new[NVAR]; - float k1[NVAR]; - float k2[NVAR]; - float k3[NVAR]; - float k4[NVAR]; - float k5[NVAR]; - float k6[NVAR]; - float y_scal[NVAR]; - - Derivatives(x, y, k1, param, data_struct); - for (int i=0; i( x, y, k1, param, data_struct ); + for ( int i = 0; i < NVAR; i++ ) + { + y_scal[ i ] = fabs( y[ i ] ) + fabs( k1[ i ] * h ) + scal_min; } - + float err; - for(;;) { - if (h > h_max) h = h_max; - if (h < h_min) h = h_min; - - for (int i=0; i h_max ) + { + h = h_max; + } + if ( h < h_min ) + { + h = h_min; } - Derivatives(x+c2*h, y_new, k2, param, - data_struct); - - for (int i=0; i(x+c3*h, y_new, k3, param, - data_struct); - for (int i=0; i( x + c2 * h, y_new, k2, param, data_struct ); + + for ( int i = 0; i < NVAR; i++ ) + { + y_new[ i ] = y[ i ] + h * ( a31 * k1[ i ] + a32 * k2[ i ] ); } - Derivatives(x+c4*h, y_new, k4, param, - data_struct); - - for (int i=0; i( x + c3 * h, y_new, k3, param, data_struct ); + + for ( int i = 0; i < NVAR; i++ ) + { + y_new[ i ] = y[ i ] + h * ( a41 * k1[ i ] + a42 * k2[ i ] + a43 * k3[ i ] ); } - Derivatives(x+c5*h, y_new, k5, param, - data_struct); - - for (int i=0; i( x + c4 * h, y_new, k4, param, data_struct ); + + for ( int i = 0; i < NVAR; i++ ) + { + y_new[ i ] = y[ i ] + h * ( a51 * k1[ i ] + a52 * k2[ i ] + a53 * k3[ i ] + a54 * k4[ i ] ); } - Derivatives(x+c6*h, y_new, k6, param, data_struct); - - for (int i=0; i( x + c5 * h, y_new, k5, param, data_struct ); + + for ( int i = 0; i < NVAR; i++ ) + { + y_new[ i ] = y[ i ] + h * ( a61 * k1[ i ] + a62 * k2[ i ] + a63 * k3[ i ] + a64 * k4[ i ] + a65 * k5[ i ] ); } - + Derivatives< NVAR, NPARAM >( x + c6 * h, y_new, k6, param, data_struct ); + + for ( int i = 0; i < NVAR; i++ ) + { + y_new[ i ] = y[ i ] + h * ( a71 * k1[ i ] + a73 * k3[ i ] + a74 * k4[ i ] + a76 * k6[ i ] ); + } + err = 0.0; - for (int i=0; i err_min) { - h = h*coeff*pow(err,exp_inc); + // if (h <= h_min) { + // h = h_min; + // } + // x_new = x + h; } - else { - h = 5.0*h; + + x += h; + + if ( err > err_min ) + { + h = h * coeff * pow( err, exp_inc ); } - - for (int i=0; i -__device__ -void RK5Update(double &x, float *y, double x1, float &h, float h_min, - float *param, DataStruct data_struct) +template < int NVAR, int NPARAM, class DataStruct > +__device__ void +RK5Update( double& x, float* y, double x1, float& h, float h_min, float* param, DataStruct data_struct ) { - bool end_time_step=false; - while(!end_time_step) { - float hmax=(float)(x1-x); - RK5Step(x, y, h, h_min, hmax, param, - data_struct); - end_time_step = (x >= x1-h_min); - ExternalUpdate(x, y, param, end_time_step, data_struct); + bool end_time_step = false; + while ( !end_time_step ) + { + float hmax = ( float ) ( x1 - x ); + RK5Step< NVAR, NPARAM, DataStruct >( x, y, h, h_min, hmax, param, data_struct ); + end_time_step = ( x >= x1 - h_min ); + ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } } -template -__global__ -void ArrayUpdate(int array_size, double *x_arr, float *h_arr, float *y_arr, - float *par_arr, double x1, float h_min, DataStruct data_struct) +template < int NVAR, int NPARAM, class DataStruct > +__global__ void +ArrayUpdate( int array_size, + double* x_arr, + float* h_arr, + float* y_arr, + float* par_arr, + double x1, + float h_min, + DataStruct data_struct ) { int ArrayIdx = threadIdx.x + blockIdx.x * blockDim.x; - if (ArrayIdx(x, y, x1, h, h_min, param, - data_struct); + RK5Update< NVAR, NPARAM, DataStruct >( x, y, x1, h, h_min, param, data_struct ); - x_arr[ArrayIdx] = x; - h_arr[ArrayIdx] = h; - for(int i=0; i +template < class DataStruct > class RungeKutta5 { int array_size_; int n_var_; int n_param_; - - double *d_XArr; - float *d_HArr; - float *d_YArr; - float *d_ParamArr; - public: + double* d_XArr; + float* d_HArr; + float* d_YArr; + float* d_ParamArr; +public: ~RungeKutta5(); - - double *GetXArr() {return d_XArr;} - float *GetHArr() {return d_HArr;} - float *GetYArr() {return d_YArr;} - float *GetParamArr() {return d_ParamArr;} - int Init(int array_size, int n_var, int n_param, double x_min, float h, - DataStruct data_struct); - int Calibrate(double x_min, float h, DataStruct data_struct); - int Free(); + double* + GetXArr() + { + return d_XArr; + } + float* + GetHArr() + { + return d_HArr; + } + float* + GetYArr() + { + return d_YArr; + } + float* + GetParamArr() + { + return d_ParamArr; + } + int Init( int array_size, int n_var, int n_param, double x_min, float h, DataStruct data_struct ); + int Calibrate( double x_min, float h, DataStruct data_struct ); - int GetX(int i_array, int n_elem, double *x); - int GetY(int i_var, int i_array, int n_elem, float *y); - int SetParam(int i_param, int i_array, int n_param, int n_elem, float val); - int SetVectParam(int i_param, int i_array, int n_param, int n_elem, - float *param, int vect_size); - template int Update(double x1, float h_min, - DataStruct data_struct); + int Free(); + int GetX( int i_array, int n_elem, double* x ); + int GetY( int i_var, int i_array, int n_elem, float* y ); + int SetParam( int i_param, int i_array, int n_param, int n_elem, float val ); + int SetVectParam( int i_param, int i_array, int n_param, int n_elem, float* param, int vect_size ); + template < int NVAR, int NPARAM > + int Update( double x1, float h_min, DataStruct data_struct ); }; -template -template - int RungeKutta5::Update(double x1, float h_min, - DataStruct data_struct) +template < class DataStruct > +template < int NVAR, int NPARAM > +int +RungeKutta5< DataStruct >::Update( double x1, float h_min, DataStruct data_struct ) { - ArrayUpdate<<<(array_size_+1023)/1024, 1024>>> - (array_size_, d_XArr, d_HArr, d_YArr, d_ParamArr, x1, h_min, data_struct); - //gpuErrchk( cudaPeekAtLastError() ); - //gpuErrchk( cudaDeviceSynchronize() ); + ArrayUpdate< NVAR, NPARAM, DataStruct > <<< ( array_size_ + 1023 ) / 1024, 1024 >>>( + array_size_, d_XArr, d_HArr, d_YArr, d_ParamArr, x1, h_min, data_struct ); + // gpuErrchk( cudaPeekAtLastError() ); + // gpuErrchk( cudaDeviceSynchronize() ); return 0; } -template -RungeKutta5::~RungeKutta5() +template < class DataStruct > +RungeKutta5< DataStruct >::~RungeKutta5() { Free(); } -template -int RungeKutta5::Free() +template < class DataStruct > +int +RungeKutta5< DataStruct >::Free() { - cudaFree(d_XArr); - cudaFree(d_HArr); - cudaFree(d_YArr); - cudaFree(d_ParamArr); + cudaFree( d_XArr ); + cudaFree( d_HArr ); + cudaFree( d_YArr ); + cudaFree( d_ParamArr ); return 0; } -template -int RungeKutta5::Init(int array_size, int n_var, int n_param, - double x_min, float h, - DataStruct data_struct) +template < class DataStruct > +int +RungeKutta5< DataStruct >::Init( int array_size, int n_var, int n_param, double x_min, float h, DataStruct data_struct ) { array_size_ = array_size; n_var_ = n_var; - n_param_ = n_param; + n_param_ = n_param; - gpuErrchk(cudaMalloc(&d_XArr, array_size_*sizeof(double))); - gpuErrchk(cudaMalloc(&d_HArr, array_size_*sizeof(float))); - gpuErrchk(cudaMalloc(&d_YArr, array_size_*n_var_*sizeof(float))); - gpuErrchk(cudaMalloc(&d_ParamArr, array_size_*n_param_*sizeof(float))); + gpuErrchk( cudaMalloc( &d_XArr, array_size_ * sizeof( double ) ) ); + gpuErrchk( cudaMalloc( &d_HArr, array_size_ * sizeof( float ) ) ); + gpuErrchk( cudaMalloc( &d_YArr, array_size_ * n_var_ * sizeof( float ) ) ); + gpuErrchk( cudaMalloc( &d_ParamArr, array_size_ * n_param_ * sizeof( float ) ) ); - ArrayInit<<<(array_size+1023)/1024, 1024>>> - (array_size_, n_var, n_param, d_XArr, d_HArr, d_YArr, d_ParamArr, - x_min, h, data_struct); + ArrayInit< DataStruct > <<< ( array_size + 1023 ) / 1024, 1024 >>>( + array_size_, n_var, n_param, d_XArr, d_HArr, d_YArr, d_ParamArr, x_min, h, data_struct ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -template -int RungeKutta5::Calibrate(double x_min, float h, - DataStruct data_struct) +template < class DataStruct > +int +RungeKutta5< DataStruct >::Calibrate( double x_min, float h, DataStruct data_struct ) { - ArrayCalibrate<<<(array_size_+1023)/1024, 1024>>> - (array_size_, n_var_, n_param_, d_XArr, d_HArr, d_YArr, d_ParamArr, - x_min, h, data_struct); + ArrayCalibrate< DataStruct > <<< ( array_size_ + 1023 ) / 1024, 1024 >>>( + array_size_, n_var_, n_param_, d_XArr, d_HArr, d_YArr, d_ParamArr, x_min, h, data_struct ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); return 0; } -template -int RungeKutta5::GetX(int i_array, int n_elem, double *x) +template < class DataStruct > +int +RungeKutta5< DataStruct >::GetX( int i_array, int n_elem, double* x ) { - cudaMemcpy(x, &d_XArr[i_array], n_elem*sizeof(double), - cudaMemcpyDeviceToHost); + cudaMemcpy( x, &d_XArr[ i_array ], n_elem * sizeof( double ), cudaMemcpyDeviceToHost ); return 0; } -template -int RungeKutta5::GetY(int i_var, int i_array, int n_elem, float *y) +template < class DataStruct > +int +RungeKutta5< DataStruct >::GetY( int i_var, int i_array, int n_elem, float* y ) { - cudaMemcpy(y, &d_YArr[i_array*n_var_ + i_var], n_elem*sizeof(float), - cudaMemcpyDeviceToHost); + cudaMemcpy( y, &d_YArr[ i_array * n_var_ + i_var ], n_elem * sizeof( float ), cudaMemcpyDeviceToHost ); return 0; } -template -int RungeKutta5::SetParam(int i_param, int i_array, int n_param, - int n_elem, float val) +template < class DataStruct > +int +RungeKutta5< DataStruct >::SetParam( int i_param, int i_array, int n_param, int n_elem, float val ) { - SetFloatArray<<<(n_elem+1023)/1024, 1024>>> - (&d_ParamArr[i_array*n_param_ + i_param], n_elem, n_param, val); + SetFloatArray<<< ( n_elem + 1023 ) / 1024, 1024 >>>( + &d_ParamArr[ i_array * n_param_ + i_param ], n_elem, n_param, val ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } diff --git a/src/rk5_interface.h b/src/rk5_interface.h index be5e61152..35ba1fa55 100644 --- a/src/rk5_interface.h +++ b/src/rk5_interface.h @@ -21,9 +21,6 @@ */ - - - #ifndef RK5INTERFACE_H #define RK5INTERFACE_H diff --git a/src/scan.cu b/src/scan.cu index 937996eab..0fd019190 100644 --- a/src/scan.cu +++ b/src/scan.cu @@ -1,335 +1,382 @@ /* - Matt Dean - https://github.com/mattdean1/cuda + Matt Dean - https://github.com/mattdean1/cuda */ +#include "scan.h" #include #include -#include "scan.h" -#define checkCudaError(o, l) _checkCudaError(o, l, __func__) +#define checkCudaError( o, l ) _checkCudaError( o, l, __func__ ) #define SHARED_MEMORY_BANKS 32 #define LOG_MEM_BANKS 5 -#define CONFLICT_FREE_OFFSET(n) ((n) >> LOG_MEM_BANKS) +#define CONFLICT_FREE_OFFSET( n ) ( ( n ) >> LOG_MEM_BANKS ) int THREADS_PER_BLOCK = 512; int ELEMENTS_PER_BLOCK = THREADS_PER_BLOCK * 2; -__global__ void prescan_arbitrary(int *output, int *input, int n, int powerOfTwo) +__global__ void +prescan_arbitrary( int* output, int* input, int n, int powerOfTwo ) { - extern __shared__ int temp[];// allocated on invocation - int threadID = threadIdx.x; - - int ai = threadID; - int bi = threadID + (n / 2); - int bankOffsetA = CONFLICT_FREE_OFFSET(ai); - int bankOffsetB = CONFLICT_FREE_OFFSET(bi); - - - if (threadID < n) { - temp[ai + bankOffsetA] = input[ai]; - temp[bi + bankOffsetB] = input[bi]; - } - else { - temp[ai + bankOffsetA] = 0; - temp[bi + bankOffsetB] = 0; - } - - - int offset = 1; - for (int d = powerOfTwo >> 1; d > 0; d >>= 1) // build sum in place up the tree - { - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - ai += CONFLICT_FREE_OFFSET(ai); - bi += CONFLICT_FREE_OFFSET(bi); - - temp[bi] += temp[ai]; - } - offset *= 2; - } - - if (threadID == 0) { - temp[powerOfTwo - 1 + CONFLICT_FREE_OFFSET(powerOfTwo - 1)] = 0; // clear the last element - } - - for (int d = 1; d < powerOfTwo; d *= 2) // traverse down tree & build scan - { - offset >>= 1; - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - ai += CONFLICT_FREE_OFFSET(ai); - bi += CONFLICT_FREE_OFFSET(bi); - - int t = temp[ai]; - temp[ai] = temp[bi]; - temp[bi] += t; - } - } - __syncthreads(); - - if (threadID < n) { - output[ai] = temp[ai + bankOffsetA]; - output[bi] = temp[bi + bankOffsetB]; - } + extern __shared__ int temp[]; // allocated on invocation + int threadID = threadIdx.x; + + int ai = threadID; + int bi = threadID + ( n / 2 ); + int bankOffsetA = CONFLICT_FREE_OFFSET( ai ); + int bankOffsetB = CONFLICT_FREE_OFFSET( bi ); + + + if ( threadID < n ) + { + temp[ ai + bankOffsetA ] = input[ ai ]; + temp[ bi + bankOffsetB ] = input[ bi ]; + } + else + { + temp[ ai + bankOffsetA ] = 0; + temp[ bi + bankOffsetB ] = 0; + } + + + int offset = 1; + for ( int d = powerOfTwo >> 1; d > 0; d >>= 1 ) // build sum in place up the tree + { + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + ai += CONFLICT_FREE_OFFSET( ai ); + bi += CONFLICT_FREE_OFFSET( bi ); + + temp[ bi ] += temp[ ai ]; + } + offset *= 2; + } + + if ( threadID == 0 ) + { + temp[ powerOfTwo - 1 + CONFLICT_FREE_OFFSET( powerOfTwo - 1 ) ] = 0; // clear the last element + } + + for ( int d = 1; d < powerOfTwo; d *= 2 ) // traverse down tree & build scan + { + offset >>= 1; + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + ai += CONFLICT_FREE_OFFSET( ai ); + bi += CONFLICT_FREE_OFFSET( bi ); + + int t = temp[ ai ]; + temp[ ai ] = temp[ bi ]; + temp[ bi ] += t; + } + } + __syncthreads(); + + if ( threadID < n ) + { + output[ ai ] = temp[ ai + bankOffsetA ]; + output[ bi ] = temp[ bi + bankOffsetB ]; + } } -__global__ void prescan_arbitrary_unoptimized(int *output, int *input, int n, int powerOfTwo) { - extern __shared__ int temp[];// allocated on invocation - int threadID = threadIdx.x; - - if (threadID < n) { - temp[2 * threadID] = input[2 * threadID]; // load input into shared memory - temp[2 * threadID + 1] = input[2 * threadID + 1]; - } - else { - temp[2 * threadID] = 0; - temp[2 * threadID + 1] = 0; - } - - - int offset = 1; - for (int d = powerOfTwo >> 1; d > 0; d >>= 1) // build sum in place up the tree - { - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - temp[bi] += temp[ai]; - } - offset *= 2; - } - - if (threadID == 0) { temp[powerOfTwo - 1] = 0; } // clear the last element - - for (int d = 1; d < powerOfTwo; d *= 2) // traverse down tree & build scan - { - offset >>= 1; - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - int t = temp[ai]; - temp[ai] = temp[bi]; - temp[bi] += t; - } - } - __syncthreads(); - - if (threadID < n) { - output[2 * threadID] = temp[2 * threadID]; // write results to device memory - output[2 * threadID + 1] = temp[2 * threadID + 1]; - } +__global__ void +prescan_arbitrary_unoptimized( int* output, int* input, int n, int powerOfTwo ) +{ + extern __shared__ int temp[]; // allocated on invocation + int threadID = threadIdx.x; + + if ( threadID < n ) + { + temp[ 2 * threadID ] = input[ 2 * threadID ]; // load input into shared memory + temp[ 2 * threadID + 1 ] = input[ 2 * threadID + 1 ]; + } + else + { + temp[ 2 * threadID ] = 0; + temp[ 2 * threadID + 1 ] = 0; + } + + + int offset = 1; + for ( int d = powerOfTwo >> 1; d > 0; d >>= 1 ) // build sum in place up the tree + { + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + temp[ bi ] += temp[ ai ]; + } + offset *= 2; + } + + if ( threadID == 0 ) + { + temp[ powerOfTwo - 1 ] = 0; + } // clear the last element + + for ( int d = 1; d < powerOfTwo; d *= 2 ) // traverse down tree & build scan + { + offset >>= 1; + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + int t = temp[ ai ]; + temp[ ai ] = temp[ bi ]; + temp[ bi ] += t; + } + } + __syncthreads(); + + if ( threadID < n ) + { + output[ 2 * threadID ] = temp[ 2 * threadID ]; // write results to device memory + output[ 2 * threadID + 1 ] = temp[ 2 * threadID + 1 ]; + } } -__global__ void prescan_large(int *output, int *input, int n, int *sums) { - extern __shared__ int temp[]; - - int blockID = blockIdx.x; - int threadID = threadIdx.x; - int blockOffset = blockID * n; - - int ai = threadID; - int bi = threadID + (n / 2); - int bankOffsetA = CONFLICT_FREE_OFFSET(ai); - int bankOffsetB = CONFLICT_FREE_OFFSET(bi); - temp[ai + bankOffsetA] = input[blockOffset + ai]; - temp[bi + bankOffsetB] = input[blockOffset + bi]; - - int offset = 1; - for (int d = n >> 1; d > 0; d >>= 1) // build sum in place up the tree - { - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - ai += CONFLICT_FREE_OFFSET(ai); - bi += CONFLICT_FREE_OFFSET(bi); - - temp[bi] += temp[ai]; - } - offset *= 2; - } - __syncthreads(); - - - if (threadID == 0) { - sums[blockID] = temp[n - 1 + CONFLICT_FREE_OFFSET(n - 1)]; - temp[n - 1 + CONFLICT_FREE_OFFSET(n - 1)] = 0; - } - - for (int d = 1; d < n; d *= 2) // traverse down tree & build scan - { - offset >>= 1; - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - ai += CONFLICT_FREE_OFFSET(ai); - bi += CONFLICT_FREE_OFFSET(bi); - - int t = temp[ai]; - temp[ai] = temp[bi]; - temp[bi] += t; - } - } - __syncthreads(); - - output[blockOffset + ai] = temp[ai + bankOffsetA]; - output[blockOffset + bi] = temp[bi + bankOffsetB]; +__global__ void +prescan_large( int* output, int* input, int n, int* sums ) +{ + extern __shared__ int temp[]; + + int blockID = blockIdx.x; + int threadID = threadIdx.x; + int blockOffset = blockID * n; + + int ai = threadID; + int bi = threadID + ( n / 2 ); + int bankOffsetA = CONFLICT_FREE_OFFSET( ai ); + int bankOffsetB = CONFLICT_FREE_OFFSET( bi ); + temp[ ai + bankOffsetA ] = input[ blockOffset + ai ]; + temp[ bi + bankOffsetB ] = input[ blockOffset + bi ]; + + int offset = 1; + for ( int d = n >> 1; d > 0; d >>= 1 ) // build sum in place up the tree + { + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + ai += CONFLICT_FREE_OFFSET( ai ); + bi += CONFLICT_FREE_OFFSET( bi ); + + temp[ bi ] += temp[ ai ]; + } + offset *= 2; + } + __syncthreads(); + + + if ( threadID == 0 ) + { + sums[ blockID ] = temp[ n - 1 + CONFLICT_FREE_OFFSET( n - 1 ) ]; + temp[ n - 1 + CONFLICT_FREE_OFFSET( n - 1 ) ] = 0; + } + + for ( int d = 1; d < n; d *= 2 ) // traverse down tree & build scan + { + offset >>= 1; + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + ai += CONFLICT_FREE_OFFSET( ai ); + bi += CONFLICT_FREE_OFFSET( bi ); + + int t = temp[ ai ]; + temp[ ai ] = temp[ bi ]; + temp[ bi ] += t; + } + } + __syncthreads(); + + output[ blockOffset + ai ] = temp[ ai + bankOffsetA ]; + output[ blockOffset + bi ] = temp[ bi + bankOffsetB ]; } -__global__ void prescan_large_unoptimized(int *output, int *input, int n, int *sums) { - int blockID = blockIdx.x; - int threadID = threadIdx.x; - int blockOffset = blockID * n; - - extern __shared__ int temp[]; - temp[2 * threadID] = input[blockOffset + (2 * threadID)]; - temp[2 * threadID + 1] = input[blockOffset + (2 * threadID) + 1]; - - int offset = 1; - for (int d = n >> 1; d > 0; d >>= 1) // build sum in place up the tree - { - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - temp[bi] += temp[ai]; - } - offset *= 2; - } - __syncthreads(); - - - if (threadID == 0) { - sums[blockID] = temp[n - 1]; - temp[n - 1] = 0; - } - - for (int d = 1; d < n; d *= 2) // traverse down tree & build scan - { - offset >>= 1; - __syncthreads(); - if (threadID < d) - { - int ai = offset * (2 * threadID + 1) - 1; - int bi = offset * (2 * threadID + 2) - 1; - int t = temp[ai]; - temp[ai] = temp[bi]; - temp[bi] += t; - } - } - __syncthreads(); - - output[blockOffset + (2 * threadID)] = temp[2 * threadID]; - output[blockOffset + (2 * threadID) + 1] = temp[2 * threadID + 1]; +__global__ void +prescan_large_unoptimized( int* output, int* input, int n, int* sums ) +{ + int blockID = blockIdx.x; + int threadID = threadIdx.x; + int blockOffset = blockID * n; + + extern __shared__ int temp[]; + temp[ 2 * threadID ] = input[ blockOffset + ( 2 * threadID ) ]; + temp[ 2 * threadID + 1 ] = input[ blockOffset + ( 2 * threadID ) + 1 ]; + + int offset = 1; + for ( int d = n >> 1; d > 0; d >>= 1 ) // build sum in place up the tree + { + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + temp[ bi ] += temp[ ai ]; + } + offset *= 2; + } + __syncthreads(); + + + if ( threadID == 0 ) + { + sums[ blockID ] = temp[ n - 1 ]; + temp[ n - 1 ] = 0; + } + + for ( int d = 1; d < n; d *= 2 ) // traverse down tree & build scan + { + offset >>= 1; + __syncthreads(); + if ( threadID < d ) + { + int ai = offset * ( 2 * threadID + 1 ) - 1; + int bi = offset * ( 2 * threadID + 2 ) - 1; + int t = temp[ ai ]; + temp[ ai ] = temp[ bi ]; + temp[ bi ] += t; + } + } + __syncthreads(); + + output[ blockOffset + ( 2 * threadID ) ] = temp[ 2 * threadID ]; + output[ blockOffset + ( 2 * threadID ) + 1 ] = temp[ 2 * threadID + 1 ]; } -__global__ void add(int *output, int length, int *n) { - int blockID = blockIdx.x; - int threadID = threadIdx.x; - int blockOffset = blockID * length; +__global__ void +add( int* output, int length, int* n ) +{ + int blockID = blockIdx.x; + int threadID = threadIdx.x; + int blockOffset = blockID * length; - output[blockOffset + threadID] += n[blockID]; + output[ blockOffset + threadID ] += n[ blockID ]; } -__global__ void add(int *output, int length, int *n1, int *n2) { - int blockID = blockIdx.x; - int threadID = threadIdx.x; - int blockOffset = blockID * length; +__global__ void +add( int* output, int length, int* n1, int* n2 ) +{ + int blockID = blockIdx.x; + int threadID = threadIdx.x; + int blockOffset = blockID * length; - output[blockOffset + threadID] += n1[blockID] + n2[blockID]; + output[ blockOffset + threadID ] += n1[ blockID ] + n2[ blockID ]; } -void prefix_scan(int *d_out, int *d_in, int length, bool bcao) { - if (length > ELEMENTS_PER_BLOCK) { - scanLargeDeviceArray(d_out, d_in, length, bcao); +void +prefix_scan( int* d_out, int* d_in, int length, bool bcao ) +{ + if ( length > ELEMENTS_PER_BLOCK ) + { + scanLargeDeviceArray( d_out, d_in, length, bcao ); } - else { - scanSmallDeviceArray(d_out, d_in, length, bcao); + else + { + scanSmallDeviceArray( d_out, d_in, length, bcao ); } } -void scanLargeDeviceArray(int *d_out, int *d_in, int length, bool bcao) { - int remainder = length % (ELEMENTS_PER_BLOCK); - if (remainder == 0) { - scanLargeEvenDeviceArray(d_out, d_in, length, bcao); - } - else { - // perform a large scan on a compatible multiple of elements - int lengthMultiple = length - remainder; - scanLargeEvenDeviceArray(d_out, d_in, lengthMultiple, bcao); +void +scanLargeDeviceArray( int* d_out, int* d_in, int length, bool bcao ) +{ + int remainder = length % ( ELEMENTS_PER_BLOCK ); + if ( remainder == 0 ) + { + scanLargeEvenDeviceArray( d_out, d_in, length, bcao ); + } + else + { + // perform a large scan on a compatible multiple of elements + int lengthMultiple = length - remainder; + scanLargeEvenDeviceArray( d_out, d_in, lengthMultiple, bcao ); + + // scan the remaining elements and add the (inclusive) last element of the large scan to this + int* startOfOutputArray = &( d_out[ lengthMultiple ] ); + scanSmallDeviceArray( startOfOutputArray, &( d_in[ lengthMultiple ] ), remainder, bcao ); + + add<<< 1, remainder>>>( + startOfOutputArray, remainder, &( d_in[ lengthMultiple - 1 ] ), &( d_out[ lengthMultiple - 1 ] ) ); + } +} - // scan the remaining elements and add the (inclusive) last element of the large scan to this - int *startOfOutputArray = &(d_out[lengthMultiple]); - scanSmallDeviceArray(startOfOutputArray, &(d_in[lengthMultiple]), remainder, bcao); +void +scanSmallDeviceArray( int* d_out, int* d_in, int length, bool bcao ) +{ + int powerOfTwo = nextPowerOfTwo( length ); - add<<<1, remainder>>>(startOfOutputArray, remainder, &(d_in[lengthMultiple - 1]), &(d_out[lengthMultiple - 1])); - } + if ( bcao ) + { + prescan_arbitrary <<< 1, ( length + 1 ) / 2, 2 * powerOfTwo * sizeof( int ) >>>( d_out, d_in, length, powerOfTwo ); + } + else + { + prescan_arbitrary_unoptimized<<< 1, ( length + 1 ) / 2, 2 * powerOfTwo * sizeof( int ) >>>( + d_out, d_in, length, powerOfTwo ); + } } -void scanSmallDeviceArray(int *d_out, int *d_in, int length, bool bcao) { - int powerOfTwo = nextPowerOfTwo(length); +void +scanLargeEvenDeviceArray( int* d_out, int* d_in, int length, bool bcao ) +{ + const int blocks = length / ELEMENTS_PER_BLOCK; + const int sharedMemArraySize = ELEMENTS_PER_BLOCK * sizeof( int ); + + int *d_sums, *d_incr; + cudaMalloc( ( void** ) &d_sums, blocks * sizeof( int ) ); + cudaMalloc( ( void** ) &d_incr, blocks * sizeof( int ) ); - if (bcao) { - prescan_arbitrary << <1, (length + 1) / 2, 2 * powerOfTwo * sizeof(int) >> >(d_out, d_in, length, powerOfTwo); - } - else { - prescan_arbitrary_unoptimized<< <1, (length + 1) / 2, 2 * powerOfTwo * sizeof(int) >> >(d_out, d_in, length, powerOfTwo); - } -} + if ( bcao ) + { + prescan_large<<< blocks, THREADS_PER_BLOCK, 2 * sharedMemArraySize>>>( d_out, d_in, ELEMENTS_PER_BLOCK, d_sums ); + } + else + { + prescan_large_unoptimized<<< blocks, THREADS_PER_BLOCK, 2 * sharedMemArraySize>>>( + d_out, d_in, ELEMENTS_PER_BLOCK, d_sums ); + } + + const int sumsArrThreadsNeeded = ( blocks + 1 ) / 2; + if ( sumsArrThreadsNeeded > THREADS_PER_BLOCK ) + { + // perform a large scan on the sums arr + scanLargeDeviceArray( d_incr, d_sums, blocks, bcao ); + } + else + { + // only need one block to scan sums arr so can use small scan + scanSmallDeviceArray( d_incr, d_sums, blocks, bcao ); + } + + add<<< blocks, ELEMENTS_PER_BLOCK>>>( d_out, ELEMENTS_PER_BLOCK, d_incr ); -void scanLargeEvenDeviceArray(int *d_out, int *d_in, int length, bool bcao) { - const int blocks = length / ELEMENTS_PER_BLOCK; - const int sharedMemArraySize = ELEMENTS_PER_BLOCK * sizeof(int); - - int *d_sums, *d_incr; - cudaMalloc((void **)&d_sums, blocks * sizeof(int)); - cudaMalloc((void **)&d_incr, blocks * sizeof(int)); - - if (bcao) { - prescan_large<<>>(d_out, d_in, ELEMENTS_PER_BLOCK, d_sums); - } - else { - prescan_large_unoptimized<<>>(d_out, d_in, ELEMENTS_PER_BLOCK, d_sums); - } - - const int sumsArrThreadsNeeded = (blocks + 1) / 2; - if (sumsArrThreadsNeeded > THREADS_PER_BLOCK) { - // perform a large scan on the sums arr - scanLargeDeviceArray(d_incr, d_sums, blocks, bcao); - } - else { - // only need one block to scan sums arr so can use small scan - scanSmallDeviceArray(d_incr, d_sums, blocks, bcao); - } - - add<<>>(d_out, ELEMENTS_PER_BLOCK, d_incr); - - cudaFree(d_sums); - cudaFree(d_incr); + cudaFree( d_sums ); + cudaFree( d_incr ); } // from https://stackoverflow.com/a/12506181 -int nextPowerOfTwo(int x) { - int power = 1; - while (power < x) { - power *= 2; - } - return power; +int +nextPowerOfTwo( int x ) +{ + int power = 1; + while ( power < x ) + { + power *= 2; + } + return power; } diff --git a/src/scan.h b/src/scan.h index 2e63c7017..78960ec2b 100644 --- a/src/scan.h +++ b/src/scan.h @@ -1,31 +1,31 @@ /* - Matt Dean - https://github.com/mattdean1/cuda + Matt Dean - https://github.com/mattdean1/cuda */ #ifndef SCANCUH #define SCANCUH -__global__ void prescan_arbitrary(int *g_odata, int *g_idata, int n, int powerOfTwo); -__global__ void prescan_arbitrary_unoptimized(int *g_odata, int *g_idata, int n, int powerOfTwo); +__global__ void prescan_arbitrary( int* g_odata, int* g_idata, int n, int powerOfTwo ); +__global__ void prescan_arbitrary_unoptimized( int* g_odata, int* g_idata, int n, int powerOfTwo ); -__global__ void prescan_large(int *g_odata, int *g_idata, int n, int* sums); -__global__ void prescan_large_unoptimized(int *output, int *input, int n, int *sums); +__global__ void prescan_large( int* g_odata, int* g_idata, int n, int* sums ); +__global__ void prescan_large_unoptimized( int* output, int* input, int n, int* sums ); -__global__ void add(int *output, int length, int *n1); -__global__ void add(int *output, int length, int *n1, int *n2); +__global__ void add( int* output, int length, int* n1 ); +__global__ void add( int* output, int length, int* n1, int* n2 ); -void _checkCudaError(const char *message, cudaError_t err, const char *caller); -void printResult(const char* prefix, int result, long nanoseconds); -void printResult(const char* prefix, int result, float milliseconds); +void _checkCudaError( const char* message, cudaError_t err, const char* caller ); +void printResult( const char* prefix, int result, long nanoseconds ); +void printResult( const char* prefix, int result, float milliseconds ); -bool isPowerOfTwo(int x); -int nextPowerOfTwo(int x); +bool isPowerOfTwo( int x ); +int nextPowerOfTwo( int x ); long get_nanos(); -void prefix_scan(int *output, int *input, int length, bool bcao); -void scanLargeDeviceArray(int *output, int *input, int length, bool bcao); -void scanSmallDeviceArray(int *d_out, int *d_in, int length, bool bcao); -void scanLargeEvenDeviceArray(int *output, int *input, int length, bool bcao); +void prefix_scan( int* output, int* input, int length, bool bcao ); +void scanLargeDeviceArray( int* output, int* input, int length, bool bcao ); +void scanSmallDeviceArray( int* d_out, int* d_in, int length, bool bcao ); +void scanLargeEvenDeviceArray( int* output, int* input, int length, bool bcao ); #endif diff --git a/src/send_spike.cu b/src/send_spike.cu index 4da3c3eb4..d273cab3c 100644 --- a/src/send_spike.cu +++ b/src/send_spike.cu @@ -21,46 +21,47 @@ */ - - - +#include "cuda_error.h" +#include "send_spike.h" #include #include -#include "send_spike.h" -#include "cuda_error.h" -int *d_SpikeNum; -int *d_SpikeSourceIdx; -int *d_SpikeConnIdx; -float *d_SpikeHeight; -int *d_SpikeTargetNum; +int* d_SpikeNum; +int* d_SpikeSourceIdx; +int* d_SpikeConnIdx; +float* d_SpikeHeight; +int* d_SpikeTargetNum; __device__ int MaxSpikeNum; -__device__ int *SpikeNum; -__device__ int *SpikeSourceIdx; -__device__ int *SpikeConnIdx; -__device__ float *SpikeHeight; -__device__ int *SpikeTargetNum; +__device__ int* SpikeNum; +__device__ int* SpikeSourceIdx; +__device__ int* SpikeConnIdx; +__device__ float* SpikeHeight; +__device__ int* SpikeTargetNum; -__device__ void SendSpike(int i_source, int i_conn, float height, - int target_num) +__device__ void +SendSpike( int i_source, int i_conn, float height, int target_num ) { - int pos = atomicAdd(SpikeNum, 1); - if (pos>=MaxSpikeNum) { - printf("Number of spikes larger than MaxSpikeNum: %d\n", MaxSpikeNum); + int pos = atomicAdd( SpikeNum, 1 ); + if ( pos >= MaxSpikeNum ) + { + printf( "Number of spikes larger than MaxSpikeNum: %d\n", MaxSpikeNum ); *SpikeNum = MaxSpikeNum; return; } - SpikeSourceIdx[pos] = i_source; - SpikeConnIdx[pos] = i_conn; - SpikeHeight[pos] = height; - SpikeTargetNum[pos] = target_num; + SpikeSourceIdx[ pos ] = i_source; + SpikeConnIdx[ pos ] = i_conn; + SpikeHeight[ pos ] = height; + SpikeTargetNum[ pos ] = target_num; } -__global__ void DeviceSpikeInit(int *spike_num, int *spike_source_idx, - int *spike_conn_idx, float *spike_height, - int *spike_target_num, - int max_spike_num) +__global__ void +DeviceSpikeInit( int* spike_num, + int* spike_source_idx, + int* spike_conn_idx, + float* spike_height, + int* spike_target_num, + int max_spike_num ) { SpikeNum = spike_num; SpikeSourceIdx = spike_source_idx; @@ -72,22 +73,24 @@ __global__ void DeviceSpikeInit(int *spike_num, int *spike_source_idx, } -void SpikeInit(int max_spike_num) +void +SpikeInit( int max_spike_num ) { - //h_SpikeTargetNum = new int[PrefixScan::AllocSize]; + // h_SpikeTargetNum = new int[PrefixScan::AllocSize]; - gpuErrchk(cudaMalloc(&d_SpikeNum, sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeSourceIdx, max_spike_num*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeConnIdx, max_spike_num*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeHeight, max_spike_num*sizeof(float))); - gpuErrchk(cudaMalloc(&d_SpikeTargetNum, max_spike_num*sizeof(int))); - //printf("here: SpikeTargetNum size: %d", max_spike_num); - DeviceSpikeInit<<<1,1>>>(d_SpikeNum, d_SpikeSourceIdx, d_SpikeConnIdx, - d_SpikeHeight, d_SpikeTargetNum, max_spike_num); + gpuErrchk( cudaMalloc( &d_SpikeNum, sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeSourceIdx, max_spike_num * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeConnIdx, max_spike_num * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeHeight, max_spike_num * sizeof( float ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeTargetNum, max_spike_num * sizeof( int ) ) ); + // printf("here: SpikeTargetNum size: %d", max_spike_num); + DeviceSpikeInit<<< 1, 1 >>>( + d_SpikeNum, d_SpikeSourceIdx, d_SpikeConnIdx, d_SpikeHeight, d_SpikeTargetNum, max_spike_num ); gpuErrchk( cudaPeekAtLastError() ); } -__global__ void SpikeReset() +__global__ void +SpikeReset() { *SpikeNum = 0; } diff --git a/src/send_spike.h b/src/send_spike.h index 39e41055f..8337940b7 100644 --- a/src/send_spike.h +++ b/src/send_spike.h @@ -21,33 +21,32 @@ */ - - - #ifndef SENDSPIKE_H #define SENDSPIKE_H -extern int *d_SpikeNum; -extern int *d_SpikeSourceIdx; -extern int *d_SpikeConnIdx; -extern float *d_SpikeHeight; -extern int *d_SpikeTargetNum; +extern int* d_SpikeNum; +extern int* d_SpikeSourceIdx; +extern int* d_SpikeConnIdx; +extern float* d_SpikeHeight; +extern int* d_SpikeTargetNum; extern __device__ int MaxSpikeNum; -extern __device__ int *SpikeNum; -extern __device__ int *SpikeSourceIdx; -extern __device__ int *SpikeConnIdx; -extern __device__ float *SpikeHeight; -extern __device__ int *SpikeTargetNum; - -__global__ void DeviceSpikeInit(int *spike_num, int *spike_source_idx, - int *spike_conn_idx, float *spike_height, - int *spike_target_num, int max_spike_num); - -__device__ void SendSpike(int i_source, int i_conn, float height, - int target_num); - -void SpikeInit(int max_spike_num); +extern __device__ int* SpikeNum; +extern __device__ int* SpikeSourceIdx; +extern __device__ int* SpikeConnIdx; +extern __device__ float* SpikeHeight; +extern __device__ int* SpikeTargetNum; + +__global__ void DeviceSpikeInit( int* spike_num, + int* spike_source_idx, + int* spike_conn_idx, + float* spike_height, + int* spike_target_num, + int max_spike_num ); + +__device__ void SendSpike( int i_source, int i_conn, float height, int target_num ); + +void SpikeInit( int max_spike_num ); __global__ void SpikeReset(); diff --git a/src/spike_buffer.cu b/src/spike_buffer.cu index dc39e74ca..32cbfb191 100644 --- a/src/spike_buffer.cu +++ b/src/spike_buffer.cu @@ -21,19 +21,16 @@ */ - - - #include #include #include #include -#include "cuda_error.h" -#include "spike_buffer.h" #include "connect.h" -#include "send_spike.h" +#include "cuda_error.h" #include "node_group.h" +#include "send_spike.h" +#include "spike_buffer.h" #ifdef HAVE_MPI #include "spike_mpi.h" @@ -45,7 +42,7 @@ extern __constant__ double NESTGPUTime; extern __constant__ long long NESTGPUTimeIdx; extern __constant__ float NESTGPUTimeResolution; extern __constant__ NodeGroupStruct NodeGroupArray[]; -extern __device__ signed char *NodeGroupMap; +extern __device__ signed char* NodeGroupMap; __device__ int MaxSpikeBufferSize; __device__ int NSpikeBuffer; @@ -54,104 +51,104 @@ __device__ int MaxDelayNum; int h_NSpikeBuffer; bool ConnectionSpikeTimeFlag; -float *d_LastSpikeHeight; // [NSpikeBuffer]; -__device__ float *LastSpikeHeight; // +float* d_LastSpikeHeight; // [NSpikeBuffer]; +__device__ float* LastSpikeHeight; // -long long *d_LastSpikeTimeIdx; // [NSpikeBuffer]; -__device__ long long *LastSpikeTimeIdx; // +long long* d_LastSpikeTimeIdx; // [NSpikeBuffer]; +__device__ long long* LastSpikeTimeIdx; // -long long *d_LastRevSpikeTimeIdx; // [NSpikeBuffer]; -__device__ long long *LastRevSpikeTimeIdx; // +long long* d_LastRevSpikeTimeIdx; // [NSpikeBuffer]; +__device__ long long* LastRevSpikeTimeIdx; // -float *d_ConnectionWeight; // [NConnection]; -__device__ float *ConnectionWeight; // +float* d_ConnectionWeight; // [NConnection]; +__device__ float* ConnectionWeight; // -unsigned char *d_ConnectionSynGroup; // [NConnection]; -__device__ unsigned char *ConnectionSynGroup; // +unsigned char* d_ConnectionSynGroup; // [NConnection]; +__device__ unsigned char* ConnectionSynGroup; // -unsigned short *d_ConnectionSpikeTime; // [NConnection]; -__device__ unsigned short *ConnectionSpikeTime; // +unsigned short* d_ConnectionSpikeTime; // [NConnection]; +__device__ unsigned short* ConnectionSpikeTime; // -int *d_ConnectionGroupSize; // [NSpikeBuffer]; -__device__ int *ConnectionGroupSize; // [NSpikeBuffer]; +int* d_ConnectionGroupSize; // [NSpikeBuffer]; +__device__ int* ConnectionGroupSize; // [NSpikeBuffer]; // ConnectionGroupSize[i_spike_buffer] // where i_spike_buffer is the source node index // Output connections from the source node are organized in groups // All connection of a group have the same delay -int *d_ConnectionGroupDelay; // [NSpikeBuffer*MaxDelayNum]; -__device__ int *ConnectionGroupDelay; // [NSpikeBuffer*MaxDelayNum]; +int* d_ConnectionGroupDelay; // [NSpikeBuffer*MaxDelayNum]; +__device__ int* ConnectionGroupDelay; // [NSpikeBuffer*MaxDelayNum]; // ConnectionGroupDelay[i_delay*NSpikeBuffer+i_spike_buffer]; // delay associated to all connections of this group -int *d_ConnectionGroupTargetSize; // [NSpikeBuffer*MaxDelayNum]; -__device__ int *ConnectionGroupTargetSize; // [NSpikeBuffer*MaxDelayNum]; +int* d_ConnectionGroupTargetSize; // [NSpikeBuffer*MaxDelayNum]; +__device__ int* ConnectionGroupTargetSize; // [NSpikeBuffer*MaxDelayNum]; // ConnectionGroupTargetSize[i_delay*NSpikeBuffer+i_spike_buffer]; // number of output connections in the group i_delay -unsigned int **d_ConnectionGroupTargetNode; // [NSpikeBuffer*MaxDelayNum]; -__device__ unsigned int **ConnectionGroupTargetNode; +unsigned int** d_ConnectionGroupTargetNode; // [NSpikeBuffer*MaxDelayNum]; +__device__ unsigned int** ConnectionGroupTargetNode; // [NSpikeBuffer*MaxDelayNum]; // ConnectionGroupTargetNode[i_delay*NSpikeBuffer+i_spike_buffer]; // is a pointer to an integer array of size ConnectionGroupTargetSize // that contains the indexes of the target nodes -unsigned char **d_ConnectionGroupTargetSynGroup; // [NSpikeBuffer*MaxDelayNum]; -__device__ unsigned char **ConnectionGroupTargetSynGroup; +unsigned char** d_ConnectionGroupTargetSynGroup; // [NSpikeBuffer*MaxDelayNum]; +__device__ unsigned char** ConnectionGroupTargetSynGroup; // [NSpikeBuffer*MaxDelayNum]; // ConnectionGroupTargetSynGroup[i_delay*NSpikeBuffer+i_spike_buffer]; // Connection target port -float **h_ConnectionGroupTargetWeight; //[NSpikeBuffer*MaxDelayNum]; -float **d_ConnectionGroupTargetWeight; // [NSpikeBuffer*MaxDelayNum]; -__device__ float **ConnectionGroupTargetWeight; // [NSpikeBuffer*MaxDelayNum]; +float** h_ConnectionGroupTargetWeight; //[NSpikeBuffer*MaxDelayNum]; +float** d_ConnectionGroupTargetWeight; // [NSpikeBuffer*MaxDelayNum]; +__device__ float** ConnectionGroupTargetWeight; // [NSpikeBuffer*MaxDelayNum]; // ConnectionGroupTargetWeight[i_delay*NSpikeBuffer+i_spike_buffer]; // Connection weight -unsigned short **d_ConnectionGroupTargetSpikeTime; //[NSpikeBuffer*MaxDelayNum]; -__device__ unsigned short **ConnectionGroupTargetSpikeTime; +unsigned short** d_ConnectionGroupTargetSpikeTime; //[NSpikeBuffer*MaxDelayNum]; +__device__ unsigned short** ConnectionGroupTargetSpikeTime; // ConnectionGroupTargetSpikeTime[i_delay*NSpikeBuffer+i_spike_buffer]; // Connection last spike time index ////////////////////////////////////////////////////////////////////// -int *d_SpikeBufferSize; // [NSpikeBuffer]; -__device__ int *SpikeBufferSize; // [NSpikeBuffer]; +int* d_SpikeBufferSize; // [NSpikeBuffer]; +__device__ int* SpikeBufferSize; // [NSpikeBuffer]; // SpikeBufferSize[i_spike_buffer]; // where i_spike_buffer is the source node index // number of spikes stored in the buffer -int *d_SpikeBufferIdx0; // [NSpikeBuffer]; -__device__ int *SpikeBufferIdx0; // [NSpikeBuffer]; +int* d_SpikeBufferIdx0; // [NSpikeBuffer]; +__device__ int* SpikeBufferIdx0; // [NSpikeBuffer]; // SpikeBufferIdx0[i_spike_buffer]; // where i_spike_buffer is the source node index // index of most recent spike stored in the buffer -int *d_SpikeBufferTimeIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; -__device__ int *SpikeBufferTimeIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; +int* d_SpikeBufferTimeIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; +__device__ int* SpikeBufferTimeIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; // SpikeBufferTimeIdx[i_spike*NSpikeBuffer+i_spike_buffer]; // time index of the spike -int *d_SpikeBufferConnIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; -__device__ int *SpikeBufferConnIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; +int* d_SpikeBufferConnIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; +__device__ int* SpikeBufferConnIdx; // [NSpikeBuffer*MaxSpikeBufferNum]; // SpikeBufferConnIdx[i_spike*NSpikeBuffer+i_spike_buffer]; // index of the next connection group that will emit this spike -float *d_SpikeBufferHeight; // [NSpikeBuffer*MaxSpikeBufferNum]; -__device__ float *SpikeBufferHeight; // [NSpikeBuffer*MaxSpikeBufferNum]; +float* d_SpikeBufferHeight; // [NSpikeBuffer*MaxSpikeBufferNum]; +__device__ float* SpikeBufferHeight; // [NSpikeBuffer*MaxSpikeBufferNum]; // SpikeBufferHeight[i_spike*NSpikeBuffer+i_spike_buffer]; // spike height -unsigned int *d_RevConnections; //[i] i=0,..., n_rev_conn - 1; -__device__ unsigned int *RevConnections; +unsigned int* d_RevConnections; //[i] i=0,..., n_rev_conn - 1; +__device__ unsigned int* RevConnections; -int *d_TargetRevConnectionSize; //[i] i=0,..., n_neuron-1; -__device__ int *TargetRevConnectionSize; +int* d_TargetRevConnectionSize; //[i] i=0,..., n_neuron-1; +__device__ int* TargetRevConnectionSize; -unsigned int **d_TargetRevConnection; //[i][j] j=0,...,RevConnectionSize[i]-1 -__device__ unsigned int **TargetRevConnection; +unsigned int** d_TargetRevConnection; //[i][j] j=0,...,RevConnectionSize[i]-1 +__device__ unsigned int** TargetRevConnection; //////////////////////////////////////////////////////////// // push a new spike in spike buffer of a node @@ -159,380 +156,399 @@ __device__ unsigned int **TargetRevConnection; // i_spike_buffer : node index // height: spike multiplicity //////////////////////////////////////////////////////////// -__device__ void PushSpike(int i_spike_buffer, float height) +__device__ void +PushSpike( int i_spike_buffer, float height ) { - LastSpikeTimeIdx[i_spike_buffer] = NESTGPUTimeIdx; - LastSpikeHeight[i_spike_buffer] = height; - int i_group = NodeGroupMap[i_spike_buffer]; + LastSpikeTimeIdx[ i_spike_buffer ] = NESTGPUTimeIdx; + LastSpikeHeight[ i_spike_buffer ] = height; + int i_group = NodeGroupMap[ i_spike_buffer ]; int den_delay_idx; - float *den_delay_arr = NodeGroupArray[i_group].den_delay_arr_; + float* den_delay_arr = NodeGroupArray[ i_group ].den_delay_arr_; // check if node has dendritic delay - if (den_delay_arr != NULL) { - int i_neuron = i_spike_buffer - NodeGroupArray[i_group].i_node_0_; - int n_param = NodeGroupArray[i_group].n_param_; + if ( den_delay_arr != NULL ) + { + int i_neuron = i_spike_buffer - NodeGroupArray[ i_group ].i_node_0_; + int n_param = NodeGroupArray[ i_group ].n_param_; // dendritic delay index is stored in the parameter array // den_delay_arr points to the dendritic delay if the first // node of the group. The other are separate by steps = n_param - den_delay_idx = (int)round(den_delay_arr[i_neuron*n_param] - /NESTGPUTimeResolution); - //printf("isb %d\tden_delay_idx: %d\n", i_spike_buffer, den_delay_idx); + den_delay_idx = ( int ) round( den_delay_arr[ i_neuron * n_param ] / NESTGPUTimeResolution ); + // printf("isb %d\tden_delay_idx: %d\n", i_spike_buffer, den_delay_idx); } - else { + else + { den_delay_idx = 0; } - if (den_delay_idx==0) { + if ( den_delay_idx == 0 ) + { // last time when spike is sent back to dendrites (e.g. for STDP) - LastRevSpikeTimeIdx[i_spike_buffer] = NESTGPUTimeIdx; + LastRevSpikeTimeIdx[ i_spike_buffer ] = NESTGPUTimeIdx; } - + #ifdef HAVE_MPI - if (NESTGPUMpiFlag) { + if ( NESTGPUMpiFlag ) + { // if MPI is active spike should eventually be sent to remote connections - PushExternalSpike(i_spike_buffer, height); + PushExternalSpike( i_spike_buffer, height ); } #endif // if recording spike counts is activated, increase counter - if (NodeGroupArray[i_group].spike_count_ != NULL) { - int i_node_0 = NodeGroupArray[i_group].i_node_0_; - NodeGroupArray[i_group].spike_count_[i_spike_buffer-i_node_0]++; + if ( NodeGroupArray[ i_group ].spike_count_ != NULL ) + { + int i_node_0 = NodeGroupArray[ i_group ].i_node_0_; + NodeGroupArray[ i_group ].spike_count_[ i_spike_buffer - i_node_0 ]++; } // check if recording spike times is activated - int max_n_rec_spike_times = NodeGroupArray[i_group].max_n_rec_spike_times_; - if (max_n_rec_spike_times != 0) { - int i_node_rel = i_spike_buffer - NodeGroupArray[i_group].i_node_0_; - int n_rec_spike_times = - NodeGroupArray[i_group].n_rec_spike_times_[i_node_rel]; - if (n_rec_spike_times>=max_n_rec_spike_times-1) { - printf("Maximum number of recorded spike times exceeded" - " for spike buffer %d\n", i_spike_buffer); + int max_n_rec_spike_times = NodeGroupArray[ i_group ].max_n_rec_spike_times_; + if ( max_n_rec_spike_times != 0 ) + { + int i_node_rel = i_spike_buffer - NodeGroupArray[ i_group ].i_node_0_; + int n_rec_spike_times = NodeGroupArray[ i_group ].n_rec_spike_times_[ i_node_rel ]; + if ( n_rec_spike_times >= max_n_rec_spike_times - 1 ) + { + printf( + "Maximum number of recorded spike times exceeded" + " for spike buffer %d\n", + i_spike_buffer ); } - else { // record spike time - NodeGroupArray[i_group].rec_spike_times_ - [i_node_rel*max_n_rec_spike_times + n_rec_spike_times] - = NESTGPUTime; - NodeGroupArray[i_group].n_rec_spike_times_[i_node_rel]++; + else + { // record spike time + NodeGroupArray[ i_group ].rec_spike_times_[ i_node_rel * max_n_rec_spike_times + n_rec_spike_times ] = + NESTGPUTime; + NodeGroupArray[ i_group ].n_rec_spike_times_[ i_node_rel ]++; } } // spike should be stored if there are output connections // or if dendritic delay is > 0 - if (ConnectionGroupSize[i_spike_buffer]>0 || den_delay_idx>0) { - int Ns = SpikeBufferSize[i_spike_buffer]; // n. of spikes in buffer - if (Ns>=MaxSpikeBufferSize) { - printf("Maximum number of spikes in spike buffer exceeded" - " for spike buffer %d\n", i_spike_buffer); - //exit(0); + if ( ConnectionGroupSize[ i_spike_buffer ] > 0 || den_delay_idx > 0 ) + { + int Ns = SpikeBufferSize[ i_spike_buffer ]; // n. of spikes in buffer + if ( Ns >= MaxSpikeBufferSize ) + { + printf( + "Maximum number of spikes in spike buffer exceeded" + " for spike buffer %d\n", + i_spike_buffer ); + // exit(0); return; } /////////////////////////////////// // push_front new spike in buffer ////////////////////////////////// - SpikeBufferSize[i_spike_buffer]++; // increase n. of spikes in buffer + SpikeBufferSize[ i_spike_buffer ]++; // increase n. of spikes in buffer // the index of the most recent spike is0 should be decreased by 1 - int is0 = (SpikeBufferIdx0[i_spike_buffer] + MaxSpikeBufferSize - 1) - % MaxSpikeBufferSize; - SpikeBufferIdx0[i_spike_buffer] = is0; - int i_arr = is0*NSpikeBuffer+i_spike_buffer; // spike index in array - SpikeBufferTimeIdx[i_arr] = 0; // time index is initialized to 0 - SpikeBufferConnIdx[i_arr] = 0; // connect. group index is initialized to 0 - SpikeBufferHeight[i_arr] = height; // spike multiplicity + int is0 = ( SpikeBufferIdx0[ i_spike_buffer ] + MaxSpikeBufferSize - 1 ) % MaxSpikeBufferSize; + SpikeBufferIdx0[ i_spike_buffer ] = is0; + int i_arr = is0 * NSpikeBuffer + i_spike_buffer; // spike index in array + SpikeBufferTimeIdx[ i_arr ] = 0; // time index is initialized to 0 + SpikeBufferConnIdx[ i_arr ] = 0; // connect. group index is initialized to 0 + SpikeBufferHeight[ i_arr ] = height; // spike multiplicity } } //////////////////////////////////////////////////////////// // Update spike buffer of a node //////////////////////////////////////////////////////////// -__global__ void SpikeBufferUpdate() +__global__ void +SpikeBufferUpdate() { int i_spike_buffer = threadIdx.x + blockIdx.x * blockDim.x; - if (i_spike_buffer>=NSpikeBuffer) return; - - int i_group=NodeGroupMap[i_spike_buffer]; + if ( i_spike_buffer >= NSpikeBuffer ) + { + return; + } + + int i_group = NodeGroupMap[ i_spike_buffer ]; int den_delay_idx; - float *den_delay_arr = NodeGroupArray[i_group].den_delay_arr_; + float* den_delay_arr = NodeGroupArray[ i_group ].den_delay_arr_; // check if node has dendritic delay - if (den_delay_arr != NULL) { - int i_neuron = i_spike_buffer - NodeGroupArray[i_group].i_node_0_; - int n_param = NodeGroupArray[i_group].n_param_; + if ( den_delay_arr != NULL ) + { + int i_neuron = i_spike_buffer - NodeGroupArray[ i_group ].i_node_0_; + int n_param = NodeGroupArray[ i_group ].n_param_; // dendritic delay index is stored in the parameter array // den_delay_arr points to the dendritic delay if the first // node of the group. The other are separate by steps = n_param - den_delay_idx = (int)round(den_delay_arr[i_neuron*n_param] - /NESTGPUTimeResolution); - //printf("isb update %d\tden_delay_idx: %d\n", i_spike_buffer, den_delay_idx); + den_delay_idx = ( int ) round( den_delay_arr[ i_neuron * n_param ] / NESTGPUTimeResolution ); + // printf("isb update %d\tden_delay_idx: %d\n", i_spike_buffer, den_delay_idx); } - else { + else + { den_delay_idx = 0; } // flag for sending spikes back through dendrites (e.g. for STDP) bool rev_spike = false; - int is0 = SpikeBufferIdx0[i_spike_buffer]; // index of most recent spike - int Ns = SpikeBufferSize[i_spike_buffer]; // n. of spikes in buffer - for (int is=0; is=ConnectionGroupSize[i_spike_buffer] - && spike_time_idx+1>=den_delay_idx) { + if ( is == Ns - 1 && i_conn >= ConnectionGroupSize[ i_spike_buffer ] && spike_time_idx + 1 >= den_delay_idx ) + { // in this case we don't need any more to keep track of the oldest spike - SpikeBufferSize[i_spike_buffer]--; // so remove it from buffer + SpikeBufferSize[ i_spike_buffer ]--; // so remove it from buffer } - else { - SpikeBufferTimeIdx[i_arr]++; + else + { + SpikeBufferTimeIdx[ i_arr ]++; // increase time index } } - if (rev_spike) { - LastRevSpikeTimeIdx[i_spike_buffer] = NESTGPUTimeIdx+1; + if ( rev_spike ) + { + LastRevSpikeTimeIdx[ i_spike_buffer ] = NESTGPUTimeIdx + 1; } } -__global__ void InitLastSpikeTimeIdx(unsigned int n_spike_buffers, - int spike_time_idx) +__global__ void +InitLastSpikeTimeIdx( unsigned int n_spike_buffers, int spike_time_idx ) { unsigned int i_spike_buffer = threadIdx.x + blockIdx.x * blockDim.x; - if (i_spike_buffer>=n_spike_buffers) { + if ( i_spike_buffer >= n_spike_buffers ) + { return; } - LastSpikeTimeIdx[i_spike_buffer] = spike_time_idx; - LastRevSpikeTimeIdx[i_spike_buffer] = spike_time_idx; + LastSpikeTimeIdx[ i_spike_buffer ] = spike_time_idx; + LastRevSpikeTimeIdx[ i_spike_buffer ] = spike_time_idx; } -int SpikeBufferInit(NetConnection *net_connection, int max_spike_buffer_size) +int +SpikeBufferInit( NetConnection* net_connection, int max_spike_buffer_size ) { unsigned int n_spike_buffers = net_connection->connection_.size(); h_NSpikeBuffer = n_spike_buffers; int max_delay_num = net_connection->MaxDelayNum(); - //printf("mdn: %d\n", max_delay_num); - - gpuErrchk(cudaMalloc(&d_LastSpikeTimeIdx, n_spike_buffers*sizeof(long long))); - gpuErrchk(cudaMalloc(&d_LastSpikeHeight, n_spike_buffers*sizeof(float))); - gpuErrchk(cudaMalloc(&d_LastRevSpikeTimeIdx, n_spike_buffers - *sizeof(long long))); - + // printf("mdn: %d\n", max_delay_num); + + gpuErrchk( cudaMalloc( &d_LastSpikeTimeIdx, n_spike_buffers * sizeof( long long ) ) ); + gpuErrchk( cudaMalloc( &d_LastSpikeHeight, n_spike_buffers * sizeof( float ) ) ); + gpuErrchk( cudaMalloc( &d_LastRevSpikeTimeIdx, n_spike_buffers * sizeof( long long ) ) ); + unsigned int n_conn = net_connection->StoredNConnections(); - unsigned int *h_conn_target = new unsigned int[n_conn]; - unsigned char *h_conn_syn_group = new unsigned char[n_conn]; - float *h_conn_weight = new float[n_conn]; + unsigned int* h_conn_target = new unsigned int[ n_conn ]; + unsigned char* h_conn_syn_group = new unsigned char[ n_conn ]; + float* h_conn_weight = new float[ n_conn ]; // unsigned short *h_conn_spike_time; //USELESS, REMOVE - unsigned int *d_conn_target; - gpuErrchk(cudaMalloc(&d_conn_target, n_conn*sizeof(unsigned int))); - gpuErrchk(cudaMalloc(&d_ConnectionSynGroup, n_conn*sizeof(unsigned char))); - gpuErrchk(cudaMalloc(&d_ConnectionWeight, n_conn*sizeof(float))); - int *h_ConnectionGroupSize = new int[n_spike_buffers]; - int *h_ConnectionGroupDelay = new int[n_spike_buffers*max_delay_num]; - int *h_ConnectionGroupTargetSize = new int[n_spike_buffers*max_delay_num]; - unsigned int **h_ConnectionGroupTargetNode = - new unsigned int*[n_spike_buffers*max_delay_num]; - unsigned char **h_ConnectionGroupTargetSynGroup = - new unsigned char*[n_spike_buffers*max_delay_num]; - h_ConnectionGroupTargetWeight = new float*[n_spike_buffers - *max_delay_num]; - unsigned short **h_ConnectionGroupTargetSpikeTime = NULL; - - gpuErrchk(cudaMalloc(&d_ConnectionGroupSize, n_spike_buffers*sizeof(int))); - gpuErrchk(cudaMalloc(&d_ConnectionGroupDelay, - n_spike_buffers*max_delay_num*sizeof(int))); - gpuErrchk(cudaMalloc(&d_ConnectionGroupTargetSize, - n_spike_buffers*max_delay_num*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeBufferSize, n_spike_buffers*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeBufferIdx0, n_spike_buffers*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeBufferTimeIdx, - n_spike_buffers*max_spike_buffer_size*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeBufferConnIdx, - n_spike_buffers*max_spike_buffer_size*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SpikeBufferHeight, - n_spike_buffers*max_spike_buffer_size*sizeof(float))); - gpuErrchk(cudaMemsetAsync(d_SpikeBufferSize, 0, n_spike_buffers*sizeof(int))); - gpuErrchk(cudaMemsetAsync(d_SpikeBufferIdx0, 0, n_spike_buffers*sizeof(int))); - - gpuErrchk(cudaMalloc(&d_ConnectionGroupTargetNode, - n_spike_buffers*max_delay_num*sizeof(unsigned int*))); - gpuErrchk(cudaMalloc(&d_ConnectionGroupTargetSynGroup, - n_spike_buffers*max_delay_num*sizeof(unsigned char*))); - gpuErrchk(cudaMalloc(&d_ConnectionGroupTargetWeight, - n_spike_buffers*max_delay_num*sizeof(float*))); - - if (ConnectionSpikeTimeFlag){ - //h_conn_spike_time = new unsigned short[n_conn]; - gpuErrchk(cudaMalloc(&d_ConnectionSpikeTime, - n_conn*sizeof(unsigned short))); - //gpuErrchk(cudaMemset(d_ConnectionSpikeTime, 0, + unsigned int* d_conn_target; + gpuErrchk( cudaMalloc( &d_conn_target, n_conn * sizeof( unsigned int ) ) ); + gpuErrchk( cudaMalloc( &d_ConnectionSynGroup, n_conn * sizeof( unsigned char ) ) ); + gpuErrchk( cudaMalloc( &d_ConnectionWeight, n_conn * sizeof( float ) ) ); + int* h_ConnectionGroupSize = new int[ n_spike_buffers ]; + int* h_ConnectionGroupDelay = new int[ n_spike_buffers * max_delay_num ]; + int* h_ConnectionGroupTargetSize = new int[ n_spike_buffers * max_delay_num ]; + unsigned int** h_ConnectionGroupTargetNode = new unsigned int*[ n_spike_buffers * max_delay_num ]; + unsigned char** h_ConnectionGroupTargetSynGroup = new unsigned char*[ n_spike_buffers * max_delay_num ]; + h_ConnectionGroupTargetWeight = new float*[ n_spike_buffers * max_delay_num ]; + unsigned short** h_ConnectionGroupTargetSpikeTime = NULL; + + gpuErrchk( cudaMalloc( &d_ConnectionGroupSize, n_spike_buffers * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ConnectionGroupDelay, n_spike_buffers * max_delay_num * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ConnectionGroupTargetSize, n_spike_buffers * max_delay_num * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeBufferSize, n_spike_buffers * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeBufferIdx0, n_spike_buffers * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeBufferTimeIdx, n_spike_buffers * max_spike_buffer_size * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeBufferConnIdx, n_spike_buffers * max_spike_buffer_size * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SpikeBufferHeight, n_spike_buffers * max_spike_buffer_size * sizeof( float ) ) ); + gpuErrchk( cudaMemsetAsync( d_SpikeBufferSize, 0, n_spike_buffers * sizeof( int ) ) ); + gpuErrchk( cudaMemsetAsync( d_SpikeBufferIdx0, 0, n_spike_buffers * sizeof( int ) ) ); + + gpuErrchk( cudaMalloc( &d_ConnectionGroupTargetNode, n_spike_buffers * max_delay_num * sizeof( unsigned int* ) ) ); + gpuErrchk( + cudaMalloc( &d_ConnectionGroupTargetSynGroup, n_spike_buffers * max_delay_num * sizeof( unsigned char* ) ) ); + gpuErrchk( cudaMalloc( &d_ConnectionGroupTargetWeight, n_spike_buffers * max_delay_num * sizeof( float* ) ) ); + + if ( ConnectionSpikeTimeFlag ) + { + // h_conn_spike_time = new unsigned short[n_conn]; + gpuErrchk( cudaMalloc( &d_ConnectionSpikeTime, n_conn * sizeof( unsigned short ) ) ); + // gpuErrchk(cudaMemset(d_ConnectionSpikeTime, 0, // n_conn*sizeof(unsigned short))); - h_ConnectionGroupTargetSpikeTime - = new unsigned short*[n_spike_buffers*max_delay_num]; - gpuErrchk(cudaMalloc(&d_ConnectionGroupTargetSpikeTime, - n_spike_buffers*max_delay_num - *sizeof(unsigned short*))); + h_ConnectionGroupTargetSpikeTime = new unsigned short*[ n_spike_buffers * max_delay_num ]; + gpuErrchk( + cudaMalloc( &d_ConnectionGroupTargetSpikeTime, n_spike_buffers * max_delay_num * sizeof( unsigned short* ) ) ); } - + unsigned int i_conn = 0; - for (unsigned int i_source=0; i_source *conn = &(net_connection->connection_[i_source]); - h_ConnectionGroupSize[i_source] = conn->size(); - for (unsigned int id=0; idsize(); id++) { - h_ConnectionGroupDelay[id*n_spike_buffers+i_source] = conn->at(id).delay; - int n_target = conn->at(id).target_vect.size(); - h_ConnectionGroupTargetSize[id*n_spike_buffers+i_source] = n_target; - - h_ConnectionGroupTargetNode[id*n_spike_buffers+i_source] - = &d_conn_target[i_conn]; - h_ConnectionGroupTargetSynGroup[id*n_spike_buffers+i_source] - = &d_ConnectionSynGroup[i_conn]; - h_ConnectionGroupTargetWeight[id*n_spike_buffers+i_source] - = &d_ConnectionWeight[i_conn]; - if (ConnectionSpikeTimeFlag){ - h_ConnectionGroupTargetSpikeTime[id*n_spike_buffers+i_source] - = &d_ConnectionSpikeTime[i_conn]; - } - unsigned int *target_arr = &h_conn_target[i_conn]; - unsigned char *syn_group_arr = &h_conn_syn_group[i_conn]; - float *weight_arr = &h_conn_weight[i_conn]; - for (int it=0; itat(id).target_vect[it].node; - unsigned int port = conn->at(id).target_vect[it].port; - target_arr[it] = (port << (24 + PORT_N_SHIFT)) | target; - syn_group_arr[it] = conn->at(id).target_vect[it].syn_group; - weight_arr[it] = conn->at(id).target_vect[it].weight; - } - i_conn += n_target; - } + for ( unsigned int i_source = 0; i_source < n_spike_buffers; i_source++ ) + { + std::vector< ConnGroup >* conn = &( net_connection->connection_[ i_source ] ); + h_ConnectionGroupSize[ i_source ] = conn->size(); + for ( unsigned int id = 0; id < conn->size(); id++ ) + { + h_ConnectionGroupDelay[ id * n_spike_buffers + i_source ] = conn->at( id ).delay; + int n_target = conn->at( id ).target_vect.size(); + h_ConnectionGroupTargetSize[ id * n_spike_buffers + i_source ] = n_target; + + h_ConnectionGroupTargetNode[ id * n_spike_buffers + i_source ] = &d_conn_target[ i_conn ]; + h_ConnectionGroupTargetSynGroup[ id * n_spike_buffers + i_source ] = &d_ConnectionSynGroup[ i_conn ]; + h_ConnectionGroupTargetWeight[ id * n_spike_buffers + i_source ] = &d_ConnectionWeight[ i_conn ]; + if ( ConnectionSpikeTimeFlag ) + { + h_ConnectionGroupTargetSpikeTime[ id * n_spike_buffers + i_source ] = &d_ConnectionSpikeTime[ i_conn ]; + } + unsigned int* target_arr = &h_conn_target[ i_conn ]; + unsigned char* syn_group_arr = &h_conn_syn_group[ i_conn ]; + float* weight_arr = &h_conn_weight[ i_conn ]; + for ( int it = 0; it < n_target; it++ ) + { + unsigned int target = conn->at( id ).target_vect[ it ].node; + unsigned int port = conn->at( id ).target_vect[ it ].port; + target_arr[ it ] = ( port << ( 24 + PORT_N_SHIFT ) ) | target; + syn_group_arr[ it ] = conn->at( id ).target_vect[ it ].syn_group; + weight_arr[ it ] = conn->at( id ).target_vect[ it ].weight; + } + i_conn += n_target; + } } - - cudaMemcpyAsync(d_conn_target, h_conn_target, n_conn*sizeof(unsigned int), - cudaMemcpyHostToDevice); - cudaMemcpyAsync(d_ConnectionSynGroup, h_conn_syn_group, - n_conn*sizeof(unsigned char), cudaMemcpyHostToDevice); - cudaMemcpyAsync(d_ConnectionWeight, h_conn_weight, n_conn*sizeof(float), - cudaMemcpyHostToDevice); + + cudaMemcpyAsync( d_conn_target, h_conn_target, n_conn * sizeof( unsigned int ), cudaMemcpyHostToDevice ); + cudaMemcpyAsync( d_ConnectionSynGroup, h_conn_syn_group, n_conn * sizeof( unsigned char ), cudaMemcpyHostToDevice ); + cudaMemcpyAsync( d_ConnectionWeight, h_conn_weight, n_conn * sizeof( float ), cudaMemcpyHostToDevice ); unsigned int n_rev_conn = 0; - std::vector > rev_connections(n_spike_buffers); - for (unsigned int i_conn=0; i_conn=1) { // TEMPORARY, TO BE IMPROVED + std::vector< std::vector< unsigned int > > rev_connections( n_spike_buffers ); + for ( unsigned int i_conn = 0; i_conn < n_conn; i_conn++ ) + { + unsigned char syn_group = h_conn_syn_group[ i_conn ]; + if ( syn_group >= 1 ) + { // TEMPORARY, TO BE IMPROVED n_rev_conn++; - int target = h_conn_target[i_conn] & PORT_MASK; - rev_connections[target].push_back(i_conn); + int target = h_conn_target[ i_conn ] & PORT_MASK; + rev_connections[ target ].push_back( i_conn ); } } - - net_connection->SetNRevConnections(n_rev_conn); - - if (n_rev_conn>0) { - unsigned int *h_rev_conn = new unsigned int[n_rev_conn]; - int *h_target_rev_conn_size = new int[n_spike_buffers]; - unsigned int **h_target_rev_conn = new unsigned int*[n_spike_buffers]; - - gpuErrchk(cudaMalloc(&d_RevConnections, n_rev_conn*sizeof(unsigned int))); - gpuErrchk(cudaMalloc(&d_TargetRevConnectionSize, - n_spike_buffers*sizeof(int))); - gpuErrchk(cudaMalloc(&d_TargetRevConnection, n_spike_buffers - *sizeof(unsigned int*))); + + net_connection->SetNRevConnections( n_rev_conn ); + + if ( n_rev_conn > 0 ) + { + unsigned int* h_rev_conn = new unsigned int[ n_rev_conn ]; + int* h_target_rev_conn_size = new int[ n_spike_buffers ]; + unsigned int** h_target_rev_conn = new unsigned int*[ n_spike_buffers ]; + + gpuErrchk( cudaMalloc( &d_RevConnections, n_rev_conn * sizeof( unsigned int ) ) ); + gpuErrchk( cudaMalloc( &d_TargetRevConnectionSize, n_spike_buffers * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_TargetRevConnection, n_spike_buffers * sizeof( unsigned int* ) ) ); unsigned int i_rev_conn = 0; - for (unsigned int target=0; target>>(n_spike_buffers, max_delay_num, - max_spike_buffer_size, - d_LastSpikeTimeIdx, d_LastSpikeHeight, - d_ConnectionWeight, d_ConnectionSynGroup, - d_ConnectionSpikeTime, - d_ConnectionGroupSize, d_ConnectionGroupDelay, - d_ConnectionGroupTargetSize, - d_ConnectionGroupTargetNode, - d_ConnectionGroupTargetSynGroup, - d_ConnectionGroupTargetWeight, - d_ConnectionGroupTargetSpikeTime, - d_SpikeBufferSize, d_SpikeBufferIdx0, - d_SpikeBufferTimeIdx, - d_SpikeBufferConnIdx, d_SpikeBufferHeight, - d_RevConnections, d_TargetRevConnectionSize, - d_TargetRevConnection, d_LastRevSpikeTimeIdx - ); + DeviceSpikeBufferInit<<< 1, 1 >>>( n_spike_buffers, + max_delay_num, + max_spike_buffer_size, + d_LastSpikeTimeIdx, + d_LastSpikeHeight, + d_ConnectionWeight, + d_ConnectionSynGroup, + d_ConnectionSpikeTime, + d_ConnectionGroupSize, + d_ConnectionGroupDelay, + d_ConnectionGroupTargetSize, + d_ConnectionGroupTargetNode, + d_ConnectionGroupTargetSynGroup, + d_ConnectionGroupTargetWeight, + d_ConnectionGroupTargetSpikeTime, + d_SpikeBufferSize, + d_SpikeBufferIdx0, + d_SpikeBufferTimeIdx, + d_SpikeBufferConnIdx, + d_SpikeBufferHeight, + d_RevConnections, + d_TargetRevConnectionSize, + d_TargetRevConnection, + d_LastRevSpikeTimeIdx ); gpuErrchk( cudaPeekAtLastError() ); - - InitLastSpikeTimeIdx - <<<(n_spike_buffers+1023)/1024, 1024>>> - (n_spike_buffers, LAST_SPIKE_TIME_GUARD); + + InitLastSpikeTimeIdx <<< ( n_spike_buffers + 1023 ) / 1024, 1024 >>>( n_spike_buffers, LAST_SPIKE_TIME_GUARD ); gpuErrchk( cudaPeekAtLastError() ); - gpuErrchk(cudaMemsetAsync(d_LastSpikeHeight, 0, - n_spike_buffers*sizeof(unsigned short))); + gpuErrchk( cudaMemsetAsync( d_LastSpikeHeight, 0, n_spike_buffers * sizeof( unsigned short ) ) ); gpuErrchk( cudaDeviceSynchronize() ); delete[] h_conn_weight; @@ -544,35 +560,40 @@ int SpikeBufferInit(NetConnection *net_connection, int max_spike_buffer_size) delete[] h_ConnectionGroupDelay; delete[] h_ConnectionGroupTargetNode; delete[] h_ConnectionGroupTargetSynGroup; - //delete[] h_ConnectionGroupTargetWeight; - if(h_ConnectionGroupTargetSpikeTime != NULL) { + // delete[] h_ConnectionGroupTargetWeight; + if ( h_ConnectionGroupTargetSpikeTime != NULL ) + { delete[] h_ConnectionGroupTargetSpikeTime; } - + return 0; } -__global__ void DeviceSpikeBufferInit(int n_spike_buffers, int max_delay_num, - int max_spike_buffer_size, - long long *last_spike_time_idx, - float *last_spike_height, - float *conn_weight, - unsigned char *conn_syn_group, - unsigned short *conn_spike_time, - int *conn_group_size, int *conn_group_delay, - int *conn_group_target_size, - unsigned int **conn_group_target_node, - unsigned char **conn_group_target_syn_group, - float **conn_group_target_weight, - unsigned short **conn_group_target_spike_time, - int *spike_buffer_size, int *spike_buffer_idx0, - int *spike_buffer_time, - int *spike_buffer_conn, - float *spike_buffer_height, - unsigned int *rev_conn, - int *target_rev_conn_size, - unsigned int **target_rev_conn, - long long *last_rev_spike_time_idx) +__global__ void +DeviceSpikeBufferInit( int n_spike_buffers, + int max_delay_num, + int max_spike_buffer_size, + long long* last_spike_time_idx, + float* last_spike_height, + float* conn_weight, + unsigned char* conn_syn_group, + unsigned short* conn_spike_time, + int* conn_group_size, + int* conn_group_delay, + int* conn_group_target_size, + unsigned int** conn_group_target_node, + unsigned char** conn_group_target_syn_group, + float** conn_group_target_weight, + unsigned short** conn_group_target_spike_time, + int* spike_buffer_size, + int* spike_buffer_idx0, + int* spike_buffer_time, + int* spike_buffer_conn, + float* spike_buffer_height, + unsigned int* rev_conn, + int* target_rev_conn_size, + unsigned int** target_rev_conn, + long long* last_rev_spike_time_idx ) { NSpikeBuffer = n_spike_buffers; MaxDelayNum = max_delay_num; diff --git a/src/spike_buffer.h b/src/spike_buffer.h index f5e616a86..41e0f26f5 100644 --- a/src/spike_buffer.h +++ b/src/spike_buffer.h @@ -21,9 +21,6 @@ */ - - - #ifndef SPIKEBUFFER_H #define SPIKEBUFFER_H #include "connect.h" @@ -35,114 +32,117 @@ extern __device__ int MaxDelayNum; extern int h_NSpikeBuffer; extern bool ConnectionSpikeTimeFlag; -extern float *d_LastSpikeHeight; // [NSpikeBuffer]; -extern __device__ float *LastSpikeHeight; // +extern float* d_LastSpikeHeight; // [NSpikeBuffer]; +extern __device__ float* LastSpikeHeight; // -extern long long *d_LastSpikeTimeIdx; // [NSpikeBuffer]; -extern __device__ long long *LastSpikeTimeIdx; // +extern long long* d_LastSpikeTimeIdx; // [NSpikeBuffer]; +extern __device__ long long* LastSpikeTimeIdx; // -extern long long *d_LastRevSpikeTimeIdx; // [NSpikeBuffer]; -extern __device__ long long *LastRevSpikeTimeIdx; // +extern long long* d_LastRevSpikeTimeIdx; // [NSpikeBuffer]; +extern __device__ long long* LastRevSpikeTimeIdx; // -extern float *d_ConnectionWeight; // [NConnection]; -extern __device__ float *ConnectionWeight; // +extern float* d_ConnectionWeight; // [NConnection]; +extern __device__ float* ConnectionWeight; // -extern unsigned char *d_ConnectionSynGroup; // [NConnection]; -extern __device__ unsigned char *ConnectionSynGroup; // +extern unsigned char* d_ConnectionSynGroup; // [NConnection]; +extern __device__ unsigned char* ConnectionSynGroup; // -extern unsigned short *d_ConnectionSpikeTime; // [NConnection]; -extern __device__ unsigned short *ConnectionSpikeTime; // +extern unsigned short* d_ConnectionSpikeTime; // [NConnection]; +extern __device__ unsigned short* ConnectionSpikeTime; // -extern int *d_ConnectionGroupSize; -extern __device__ int *ConnectionGroupSize; +extern int* d_ConnectionGroupSize; +extern __device__ int* ConnectionGroupSize; // Output connections from the source node are organized in groups // All connection of a group have the same delay -extern int *d_ConnectionGroupDelay; -extern __device__ int *ConnectionGroupDelay; +extern int* d_ConnectionGroupDelay; +extern __device__ int* ConnectionGroupDelay; // delay associated to all connections of this group -extern int *d_ConnectionGroupTargetSize; -extern __device__ int *ConnectionGroupTargetSize; +extern int* d_ConnectionGroupTargetSize; +extern __device__ int* ConnectionGroupTargetSize; // number of output connections in the group i_delay -extern unsigned int **d_ConnectionGroupTargetNode; -extern __device__ unsigned int **ConnectionGroupTargetNode; +extern unsigned int** d_ConnectionGroupTargetNode; +extern __device__ unsigned int** ConnectionGroupTargetNode; // is a pointer to an integer array of size ConnectionGroupTargetSize // that contains the indexes of the target nodes -extern unsigned char **d_ConnectionGroupTargetSynGroup; -extern __device__ unsigned char **ConnectionGroupTargetSynGroup; +extern unsigned char** d_ConnectionGroupTargetSynGroup; +extern __device__ unsigned char** ConnectionGroupTargetSynGroup; // Connection target synapse group -extern float **h_ConnectionGroupTargetWeight; -extern float **d_ConnectionGroupTargetWeight; -extern __device__ float **ConnectionGroupTargetWeight; +extern float** h_ConnectionGroupTargetWeight; +extern float** d_ConnectionGroupTargetWeight; +extern __device__ float** ConnectionGroupTargetWeight; // Connection weight -extern unsigned short **d_ConnectionGroupTargetSpikeTime; -extern __device__ unsigned short **ConnectionGroupTargetSpikeTime; +extern unsigned short** d_ConnectionGroupTargetSpikeTime; +extern __device__ unsigned short** ConnectionGroupTargetSpikeTime; // Connection last spike time index ////////////////////////////////////////////////////////////////////// -extern int *d_SpikeBufferSize; -extern __device__ int *SpikeBufferSize; +extern int* d_SpikeBufferSize; +extern __device__ int* SpikeBufferSize; // number of spikes stored in the buffer -extern int *d_SpikeBufferIdx0; -extern __device__ int *SpikeBufferIdx0; +extern int* d_SpikeBufferIdx0; +extern __device__ int* SpikeBufferIdx0; // index of most recent spike stored in the buffer -extern int *d_SpikeBufferTimeIdx; -extern __device__ int *SpikeBufferTimeIdx; +extern int* d_SpikeBufferTimeIdx; +extern __device__ int* SpikeBufferTimeIdx; // time index of the spike -extern int *d_SpikeBufferConnIdx; -extern __device__ int *SpikeBufferConnIdx; +extern int* d_SpikeBufferConnIdx; +extern __device__ int* SpikeBufferConnIdx; // index of the next connection group that will emit this spike -extern float *d_SpikeBufferHeight; -extern __device__ float *SpikeBufferHeight; +extern float* d_SpikeBufferHeight; +extern __device__ float* SpikeBufferHeight; // spike height -extern unsigned int *d_RevConnections; //[i] i=0,..., n_rev_conn - 1; -extern __device__ unsigned int *RevConnections; +extern unsigned int* d_RevConnections; //[i] i=0,..., n_rev_conn - 1; +extern __device__ unsigned int* RevConnections; -extern int *d_TargetRevConnectionSize; //[i] i=0,..., n_neuron-1; -extern __device__ int *TargetRevConnectionSize; +extern int* d_TargetRevConnectionSize; //[i] i=0,..., n_neuron-1; +extern __device__ int* TargetRevConnectionSize; -extern unsigned int **d_TargetRevConnection; //[i][j] j<=RevConnectionSize[i]-1 -extern __device__ unsigned int **TargetRevConnection; +extern unsigned int** d_TargetRevConnection; //[i][j] j<=RevConnectionSize[i]-1 +extern __device__ unsigned int** TargetRevConnection; -__device__ void PushSpike(int i_spike_buffer, float height); +__device__ void PushSpike( int i_spike_buffer, float height ); __global__ void SpikeBufferUpdate(); -__global__ void DeviceSpikeBufferInit(int n_spike_buffers, int max_delay_num, - int max_spike_buffer_size, - long long *last_spike_time_idx, - float *last_spike_height, - float *conn_weight, - unsigned char *conn_syn_group, - unsigned short *conn_spike_time, - int *conn_group_size, int *conn_group_delay, - int *conn_group_target_size, - unsigned int **conn_group_target_node, - unsigned char **conn_group_target_syn_group, - float **conn_group_target_weight, - unsigned short **conn_group_target_spike_time, - int *spike_buffer_size, int *spike_buffer_idx0, - int *spike_buffer_time, - int *spike_buffer_conn, - float *spike_buffer_height, - unsigned int *rev_conn, - int *target_rev_conn_size, - unsigned int **target_rev_conn, - long long *last_rev_spike_time_idx); - -int SpikeBufferInit(NetConnection *net_connection, int max_spike_buffer_size); +__global__ void DeviceSpikeBufferInit( int n_spike_buffers, + int max_delay_num, + int max_spike_buffer_size, + long long* last_spike_time_idx, + float* last_spike_height, + float* conn_weight, + unsigned char* conn_syn_group, + unsigned short* conn_spike_time, + int* conn_group_size, + int* conn_group_delay, + int* conn_group_target_size, + unsigned int** conn_group_target_node, + unsigned char** conn_group_target_syn_group, + float** conn_group_target_weight, + unsigned short** conn_group_target_spike_time, + int* spike_buffer_size, + int* spike_buffer_idx0, + int* spike_buffer_time, + int* spike_buffer_conn, + float* spike_buffer_height, + unsigned int* rev_conn, + int* target_rev_conn_size, + unsigned int** target_rev_conn, + long long* last_rev_spike_time_idx ); + +int SpikeBufferInit( NetConnection* net_connection, int max_spike_buffer_size ); #endif diff --git a/src/spike_detector.cu b/src/spike_detector.cu index 237aafc2f..26e5d0f15 100644 --- a/src/spike_detector.cu +++ b/src/spike_detector.cu @@ -21,57 +21,53 @@ */ - - - -#include #include +#include #include #include -//#include +// #include #include "cuda_error.h" #include "nestgpu.h" #include "neuron_models.h" #include "spike_detector.h" - //#include "spike_buffer.h" -//#include "parrot_neuron_variables.h" +// #include "spike_buffer.h" +// #include "parrot_neuron_variables.h" -enum { - i_spike_detector_hold_spike_height=0, +enum +{ + i_spike_detector_hold_spike_height = 0, N_SPIKE_DETECTOR_SCAL_PARAM }; -const std::string spike_detector_scal_param_name[N_SPIKE_DETECTOR_SCAL_PARAM] -= {"hold_spike_height"}; +const std::string spike_detector_scal_param_name[ N_SPIKE_DETECTOR_SCAL_PARAM ] = { "hold_spike_height" }; -enum { - i_spike_detector_input_spike_height=0, +enum +{ + i_spike_detector_input_spike_height = 0, i_spike_detector_spike_height, N_SPIKE_DETECTOR_SCAL_VAR }; -const std::string spike_detector_scal_var_name[N_SPIKE_DETECTOR_SCAL_VAR] -= {"input_spike_height", "spike_height"}; +const std::string spike_detector_scal_var_name[ N_SPIKE_DETECTOR_SCAL_VAR ] = { "input_spike_height", "spike_height" }; -__global__ -void spike_detector_UpdateKernel(int i_node_0, int n_node, float *var_arr, - float *param_arr, int n_var, int n_param) +__global__ void +spike_detector_UpdateKernel( int i_node_0, int n_node, float* var_arr, float* param_arr, int n_var, int n_param ) { int irel_node = threadIdx.x + blockIdx.x * blockDim.x; - if (irel_node < n_node) { - float *input_spike_height_pt = var_arr + irel_node*n_var - + i_spike_detector_input_spike_height; - float *spike_height_pt = var_arr + irel_node*n_var - + i_spike_detector_spike_height; - float *hold_spike_height_pt = param_arr + irel_node*n_param + - i_spike_detector_hold_spike_height; - //int i_node = i_node_0 + irel_node; + if ( irel_node < n_node ) + { + float* input_spike_height_pt = var_arr + irel_node * n_var + i_spike_detector_input_spike_height; + float* spike_height_pt = var_arr + irel_node * n_var + i_spike_detector_spike_height; + float* hold_spike_height_pt = param_arr + irel_node * n_param + i_spike_detector_hold_spike_height; + // int i_node = i_node_0 + irel_node; float spike_height = *input_spike_height_pt; - if (spike_height != 0.0) { - if (*hold_spike_height_pt==0.0) { - spike_height = 1.0; + if ( spike_height != 0.0 ) + { + if ( *hold_spike_height_pt == 0.0 ) + { + spike_height = 1.0; } *input_spike_height_pt = 0; } @@ -80,67 +76,69 @@ void spike_detector_UpdateKernel(int i_node_0, int n_node, float *var_arr, } -int spike_detector::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +spike_detector::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_spike_detector_model; n_scal_var_ = N_SPIKE_DETECTOR_SCAL_VAR; n_var_ = n_scal_var_; scal_var_name_ = spike_detector_scal_var_name; - + n_scal_param_ = N_SPIKE_DETECTOR_SCAL_PARAM; n_param_ = n_scal_param_; scal_param_name_ = spike_detector_scal_param_name; - gpuErrchk(cudaMalloc(&var_arr_, n_node_*n_var_*sizeof(float))); + gpuErrchk( cudaMalloc( &var_arr_, n_node_ * n_var_ * sizeof( float ) ) ); - gpuErrchk(cudaMalloc(¶m_arr_, n_node_*n_param_*sizeof(float))); + gpuErrchk( cudaMalloc( ¶m_arr_, n_node_ * n_param_ * sizeof( float ) ) ); - SetScalParam(0, n_node, "hold_spike_height", 1.0); + SetScalParam( 0, n_node, "hold_spike_height", 1.0 ); - SetScalVar(0, n_node, "input_spike_height", 0.0); + SetScalVar( 0, n_node, "input_spike_height", 0.0 ); - SetScalVar(0, n_node, "spike_height", 0.0); + SetScalVar( 0, n_node, "spike_height", 0.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input signal is stored in input_spike_height - port_input_arr_ = GetVarArr() + GetScalVarIdx("input_spike_height"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "input_spike_height" ); port_input_arr_step_ = n_var_; port_input_port_step_ = n_port_var_; - + return 0; } -int spike_detector::Update(long long /*i_time*/, double /*t1*/) +int +spike_detector::Update( long long /*i_time*/, double /*t1*/ ) { - spike_detector_UpdateKernel<<<(n_node_+1023)/1024, 1024>>> - (i_node_0_, n_node_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaPeekAtLastError() ); - //gpuErrchk( cudaDeviceSynchronize() ); + spike_detector_UpdateKernel<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + i_node_0_, n_node_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaPeekAtLastError() ); + // gpuErrchk( cudaDeviceSynchronize() ); return 0; } -int spike_detector::Free() +int +spike_detector::Free() { - gpuErrchk(cudaFree(var_arr_)); - gpuErrchk(cudaFree(param_arr_)); + gpuErrchk( cudaFree( var_arr_ ) ); + gpuErrchk( cudaFree( param_arr_ ) ); return 0; } spike_detector::~spike_detector() { - if (n_node_>0) { + if ( n_node_ > 0 ) + { Free(); } } diff --git a/src/spike_detector.h b/src/spike_detector.h index 047366ac8..f787a7a0a 100644 --- a/src/spike_detector.h +++ b/src/spike_detector.h @@ -21,15 +21,12 @@ */ - - - #ifndef SPIKEDETECTOR_H #define SPIKEDETECTOR_H #include #include -//#include "node_group.h" +// #include "node_group.h" #include "base_neuron.h" /* BeginUserDocs: device, recorder, spike @@ -46,7 +43,7 @@ The ``spike_detector`` collects and records all spikes it receives from neurons that are connected to it. Any neuron from which spikes have to be recorded must be connected to -the spike recorder using the standard ``Connect`` command. +the spike recorder using the standard ``Connect`` command. .. warning:: @@ -70,17 +67,17 @@ Here follows an example: recorder = nestgpu.CreateRecord("", ["spike_height"], [spike_det[0]], [0]) nestgpu.Simulate() - + recorded_data = nestgpu.GetRecordData(record) time = [row[0] for row in recorded_data] spike_height = [row[1] for row in recorded_data] The output is thus a continuous variable, which is 0 when no spikes are emitted -by the neuron, and is ``weights`` when a spike is emitted. +by the neuron, and is ``weights`` when a spike is emitted. .. note:: - A faster implementation for spike recording, which is also similar to + A faster implementation for spike recording, which is also similar to the one of NEST in terms of output, is described in the guide of :doc:`how to record spikes <../guides/how_to_record_spikes>`. @@ -94,16 +91,14 @@ EndUserDocs */ class spike_detector : public BaseNeuron { - public: +public: ~spike_detector(); - int Init(int i_node_0, int n_node, int n_port, int i_group, - unsigned long long *seed); + int Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ); int Free(); - - int Update(long long it, double t1); + int Update( long long it, double t1 ); }; diff --git a/src/spike_generator.cu b/src/spike_generator.cu index 145989519..d6d56b944 100644 --- a/src/spike_generator.cu +++ b/src/spike_generator.cu @@ -21,277 +21,310 @@ */ - - - -#include #include +#include #include -//#include +// #include +#include "cuda_error.h" #include "nestgpu.h" #include "neuron_models.h" -#include "spike_generator.h" #include "spike_buffer.h" -#include "cuda_error.h" -//#include "spike_generator_variables.h" +#include "spike_generator.h" +// #include "spike_generator_variables.h" const int N_SPIKE_GEN_SCAL_PARAM = 0; -const std::string *spike_gen_scal_param_name = NULL; -enum { - i_SPIKE_TIME_ARRAY_PARAM=0, +const std::string* spike_gen_scal_param_name = NULL; +enum +{ + i_SPIKE_TIME_ARRAY_PARAM = 0, i_SPIKE_HEIGHT_ARRAY_PARAM, N_SPIKE_GEN_ARRAY_PARAM }; -const std::string spike_gen_array_param_name[N_SPIKE_GEN_ARRAY_PARAM] -= {"spike_times", "spike_heights"}; +const std::string spike_gen_array_param_name[ N_SPIKE_GEN_ARRAY_PARAM ] = { "spike_times", "spike_heights" }; -__global__ -void spike_generatorUpdate(int i_node_0, int n_node, long long i_time, - int *n_spikes, int *i_spike, int **spike_time_idx, - float **spike_height) +__global__ void +spike_generatorUpdate( int i_node_0, + int n_node, + long long i_time, + int* n_spikes, + int* i_spike, + int** spike_time_idx, + float** spike_height ) { int irel_node = threadIdx.x + blockIdx.x * blockDim.x; - if (irel_node < n_node) { - if (n_spikes[irel_node] > 0) { - int is = i_spike[irel_node]; - if (is 0 ) + { + int is = i_spike[ irel_node ]; + if ( is < n_spikes[ irel_node ] && spike_time_idx[ irel_node ][ is ] == i_time ) + { + int i_node = i_node_0 + irel_node; + float height = spike_height[ irel_node ][ is ]; + PushSpike( i_node, height ); + i_spike[ irel_node ]++; } } } } -int spike_generator::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +spike_generator::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 0 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 0 /*n_port*/, i_group, seed ); node_type_ = i_spike_generator_model; n_scal_param_ = N_SPIKE_GEN_SCAL_PARAM; n_param_ = n_scal_param_; scal_param_name_ = spike_gen_scal_param_name; - for (int i=0; i empty_vect; + for ( int i = 0; i < N_SPIKE_GEN_ARRAY_PARAM; i++ ) + { + array_param_name_.push_back( spike_gen_array_param_name[ i ] ); + } + std::vector< float > empty_vect; spike_time_vect_.clear(); - spike_time_vect_.insert(spike_time_vect_.begin(), n_node, empty_vect); + spike_time_vect_.insert( spike_time_vect_.begin(), n_node, empty_vect ); spike_height_vect_.clear(); - spike_height_vect_.insert(spike_height_vect_.begin(), n_node, empty_vect); - - gpuErrchk(cudaMalloc(¶m_arr_, n_node_*n_param_*sizeof(float))); - - //SetScalParam(0, n_node, "origin", 0.0); - - h_spike_time_idx_ = new int*[n_node_]; - h_spike_height_ = new float*[n_node_]; - for (int i_node=0; i_node0) { + if ( n_node_ > 0 ) + { Free(); } } -int spike_generator::Update(long long i_time, double /*t1*/) +int +spike_generator::Update( long long i_time, double /*t1*/ ) { - spike_generatorUpdate<<<(n_node_+1023)/1024, 1024>>> - (i_node_0_, n_node_, i_time, d_n_spikes_, d_i_spike_, d_spike_time_idx_, - d_spike_height_); - //gpuErrchk( cudaPeekAtLastError() ); - //gpuErrchk( cudaDeviceSynchronize() ); + spike_generatorUpdate<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + i_node_0_, n_node_, i_time, d_n_spikes_, d_i_spike_, d_spike_time_idx_, d_spike_height_ ); + // gpuErrchk( cudaPeekAtLastError() ); + // gpuErrchk( cudaDeviceSynchronize() ); return 0; } -int spike_generator::SetArrayParam(int i_neuron, int n_neuron, - std::string param_name, float *array, - int array_size) +int +spike_generator::SetArrayParam( int i_neuron, int n_neuron, std::string param_name, float* array, int array_size ) { - CheckNeuronIdx(i_neuron); - CheckNeuronIdx(i_neuron + n_neuron - 1); + CheckNeuronIdx( i_neuron ); + CheckNeuronIdx( i_neuron + n_neuron - 1 ); - if (param_name==array_param_name_[i_SPIKE_TIME_ARRAY_PARAM]) { - for (int in=i_neuron; in(array, array+array_size); + if ( param_name == array_param_name_[ i_SPIKE_TIME_ARRAY_PARAM ] ) + { + for ( int in = i_neuron; in < i_neuron + n_neuron; in++ ) + { + spike_time_vect_[ in ] = std::vector< float >( array, array + array_size ); } } - else if (param_name==array_param_name_[i_SPIKE_HEIGHT_ARRAY_PARAM]) { - for (int in=i_neuron; in(array, array+array_size); + else if ( param_name == array_param_name_[ i_SPIKE_HEIGHT_ARRAY_PARAM ] ) + { + for ( int in = i_neuron; in < i_neuron + n_neuron; in++ ) + { + spike_height_vect_[ in ] = std::vector< float >( array, array + array_size ); } } - else { - throw ngpu_exception(std::string("Unrecognized array parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized array parameter " ) + param_name ); } return 0; } - -int spike_generator::SetArrayParam(int *i_neuron, int n_neuron, - std::string param_name, float *array, - int array_size) + +int +spike_generator::SetArrayParam( int* i_neuron, int n_neuron, std::string param_name, float* array, int array_size ) { - if (param_name==array_param_name_[i_SPIKE_TIME_ARRAY_PARAM]) { - for (int i=0; i(array, array+array_size); + if ( param_name == array_param_name_[ i_SPIKE_TIME_ARRAY_PARAM ] ) + { + for ( int i = 0; i < n_neuron; i++ ) + { + int in = i_neuron[ i ]; + CheckNeuronIdx( in ); + spike_time_vect_[ in ] = std::vector< float >( array, array + array_size ); } } - else if (param_name==array_param_name_[i_SPIKE_HEIGHT_ARRAY_PARAM]) { - for (int i=0; i(array, array+array_size); + else if ( param_name == array_param_name_[ i_SPIKE_HEIGHT_ARRAY_PARAM ] ) + { + for ( int i = 0; i < n_neuron; i++ ) + { + int in = i_neuron[ i ]; + CheckNeuronIdx( in ); + spike_height_vect_[ in ] = std::vector< float >( array, array + array_size ); } } - else { - throw ngpu_exception(std::string("Unrecognized array parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized array parameter " ) + param_name ); } return 0; } -int spike_generator::Calibrate(double time_min, float time_resolution) +int +spike_generator::Calibrate( double time_min, float time_resolution ) { - for (int in=0; in0) { - if (spike_height_vect_[in].size()==0) { - spike_height_vect_[in].insert(spike_height_vect_[in].begin(), - n_spikes, 1.0); + for ( int in = 0; in < n_node_; in++ ) + { + unsigned int n_spikes = spike_time_vect_[ in ].size(); + if ( n_spikes > 0 ) + { + if ( spike_height_vect_[ in ].size() == 0 ) + { + spike_height_vect_[ in ].insert( spike_height_vect_[ in ].begin(), n_spikes, 1.0 ); } - else if (spike_height_vect_[in].size()!=n_spikes) { - throw ngpu_exception("spike time array and spike height array " - "must have the same size in spike generator"); + else if ( spike_height_vect_[ in ].size() != n_spikes ) + { + throw ngpu_exception( + "spike time array and spike height array " + "must have the same size in spike generator" ); } - SetSpikes(in, n_spikes, spike_time_vect_[in].data(), - spike_height_vect_[in].data(), (float)time_min, time_resolution); + SetSpikes( in, + n_spikes, + spike_time_vect_[ in ].data(), + spike_height_vect_[ in ].data(), + ( float ) time_min, + time_resolution ); } } - + return 0; } - -int spike_generator::SetSpikes(int irel_node, int n_spikes, float *spike_time, - float *spike_height, float time_min, - float time_resolution) +int +spike_generator::SetSpikes( int irel_node, + int n_spikes, + float* spike_time, + float* spike_height, + float time_min, + float time_resolution ) { - if (n_spikes <=0) { - throw ngpu_exception("Number of spikes must be greater than 0 " - "in spike generator setting"); + if ( n_spikes <= 0 ) + { + throw ngpu_exception( + "Number of spikes must be greater than 0 " + "in spike generator setting" ); } - - cudaMemcpy(&d_n_spikes_[irel_node], &n_spikes, sizeof(int), - cudaMemcpyHostToDevice); - if (h_spike_time_idx_[irel_node] != 0) { - gpuErrchk(cudaFree(h_spike_time_idx_[irel_node])); - gpuErrchk(cudaFree(h_spike_height_[irel_node])); + + cudaMemcpy( &d_n_spikes_[ irel_node ], &n_spikes, sizeof( int ), cudaMemcpyHostToDevice ); + if ( h_spike_time_idx_[ irel_node ] != 0 ) + { + gpuErrchk( cudaFree( h_spike_time_idx_[ irel_node ] ) ); + gpuErrchk( cudaFree( h_spike_height_[ irel_node ] ) ); } - gpuErrchk(cudaMalloc(&h_spike_time_idx_[irel_node], n_spikes*sizeof(int))); - gpuErrchk(cudaMalloc(&h_spike_height_[irel_node], n_spikes*sizeof(float))); - - cudaMemcpy(&d_spike_time_idx_[irel_node], &h_spike_time_idx_[irel_node], - sizeof(int*), cudaMemcpyHostToDevice); - cudaMemcpy(&d_spike_height_[irel_node], &h_spike_height_[irel_node], sizeof(float*), - cudaMemcpyHostToDevice); - - int *spike_time_idx = new int[n_spikes]; - for(int i=0; i0 && spike_time_idx[i]<=spike_time_idx[i-1]) { - throw ngpu_exception("Spike times must be ordered, and the difference " - "between\nconsecutive spikes must be >= the " - "time resolution"); + gpuErrchk( cudaMalloc( &h_spike_time_idx_[ irel_node ], n_spikes * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &h_spike_height_[ irel_node ], n_spikes * sizeof( float ) ) ); + + cudaMemcpy( + &d_spike_time_idx_[ irel_node ], &h_spike_time_idx_[ irel_node ], sizeof( int* ), cudaMemcpyHostToDevice ); + cudaMemcpy( &d_spike_height_[ irel_node ], &h_spike_height_[ irel_node ], sizeof( float* ), cudaMemcpyHostToDevice ); + + int* spike_time_idx = new int[ n_spikes ]; + for ( int i = 0; i < n_spikes; i++ ) + { + spike_time_idx[ i ] = ( int ) round( ( spike_time[ i ] - time_min ) / time_resolution ); + if ( i > 0 && spike_time_idx[ i ] <= spike_time_idx[ i - 1 ] ) + { + throw ngpu_exception( + "Spike times must be ordered, and the difference " + "between\nconsecutive spikes must be >= the " + "time resolution" ); } - //cout << "ti " << spike_time_idx[i] << endl; - //cout << spike_time[i] << " " << time_min << endl; - + // cout << "ti " << spike_time_idx[i] << endl; + // cout << spike_time[i] << " " << time_min << endl; } - - cudaMemcpy(h_spike_time_idx_[irel_node], spike_time_idx, n_spikes*sizeof(int), - cudaMemcpyHostToDevice); - cudaMemcpy(h_spike_height_[irel_node], spike_height, n_spikes*sizeof(float), - cudaMemcpyHostToDevice); + + cudaMemcpy( h_spike_time_idx_[ irel_node ], spike_time_idx, n_spikes * sizeof( int ), cudaMemcpyHostToDevice ); + cudaMemcpy( h_spike_height_[ irel_node ], spike_height, n_spikes * sizeof( float ), cudaMemcpyHostToDevice ); return 0; } -int spike_generator::GetArrayParamSize(int i_neuron, std::string param_name) +int +spike_generator::GetArrayParamSize( int i_neuron, std::string param_name ) { - if (param_name==array_param_name_[i_SPIKE_TIME_ARRAY_PARAM]) { - return spike_time_vect_[i_neuron].size(); + if ( param_name == array_param_name_[ i_SPIKE_TIME_ARRAY_PARAM ] ) + { + return spike_time_vect_[ i_neuron ].size(); } - else if (param_name==array_param_name_[i_SPIKE_HEIGHT_ARRAY_PARAM]) { - return spike_height_vect_[i_neuron].size(); + else if ( param_name == array_param_name_[ i_SPIKE_HEIGHT_ARRAY_PARAM ] ) + { + return spike_height_vect_[ i_neuron ].size(); } - else { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } } -float *spike_generator::GetArrayParam(int i_neuron, std::string param_name) +float* +spike_generator::GetArrayParam( int i_neuron, std::string param_name ) { - if (param_name==array_param_name_[i_SPIKE_TIME_ARRAY_PARAM]) { - return spike_time_vect_[i_neuron].data(); + if ( param_name == array_param_name_[ i_SPIKE_TIME_ARRAY_PARAM ] ) + { + return spike_time_vect_[ i_neuron ].data(); } - else if (param_name==array_param_name_[i_SPIKE_HEIGHT_ARRAY_PARAM]) { - return spike_height_vect_[i_neuron].data(); + else if ( param_name == array_param_name_[ i_SPIKE_HEIGHT_ARRAY_PARAM ] ) + { + return spike_height_vect_[ i_neuron ].data(); } - else { - throw ngpu_exception(std::string("Unrecognized parameter ") - + param_name); + else + { + throw ngpu_exception( std::string( "Unrecognized parameter " ) + param_name ); } } diff --git a/src/spike_generator.h b/src/spike_generator.h index e4ad9a61d..6beae1619 100644 --- a/src/spike_generator.h +++ b/src/spike_generator.h @@ -21,16 +21,13 @@ */ - - - #ifndef SPIKEGENERATOR_H #define SPIKEGENERATOR_H +#include "cuda_error.h" #include #include -#include "cuda_error.h" - //#include "node_group.h" +// #include "node_group.h" #include "base_neuron.h" #include "neuron_models.h" @@ -58,7 +55,7 @@ The following parameters can be set in the status dictionary. Spike times are given in milliseconds, and must be sorted with the earliest spike first. All spike times must be strictly in the future -(i.e. greater than the current time step). +(i.e. greater than the current time step). It is possible that spike times do not coincide with a time step, i.e., are not a multiple of the simulation resolution. @@ -82,40 +79,40 @@ EndUserDocs class spike_generator : public BaseNeuron { - int *d_n_spikes_; - int *d_i_spike_; - int **d_spike_time_idx_; - float **d_spike_height_; - int **h_spike_time_idx_; - float ** h_spike_height_; - std::vector > spike_time_vect_; - std::vector > spike_height_vect_; - - int SetSpikes(int irel_node, int n_spikes, float *spike_time, - float *spike_height, float time_min, float time_resolution); - - public: + int* d_n_spikes_; + int* d_i_spike_; + int** d_spike_time_idx_; + float** d_spike_height_; + int** h_spike_time_idx_; + float** h_spike_height_; + std::vector< std::vector< float > > spike_time_vect_; + std::vector< std::vector< float > > spike_height_vect_; + + int SetSpikes( int irel_node, + int n_spikes, + float* spike_time, + float* spike_height, + float time_min, + float time_resolution ); + +public: ~spike_generator(); - - int Init(int i_node_0, int n_node, int n_port, int i_group, - unsigned long long *seed); + + int Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ); int Free(); - - int Update(long long i_time, double t1); - int Calibrate(double time_min, float time_resolution); + int Update( long long i_time, double t1 ); + + int Calibrate( double time_min, float time_resolution ); + + int SetArrayParam( int i_neuron, int n_neuron, std::string param_name, float* array, int array_size ); - int SetArrayParam(int i_neuron, int n_neuron, std::string param_name, - float *array, int array_size); - - int SetArrayParam(int *i_neuron, int n_neuron, std::string param_name, - float *array, int array_size); - - int GetArrayParamSize(int i_neuron, std::string param_name); + int SetArrayParam( int* i_neuron, int n_neuron, std::string param_name, float* array, int array_size ); - float *GetArrayParam(int i_neuron, std::string param_name); + int GetArrayParamSize( int i_neuron, std::string param_name ); + float* GetArrayParam( int i_neuron, std::string param_name ); }; diff --git a/src/spike_mpi.cu b/src/spike_mpi.cu index babe29c01..addd658de 100644 --- a/src/spike_mpi.cu +++ b/src/spike_mpi.cu @@ -23,33 +23,35 @@ #include +#include #include #include -#include #include "cuda_error.h" -#include "spike_buffer.h" #include "getRealTime.h" +#include "spike_buffer.h" -#include "spike_mpi.h" #include "connect_mpi.h" #include "scan.h" +#include "spike_mpi.h" -__device__ int locate(int val, int *data, int n); +__device__ int locate( int val, int* data, int n ); // Combined function of PushedSpikeFromRemote with // AddOffset using default values for arguments -__global__ void PushSpikeFromRemote(int n_spikes, int *spike_buffer_id, - float *spike_height, int offset) +__global__ void +PushSpikeFromRemote( int n_spikes, int* spike_buffer_id, float* spike_height, int offset ) { int i_spike = threadIdx.x + blockIdx.x * blockDim.x; - if (i_spike=MaxSpikePerHost) { - printf("Number of spikes larger than MaxSpikePerHost: %d\n", MaxSpikePerHost); + int pos = atomicAdd( ExternalSpikeNum, 1 ); + if ( pos >= MaxSpikePerHost ) + { + printf( "Number of spikes larger than MaxSpikePerHost: %d\n", MaxSpikePerHost ); *ExternalSpikeNum = MaxSpikePerHost; return; } - ExternalSpikeSourceNode[pos] = i_source; - ExternalSpikeHeight[pos] = height; + ExternalSpikeSourceNode[ pos ] = i_source; + ExternalSpikeHeight[ pos ] = height; } // Properly organize the spikes that must be sent externally -__global__ void SendExternalSpike() +__global__ void +SendExternalSpike() { int i_spike = threadIdx.x + blockIdx.x * blockDim.x; - if (i_spike < *ExternalSpikeNum) { - int i_source = ExternalSpikeSourceNode[i_spike]; - float height = ExternalSpikeHeight[i_spike]; - int Nth = NExternalNodeTargetHost[i_source]; - - for (int ith=0; ith *conn = &extern_connection_[i_source]; + int* h_NExternalNodeTargetHost = new int[ n_node ]; + int** h_ExternalNodeTargetHostId = new int*[ n_node ]; + int** h_ExternalNodeId = new int*[ n_node ]; + + // h_ExternalSpikeNodeId = new int[max_spike_per_host]; + h_ExternalTargetSpikeNum = new int[ n_hosts ]; + h_ExternalTargetSpikeCumul = new int[ n_hosts + 1 ]; + h_ExternalSourceSpikeNum = new int[ n_hosts ]; + h_ExternalTargetSpikeNodeId = new int[ n_hosts * ( max_spike_per_host + 1 ) ]; + h_ExternalSourceSpikeNodeId = new int[ n_hosts * ( max_spike_per_host + 1 ) ]; + + h_ExternalSpikeHeight = new float[ max_spike_per_host ]; + + recv_mpi_request = new MPI_Request[ n_hosts ]; + + gpuErrchk( cudaMalloc( &d_ExternalSpikeNum, sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalSpikeSourceNode, max_spike_per_host * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalSpikeHeight, max_spike_per_host * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalTargetSpikeNum, n_hosts * sizeof( int ) ) ); + + // printf("n_hosts, max_spike_per_host: %d %d\n", n_hosts, max_spike_per_host); + + gpuErrchk( cudaMalloc( &d_ExternalTargetSpikeNodeId, n_hosts * max_spike_per_host * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalTargetSpikeHeight, n_hosts * max_spike_per_host * sizeof( float ) ) ); + // gpuErrchk(cudaMalloc(&d_ExternalSourceSpikeNum, n_hosts*sizeof(int))); + gpuErrchk( cudaMalloc( &d_ExternalSourceSpikeNodeId, n_hosts * max_spike_per_host * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalSourceSpikeHeight, n_hosts * max_spike_per_host * sizeof( float ) ) ); + + gpuErrchk( cudaMalloc( &d_ExternalTargetSpikeNodeIdJoin, n_hosts * max_spike_per_host * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalTargetSpikeCumul, ( n_hosts + 1 ) * sizeof( int ) ) ); + + gpuErrchk( cudaMalloc( &d_NExternalNodeTargetHost, n_node * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalNodeTargetHostId, n_node * sizeof( int* ) ) ); + gpuErrchk( cudaMalloc( &d_ExternalNodeId, n_node * sizeof( int* ) ) ); + + for ( int i_source = 0; i_source < n_node; i_source++ ) + { + std::vector< ExternalConnectionNode >* conn = &extern_connection_[ i_source ]; int Nth = conn->size(); - h_NExternalNodeTargetHost[i_source] = Nth; - if (Nth>0) { - gpuErrchk(cudaMalloc(&h_ExternalNodeTargetHostId[i_source], - Nth*sizeof(int))); - gpuErrchk(cudaMalloc(&h_ExternalNodeId[i_source], Nth*sizeof(int))); - int *target_host_arr = new int[Nth]; - int *node_id_arr = new int[Nth]; - for (int ith=0; ithat(ith).target_host_id; - node_id_arr[ith] = conn->at(ith).remote_node_id; - } - cudaMemcpyAsync(h_ExternalNodeTargetHostId[i_source], target_host_arr, - Nth*sizeof(int), cudaMemcpyHostToDevice); - cudaMemcpy(h_ExternalNodeId[i_source], node_id_arr, - Nth*sizeof(int), cudaMemcpyHostToDevice); - delete[] target_host_arr; - delete[] node_id_arr; - } + h_NExternalNodeTargetHost[ i_source ] = Nth; + if ( Nth > 0 ) + { + gpuErrchk( cudaMalloc( &h_ExternalNodeTargetHostId[ i_source ], Nth * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &h_ExternalNodeId[ i_source ], Nth * sizeof( int ) ) ); + int* target_host_arr = new int[ Nth ]; + int* node_id_arr = new int[ Nth ]; + for ( int ith = 0; ith < Nth; ith++ ) + { + target_host_arr[ ith ] = conn->at( ith ).target_host_id; + node_id_arr[ ith ] = conn->at( ith ).remote_node_id; + } + cudaMemcpyAsync( + h_ExternalNodeTargetHostId[ i_source ], target_host_arr, Nth * sizeof( int ), cudaMemcpyHostToDevice ); + cudaMemcpy( h_ExternalNodeId[ i_source ], node_id_arr, Nth * sizeof( int ), cudaMemcpyHostToDevice ); + delete[] target_host_arr; + delete[] node_id_arr; + } } - cudaMemcpyAsync(d_NExternalNodeTargetHost, h_NExternalNodeTargetHost, - n_node*sizeof(int), cudaMemcpyHostToDevice); - cudaMemcpyAsync(d_ExternalNodeTargetHostId, h_ExternalNodeTargetHostId, - n_node*sizeof(int*), cudaMemcpyHostToDevice); - cudaMemcpyAsync(d_ExternalNodeId, h_ExternalNodeId, - n_node*sizeof(int*), cudaMemcpyHostToDevice); - - DeviceExternalSpikeInit<<<1,1>>>(n_hosts, max_spike_per_host, - d_ExternalSpikeNum, - d_ExternalSpikeSourceNode, - d_ExternalSpikeHeight, - d_ExternalTargetSpikeNum, - d_ExternalTargetSpikeNodeId, - d_ExternalTargetSpikeHeight, - d_NExternalNodeTargetHost, - d_ExternalNodeTargetHostId, - d_ExternalNodeId - ); + cudaMemcpyAsync( + d_NExternalNodeTargetHost, h_NExternalNodeTargetHost, n_node * sizeof( int ), cudaMemcpyHostToDevice ); + cudaMemcpyAsync( + d_ExternalNodeTargetHostId, h_ExternalNodeTargetHostId, n_node * sizeof( int* ), cudaMemcpyHostToDevice ); + cudaMemcpyAsync( d_ExternalNodeId, h_ExternalNodeId, n_node * sizeof( int* ), cudaMemcpyHostToDevice ); + + DeviceExternalSpikeInit<<< 1, 1 >>>( n_hosts, + max_spike_per_host, + d_ExternalSpikeNum, + d_ExternalSpikeSourceNode, + d_ExternalSpikeHeight, + d_ExternalTargetSpikeNum, + d_ExternalTargetSpikeNodeId, + d_ExternalTargetSpikeHeight, + d_NExternalNodeTargetHost, + d_ExternalNodeTargetHostId, + d_ExternalNodeId ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); @@ -255,22 +257,22 @@ int ConnectMpi::ExternalSpikeInit(int n_node, int n_hosts, int max_spike_per_hos } // initialize external spike array pointers in the GPU -__global__ void DeviceExternalSpikeInit(int n_hosts, - int max_spike_per_host, - int *ext_spike_num, - int *ext_spike_source_node, - float *ext_spike_height, - int *ext_target_spike_num, - int *ext_target_spike_node_id, - float *ext_target_spike_height, - int *n_ext_node_target_host, - int **ext_node_target_host_id, - int **ext_node_id - ) - +__global__ void +DeviceExternalSpikeInit( int n_hosts, + int max_spike_per_host, + int* ext_spike_num, + int* ext_spike_source_node, + float* ext_spike_height, + int* ext_target_spike_num, + int* ext_target_spike_node_id, + float* ext_target_spike_height, + int* n_ext_node_target_host, + int** ext_node_target_host_id, + int** ext_node_id ) + { NExternalTargetHost = n_hosts; - MaxSpikePerHost = max_spike_per_host; + MaxSpikePerHost = max_spike_per_host; ExternalSpikeNum = ext_spike_num; ExternalSpikeSourceNode = ext_spike_source_node; ExternalSpikeHeight = ext_spike_height; @@ -281,195 +283,218 @@ __global__ void DeviceExternalSpikeInit(int n_hosts, ExternalNodeTargetHostId = ext_node_target_host_id; ExternalNodeId = ext_node_id; *ExternalSpikeNum = 0; - for (int ith=0; ith0) { + if ( n_spike_tot > 0 ) + { time_mark = getRealTime(); // Memcopy will be synchronized with AddOffset kernel // copy to GPU memory packed spikes from remote MPI proc - gpuErrchk(cudaMemcpyAsync(d_ExternalSourceSpikeNodeId, - h_ExternalSourceSpikeNodeId, - n_spike_tot*sizeof(int), cudaMemcpyHostToDevice)); - RecvSpikeFromRemote_CUDAcp_time_ += (getRealTime() - time_mark); + gpuErrchk( cudaMemcpyAsync( + d_ExternalSourceSpikeNodeId, h_ExternalSourceSpikeNodeId, n_spike_tot * sizeof( int ), cudaMemcpyHostToDevice ) ); + RecvSpikeFromRemote_CUDAcp_time_ += ( getRealTime() - time_mark ); // convert node group indexes to spike buffer indexes - // by adding the index of the first node of the node group - //AddOffset<<<(n_spike_tot+1023)/1024, 1024>>> + // by adding the index of the first node of the node group + // AddOffset<<<(n_spike_tot+1023)/1024, 1024>>> // (n_spike_tot, d_ExternalSourceSpikeNodeId, i_remote_node_0); - //gpuErrchk( cudaPeekAtLastError() ); - //cudaDeviceSynchronize(); + // gpuErrchk( cudaPeekAtLastError() ); + // cudaDeviceSynchronize(); // push remote spikes in local spike buffers - PushSpikeFromRemote<<<(n_spike_tot+1023)/1024, 1024>>> - (n_spike_tot, d_ExternalSourceSpikeNodeId, NULL, i_remote_node_0); + PushSpikeFromRemote<<< ( n_spike_tot + 1023 ) / 1024, 1024 >>>( + n_spike_tot, d_ExternalSourceSpikeNodeId, NULL, i_remote_node_0 ); gpuErrchk( cudaPeekAtLastError() ); - //cudaDeviceSynchronize(); + // cudaDeviceSynchronize(); } - + return n_spike_tot; } // pack the spikes in GPU memory that must be sent externally -__global__ void JoinSpikeKernel(int n_hosts, int *ExternalTargetSpikeCumul, - int *ExternalTargetSpikeNodeId, - int *ExternalTargetSpikeNodeIdJoin, - int n_spike_tot, int max_spike_per_host) +__global__ void +JoinSpikeKernel( int n_hosts, + int* ExternalTargetSpikeCumul, + int* ExternalTargetSpikeNodeId, + int* ExternalTargetSpikeNodeIdJoin, + int n_spike_tot, + int max_spike_per_host ) { // parallel implementation of nested loop // outer loop index i_host = 0, ... , n_hosts // inner loop index i_spike = 0, ... , ExternalTargetSpikeNum[i_host]; // array_idx is the index in the packed spike array int array_idx = threadIdx.x + blockIdx.x * blockDim.x; - if (array_idx0) { + if ( n_spike_tot > 0 ) + { // pack the spikes in GPU memory - JoinSpikeKernel<<<(n_spike_tot+1023)/1024, 1024>>>(n_hosts, - d_ExternalTargetSpikeCumul, - d_ExternalTargetSpikeNodeId, - d_ExternalTargetSpikeNodeIdJoin, - n_spike_tot, max_spike_per_host); + JoinSpikeKernel<<< ( n_spike_tot + 1023 ) / 1024, 1024 >>>( n_hosts, + d_ExternalTargetSpikeCumul, + d_ExternalTargetSpikeNodeId, + d_ExternalTargetSpikeNodeIdJoin, + n_spike_tot, + max_spike_per_host ); gpuErrchk( cudaPeekAtLastError() ); } - JoinSpike_time_ += (getRealTime() - time_mark); - + JoinSpike_time_ += ( getRealTime() - time_mark ); + return n_spike_tot; } diff --git a/src/spike_mpi.h b/src/spike_mpi.h index c22784ff9..b13861619 100644 --- a/src/spike_mpi.h +++ b/src/spike_mpi.h @@ -21,9 +21,6 @@ */ - - - #ifndef SPIKEMPI_H #define SPIKEMPI_H @@ -31,16 +28,15 @@ Combined version of PushedSpikeFromRemote and AddOffset kernels using default values for arguments Args: - - int n_spikes: number of spikes to push - - int* spike_buffer_id: pointer to array of spike buffer ids - - float* spike_height: pointer to array of spike heights to send - Defaults to NULL, if no spike height given then a height of 1.0 is pushed - Must be of length == n_spikes - - int offset: Offset to be used for spike_buffer indexes - Defaults to 0 + - int n_spikes: number of spikes to push + - int* spike_buffer_id: pointer to array of spike buffer ids + - float* spike_height: pointer to array of spike heights to send + Defaults to NULL, if no spike height given then a height of 1.0 is pushed + Must be of length == n_spikes + - int offset: Offset to be used for spike_buffer indexes + Defaults to 0 */ -__global__ void PushSpikeFromRemote(int n_spikes, int *spike_buffer_id, - float *spike_height = NULL, int offset = 0); +__global__ void PushSpikeFromRemote( int n_spikes, int* spike_buffer_id, float* spike_height = NULL, int offset = 0 ); #ifdef HAVE_MPI @@ -49,60 +45,59 @@ extern __constant__ bool NESTGPUMpiFlag; extern __device__ int NExternalTargetHost; extern __device__ int MaxSpikePerHost; -extern int *d_ExternalSpikeNum; -extern __device__ int *ExternalSpikeNum; +extern int* d_ExternalSpikeNum; +extern __device__ int* ExternalSpikeNum; -extern int *d_ExternalSpikeSourceNode; // [MaxSpikeNum]; -extern __device__ int *ExternalSpikeSourceNode; +extern int* d_ExternalSpikeSourceNode; // [MaxSpikeNum]; +extern __device__ int* ExternalSpikeSourceNode; -extern float *d_ExternalSpikeHeight; // [MaxSpikeNum]; -extern __device__ float *ExternalSpikeHeight; +extern float* d_ExternalSpikeHeight; // [MaxSpikeNum]; +extern __device__ float* ExternalSpikeHeight; -extern int *d_ExternalTargetSpikeNum; -extern __device__ int *ExternalTargetSpikeNum; +extern int* d_ExternalTargetSpikeNum; +extern __device__ int* ExternalTargetSpikeNum; -extern int *d_ExternalTargetSpikeNodeId; -extern __device__ int *ExternalTargetSpikeNodeId; +extern int* d_ExternalTargetSpikeNodeId; +extern __device__ int* ExternalTargetSpikeNodeId; -extern float *d_ExternalTargetSpikeHeight; -extern __device__ float *ExternalTargetSpikeHeight; +extern float* d_ExternalTargetSpikeHeight; +extern __device__ float* ExternalTargetSpikeHeight; -extern int *d_NExternalNodeTargetHost; -extern __device__ int *NExternalNodeTargetHost; +extern int* d_NExternalNodeTargetHost; +extern __device__ int* NExternalNodeTargetHost; -extern int **d_ExternalNodeTargetHostId; -extern __device__ int **ExternalNodeTargetHostId; +extern int** d_ExternalNodeTargetHostId; +extern __device__ int** ExternalNodeTargetHostId; -extern int **d_ExternalNodeId; -extern __device__ int **ExternalNodeId; +extern int** d_ExternalNodeId; +extern __device__ int** ExternalNodeId; -//extern int *d_ExternalSourceSpikeNum; -//extern __device__ int *ExternalSourceSpikeNum; +// extern int *d_ExternalSourceSpikeNum; +// extern __device__ int *ExternalSourceSpikeNum; -extern int *d_ExternalSourceSpikeNodeId; -extern __device__ int *ExternalSourceSpikeNodeId; +extern int* d_ExternalSourceSpikeNodeId; +extern __device__ int* ExternalSourceSpikeNodeId; -extern float *d_ExternalSourceSpikeHeight; -extern __device__ float *ExternalSourceSpikeHeight; +extern float* d_ExternalSourceSpikeHeight; +extern __device__ float* ExternalSourceSpikeHeight; -__device__ void PushExternalSpike(int i_source, float height); +__device__ void PushExternalSpike( int i_source, float height ); __global__ void SendExternalSpike(); __global__ void ExternalSpikeReset(); -__global__ void DeviceExternalSpikeInit(int n_hosts, - int max_spike_per_host, - int *ext_spike_num, - int *ext_spike_source_node, - float *ext_spike_height, - int *ext_target_spike_num, - int *ext_target_spike_node_id, - float *ext_target_spike_height, - int *n_ext_node_target_host, - int **ext_node_target_host_id, - int **ext_node_id - ); +__global__ void DeviceExternalSpikeInit( int n_hosts, + int max_spike_per_host, + int* ext_spike_num, + int* ext_spike_source_node, + float* ext_spike_height, + int* ext_target_spike_num, + int* ext_target_spike_node_id, + float* ext_target_spike_height, + int* n_ext_node_target_host, + int** ext_node_target_host_id, + int** ext_node_id ); #endif #endif diff --git a/src/stdp.cu b/src/stdp.cu index 36a2223a8..052e3ddfa 100644 --- a/src/stdp.cu +++ b/src/stdp.cu @@ -21,61 +21,62 @@ */ - - - -#include -#include -#include -#include "ngpu_exception.h" #include "cuda_error.h" +#include "ngpu_exception.h" #include "stdp.h" +#include +#include +#include using namespace stdp_ns; -__device__ void STDPUpdate(float *weight_pt, float Dt, float *param) +__device__ void +STDPUpdate( float* weight_pt, float Dt, float* param ) { - //printf("Dt: %f\n", Dt); - double tau_plus = param[i_tau_plus]; - double tau_minus = param[i_tau_minus]; - double lambda = param[i_lambda]; - double alpha = param[i_alpha]; - double mu_plus = param[i_mu_plus]; - double mu_minus = param[i_mu_minus]; - double Wmax = param[i_Wmax]; - //double den_delay = param[i_den_delay]; + // printf("Dt: %f\n", Dt); + double tau_plus = param[ i_tau_plus ]; + double tau_minus = param[ i_tau_minus ]; + double lambda = param[ i_lambda ]; + double alpha = param[ i_alpha ]; + double mu_plus = param[ i_mu_plus ]; + double mu_minus = param[ i_mu_minus ]; + double Wmax = param[ i_Wmax ]; + // double den_delay = param[i_den_delay]; double w = *weight_pt; double w1; - //Dt += den_delay; - if (Dt>=0) { - double fact = lambda*exp(-(double)Dt/tau_plus); - w1 = w + fact*Wmax*pow(1.0 - w/Wmax, mu_plus); + // Dt += den_delay; + if ( Dt >= 0 ) + { + double fact = lambda * exp( -( double ) Dt / tau_plus ); + w1 = w + fact * Wmax * pow( 1.0 - w / Wmax, mu_plus ); } - else { - double fact = -alpha*lambda*exp((double)Dt/tau_minus); - w1 = w + fact*Wmax*pow(w/Wmax, mu_minus); + else + { + double fact = -alpha * lambda * exp( ( double ) Dt / tau_minus ); + w1 = w + fact * Wmax * pow( w / Wmax, mu_minus ); } - - w1 = w1 >0.0 ? w1 : 0.0; + + w1 = w1 > 0.0 ? w1 : 0.0; w1 = w1 < Wmax ? w1 : Wmax; - *weight_pt = (float)w1; + *weight_pt = ( float ) w1; } -int STDP::Init() +int +STDP::_Init() { type_ = i_stdp_model; n_param_ = N_PARAM; param_name_ = stdp_param_name; - gpuErrchk(cudaMalloc(&d_param_arr_, n_param_*sizeof(float))); - SetParam("tau_plus", 20.0); - SetParam("tau_minus", 20.0); - SetParam("lambda", 1.0e-4); - SetParam("alpha", 1.0); - SetParam("mu_plus", 1.0); - SetParam("mu_minus", 1.0); - SetParam("Wmax", 100.0); - //SetParam("den_delay", 0.0); + gpuErrchk( cudaMalloc( &d_param_arr_, n_param_ * sizeof( float ) ) ); + SetParam( "tau_plus", 20.0 ); + SetParam( "tau_minus", 20.0 ); + SetParam( "lambda", 1.0e-4 ); + SetParam( "alpha", 1.0 ); + SetParam( "mu_plus", 1.0 ); + SetParam( "mu_minus", 1.0 ); + SetParam( "Wmax", 100.0 ); + // SetParam("den_delay", 0.0); return 0; } diff --git a/src/stdp.h b/src/stdp.h index 97c568b42..97c7e63a1 100644 --- a/src/stdp.h +++ b/src/stdp.h @@ -21,9 +21,6 @@ */ - - - #ifndef STDP_H #define STDP_H @@ -41,7 +38,7 @@ Description The STDP class is a type of synapse model used to create synapses that enable spike timing dependent plasticity -(as defined in [1]_). +(as defined in [1]_). Here the weight dependence exponent can be set separately for potentiation and depression. @@ -72,25 +69,30 @@ References EndUserDocs */ -class STDP : public SynModel +namespace stdp_ns { - public: - STDP() {Init();} - int Init(); +enum ParamIndexes +{ + i_tau_plus = 0, + i_tau_minus, + i_lambda, + i_alpha, + i_mu_plus, + i_mu_minus, + i_Wmax, // i_den_delay, + N_PARAM }; -namespace stdp_ns -{ - enum ParamIndexes { - i_tau_plus = 0, i_tau_minus, i_lambda, i_alpha, i_mu_plus, i_mu_minus, - i_Wmax, // i_den_delay, - N_PARAM - }; - - const std::string stdp_param_name[N_PARAM] = { - "tau_plus", "tau_minus", "lambda", "alpha", "mu_plus", "mu_minus", "Wmax" - //, "den_delay" - }; +const std::string stdp_param_name[ N_PARAM ] = { + "tau_plus", + "tau_minus", + "lambda", + "alpha", + "mu_plus", + "mu_minus", + "Wmax" + //, "den_delay" +}; } diff --git a/src/syn_model.cu b/src/syn_model.cu index 797e76c6f..46d2c1db4 100644 --- a/src/syn_model.cu +++ b/src/syn_model.cu @@ -21,216 +21,241 @@ */ - - - -#include -#include -#include "ngpu_exception.h" #include "cuda_error.h" #include "nestgpu.h" +#include "ngpu_exception.h" +#include "stdp.h" #include "syn_model.h" #include "test_syn_model.h" -#include "stdp.h" +#include +#include -int *d_SynGroupTypeMap; -__device__ int *SynGroupTypeMap; +int* d_SynGroupTypeMap; +__device__ int* SynGroupTypeMap; -float **d_SynGroupParamMap; -__device__ float **SynGroupParamMap; +float** d_SynGroupParamMap; +__device__ float** SynGroupParamMap; -__device__ void TestSynModelUpdate(float *w, float Dt, float *param); +__device__ void TestSynModelUpdate( float* w, float Dt, float* param ); -__device__ void STDPUpdate(float *w, float Dt, float *param); +__device__ void STDPUpdate( float* w, float Dt, float* param ); -__device__ void SynapseUpdate(int syn_group, float *w, float Dt) +__device__ void +SynapseUpdate( int syn_group, float* w, float Dt ) { - int syn_type = SynGroupTypeMap[syn_group-1]; - float *param = SynGroupParamMap[syn_group-1]; - switch(syn_type) { + int syn_type = SynGroupTypeMap[ syn_group - 1 ]; + float* param = SynGroupParamMap[ syn_group - 1 ]; + switch ( syn_type ) + { case i_test_syn_model: - TestSynModelUpdate(w, Dt, param); + TestSynModelUpdate( w, Dt, param ); break; case i_stdp_model: - STDPUpdate(w, Dt, param); + STDPUpdate( w, Dt, param ); break; } } -__global__ void SynGroupInit(int *syn_group_type_map, - float **syn_group_param_map) +__global__ void +SynGroupInit( int* syn_group_type_map, float** syn_group_param_map ) { SynGroupTypeMap = syn_group_type_map; SynGroupParamMap = syn_group_param_map; - } -int SynModel::GetNParam() +int +SynModel::GetNParam() { return n_param_; } -std::vector SynModel::GetParamNames() +std::vector< std::string > +SynModel::GetParamNames() { - std::vector param_name_vect; - for (int i=0; i param_name_vect; + for ( int i = 0; i < n_param_; i++ ) + { + param_name_vect.push_back( param_name_[ i ] ); } - + return param_name_vect; } -bool SynModel::IsParam(std::string param_name) +bool +SynModel::IsParam( std::string param_name ) { int i_param; - for (i_param=0; i_param(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->GetNParam(); + return syn_group_vect_[ syn_group - 1 ]->GetNParam(); } -std::vector NESTGPU::GetSynGroupParamNames(int syn_group) +std::vector< std::string > +NESTGPU::GetSynGroupParamNames( int syn_group ) { - if (syn_group<1 || syn_group>(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->GetParamNames(); + return syn_group_vect_[ syn_group - 1 ]->GetParamNames(); } -bool NESTGPU::IsSynGroupParam(int syn_group, std::string param_name) +bool +NESTGPU::IsSynGroupParam( int syn_group, std::string param_name ) { - if (syn_group<1 || syn_group>(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->IsParam(param_name); + return syn_group_vect_[ syn_group - 1 ]->IsParam( param_name ); } -int NESTGPU::GetSynGroupParamIdx(int syn_group, std::string param_name) +int +NESTGPU::GetSynGroupParamIdx( int syn_group, std::string param_name ) { - if (syn_group<1 || syn_group>(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->GetParamIdx(param_name); + return syn_group_vect_[ syn_group - 1 ]->GetParamIdx( param_name ); } -float NESTGPU::GetSynGroupParam(int syn_group, std::string param_name) +float +NESTGPU::GetSynGroupParam( int syn_group, std::string param_name ) { - if (syn_group<1 || syn_group>(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->GetParam(param_name); + return syn_group_vect_[ syn_group - 1 ]->GetParam( param_name ); } -int NESTGPU::SetSynGroupParam(int syn_group, std::string param_name, - float val) +int +NESTGPU::SetSynGroupParam( int syn_group, std::string param_name, float val ) { - if (syn_group<1 || syn_group>(int)syn_group_vect_.size()) { - throw ngpu_exception("Unrecognized synapse group"); + if ( syn_group < 1 || syn_group > ( int ) syn_group_vect_.size() ) + { + throw ngpu_exception( "Unrecognized synapse group" ); } - return syn_group_vect_[syn_group-1]->SetParam(param_name, val); + return syn_group_vect_[ syn_group - 1 ]->SetParam( param_name, val ); } -int NESTGPU::SynGroupCalibrate() +int +NESTGPU::SynGroupCalibrate() { int n_group = syn_group_vect_.size(); - int *h_SynGroupTypeMap = new int[n_group]; - float **h_SynGroupParamMap = new float*[n_group]; + int* h_SynGroupTypeMap = new int[ n_group ]; + float** h_SynGroupParamMap = new float*[ n_group ]; - for (int syn_group=1; syn_group<=n_group; syn_group++) { - h_SynGroupTypeMap[syn_group-1] = syn_group_vect_[syn_group-1]->type_; - h_SynGroupParamMap[syn_group-1] - = syn_group_vect_[syn_group-1]->d_param_arr_; + for ( int syn_group = 1; syn_group <= n_group; syn_group++ ) + { + h_SynGroupTypeMap[ syn_group - 1 ] = syn_group_vect_[ syn_group - 1 ]->type_; + h_SynGroupParamMap[ syn_group - 1 ] = syn_group_vect_[ syn_group - 1 ]->d_param_arr_; } - gpuErrchk(cudaMalloc(&d_SynGroupTypeMap, n_group*sizeof(int))); - gpuErrchk(cudaMalloc(&d_SynGroupParamMap, n_group*sizeof(float*))); + gpuErrchk( cudaMalloc( &d_SynGroupTypeMap, n_group * sizeof( int ) ) ); + gpuErrchk( cudaMalloc( &d_SynGroupParamMap, n_group * sizeof( float* ) ) ); // Memcopies will be synchronised with SynGroupInit kernel - gpuErrchk(cudaMemcpyAsync(d_SynGroupTypeMap, h_SynGroupTypeMap, - n_group*sizeof(int), cudaMemcpyHostToDevice)); - gpuErrchk(cudaMemcpyAsync(d_SynGroupParamMap, h_SynGroupParamMap, - n_group*sizeof(float*), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMemcpyAsync( d_SynGroupTypeMap, h_SynGroupTypeMap, n_group * sizeof( int ), cudaMemcpyHostToDevice ) ); + gpuErrchk( + cudaMemcpyAsync( d_SynGroupParamMap, h_SynGroupParamMap, n_group * sizeof( float* ), cudaMemcpyHostToDevice ) ); - SynGroupInit<<<1,1>>>(d_SynGroupTypeMap, d_SynGroupParamMap); + SynGroupInit<<< 1, 1 >>>( d_SynGroupTypeMap, d_SynGroupParamMap ); gpuErrchk( cudaPeekAtLastError() ); gpuErrchk( cudaDeviceSynchronize() ); - + delete[] h_SynGroupTypeMap; delete[] h_SynGroupParamMap; diff --git a/src/syn_model.h b/src/syn_model.h index 16570e3ff..5ac4bddfa 100644 --- a/src/syn_model.h +++ b/src/syn_model.h @@ -21,9 +21,6 @@ */ - - - #ifndef SYNMODEL_H #define SYNMODEL_H @@ -31,32 +28,55 @@ #include #define MAX_SYN_DT 16384 -enum SynModels { - i_null_syn_model = 0, i_test_syn_model, i_stdp_model, +enum SynModels +{ + i_null_syn_model = 0, + i_test_syn_model, + i_stdp_model, N_SYN_MODELS }; -const std::string syn_model_name[N_SYN_MODELS] = { - "", "test_syn_model", "stdp" -}; +const std::string syn_model_name[ N_SYN_MODELS ] = { "", "test_syn_model", "stdp" }; class SynModel { - protected: +protected: int type_; int n_param_; - const std::string *param_name_; - float *d_param_arr_; - public: - virtual int Init() {return 0;} + const std::string* param_name_; + float* d_param_arr_; + +public: + virtual int + Init() + { + return 0; + } int GetNParam(); - std::vector GetParamNames(); - bool IsParam(std::string param_name); - int GetParamIdx(std::string param_name); - virtual float GetParam(std::string param_name); - virtual int SetParam(std::string param_name, float val); + std::vector< std::string > GetParamNames(); + bool IsParam( std::string param_name ); + int GetParamIdx( std::string param_name ); + virtual float GetParam( std::string param_name ); + virtual int SetParam( std::string param_name, float val ); friend class NESTGPU; }; +class STDP : public SynModel +{ + int _Init(); + +public: + STDP() + { + _Init(); + } + + int + Init() + { + return _Init(); + } +}; + #endif diff --git a/src/test_syn_model.cu b/src/test_syn_model.cu index a1531e3fb..29b069192 100644 --- a/src/test_syn_model.cu +++ b/src/test_syn_model.cu @@ -21,33 +21,32 @@ */ - - - -#include -#include -#include -#include "ngpu_exception.h" #include "cuda_error.h" +#include "ngpu_exception.h" #include "test_syn_model.h" +#include +#include +#include using namespace test_syn_model_ns; -__device__ void TestSynModelUpdate(float *w, float Dt, float *param) +__device__ void +TestSynModelUpdate( float* w, float Dt, float* param ) { - float fact = param[0]; - float offset = param[1]; - *w += offset + fact*Dt; + float fact = param[ 0 ]; + float offset = param[ 1 ]; + *w += offset + fact * Dt; } -int TestSynModel::Init() +int +TestSynModel::_Init() { type_ = i_test_syn_model; n_param_ = N_PARAM; param_name_ = test_syn_model_param_name; - gpuErrchk(cudaMalloc(&d_param_arr_, n_param_*sizeof(float))); - SetParam("fact", 0.1); - SetParam("offset", 0.0); + gpuErrchk( cudaMalloc( &d_param_arr_, n_param_ * sizeof( float ) ) ); + SetParam( "fact", 0.1 ); + SetParam( "offset", 0.0 ); return 0; } diff --git a/src/test_syn_model.h b/src/test_syn_model.h index d610021f8..eec22d711 100644 --- a/src/test_syn_model.h +++ b/src/test_syn_model.h @@ -21,9 +21,6 @@ */ - - - #ifndef TESTSYNMODEL_H #define TESTSYNMODEL_H @@ -31,21 +28,30 @@ class TestSynModel : public SynModel { - public: - TestSynModel() {Init();} - int Init(); + int _Init(); + +public: + TestSynModel() + { + _Init(); + } + int + Init() + { + return _Init(); + } }; namespace test_syn_model_ns { - enum ParamIndexes { - i_fact = 0, i_offset, - N_PARAM - }; - - const std::string test_syn_model_param_name[N_PARAM] = { - "fact", "offset" - }; +enum ParamIndexes +{ + i_fact = 0, + i_offset, + N_PARAM +}; + +const std::string test_syn_model_param_name[ N_PARAM ] = { "fact", "offset" }; } diff --git a/src/user_m1.cu b/src/user_m1.cu index 77c3056ce..17f9e67c0 100644 --- a/src/user_m1.cu +++ b/src/user_m1.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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 +50,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 user_m1::UpdateNR<0>(long long it, double t1) +int +user_m1::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m1::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m1::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m1.h b/src/user_m1.h index f2192726c..00e678163 100644 --- a/src/user_m1.h +++ b/src/user_m1.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1_H #define USERM1_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m1_cond_alpha.cu b/src/user_m1_cond_alpha.cu index 04daec8f7..56a471332 100644 --- a/src/user_m1_cond_alpha.cu +++ b/src/user_m1_cond_alpha.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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 +50,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 user_m1::UpdateNR<0>(long long it, double t1) +int +user_m1::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m1::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m1::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m1_cond_alpha.h b/src/user_m1_cond_alpha.h index 54f4fc07b..37f65a5a8 100644 --- a/src/user_m1_cond_alpha.h +++ b/src/user_m1_cond_alpha.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1CONDALPHA_H #define USERM1CONDALPHA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m1_cond_alpha_kernel.h b/src/user_m1_cond_alpha_kernel.h index 15f0d8cf5..8ac12ab91 100644 --- a/src/user_m1_cond_alpha_kernel.h +++ b/src/user_m1_cond_alpha_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM1CONDALPHAKERNEL_H #define USERM1CONDALPHAKERNEL_H #include - //#include -#include "spike_buffer.h" +// #include #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_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 +69,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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m1_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -106,117 +101,117 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_syn", - "g0" -}; +const std::string user_m1_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_syn", "g0" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_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, - user_m1_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, user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -226,43 +221,39 @@ __device__ }; template <> -int user_m1::UpdateNR<0>(long long it, double t1); +int user_m1::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m1::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m1::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m1_ns::N_SCAL_VAR - + user_m1_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m1_ns::N_SCAL_PARAM - + user_m1_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m1_ns::N_SCAL_VAR + user_m1_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m1_ns::N_SCAL_PARAM + user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_cond_alpha_rk5.h b/src/user_m1_cond_alpha_rk5.h index b7e2613c8..8459de31e 100644 --- a/src/user_m1_cond_alpha_rk5.h +++ b/src/user_m1_cond_alpha_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1CONDALPHARK5_H #define USERM1CONDALPHARK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m1_cond_beta.cu b/src/user_m1_cond_beta.cu index a621a65b0..d1b82df22 100644 --- a/src/user_m1_cond_beta.cu +++ b/src/user_m1_cond_beta.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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 +50,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 user_m1::UpdateNR<0>(long long it, double t1) +int +user_m1::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m1::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m1::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m1_cond_beta.h b/src/user_m1_cond_beta.h index 87cb0e83b..0d6084b55 100644 --- a/src/user_m1_cond_beta.h +++ b/src/user_m1_cond_beta.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1CONDBETA_H #define USERM1CONDBETA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m1_cond_beta_kernel.h b/src/user_m1_cond_beta_kernel.h index 2d607b4a8..f81f34a48 100644 --- a/src/user_m1_cond_beta_kernel.h +++ b/src/user_m1_cond_beta_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM1CONDBETAKERNEL_H #define USERM1CONDBETAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_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 +69,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -77,25 +78,19 @@ 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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m1_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -108,118 +103,117 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_rise", - "tau_decay", - "g0" -}; +const std::string user_m1_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_rise", "tau_decay", "g0" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_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, - user_m1_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, user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -229,43 +223,39 @@ __device__ }; template <> -int user_m1::UpdateNR<0>(long long it, double t1); +int user_m1::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m1::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m1::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m1_ns::N_SCAL_VAR - + user_m1_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m1_ns::N_SCAL_PARAM - + user_m1_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m1_ns::N_SCAL_VAR + user_m1_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m1_ns::N_SCAL_PARAM + user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_cond_beta_rk5.h b/src/user_m1_cond_beta_rk5.h index d5c9763f3..8589c115a 100644 --- a/src/user_m1_cond_beta_rk5.h +++ b/src/user_m1_cond_beta_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1CONDBETARK5_H #define USERM1CONDBETARK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m1_iaf_psc_exp.cu b/src/user_m1_iaf_psc_exp.cu index a0bb45bc0..06b94cde0 100644 --- a/src/user_m1_iaf_psc_exp.cu +++ b/src/user_m1_iaf_psc_exp.cu @@ -21,90 +21,92 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m1.cpp -#include -#include -#include -#include "user_m1.h" #include "propagator_stability.h" #include "spike_buffer.h" +#include "user_m1.h" +#include +#include +#include using namespace user_m1_ns; extern __constant__ float NESTGPUTimeResolution; -extern __device__ double propagator_32(double, double, double, double); - -#define I_syn_ex var[i_I_syn_ex] -#define I_syn_in var[i_I_syn_in] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] - -#define tau_m param[i_tau_m] -#define C_m param[i_C_m] -#define E_L param[i_E_L] -#define I_e param[i_I_e] -#define Theta_rel param[i_Theta_rel] -#define V_reset_rel param[i_V_reset_rel] -#define tau_ex param[i_tau_ex] -#define tau_in param[i_tau_in] -//#define rho param[i_rho] -//#define delta param[i_delta] -#define t_ref param[i_t_ref] -#define den_delay param[i_den_delay] - -#define P20 param[i_P20] -#define P11ex param[i_P11ex] -#define P11in param[i_P11in] -#define P21ex param[i_P21ex] -#define P21in param[i_P21in] -#define P22 param[i_P22] - -__global__ void user_m1_Calibrate(int n_node, float *param_arr, - int n_param, float h) +extern __device__ double propagator_32( double, double, double, double ); + +#define I_syn_ex var[ i_I_syn_ex ] +#define I_syn_in var[ i_I_syn_in ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] + +#define tau_m param[ i_tau_m ] +#define C_m param[ i_C_m ] +#define E_L param[ i_E_L ] +#define I_e param[ i_I_e ] +#define Theta_rel param[ i_Theta_rel ] +#define V_reset_rel param[ i_V_reset_rel ] +#define tau_ex param[ i_tau_ex ] +#define tau_in param[ i_tau_in ] +// #define rho param[i_rho] +// #define delta param[i_delta] +#define t_ref param[ i_t_ref ] +#define den_delay param[ i_den_delay ] + +#define P20 param[ i_P20 ] +#define P11ex param[ i_P11ex ] +#define P11in param[ i_P11in ] +#define P21ex param[ i_P21ex ] +#define P21in param[ i_P21in ] +#define P22 param[ i_P22 ] + +__global__ void +user_m1_Calibrate( int n_node, float* param_arr, int n_param, float h ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn_ex * P21ex + I_syn_in * P21in + I_e * P20; } // exponential decaying PSCs I_syn_ex *= P11ex; I_syn_in *= P11in; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; - refractory_step = (int)round(t_ref/NESTGPUTimeResolution); - } + refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution ); + } } } @@ -114,87 +116,87 @@ user_m1::~user_m1() FreeParamArr(); } -int user_m1::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m1::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_user_m1_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m1_scal_var_name; scal_param_name_ = user_m1_scal_param_name; - SetScalParam(0, n_node, "tau_m", 10.0 ); // in ms - SetScalParam(0, n_node, "C_m", 250.0 ); // in pF - SetScalParam(0, n_node, "E_L", -70.0 ); // in mV - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "Theta_rel", -55.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "V_reset_rel", -70.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "tau_ex", 2.0 ); // in ms - SetScalParam(0, n_node, "tau_in", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_m", 10.0 ); // in ms + SetScalParam( 0, n_node, "C_m", 250.0 ); // in pF + SetScalParam( 0, n_node, "E_L", -70.0 ); // in mV + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "Theta_rel", -55.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "V_reset_rel", -70.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "tau_ex", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_in", 2.0 ); // in ms // SetScalParam(0, n_node, "rho", 0.01 ); // in 1/s // SetScalParam(0, n_node, "delta", 0.0 ); // in mV - SetScalParam(0, n_node, "t_ref", 2.0 ); // in ms - SetScalParam(0, n_node, "den_delay", 0.0); // in ms - SetScalParam(0, n_node, "P20", 0.0); - SetScalParam(0, n_node, "P11ex", 0.0); - SetScalParam(0, n_node, "P11in", 0.0); - SetScalParam(0, n_node, "P21ex", 0.0); - SetScalParam(0, n_node, "P21in", 0.0); - SetScalParam(0, n_node, "P22", 0.0); - - SetScalVar(0, n_node, "I_syn_ex", 0.0 ); - SetScalVar(0, n_node, "I_syn_in", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", -70.0 - (-70.0) ); // in mV, relative to E_L - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalParam( 0, n_node, "t_ref", 2.0 ); // in ms + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + SetScalParam( 0, n_node, "P20", 0.0 ); + SetScalParam( 0, n_node, "P11ex", 0.0 ); + SetScalParam( 0, n_node, "P11in", 0.0 ); + SetScalParam( 0, n_node, "P21ex", 0.0 ); + SetScalParam( 0, n_node, "P21in", 0.0 ); + SetScalParam( 0, n_node, "P22", 0.0 ); + + SetScalVar( 0, n_node, "I_syn_ex", 0.0 ); + SetScalVar( 0, n_node, "I_syn_in", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", -70.0 - ( -70.0 ) ); // in mV, relative to E_L + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn_ex, I_syn_in - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn_ex"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_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 user_m1::Update(long long it, double t1) +int +user_m1::Update( long long it, double t1 ) { // std::cout << "user_m1 neuron update\n"; - user_m1_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); + user_m1_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); // gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -int user_m1::Free() +int +user_m1::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } -int user_m1::Calibrate(double, float time_resolution) +int +user_m1::Calibrate( double, float time_resolution ) { - user_m1_Calibrate<<<(n_node_+1023)/1024, 1024>>> - (n_node_, param_arr_, n_param_, time_resolution); + user_m1_Calibrate<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, param_arr_, n_param_, time_resolution ); return 0; } diff --git a/src/user_m1_iaf_psc_exp.h b/src/user_m1_iaf_psc_exp.h index 994fcf153..eb49f885e 100644 --- a/src/user_m1_iaf_psc_exp.h +++ b/src/user_m1_iaf_psc_exp.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m1.h @@ -31,37 +28,39 @@ #ifndef USERM1IAFPSCEXP_H #define USERM1IAFPSCEXP_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m1_ns { -enum ScalVarIndexes { - i_I_syn_ex = 0, // postsynaptic current for exc. inputs - i_I_syn_in, // postsynaptic current for inh. inputs - i_V_m_rel, // membrane potential - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn_ex = 0, // postsynaptic current for exc. inputs + i_I_syn_in, // postsynaptic current for inh. inputs + i_V_m_rel, // membrane potential + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_I_e, // External current in pA - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_ex, // Time constant of excitatory synaptic current in ms - i_tau_in, // Time constant of inhibitory synaptic current in ms +enum ScalParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_I_e, // External current in pA + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_ex, // Time constant of excitatory synaptic current in ms + i_tau_in, // Time constant of inhibitory synaptic current in ms // i_rho, // Stochastic firing intensity at threshold in 1/s // i_delta, // Width of threshold region in mV - i_t_ref, // Refractory period in ms + i_t_ref, // Refractory period in ms i_den_delay, // dendritic backpropagation delay // time evolution operator i_P20, @@ -73,17 +72,11 @@ enum ScalParamIndexes { N_SCAL_PARAM }; - -const std::string user_m1_scal_var_name[N_SCAL_VAR] = { - "I_syn_ex", - "I_syn_in", - "V_m_rel", - "refractory_step" -}; + +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex", "I_syn_in", "V_m_rel", "refractory_step" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "tau_m", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "tau_m", "C_m", "E_L", "I_e", @@ -100,25 +93,22 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "P11in", "P21ex", "P21in", - "P22" -}; + "P22" }; } // namespace - + class user_m1 : public BaseNeuron { - public: +public: ~user_m1(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double, float time_resolution); - - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Calibrate( double, float time_resolution ); + int Update( long long it, double t1 ); + + int Free(); }; diff --git a/src/user_m1_iaf_psc_exp_g.cu b/src/user_m1_iaf_psc_exp_g.cu index 2a56e9c79..1bf54e8f9 100644 --- a/src/user_m1_iaf_psc_exp_g.cu +++ b/src/user_m1_iaf_psc_exp_g.cu @@ -21,73 +21,82 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m1.h" #include +#include #include -#include "user_m1.h" -#include "spike_buffer.h" using namespace user_m1_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] - -#define tau_m_ group_param_[i_tau_m] -#define C_m_ group_param_[i_C_m] -#define E_L_ group_param_[i_E_L] -#define Theta_rel_ group_param_[i_Theta_rel] -#define V_reset_rel_ group_param_[i_V_reset_rel] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void user_m1_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float Theta_rel, float V_reset_rel, int n_refractory_steps, - float P11, float P22, float P21, float P20 ) +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] + +#define tau_m_ group_param_[ i_tau_m ] +#define C_m_ group_param_[ i_C_m ] +#define E_L_ group_param_[ i_E_L ] +#define Theta_rel_ group_param_[ i_Theta_rel ] +#define V_reset_rel_ group_param_[ i_V_reset_rel ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +user_m1_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float Theta_rel, + float V_reset_rel, + int n_refractory_steps, + float P11, + float P22, + float P21, + float P20 ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } -double h_propagator_32( double tau_syn, double tau, double C, double h ) +double +h_propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -103,10 +112,10 @@ user_m1::~user_m1() FreeParamArr(); } -int user_m1::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m1::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m1_model; n_scal_var_ = N_SCAL_VAR; @@ -114,46 +123,46 @@ int user_m1::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = user_m1_scal_var_name; scal_param_name_ = user_m1_scal_param_name; group_param_name_ = user_m1_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); - SetGroupParam("tau_m", 10.0); - SetGroupParam("C_m", 250.0); - SetGroupParam("E_L", -65.0); - SetGroupParam("Theta_rel", 15.0); - SetGroupParam("V_reset_rel", 0.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 2.0); + SetGroupParam( "tau_m", 10.0 ); + SetGroupParam( "C_m", 250.0 ); + SetGroupParam( "E_L", -65.0 ); + SetGroupParam( "Theta_rel", 15.0 ); + SetGroupParam( "V_reset_rel", 0.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 2.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m1::Update(long long it, double t1) +int +user_m1::Update( long long it, double t1 ) { // std::cout << "user_m1 neuron update\n"; float h = time_resolution_; @@ -161,21 +170,32 @@ int user_m1::Update(long long it, double t1) float P22 = exp( -h / tau_m_ ); float P21 = h_propagator_32( tau_syn_, tau_m_, C_m_, h ); float P20 = tau_m_ / C_m_ * ( 1.0 - P22 ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + user_m1_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, + i_node_0_, + var_arr_, + param_arr_, + n_var_, + n_param_, + Theta_rel_, + V_reset_rel_, + n_refractory_steps, + P11, + P22, + P21, + P20 ); + // gpuErrchk( cudaDeviceSynchronize() ); - user_m1_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - Theta_rel_, V_reset_rel_, n_refractory_steps, P11, P22, P21, P20 ); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int user_m1::Free() +int +user_m1::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/user_m1_iaf_psc_exp_g.h b/src/user_m1_iaf_psc_exp_g.h index 96d7686f9..b89b2cfd9 100644 --- a/src/user_m1_iaf_psc_exp_g.h +++ b/src/user_m1_iaf_psc_exp_g.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,85 +28,72 @@ #ifndef USERM1IAFPSCEXPG_H #define USERM1IAFPSCEXPG_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m1_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; -enum GroupParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms +enum GroupParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string user_m1_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "tau_m", - "C_m", - "E_L", - "Theta_rel", - "V_reset_rel", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + user_m1_group_param_name[ N_GROUP_PARAM ] = { "tau_m", "C_m", "E_L", "Theta_rel", "V_reset_rel", "tau_syn", "t_ref" }; +} // namespace class user_m1 : public BaseNeuron { float time_resolution_; - public: +public: ~user_m1(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m1_iaf_psc_exp_hc.cu b/src/user_m1_iaf_psc_exp_hc.cu index f0ca56a9a..cdbe339b4 100644 --- a/src/user_m1_iaf_psc_exp_hc.cu +++ b/src/user_m1_iaf_psc_exp_hc.cu @@ -21,50 +21,50 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m1_hc.h" #include +#include #include -#include "user_m1_hc.h" -#include "spike_buffer.h" using namespace user_m1_hc_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] #include "user_m1_hc_params.h" -__global__ void user_m1_hc_Update(int n_node, int i_node_0, - float *var_arr, float *param_arr, - int n_var, int n_param) +__global__ void +user_m1_hc_Update( int n_node, int i_node_0, float* var_arr, float* param_arr, int n_var, int n_param ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } @@ -74,59 +74,60 @@ user_m1_hc::~user_m1_hc() FreeParamArr(); } -int user_m1_hc::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m1_hc::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m1_hc_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m1_hc_scal_var_name; scal_param_name_ = user_m1_hc_scal_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m1_hc::Update(long long it, double t1) +int +user_m1_hc::Update( long long it, double t1 ) { // std::cout << "user_m1_hc neuron update\n"; - user_m1_hc_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaDeviceSynchronize() ); - + user_m1_hc_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int user_m1_hc::Free() +int +user_m1_hc::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } diff --git a/src/user_m1_iaf_psc_exp_hc.h b/src/user_m1_iaf_psc_exp_hc.h index 1dddb8a80..eef1abbe3 100644 --- a/src/user_m1_iaf_psc_exp_hc.h +++ b/src/user_m1_iaf_psc_exp_hc.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m1.h @@ -31,53 +28,47 @@ #ifndef USERM1IAFPSCEXPHC_H #define USERM1IAFPSCEXPHC_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m1_hc_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; - const std::string user_m1_hc_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m1_hc_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m1_hc_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m1_hc_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; } // namespace - + class user_m1_hc : public BaseNeuron { - public: +public: ~user_m1_hc(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m1_kernel.h b/src/user_m1_kernel.h index 377d2147c..ce2f49561 100644 --- a/src/user_m1_kernel.h +++ b/src/user_m1_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM1KERNEL_H #define USERM1KERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_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 +69,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -77,25 +78,19 @@ 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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m1_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -108,118 +103,117 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_rise", - "tau_decay", - "g0" -}; +const std::string user_m1_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_rise", "tau_decay", "g0" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_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, - user_m1_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, user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -229,43 +223,39 @@ __device__ }; template <> -int user_m1::UpdateNR<0>(long long it, double t1); +int user_m1::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m1::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m1::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m1_ns::N_SCAL_VAR - + user_m1_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m1_ns::N_SCAL_PARAM - + user_m1_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m1_ns::N_SCAL_VAR + user_m1_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m1_ns::N_SCAL_PARAM + user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_psc_alpha.cu b/src/user_m1_psc_alpha.cu index 719f8f8b3..40e608eda 100644 --- a/src/user_m1_psc_alpha.cu +++ b/src/user_m1_psc_alpha.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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 +50,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 user_m1::UpdateNR<0>(long long it, double t1) +int +user_m1::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m1::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m1::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m1_psc_alpha.h b/src/user_m1_psc_alpha.h index 26753e4f3..0e44fec32 100644 --- a/src/user_m1_psc_alpha.h +++ b/src/user_m1_psc_alpha.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1PSCALPHA_H #define USERM1PSCALPHA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m1_psc_alpha_kernel.h b/src/user_m1_psc_alpha_kernel.h index e866044ab..3e39b5a16 100644 --- a/src/user_m1_psc_alpha_kernel.h +++ b/src/user_m1_psc_alpha_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM1PSCALPHAKERNEL_H #define USERM1PSCALPHAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_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 +69,26 @@ 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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_port_var_name[N_PORT_VAR] = { - "I_syn", - "I1_syn" -}; +const std::string user_m1_port_var_name[ N_PORT_VAR ] = { "I_syn", "I1_syn" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -106,115 +101,116 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_port_param_name[N_PORT_PARAM] = { - "tau_syn", - "I0" -}; +const std::string user_m1_port_param_name[ N_PORT_PARAM ] = { "tau_syn", "I0" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_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, - user_m1_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, user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -224,43 +220,39 @@ __device__ }; template <> -int user_m1::UpdateNR<0>(long long it, double t1); +int user_m1::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m1::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m1::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m1_ns::N_SCAL_VAR - + user_m1_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m1_ns::N_SCAL_PARAM - + user_m1_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m1_ns::N_SCAL_VAR + user_m1_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m1_ns::N_SCAL_PARAM + user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_psc_alpha_rk5.h b/src/user_m1_psc_alpha_rk5.h index 328ec8532..80c7671cb 100644 --- a/src/user_m1_psc_alpha_rk5.h +++ b/src/user_m1_psc_alpha_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1PSCALPHARK5_H #define USERM1PSCALPHARK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m1_psc_delta.cu b/src/user_m1_psc_delta.cu index 583d2a5d7..a9edf655d 100644 --- a/src/user_m1_psc_delta.cu +++ b/src/user_m1_psc_delta.cu @@ -21,24 +21,20 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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 +49,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, user_m1_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_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. } } } -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::NodeInit(n_var, n_param, x, y, param, data_struct); + user_m1_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, user_m1_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct); + user_m1_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct ); } using namespace user_m1_ns; -int user_m1::Init(int i_node_0, int n_node, int n_port, - int i_group, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, n_port, i_group, seed); +int +user_m1::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, n_port, i_group, seed ); node_type_ = i_user_m1_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_ = user_m1_scal_var_name; scal_param_name_ = user_m1_scal_param_name; group_param_name_ = user_m1_group_param_name; - //rk5_data_struct_.node_type_ = i_user_m1_model; + // rk5_data_struct_.node_type_ = i_user_m1_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; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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 user_m1::Calibrate(double time_min, float time_resolution) +int +user_m1::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 user_m1::Update(long long it, double t1) +int +user_m1::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/user_m1_psc_delta.h b/src/user_m1_psc_delta.h index 7495ac3f7..a566927bc 100644 --- a/src/user_m1_psc_delta.h +++ b/src/user_m1_psc_delta.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1PSCDELTA_H #define USERM1PSCDELTA_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 #define MAX_PORT_NUM 20 @@ -44,27 +41,29 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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 ); } - }; #endif diff --git a/src/user_m1_psc_delta_kernel.h b/src/user_m1_psc_delta_kernel.h index 212c79a1d..762b68b2f 100644 --- a/src/user_m1_psc_delta_kernel.h +++ b/src/user_m1_psc_delta_kernel.h @@ -21,35 +21,35 @@ */ - - - #ifndef USERM1PSCDELTAKERNEL_H #define USERM1PSCDELTAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ N_PORT_VAR = 0 }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -67,20 +67,17 @@ 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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -93,13 +90,9 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" }; // @@ -107,80 +100,83 @@ const std::string user_m1_group_param_name[N_GROUP_PARAM] = { // 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 dVdt dydx[i_V_m] -#define dwdt dydx[i_w] - -#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, - user_m1_rk5 data_struct) +#define V_m y[ i_V_m ] +#define w y[ i_w ] + +#define dVdt dydx[ i_V_m ] +#define dwdt dydx[ i_w ] + +#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, user_m1_rk5 data_struct ) { - - float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak); - float V_spike = Delta_T == 0. ? 0. : Delta_T*exp((V - V_th)/Delta_T); + float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak ); + + 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) - w + I_e) / C_m; + dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) - w + I_e ) / C_m; // Adaptation current w. - dwdt = (a*(V - E_L) - w) / tau_w; + dwdt = ( a * ( V - E_L ) - w ) / tau_w; } - template //, class DataStruct> -__device__ - void ExternalUpdate - (double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -190,23 +186,18 @@ __device__ }; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_psc_delta_rk5.h b/src/user_m1_psc_delta_rk5.h index 0ea128b9d..78cda0049 100644 --- a/src/user_m1_psc_delta_rk5.h +++ b/src/user_m1_psc_delta_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1PSCDELTARK5_H #define USERM1PSCDELTARK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m1_psc_exp.cu b/src/user_m1_psc_exp.cu index f62ffc914..6d941b5e3 100644 --- a/src/user_m1_psc_exp.cu +++ b/src/user_m1_psc_exp.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m1_kernel.h" #include "rk5.h" #include "user_m1.h" +#include "user_m1_kernel.h" +#include +#include +#include namespace user_m1_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m1_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_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,52 +50,52 @@ 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 user_m1::UpdateNR<0>(long long it, double t1) +int +user_m1::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m1::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m1::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m1_psc_exp.h b/src/user_m1_psc_exp.h index f228ad9e0..356f05ebc 100644 --- a/src/user_m1_psc_exp.h +++ b/src/user_m1_psc_exp.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM1PSCEXP_H #define USERM1PSCEXP_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m1_rk5 class user_m1 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m1_rk5 > rk5_; float h_min_; float h_; user_m1_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m1_psc_exp_g.cu b/src/user_m1_psc_exp_g.cu index 01a460060..365850075 100644 --- a/src/user_m1_psc_exp_g.cu +++ b/src/user_m1_psc_exp_g.cu @@ -21,73 +21,82 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m1.h" #include +#include #include -#include "user_m1.h" -#include "spike_buffer.h" using namespace user_m1_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] - -#define tau_m_ group_param_[i_tau_m] -#define C_m_ group_param_[i_C_m] -#define E_L_ group_param_[i_E_L] -#define Theta_rel_ group_param_[i_Theta_rel] -#define V_reset_rel_ group_param_[i_V_reset_rel] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void user_m1_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float Theta_rel, float V_reset_rel, int n_refractory_steps, - float P11, float P22, float P21, float P20 ) +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] + +#define tau_m_ group_param_[ i_tau_m ] +#define C_m_ group_param_[ i_C_m ] +#define E_L_ group_param_[ i_E_L ] +#define Theta_rel_ group_param_[ i_Theta_rel ] +#define V_reset_rel_ group_param_[ i_V_reset_rel ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +user_m1_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float Theta_rel, + float V_reset_rel, + int n_refractory_steps, + float P11, + float P22, + float P21, + float P20 ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } -double h_propagator_32( double tau_syn, double tau, double C, double h ) +double +h_propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -103,10 +112,10 @@ user_m1::~user_m1() FreeParamArr(); } -int user_m1::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m1::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m1_model; n_scal_var_ = N_SCAL_VAR; @@ -114,46 +123,46 @@ int user_m1::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = user_m1_scal_var_name; scal_param_name_ = user_m1_scal_param_name; group_param_name_ = user_m1_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); - SetGroupParam("tau_m", 10.0); - SetGroupParam("C_m", 250.0); - SetGroupParam("E_L", -65.0); - SetGroupParam("Theta_rel", 15.0); - SetGroupParam("V_reset_rel", 0.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 2.0); + SetGroupParam( "tau_m", 10.0 ); + SetGroupParam( "C_m", 250.0 ); + SetGroupParam( "E_L", -65.0 ); + SetGroupParam( "Theta_rel", 15.0 ); + SetGroupParam( "V_reset_rel", 0.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 2.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m1::Update(long long it, double t1) +int +user_m1::Update( long long it, double t1 ) { // std::cout << "user_m1 neuron update\n"; float h = time_resolution_; @@ -161,21 +170,32 @@ int user_m1::Update(long long it, double t1) float P22 = exp( -h / tau_m_ ); float P21 = h_propagator_32( tau_syn_, tau_m_, C_m_, h ); float P20 = tau_m_ / C_m_ * ( 1.0 - P22 ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + user_m1_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, + i_node_0_, + var_arr_, + param_arr_, + n_var_, + n_param_, + Theta_rel_, + V_reset_rel_, + n_refractory_steps, + P11, + P22, + P21, + P20 ); + // gpuErrchk( cudaDeviceSynchronize() ); - user_m1_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - Theta_rel_, V_reset_rel_, n_refractory_steps, P11, P22, P21, P20 ); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int user_m1::Free() +int +user_m1::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/user_m1_psc_exp_g.h b/src/user_m1_psc_exp_g.h index e01eefb03..23b3926f0 100644 --- a/src/user_m1_psc_exp_g.h +++ b/src/user_m1_psc_exp_g.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,85 +28,72 @@ #ifndef USERM1PSCEXPG_H #define USERM1PSCEXPG_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m1_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; -enum GroupParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms +enum GroupParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string user_m1_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "tau_m", - "C_m", - "E_L", - "Theta_rel", - "V_reset_rel", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + user_m1_group_param_name[ N_GROUP_PARAM ] = { "tau_m", "C_m", "E_L", "Theta_rel", "V_reset_rel", "tau_syn", "t_ref" }; +} // namespace class user_m1 : public BaseNeuron { float time_resolution_; - public: +public: ~user_m1(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m1_psc_exp_hc.cu b/src/user_m1_psc_exp_hc.cu index 15e7624d6..add37fcf8 100644 --- a/src/user_m1_psc_exp_hc.cu +++ b/src/user_m1_psc_exp_hc.cu @@ -21,50 +21,50 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m1_hc.h" #include +#include #include -#include "user_m1_hc.h" -#include "spike_buffer.h" using namespace user_m1_hc_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] #include "user_m1_hc_params.h" -__global__ void user_m1_hc_Update(int n_node, int i_node_0, - float *var_arr, float *param_arr, - int n_var, int n_param) +__global__ void +user_m1_hc_Update( int n_node, int i_node_0, float* var_arr, float* param_arr, int n_var, int n_param ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } @@ -74,59 +74,60 @@ user_m1_hc::~user_m1_hc() FreeParamArr(); } -int user_m1_hc::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m1_hc::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m1_hc_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m1_hc_scal_var_name; scal_param_name_ = user_m1_hc_scal_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m1_hc::Update(long long it, double t1) +int +user_m1_hc::Update( long long it, double t1 ) { // std::cout << "user_m1_hc neuron update\n"; - user_m1_hc_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaDeviceSynchronize() ); - + user_m1_hc_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int user_m1_hc::Free() +int +user_m1_hc::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } diff --git a/src/user_m1_psc_exp_hc.h b/src/user_m1_psc_exp_hc.h index bc2974cfc..1f49c7dd6 100644 --- a/src/user_m1_psc_exp_hc.h +++ b/src/user_m1_psc_exp_hc.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m1.h @@ -31,53 +28,47 @@ #ifndef USERM1PSCEXPHC_H #define USERM1PSCEXPHC_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m1_hc_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; - const std::string user_m1_hc_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m1_hc_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m1_hc_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m1_hc_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; } // namespace - + class user_m1_hc : public BaseNeuron { - public: +public: ~user_m1_hc(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m1_psc_exp_kernel.h b/src/user_m1_psc_exp_kernel.h index 7133ff8c4..7b7f9f5d2 100644 --- a/src/user_m1_psc_exp_kernel.h +++ b/src/user_m1_psc_exp_kernel.h @@ -21,36 +21,36 @@ */ - - - #ifndef USERM1PSCEXPKERNEL_H #define USERM1PSCEXPKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m1.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m1_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ i_I_syn = 0, N_PORT_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -68,28 +68,24 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_tau_syn = 0, 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 user_m1_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m1_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m1_port_var_name[N_PORT_VAR] = { - "I_syn" -}; +const std::string user_m1_port_var_name[ N_PORT_VAR ] = { "I_syn" }; -const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m1_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -102,110 +98,114 @@ const std::string user_m1_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m1_port_param_name[N_PORT_PARAM] = { +const std::string user_m1_port_param_name[ N_PORT_PARAM ] = { "tau_syn", }; -const std::string user_m1_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m1_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 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 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, - user_m1_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 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 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, user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_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; } } } @@ -215,43 +215,39 @@ __device__ }; template <> -int user_m1::UpdateNR<0>(long long it, double t1); +int user_m1::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m1::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m1::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m1_ns::N_SCAL_VAR - + user_m1_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m1_ns::N_SCAL_PARAM - + user_m1_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m1_ns::N_SCAL_VAR + user_m1_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m1_ns::N_SCAL_PARAM + user_m1_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, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ) { - user_m1_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m1_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ) { - user_m1_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m1_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m1_psc_exp_rk5.h b/src/user_m1_psc_exp_rk5.h index 48c513bbd..d45c7f19f 100644 --- a/src/user_m1_psc_exp_rk5.h +++ b/src/user_m1_psc_exp_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1PSCEXPRK5_H #define USERM1PSCEXPRK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m1_rk5.h b/src/user_m1_rk5.h index 2692c5b69..522d10bb1 100644 --- a/src/user_m1_rk5.h +++ b/src/user_m1_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM1RK5_H #define USERM1RK5_H struct user_m1_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m1_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m1_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m1_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m1_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m1_rk5 data_struct ); #endif diff --git a/src/user_m2.cu b/src/user_m2.cu index accb9bd9e..0e7ade3cb 100644 --- a/src/user_m2.cu +++ b/src/user_m2.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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 +50,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 user_m2::UpdateNR<0>(long long it, double t1) +int +user_m2::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m2::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m2::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m2.h b/src/user_m2.h index 7efc647c0..37c166905 100644 --- a/src/user_m2.h +++ b/src/user_m2.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2_H #define USERM2_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m2_cond_alpha.cu b/src/user_m2_cond_alpha.cu index b88aaf1a9..f1dcf3ffd 100644 --- a/src/user_m2_cond_alpha.cu +++ b/src/user_m2_cond_alpha.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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 +50,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 user_m2::UpdateNR<0>(long long it, double t1) +int +user_m2::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m2::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m2::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m2_cond_alpha.h b/src/user_m2_cond_alpha.h index d727b12da..7c9c1b9cf 100644 --- a/src/user_m2_cond_alpha.h +++ b/src/user_m2_cond_alpha.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2CONDALPHA_H #define USERM2CONDALPHA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m2_cond_alpha_kernel.h b/src/user_m2_cond_alpha_kernel.h index 67163e4bd..93b7702f1 100644 --- a/src/user_m2_cond_alpha_kernel.h +++ b/src/user_m2_cond_alpha_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM2CONDALPHAKERNEL_H #define USERM2CONDALPHAKERNEL_H #include - //#include -#include "spike_buffer.h" +// #include #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_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 +69,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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m2_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -106,117 +101,117 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_syn", - "g0" -}; +const std::string user_m2_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_syn", "g0" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_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, - user_m2_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, user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -226,43 +221,39 @@ __device__ }; template <> -int user_m2::UpdateNR<0>(long long it, double t1); +int user_m2::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m2::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m2::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m2_ns::N_SCAL_VAR - + user_m2_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m2_ns::N_SCAL_PARAM - + user_m2_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m2_ns::N_SCAL_VAR + user_m2_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m2_ns::N_SCAL_PARAM + user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_cond_alpha_rk5.h b/src/user_m2_cond_alpha_rk5.h index 818673aa3..bbddfce55 100644 --- a/src/user_m2_cond_alpha_rk5.h +++ b/src/user_m2_cond_alpha_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2CONDALPHARK5_H #define USERM2CONDALPHARK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif diff --git a/src/user_m2_cond_beta.cu b/src/user_m2_cond_beta.cu index 61a4cd390..d4440d9fe 100644 --- a/src/user_m2_cond_beta.cu +++ b/src/user_m2_cond_beta.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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 +50,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 user_m2::UpdateNR<0>(long long it, double t1) +int +user_m2::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m2::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m2::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m2_cond_beta.h b/src/user_m2_cond_beta.h index 32ff7723b..3d2b22dd3 100644 --- a/src/user_m2_cond_beta.h +++ b/src/user_m2_cond_beta.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2CONDBETA_H #define USERM2CONDBETA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m2_cond_beta_kernel.h b/src/user_m2_cond_beta_kernel.h index 914adb95c..fd935e5d6 100644 --- a/src/user_m2_cond_beta_kernel.h +++ b/src/user_m2_cond_beta_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM2CONDBETAKERNEL_H #define USERM2CONDBETAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_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 +69,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -77,25 +78,19 @@ 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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m2_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -108,118 +103,117 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_rise", - "tau_decay", - "g0" -}; +const std::string user_m2_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_rise", "tau_decay", "g0" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_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, - user_m2_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, user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -229,43 +223,39 @@ __device__ }; template <> -int user_m2::UpdateNR<0>(long long it, double t1); +int user_m2::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m2::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m2::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m2_ns::N_SCAL_VAR - + user_m2_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m2_ns::N_SCAL_PARAM - + user_m2_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m2_ns::N_SCAL_VAR + user_m2_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m2_ns::N_SCAL_PARAM + user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_cond_beta_rk5.h b/src/user_m2_cond_beta_rk5.h index b45fc9610..5f7b9784c 100644 --- a/src/user_m2_cond_beta_rk5.h +++ b/src/user_m2_cond_beta_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2CONDBETARK5_H #define USERM2CONDBETARK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif diff --git a/src/user_m2_iaf_psc_exp.cu b/src/user_m2_iaf_psc_exp.cu index d09af4694..22ee984c2 100644 --- a/src/user_m2_iaf_psc_exp.cu +++ b/src/user_m2_iaf_psc_exp.cu @@ -21,92 +21,93 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m2.cpp -#include -#include -#include -#include "user_m2.h" #include "propagator_stability.h" #include "spike_buffer.h" +#include "user_m2.h" +#include +#include +#include using namespace user_m2_ns; extern __constant__ float NESTGPUTimeResolution; -extern __device__ double propagator_32(double, double, double, double); - -#define I_syn_ex var[i_I_syn_ex] -#define I_syn_in var[i_I_syn_in] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] - -#define tau_m param[i_tau_m] -#define C_m param[i_C_m] -#define E_L param[i_E_L] -#define I_e param[i_I_e] -#define Theta_rel param[i_Theta_rel] -#define V_reset_rel param[i_V_reset_rel] -#define tau_ex param[i_tau_ex] -#define tau_in param[i_tau_in] -//#define rho param[i_rho] -//#define delta param[i_delta] -#define t_ref param[i_t_ref] -#define den_delay param[i_den_delay] - -#define P20 param[i_P20] -#define P11ex param[i_P11ex] -#define P11in param[i_P11in] -#define P21ex param[i_P21ex] -#define P21in param[i_P21in] -#define P22 param[i_P22] - - - -__global__ void user_m2_Calibrate(int n_node, float *param_arr, - int n_param, float h) +extern __device__ double propagator_32( double, double, double, double ); + +#define I_syn_ex var[ i_I_syn_ex ] +#define I_syn_in var[ i_I_syn_in ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] + +#define tau_m param[ i_tau_m ] +#define C_m param[ i_C_m ] +#define E_L param[ i_E_L ] +#define I_e param[ i_I_e ] +#define Theta_rel param[ i_Theta_rel ] +#define V_reset_rel param[ i_V_reset_rel ] +#define tau_ex param[ i_tau_ex ] +#define tau_in param[ i_tau_in ] +// #define rho param[i_rho] +// #define delta param[i_delta] +#define t_ref param[ i_t_ref ] +#define den_delay param[ i_den_delay ] + +#define P20 param[ i_P20 ] +#define P11ex param[ i_P11ex ] +#define P11in param[ i_P11in ] +#define P21ex param[ i_P21ex ] +#define P21in param[ i_P21in ] +#define P22 param[ i_P22 ] + + +__global__ void +user_m2_Calibrate( int n_node, float* param_arr, int n_param, float h ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn_ex * P21ex + I_syn_in * P21in + I_e * P20; } // exponential decaying PSCs I_syn_ex *= P11ex; I_syn_in *= P11in; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; - refractory_step = (int)round(t_ref/NESTGPUTimeResolution); - } + refractory_step = ( int ) round( t_ref / NESTGPUTimeResolution ); + } } } @@ -116,87 +117,87 @@ user_m2::~user_m2() FreeParamArr(); } -int user_m2::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m2::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 2 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 2 /*n_port*/, i_group, seed ); node_type_ = i_user_m2_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m2_scal_var_name; scal_param_name_ = user_m2_scal_param_name; - SetScalParam(0, n_node, "tau_m", 10.0 ); // in ms - SetScalParam(0, n_node, "C_m", 250.0 ); // in pF - SetScalParam(0, n_node, "E_L", -70.0 ); // in mV - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA - SetScalParam(0, n_node, "Theta_rel", -55.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "V_reset_rel", -70.0 - (-70.0) ); // relative to E_L_ - SetScalParam(0, n_node, "tau_ex", 2.0 ); // in ms - SetScalParam(0, n_node, "tau_in", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_m", 10.0 ); // in ms + SetScalParam( 0, n_node, "C_m", 250.0 ); // in pF + SetScalParam( 0, n_node, "E_L", -70.0 ); // in mV + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "Theta_rel", -55.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "V_reset_rel", -70.0 - ( -70.0 ) ); // relative to E_L_ + SetScalParam( 0, n_node, "tau_ex", 2.0 ); // in ms + SetScalParam( 0, n_node, "tau_in", 2.0 ); // in ms // SetScalParam(0, n_node, "rho", 0.01 ); // in 1/s // SetScalParam(0, n_node, "delta", 0.0 ); // in mV - SetScalParam(0, n_node, "t_ref", 2.0 ); // in ms - SetScalParam(0, n_node, "den_delay", 0.0); // in ms - SetScalParam(0, n_node, "P20", 0.0); - SetScalParam(0, n_node, "P11ex", 0.0); - SetScalParam(0, n_node, "P11in", 0.0); - SetScalParam(0, n_node, "P21ex", 0.0); - SetScalParam(0, n_node, "P21in", 0.0); - SetScalParam(0, n_node, "P22", 0.0); - - SetScalVar(0, n_node, "I_syn_ex", 0.0 ); - SetScalVar(0, n_node, "I_syn_in", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", -70.0 - (-70.0) ); // in mV, relative to E_L - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalParam( 0, n_node, "t_ref", 2.0 ); // in ms + SetScalParam( 0, n_node, "den_delay", 0.0 ); // in ms + SetScalParam( 0, n_node, "P20", 0.0 ); + SetScalParam( 0, n_node, "P11ex", 0.0 ); + SetScalParam( 0, n_node, "P11in", 0.0 ); + SetScalParam( 0, n_node, "P21ex", 0.0 ); + SetScalParam( 0, n_node, "P21in", 0.0 ); + SetScalParam( 0, n_node, "P22", 0.0 ); + + SetScalVar( 0, n_node, "I_syn_ex", 0.0 ); + SetScalVar( 0, n_node, "I_syn_in", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", -70.0 - ( -70.0 ) ); // in mV, relative to E_L + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn_ex, I_syn_in - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn_ex"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_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 user_m2::Update(long long it, double t1) +int +user_m2::Update( long long it, double t1 ) { // std::cout << "user_m2 neuron update\n"; - user_m2_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); + user_m2_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); // gpuErrchk( cudaDeviceSynchronize() ); - + return 0; } -int user_m2::Free() +int +user_m2::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } -int user_m2::Calibrate(double, float time_resolution) +int +user_m2::Calibrate( double, float time_resolution ) { - user_m2_Calibrate<<<(n_node_+1023)/1024, 1024>>> - (n_node_, param_arr_, n_param_, time_resolution); + user_m2_Calibrate<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, param_arr_, n_param_, time_resolution ); return 0; } diff --git a/src/user_m2_iaf_psc_exp.h b/src/user_m2_iaf_psc_exp.h index e29462d9d..af3c0668c 100644 --- a/src/user_m2_iaf_psc_exp.h +++ b/src/user_m2_iaf_psc_exp.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m2.h @@ -31,37 +28,39 @@ #ifndef USERM2IAFPSCEXP_H #define USERM2IAFPSCEXP_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m2_ns { -enum ScalVarIndexes { - i_I_syn_ex = 0, // postsynaptic current for exc. inputs - i_I_syn_in, // postsynaptic current for inh. inputs - i_V_m_rel, // membrane potential - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn_ex = 0, // postsynaptic current for exc. inputs + i_I_syn_in, // postsynaptic current for inh. inputs + i_V_m_rel, // membrane potential + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_I_e, // External current in pA - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_ex, // Time constant of excitatory synaptic current in ms - i_tau_in, // Time constant of inhibitory synaptic current in ms +enum ScalParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_I_e, // External current in pA + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTAIL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_ex, // Time constant of excitatory synaptic current in ms + i_tau_in, // Time constant of inhibitory synaptic current in ms // i_rho, // Stochastic firing intensity at threshold in 1/s // i_delta, // Width of threshold region in mV - i_t_ref, // Refractory period in ms + i_t_ref, // Refractory period in ms i_den_delay, // dendritic backpropagation delay // time evolution operator i_P20, @@ -73,17 +72,11 @@ enum ScalParamIndexes { N_SCAL_PARAM }; - -const std::string user_m2_scal_var_name[N_SCAL_VAR] = { - "I_syn_ex", - "I_syn_in", - "V_m_rel", - "refractory_step" -}; + +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "I_syn_ex", "I_syn_in", "V_m_rel", "refractory_step" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "tau_m", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "tau_m", "C_m", "E_L", "I_e", @@ -100,25 +93,22 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "P11in", "P21ex", "P21in", - "P22" -}; + "P22" }; } // namespace - + class user_m2 : public BaseNeuron { - public: +public: ~user_m2(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double, float time_resolution); - - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Calibrate( double, float time_resolution ); + int Update( long long it, double t1 ); + + int Free(); }; diff --git a/src/user_m2_iaf_psc_exp_g.cu b/src/user_m2_iaf_psc_exp_g.cu index 22a7e3393..ba44a571c 100644 --- a/src/user_m2_iaf_psc_exp_g.cu +++ b/src/user_m2_iaf_psc_exp_g.cu @@ -21,73 +21,82 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m2.h" #include +#include #include -#include "user_m2.h" -#include "spike_buffer.h" using namespace user_m2_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] - -#define tau_m_ group_param_[i_tau_m] -#define C_m_ group_param_[i_C_m] -#define E_L_ group_param_[i_E_L] -#define Theta_rel_ group_param_[i_Theta_rel] -#define V_reset_rel_ group_param_[i_V_reset_rel] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void user_m2_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float Theta_rel, float V_reset_rel, int n_refractory_steps, - float P11, float P22, float P21, float P20 ) +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] + +#define tau_m_ group_param_[ i_tau_m ] +#define C_m_ group_param_[ i_C_m ] +#define E_L_ group_param_[ i_E_L ] +#define Theta_rel_ group_param_[ i_Theta_rel ] +#define V_reset_rel_ group_param_[ i_V_reset_rel ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +user_m2_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float Theta_rel, + float V_reset_rel, + int n_refractory_steps, + float P11, + float P22, + float P21, + float P20 ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } -double h_propagator_32( double tau_syn, double tau, double C, double h ) +double +h_propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -103,10 +112,10 @@ user_m2::~user_m2() FreeParamArr(); } -int user_m2::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m2::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m2_model; n_scal_var_ = N_SCAL_VAR; @@ -114,46 +123,46 @@ int user_m2::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = user_m2_scal_var_name; scal_param_name_ = user_m2_scal_param_name; group_param_name_ = user_m2_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); - SetGroupParam("tau_m", 10.0); - SetGroupParam("C_m", 250.0); - SetGroupParam("E_L", -65.0); - SetGroupParam("Theta_rel", 15.0); - SetGroupParam("V_reset_rel", 0.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 2.0); + SetGroupParam( "tau_m", 10.0 ); + SetGroupParam( "C_m", 250.0 ); + SetGroupParam( "E_L", -65.0 ); + SetGroupParam( "Theta_rel", 15.0 ); + SetGroupParam( "V_reset_rel", 0.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 2.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m2::Update(long long it, double t1) +int +user_m2::Update( long long it, double t1 ) { // std::cout << "user_m2 neuron update\n"; float h = time_resolution_; @@ -161,21 +170,32 @@ int user_m2::Update(long long it, double t1) float P22 = exp( -h / tau_m_ ); float P21 = h_propagator_32( tau_syn_, tau_m_, C_m_, h ); float P20 = tau_m_ / C_m_ * ( 1.0 - P22 ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + user_m2_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, + i_node_0_, + var_arr_, + param_arr_, + n_var_, + n_param_, + Theta_rel_, + V_reset_rel_, + n_refractory_steps, + P11, + P22, + P21, + P20 ); + // gpuErrchk( cudaDeviceSynchronize() ); - user_m2_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - Theta_rel_, V_reset_rel_, n_refractory_steps, P11, P22, P21, P20 ); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int user_m2::Free() +int +user_m2::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/user_m2_iaf_psc_exp_g.h b/src/user_m2_iaf_psc_exp_g.h index 00eb07ba0..d4e83bb28 100644 --- a/src/user_m2_iaf_psc_exp_g.h +++ b/src/user_m2_iaf_psc_exp_g.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,85 +28,72 @@ #ifndef USERM2IAFPSCEXPG_H #define USERM2IAFPSCEXPG_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m2_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; -enum GroupParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms +enum GroupParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string user_m2_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "tau_m", - "C_m", - "E_L", - "Theta_rel", - "V_reset_rel", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + user_m2_group_param_name[ N_GROUP_PARAM ] = { "tau_m", "C_m", "E_L", "Theta_rel", "V_reset_rel", "tau_syn", "t_ref" }; +} // namespace class user_m2 : public BaseNeuron { float time_resolution_; - public: +public: ~user_m2(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m2_iaf_psc_exp_hc.cu b/src/user_m2_iaf_psc_exp_hc.cu index 4b20ebb0a..ea3c8eb39 100644 --- a/src/user_m2_iaf_psc_exp_hc.cu +++ b/src/user_m2_iaf_psc_exp_hc.cu @@ -21,50 +21,50 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m2_hc.h" #include +#include #include -#include "user_m2_hc.h" -#include "spike_buffer.h" using namespace user_m2_hc_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] #include "user_m2_hc_params.h" -__global__ void user_m2_hc_Update(int n_node, int i_node_0, - float *var_arr, float *param_arr, - int n_var, int n_param) +__global__ void +user_m2_hc_Update( int n_node, int i_node_0, float* var_arr, float* param_arr, int n_var, int n_param ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } @@ -74,59 +74,60 @@ user_m2_hc::~user_m2_hc() FreeParamArr(); } -int user_m2_hc::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m2_hc::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m2_hc_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m2_hc_scal_var_name; scal_param_name_ = user_m2_hc_scal_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m2_hc::Update(long long it, double t1) +int +user_m2_hc::Update( long long it, double t1 ) { // std::cout << "user_m2_hc neuron update\n"; - user_m2_hc_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaDeviceSynchronize() ); - + user_m2_hc_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int user_m2_hc::Free() +int +user_m2_hc::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } diff --git a/src/user_m2_iaf_psc_exp_hc.h b/src/user_m2_iaf_psc_exp_hc.h index c3307c56b..df45007bb 100644 --- a/src/user_m2_iaf_psc_exp_hc.h +++ b/src/user_m2_iaf_psc_exp_hc.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m2.h @@ -31,53 +28,47 @@ #ifndef USERM2IAFPSCEXPHC_H #define USERM2IAFPSCEXPHC_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m2_hc_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; - const std::string user_m2_hc_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m2_hc_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m2_hc_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m2_hc_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; } // namespace - + class user_m2_hc : public BaseNeuron { - public: +public: ~user_m2_hc(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m2_kernel.h b/src/user_m2_kernel.h index 4648b3a84..4741a7514 100644 --- a/src/user_m2_kernel.h +++ b/src/user_m2_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM2KERNEL_H #define USERM2KERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_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 +69,8 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_E_rev = 0, i_tau_rise, i_tau_decay, @@ -77,25 +78,19 @@ 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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_port_var_name[N_PORT_VAR] = { - "g", - "g1" -}; +const std::string user_m2_port_var_name[ N_PORT_VAR ] = { "g", "g1" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -108,118 +103,117 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_port_param_name[N_PORT_PARAM] = { - "E_rev", - "tau_rise", - "tau_decay", - "g0" -}; +const std::string user_m2_port_param_name[ N_PORT_PARAM ] = { "E_rev", "tau_rise", "tau_decay", "g0" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_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, - user_m2_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, user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -229,43 +223,39 @@ __device__ }; template <> -int user_m2::UpdateNR<0>(long long it, double t1); +int user_m2::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m2::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m2::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m2_ns::N_SCAL_VAR - + user_m2_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m2_ns::N_SCAL_PARAM - + user_m2_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m2_ns::N_SCAL_VAR + user_m2_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m2_ns::N_SCAL_PARAM + user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_psc_alpha.cu b/src/user_m2_psc_alpha.cu index 54ce67729..078fb0779 100644 --- a/src/user_m2_psc_alpha.cu +++ b/src/user_m2_psc_alpha.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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 +50,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 user_m2::UpdateNR<0>(long long it, double t1) +int +user_m2::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m2::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m2::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m2_psc_alpha.h b/src/user_m2_psc_alpha.h index be345a990..8f83e4b79 100644 --- a/src/user_m2_psc_alpha.h +++ b/src/user_m2_psc_alpha.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2PSCALPHA_H #define USERM2PSCALPHA_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m2_psc_alpha_kernel.h b/src/user_m2_psc_alpha_kernel.h index a0a1cc129..b99f005c9 100644 --- a/src/user_m2_psc_alpha_kernel.h +++ b/src/user_m2_psc_alpha_kernel.h @@ -21,37 +21,37 @@ */ - - - #ifndef USERM2PSCALPHAKERNEL_H #define USERM2PSCALPHAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_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 +69,26 @@ 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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_port_var_name[N_PORT_VAR] = { - "I_syn", - "I1_syn" -}; +const std::string user_m2_port_var_name[ N_PORT_VAR ] = { "I_syn", "I1_syn" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -106,115 +101,116 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_port_param_name[N_PORT_PARAM] = { - "tau_syn", - "I0" -}; +const std::string user_m2_port_param_name[ N_PORT_PARAM ] = { "tau_syn", "I0" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_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, - user_m2_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, user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -224,43 +220,39 @@ __device__ }; template <> -int user_m2::UpdateNR<0>(long long it, double t1); +int user_m2::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m2::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m2::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m2_ns::N_SCAL_VAR - + user_m2_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m2_ns::N_SCAL_PARAM - + user_m2_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m2_ns::N_SCAL_VAR + user_m2_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m2_ns::N_SCAL_PARAM + user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_psc_alpha_rk5.h b/src/user_m2_psc_alpha_rk5.h index 81e485e43..41ff936d4 100644 --- a/src/user_m2_psc_alpha_rk5.h +++ b/src/user_m2_psc_alpha_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2PSCALPHARK5_H #define USERM2PSCALPHARK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif diff --git a/src/user_m2_psc_delta.cu b/src/user_m2_psc_delta.cu index c7d318d37..8738c6add 100644 --- a/src/user_m2_psc_delta.cu +++ b/src/user_m2_psc_delta.cu @@ -21,24 +21,20 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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 +49,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, user_m2_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_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. } } } -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::NodeInit(n_var, n_param, x, y, param, data_struct); + user_m2_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, user_m2_rk5 data_struct) +__device__ void +NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::NodeCalibrate(n_var, n_param, x, y, param, data_struct); + user_m2_ns::NodeCalibrate( n_var, n_param, x, y, param, data_struct ); } using namespace user_m2_ns; -int user_m2::Init(int i_node_0, int n_node, int n_port, - int i_group, unsigned long long *seed) { - BaseNeuron::Init(i_node_0, n_node, n_port, i_group, seed); +int +user_m2::Init( int i_node_0, int n_node, int n_port, int i_group, unsigned long long* seed ) +{ + BaseNeuron::Init( i_node_0, n_node, n_port, i_group, seed ); node_type_ = i_user_m2_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_ = user_m2_scal_var_name; scal_param_name_ = user_m2_scal_param_name; group_param_name_ = user_m2_group_param_name; - //rk5_data_struct_.node_type_ = i_user_m2_model; + // rk5_data_struct_.node_type_ = i_user_m2_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; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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 user_m2::Calibrate(double time_min, float time_resolution) +int +user_m2::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 user_m2::Update(long long it, double t1) +int +user_m2::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/user_m2_psc_delta.h b/src/user_m2_psc_delta.h index ffa95e367..dbc4f9b73 100644 --- a/src/user_m2_psc_delta.h +++ b/src/user_m2_psc_delta.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2PSCDELTA_H #define USERM2PSCDELTA_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 #define MAX_PORT_NUM 20 @@ -44,27 +41,29 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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 ); } - }; #endif diff --git a/src/user_m2_psc_delta_kernel.h b/src/user_m2_psc_delta_kernel.h index 4b505c0fc..34feba18b 100644 --- a/src/user_m2_psc_delta_kernel.h +++ b/src/user_m2_psc_delta_kernel.h @@ -21,35 +21,35 @@ */ - - - #ifndef USERM2PSCDELTAKERNEL_H #define USERM2PSCDELTAKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ N_PORT_VAR = 0 }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -67,20 +67,17 @@ 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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -93,13 +90,9 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_group_param_name[ N_GROUP_PARAM ] = { "h_min_rel", "h0_rel" }; // @@ -107,80 +100,83 @@ const std::string user_m2_group_param_name[N_GROUP_PARAM] = { // 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 dVdt dydx[i_V_m] -#define dwdt dydx[i_w] - -#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, - user_m2_rk5 data_struct) +#define V_m y[ i_V_m ] +#define w y[ i_w ] + +#define dVdt dydx[ i_V_m ] +#define dwdt dydx[ i_w ] + +#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, user_m2_rk5 data_struct ) { - - float V = ( refractory_step > 0 ) ? V_reset : MIN(V_m, V_peak); - float V_spike = Delta_T == 0. ? 0. : Delta_T*exp((V - V_th)/Delta_T); + float V = ( refractory_step > 0 ) ? V_reset : MIN( V_m, V_peak ); + + 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) - w + I_e) / C_m; + dVdt = ( refractory_step > 0 ) ? 0 : ( -g_L * ( V - E_L - V_spike ) - w + I_e ) / C_m; // Adaptation current w. - dwdt = (a*(V - E_L) - w) / tau_w; + dwdt = ( a * ( V - E_L ) - w ) / tau_w; } - template //, class DataStruct> -__device__ - void ExternalUpdate - (double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -190,23 +186,18 @@ __device__ }; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_psc_delta_rk5.h b/src/user_m2_psc_delta_rk5.h index a0dafdaf4..c8f8d532b 100644 --- a/src/user_m2_psc_delta_rk5.h +++ b/src/user_m2_psc_delta_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2PSCDELTARK5_H #define USERM2PSCDELTARK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif diff --git a/src/user_m2_psc_exp.cu b/src/user_m2_psc_exp.cu index a0e99d306..7494ccc7f 100644 --- a/src/user_m2_psc_exp.cu +++ b/src/user_m2_psc_exp.cu @@ -21,25 +21,21 @@ */ - - - -#include -#include -#include -#include "user_m2_kernel.h" #include "rk5.h" #include "user_m2.h" +#include "user_m2_kernel.h" +#include +#include +#include namespace user_m2_ns { -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, float *param, - user_m2_rk5 data_struct) +__device__ void +NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_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,52 +50,52 @@ 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 user_m2::UpdateNR<0>(long long it, double t1) +int +user_m2::UpdateNR< 0 >( long long it, double t1 ) { return 0; } -int user_m2::Update(long long it, double t1) { - UpdateNR(it, t1); +int +user_m2::Update( long long it, double t1 ) +{ + UpdateNR< MAX_PORT_NUM >( it, t1 ); return 0; } diff --git a/src/user_m2_psc_exp.h b/src/user_m2_psc_exp.h index f7add6d19..c744a1190 100644 --- a/src/user_m2_psc_exp.h +++ b/src/user_m2_psc_exp.h @@ -21,19 +21,16 @@ */ - - - #ifndef USERM2PSCEXP_H #define USERM2PSCEXP_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 #define MAX_PORT_NUM 20 @@ -44,30 +41,32 @@ struct user_m2_rk5 class user_m2 : public BaseNeuron { - public: - RungeKutta5 rk5_; +public: + RungeKutta5< user_m2_rk5 > rk5_; float h_min_; float h_; user_m2_rk5 rk5_data_struct_; - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - 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, unsigned long long* seed ); + + 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/user_m2_psc_exp_g.cu b/src/user_m2_psc_exp_g.cu index e776615fc..83942e524 100644 --- a/src/user_m2_psc_exp_g.cu +++ b/src/user_m2_psc_exp_g.cu @@ -21,73 +21,82 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m2.h" #include +#include #include -#include "user_m2.h" -#include "spike_buffer.h" using namespace user_m2_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] - -#define tau_m_ group_param_[i_tau_m] -#define C_m_ group_param_[i_C_m] -#define E_L_ group_param_[i_E_L] -#define Theta_rel_ group_param_[i_Theta_rel] -#define V_reset_rel_ group_param_[i_V_reset_rel] -#define tau_syn_ group_param_[i_tau_syn] -#define t_ref_ group_param_[i_t_ref] - -__global__ void user_m2_Update -( int n_node, int i_node_0, float *var_arr, float *param_arr, int n_var, - int n_param, float Theta_rel, float V_reset_rel, int n_refractory_steps, - float P11, float P22, float P21, float P20 ) +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] + +#define tau_m_ group_param_[ i_tau_m ] +#define C_m_ group_param_[ i_C_m ] +#define E_L_ group_param_[ i_E_L ] +#define Theta_rel_ group_param_[ i_Theta_rel ] +#define V_reset_rel_ group_param_[ i_V_reset_rel ] +#define tau_syn_ group_param_[ i_tau_syn ] +#define t_ref_ group_param_[ i_t_ref ] + +__global__ void +user_m2_Update( int n_node, + int i_node_0, + float* var_arr, + float* param_arr, + int n_var, + int n_param, + float Theta_rel, + float V_reset_rel, + int n_refractory_steps, + float P11, + float P22, + float P21, + float P20 ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } -double h_propagator_32( double tau_syn, double tau, double C, double h ) +double +h_propagator_32( double tau_syn, double tau, double C, double h ) { - const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h - * ( tau_syn - tau ) * exp( -h / tau ); + const double P32_linear = 1.0 / ( 2.0 * C * tau * tau ) * h * h * ( tau_syn - tau ) * exp( -h / tau ); const double P32_singular = h / C * exp( -h / tau ); const double P32 = - -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) - * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); + -tau / ( C * ( 1.0 - tau / tau_syn ) ) * exp( -h / tau_syn ) * expm1( h * ( 1.0 / tau_syn - 1.0 / tau ) ); const double dev_P32 = fabs( P32 - P32_singular ); - if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 - * fabs( P32_linear ) ) ) + if ( tau == tau_syn || ( fabs( tau - tau_syn ) < 0.1 && dev_P32 > 2.0 * fabs( P32_linear ) ) ) { return P32_singular; } @@ -103,10 +112,10 @@ user_m2::~user_m2() FreeParamArr(); } -int user_m2::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m2::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m2_model; n_scal_var_ = N_SCAL_VAR; @@ -114,46 +123,46 @@ int user_m2::Init(int i_node_0, int n_node, int /*n_port*/, n_scal_param_ = N_SCAL_PARAM; n_group_param_ = N_GROUP_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); - group_param_ = new float[N_GROUP_PARAM]; + group_param_ = new float[ N_GROUP_PARAM ]; scal_var_name_ = user_m2_scal_var_name; scal_param_name_ = user_m2_scal_param_name; group_param_name_ = user_m2_group_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); - SetGroupParam("tau_m", 10.0); - SetGroupParam("C_m", 250.0); - SetGroupParam("E_L", -65.0); - SetGroupParam("Theta_rel", 15.0); - SetGroupParam("V_reset_rel", 0.0); - SetGroupParam("tau_syn", 0.5); - SetGroupParam("t_ref", 2.0); + SetGroupParam( "tau_m", 10.0 ); + SetGroupParam( "C_m", 250.0 ); + SetGroupParam( "E_L", -65.0 ); + SetGroupParam( "Theta_rel", 15.0 ); + SetGroupParam( "V_reset_rel", 0.0 ); + SetGroupParam( "tau_syn", 0.5 ); + SetGroupParam( "t_ref", 2.0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m2::Update(long long it, double t1) +int +user_m2::Update( long long it, double t1 ) { // std::cout << "user_m2 neuron update\n"; float h = time_resolution_; @@ -161,21 +170,32 @@ int user_m2::Update(long long it, double t1) float P22 = exp( -h / tau_m_ ); float P21 = h_propagator_32( tau_syn_, tau_m_, C_m_, h ); float P20 = tau_m_ / C_m_ * ( 1.0 - P22 ); - int n_refractory_steps = int(round(t_ref_ / h)); + int n_refractory_steps = int( round( t_ref_ / h ) ); + + user_m2_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( n_node_, + i_node_0_, + var_arr_, + param_arr_, + n_var_, + n_param_, + Theta_rel_, + V_reset_rel_, + n_refractory_steps, + P11, + P22, + P21, + P20 ); + // gpuErrchk( cudaDeviceSynchronize() ); - user_m2_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_, - Theta_rel_, V_reset_rel_, n_refractory_steps, P11, P22, P21, P20 ); - //gpuErrchk( cudaDeviceSynchronize() ); - return 0; } -int user_m2::Free() +int +user_m2::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); delete[] group_param_; - + return 0; } diff --git a/src/user_m2_psc_exp_g.h b/src/user_m2_psc_exp_g.h index b20d08894..6452885f1 100644 --- a/src/user_m2_psc_exp_g.h +++ b/src/user_m2_psc_exp_g.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/iaf_psc_exp.h @@ -31,85 +28,72 @@ #ifndef USERM2PSCEXPG_H #define USERM2PSCEXPG_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m2_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; -enum GroupParamIndexes { - i_tau_m = 0, // Membrane time constant in ms - i_C_m, // Membrane capacitance in pF - i_E_L, // Resting potential in mV - i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) - // i.e. the real threshold is (E_L_+Theta_rel_) - i_V_reset_rel, // relative reset value of the membrane potential - i_tau_syn, // Time constant of synaptic current in ms - i_t_ref, // Refractory period in ms +enum GroupParamIndexes +{ + i_tau_m = 0, // Membrane time constant in ms + i_C_m, // Membrane capacitance in pF + i_E_L, // Resting potential in mV + i_Theta_rel, // Threshold, RELATIVE TO RESTING POTENTIAL(!) + // i.e. the real threshold is (E_L_+Theta_rel_) + i_V_reset_rel, // relative reset value of the membrane potential + i_tau_syn, // Time constant of synaptic current in ms + i_t_ref, // Refractory period in ms N_GROUP_PARAM }; - -const std::string user_m2_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "tau_m", - "C_m", - "E_L", - "Theta_rel", - "V_reset_rel", - "tau_syn", - "t_ref" -}; - -} // namespace - +const std::string + user_m2_group_param_name[ N_GROUP_PARAM ] = { "tau_m", "C_m", "E_L", "Theta_rel", "V_reset_rel", "tau_syn", "t_ref" }; +} // namespace class user_m2 : public BaseNeuron { float time_resolution_; - public: +public: ~user_m2(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Calibrate(double /*time_min*/, float time_res) { + + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); + int + Calibrate( double /*time_min*/, float time_res ) + { time_resolution_ = time_res; return 0; } - - int Update(long long it, double t1); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m2_psc_exp_hc.cu b/src/user_m2_psc_exp_hc.cu index 7ea75ba1e..b535a7d57 100644 --- a/src/user_m2_psc_exp_hc.cu +++ b/src/user_m2_psc_exp_hc.cu @@ -21,50 +21,50 @@ */ - - - -#include +#include "spike_buffer.h" +#include "user_m2_hc.h" #include +#include #include -#include "user_m2_hc.h" -#include "spike_buffer.h" using namespace user_m2_hc_ns; extern __constant__ float NESTGPUTimeResolution; -#define I_syn var[i_I_syn] -#define V_m_rel var[i_V_m_rel] -#define refractory_step var[i_refractory_step] -#define I_e param[i_I_e] +#define I_syn var[ i_I_syn ] +#define V_m_rel var[ i_V_m_rel ] +#define refractory_step var[ i_refractory_step ] +#define I_e param[ i_I_e ] #include "user_m2_hc_params.h" -__global__ void user_m2_hc_Update(int n_node, int i_node_0, - float *var_arr, float *param_arr, - int n_var, int n_param) +__global__ void +user_m2_hc_Update( int n_node, int i_node_0, float* var_arr, float* param_arr, int n_var, int n_param ) { int i_neuron = threadIdx.x + blockIdx.x * blockDim.x; - if (i_neuron 0.0 ) { + if ( i_neuron < n_node ) + { + float* var = var_arr + n_var * i_neuron; + float* param = param_arr + n_param * i_neuron; + + if ( refractory_step > 0.0 ) + { // neuron is absolute refractory refractory_step -= 1.0; } - else { // neuron is not refractory, so evolve V + else + { // neuron is not refractory, so evolve V V_m_rel = V_m_rel * P22 + I_syn * P21 + I_e * P20; } // exponential decaying PSC I_syn *= P11; - - if (V_m_rel >= Theta_rel ) { // threshold crossing - PushSpike(i_node_0 + i_neuron, 1.0); + + if ( V_m_rel >= Theta_rel ) + { // threshold crossing + PushSpike( i_node_0 + i_neuron, 1.0 ); V_m_rel = V_reset_rel; refractory_step = n_refractory_steps; - } + } } } @@ -74,59 +74,60 @@ user_m2_hc::~user_m2_hc() FreeParamArr(); } -int user_m2_hc::Init(int i_node_0, int n_node, int /*n_port*/, - int i_group, unsigned long long *seed) +int +user_m2_hc::Init( int i_node_0, int n_node, int /*n_port*/, int i_group, unsigned long long* seed ) { - BaseNeuron::Init(i_node_0, n_node, 1 /*n_port*/, i_group, seed); + BaseNeuron::Init( i_node_0, n_node, 1 /*n_port*/, i_group, seed ); node_type_ = i_user_m2_hc_model; n_scal_var_ = N_SCAL_VAR; n_var_ = n_scal_var_; n_scal_param_ = N_SCAL_PARAM; n_param_ = n_scal_param_; - + AllocParamArr(); AllocVarArr(); scal_var_name_ = user_m2_hc_scal_var_name; scal_param_name_ = user_m2_hc_scal_param_name; - SetScalParam(0, n_node, "I_e", 0.0 ); // in pA + SetScalParam( 0, n_node, "I_e", 0.0 ); // in pA - SetScalVar(0, n_node, "I_syn", 0.0 ); - SetScalVar(0, n_node, "V_m_rel", 0.0 ); // in mV - SetScalVar(0, n_node, "refractory_step", 0 ); + SetScalVar( 0, n_node, "I_syn", 0.0 ); + SetScalVar( 0, n_node, "V_m_rel", 0.0 ); // in mV + SetScalVar( 0, n_node, "refractory_step", 0 ); // multiplication factor of input signal is always 1 for all nodes float input_weight = 1.0; - gpuErrchk(cudaMalloc(&port_weight_arr_, sizeof(float))); - gpuErrchk(cudaMemcpy(port_weight_arr_, &input_weight, - sizeof(float), cudaMemcpyHostToDevice)); + gpuErrchk( cudaMalloc( &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; - + // input spike signal is stored in I_syn - port_input_arr_ = GetVarArr() + GetScalVarIdx("I_syn"); + port_input_arr_ = GetVarArr() + GetScalVarIdx( "I_syn" ); port_input_arr_step_ = n_var_; port_input_port_step_ = 0; return 0; } -int user_m2_hc::Update(long long it, double t1) +int +user_m2_hc::Update( long long it, double t1 ) { // std::cout << "user_m2_hc neuron update\n"; - user_m2_hc_Update<<<(n_node_+1023)/1024, 1024>>> - (n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_); - //gpuErrchk( cudaDeviceSynchronize() ); - + user_m2_hc_Update<<< ( n_node_ + 1023 ) / 1024, 1024 >>>( + n_node_, i_node_0_, var_arr_, param_arr_, n_var_, n_param_ ); + // gpuErrchk( cudaDeviceSynchronize() ); + return 0; } -int user_m2_hc::Free() +int +user_m2_hc::Free() { - FreeVarArr(); + FreeVarArr(); FreeParamArr(); - + return 0; } diff --git a/src/user_m2_psc_exp_hc.h b/src/user_m2_psc_exp_hc.h index 12886aa23..80c1f4c21 100644 --- a/src/user_m2_psc_exp_hc.h +++ b/src/user_m2_psc_exp_hc.h @@ -21,9 +21,6 @@ */ - - - // adapted from: // https://github.com/nest/nest-simulator/blob/master/models/user_m2.h @@ -31,53 +28,47 @@ #ifndef USERM2PSCEXPHC_H #define USERM2PSCEXPHC_H -#include -#include -#include "cuda_error.h" -#include "node_group.h" #include "base_neuron.h" +#include "cuda_error.h" #include "neuron_models.h" +#include "node_group.h" +#include +#include namespace user_m2_hc_ns { -enum ScalVarIndexes { - i_I_syn = 0, // postsynaptic current for exc. inputs - i_V_m_rel, // membrane potential relative to E_L - i_refractory_step, // refractory step counter +enum ScalVarIndexes +{ + i_I_syn = 0, // postsynaptic current for exc. inputs + i_V_m_rel, // membrane potential relative to E_L + i_refractory_step, // refractory step counter N_SCAL_VAR }; -enum ScalParamIndexes { - i_I_e = 0, // External current in pA +enum ScalParamIndexes +{ + i_I_e = 0, // External current in pA N_SCAL_PARAM }; - const std::string user_m2_hc_scal_var_name[N_SCAL_VAR] = { - "I_syn", - "V_m_rel", - "refractory_step" -}; +const std::string user_m2_hc_scal_var_name[ N_SCAL_VAR ] = { "I_syn", "V_m_rel", "refractory_step" }; -const std::string user_m2_hc_scal_param_name[N_SCAL_PARAM] = { - "I_e" -}; +const std::string user_m2_hc_scal_param_name[ N_SCAL_PARAM ] = { "I_e" }; } // namespace - + class user_m2_hc : public BaseNeuron { - public: +public: ~user_m2_hc(); - - int Init(int i_node_0, int n_neuron, int n_port, int i_group, - unsigned long long *seed); - int Update(long long it, double t1); + int Init( int i_node_0, int n_neuron, int n_port, int i_group, unsigned long long* seed ); - int Free(); + int Update( long long it, double t1 ); + int Free(); }; diff --git a/src/user_m2_psc_exp_kernel.h b/src/user_m2_psc_exp_kernel.h index 55fc7356a..2b298a227 100644 --- a/src/user_m2_psc_exp_kernel.h +++ b/src/user_m2_psc_exp_kernel.h @@ -21,36 +21,36 @@ */ - - - #ifndef USERM2PSCEXPKERNEL_H #define USERM2PSCEXPKERNEL_H -#include -#include -#include "spike_buffer.h" #include "node_group.h" +#include "spike_buffer.h" #include "user_m2.h" +#include +#include -#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) extern __constant__ float NESTGPUTimeResolution; namespace user_m2_ns { -enum ScalVarIndexes { +enum ScalVarIndexes +{ i_V_m = 0, i_w, N_SCAL_VAR }; -enum PortVarIndexes { +enum PortVarIndexes +{ i_I_syn = 0, N_PORT_VAR }; -enum ScalParamIndexes { +enum ScalParamIndexes +{ i_V_th = 0, i_Delta_T, i_g_L, @@ -68,28 +68,24 @@ enum ScalParamIndexes { N_SCAL_PARAM }; -enum PortParamIndexes { +enum PortParamIndexes +{ i_tau_syn = 0, 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 user_m2_scal_var_name[N_SCAL_VAR] = { - "V_m", - "w" -}; +const std::string user_m2_scal_var_name[ N_SCAL_VAR ] = { "V_m", "w" }; -const std::string user_m2_port_var_name[N_PORT_VAR] = { - "I_syn" -}; +const std::string user_m2_port_var_name[ N_PORT_VAR ] = { "I_syn" }; -const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { - "V_th", +const std::string user_m2_scal_param_name[ N_SCAL_PARAM ] = { "V_th", "Delta_T", "g_L", "E_L", @@ -102,110 +98,114 @@ const std::string user_m2_scal_param_name[N_SCAL_PARAM] = { "V_reset", "t_ref", "refractory_step", - "den_delay" -}; + "den_delay" }; -const std::string user_m2_port_param_name[N_PORT_PARAM] = { +const std::string user_m2_port_param_name[ N_PORT_PARAM ] = { "tau_syn", }; -const std::string user_m2_group_param_name[N_GROUP_PARAM] = { - "h_min_rel", - "h0_rel" -}; +const std::string user_m2_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 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 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, - user_m2_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 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 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, user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > //, class DataStruct> +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_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; } } } @@ -215,43 +215,39 @@ __device__ }; template <> -int user_m2::UpdateNR<0>(long long it, double t1); +int user_m2::UpdateNR< 0 >( long long it, double t1 ); -template -int user_m2::UpdateNR(long long it, double t1) +template < int N_PORT > +int +user_m2::UpdateNR( long long it, double t1 ) { - if (N_PORT == n_port_) { - const int NVAR = user_m2_ns::N_SCAL_VAR - + user_m2_ns::N_PORT_VAR*N_PORT; - const int NPARAM = user_m2_ns::N_SCAL_PARAM - + user_m2_ns::N_PORT_PARAM*N_PORT; + if ( N_PORT == n_port_ ) + { + const int NVAR = user_m2_ns::N_SCAL_VAR + user_m2_ns::N_PORT_VAR * N_PORT; + const int NPARAM = user_m2_ns::N_SCAL_PARAM + user_m2_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, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ) { - user_m2_ns::Derivatives(x, y, dydx, param, - data_struct); + user_m2_ns::Derivatives< NVAR, NPARAM >( x, y, dydx, param, data_struct ); } -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct) +template < int NVAR, int NPARAM > +__device__ void +ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ) { - user_m2_ns::ExternalUpdate(x, y, param, - end_time_step, - data_struct); + user_m2_ns::ExternalUpdate< NVAR, NPARAM >( x, y, param, end_time_step, data_struct ); } diff --git a/src/user_m2_psc_exp_rk5.h b/src/user_m2_psc_exp_rk5.h index d4e18656a..38314afcc 100644 --- a/src/user_m2_psc_exp_rk5.h +++ b/src/user_m2_psc_exp_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2PSCEXPRK5_H #define USERM2PSCEXPRK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif diff --git a/src/user_m2_rk5.h b/src/user_m2_rk5.h index 3c1557591..0a9316609 100644 --- a/src/user_m2_rk5.h +++ b/src/user_m2_rk5.h @@ -21,31 +21,20 @@ */ - - - #ifndef USERM2RK5_H #define USERM2RK5_H struct user_m2_rk5; -template -__device__ -void Derivatives(double x, float *y, float *dydx, float *param, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void Derivatives( double x, float* y, float* dydx, float* param, user_m2_rk5 data_struct ); -template -__device__ -void ExternalUpdate(double x, float *y, float *param, bool end_time_step, - user_m2_rk5 data_struct); +template < int NVAR, int NPARAM > +__device__ void ExternalUpdate( double x, float* y, float* param, bool end_time_step, user_m2_rk5 data_struct ); -__device__ -void NodeInit(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeInit( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); -__device__ -void NodeCalibrate(int n_var, int n_param, double x, float *y, - float *param, user_m2_rk5 data_struct); +__device__ void NodeCalibrate( int n_var, int n_param, double x, float* y, float* param, user_m2_rk5 data_struct ); #endif