Skip to content

Instantly share code, notes, and snippets.

@russelljjarvis
Last active May 10, 2024 08:44
Show Gist options
  • Save russelljjarvis/714166159c39d94fbc418d2d145be658 to your computer and use it in GitHub Desktop.
Save russelljjarvis/714166159c39d94fbc418d2d145be658 to your computer and use it in GitHub Desktop.
LIF_Neuron_As_CUDA_Kernel
"""
This is an update rule for the Leaky Integrate and Fire Neuronal Model. It is an integration step for a forward Euler solver. The update step is implemented as a CUDA kernel and it is written in Julia. The cuda kernel is designed to update a whole population of LIF neuron models in an embarrasingly parallel manner.
Further down in the code there is also a mutable struct container called IFNF which has a constructor method. The constructor method uses multi dispatch, so it is expressed as a series of related functions, and each function is distinguishable because it has different types.
In fact the constructor itself utilizes parametric types (ie the types used to make the struct are parameters).
Briefly describe what you learned when you created this code sample.
I learned how to convert conventional code meant for CPU execution, to Cuda/GPU code in the Julia language. I also learned how to make a constructor for my own type definition. The constructor in question utilizes multiple dispatch and parametric types.
"""
function lif_kernel!(N, v, ge, gi, fire, u,dt,g,tr)
τm, τe, τi, Vt, Vr, El, gL = (100.0,5.0,10.0,0.2,0.0,-60.0,10.0)
R = 1.75
i0 = threadIdx().x + (blockIdx().x - 1) * blockDim().x
stride = blockDim().x
g = g + (ge + gi)
tref = 10.0
@inbounds for i=i0:stride:N
v[i] = v[i] * exp(-dt /τm) + Vr +X+g[i]+u[i]
v[i] += (u[i]+g[i]) * (R/ τm)
ge[i] += dt * -ge[i] / τe
gi[i] += dt * -gi[i] / τi
g[i] += dt * -g[i] / (τi+τe)
if tr[i] > 0 # check if in refractory period
v[i] = vSS # set voltage to reset
tr[i] = tr[i] - 1 # reduce running counter of refractory period
elseif v[i] > θ
fire[i] = v[i] > θ
tr[i] = Int(round(tref*dt)) # set refractory time
end
end
nothing
end
"""
Example of the multidispatch integrate function that is chosen to execute when `fire` is of CuArray type.
"""
function integrate!(N::Integer,v::CuArray,dt::Real,ge::CuVector,gi::CuVector,fire::CuArray{Bool},u::CuVector,g::CuVector)
kernel = @cuda launch=false lif_kernel!(N, v, ge, gi, fire,u,dt,g,tr)
config = launch_configuration(kernel.fun)
xthreads = min(32, N)
xblocks = min(config.blocks, cld(N, xthreads))
kernel(N, v, ge, gi, fire, u,dt;threads=(xthreads), blocks=(xblocks<<2))
end
"""
A population of cells
"""
mutable struct IFNF{C<:Integer,Q<:AbstractArray{<:Bool},L<:Vector{<:Number},M<:AbstractArray{<:Any}} <: AbstractIFNF
N::C
v::L
ge::L
gi::L
fire::Q
u::L
tr::L
records::Dict
fire_cnt::L
post_synaptic_weights::M # SVector
function IFNF(N,v,ge,gi,fire,u,tr,records,post_synaptic_weights)
fire_cnt::Vector{Number} = zeros(N)
new{typeof(N),typeof(fire),typeof(ge),typeof(post_synaptic_weights)}(N,v,ge,gi,fire,u,tr,records,fire_cnt,post_synaptic_weights)
end
function IFNF(N,fire,u,sim_type::AbstractArray,post_synaptic_weights::Vector{Vector{Any}})
v = typeof(sim_type)(ones(N).-55.0)
g = typeof(sim_type)(zeros(N))
ge = typeof(sim_type)(zeros(N))
gi = typeof(sim_type)(zeros(N))
tr = zeros(typeof(N),N)
records::Dict = Dict()
IFNF(N,v,ge,gi,fire,u,tr,records,post_synaptic_weights)
end
function IFNF(N::Int,fire,u,post_synaptic_weights::Vector{Vector{Any}})
v = typeof(u)(ones(N).-55.)
g = typeof(u)(zeros(N))
ge = typeof(u)(zeros(N))
gi = typeof(u)(zeros(N))
tr = zeros(typeof(N),N)
records::Dict = Dict()
IFNF(N,v,ge,gi,fire,u,tr,records,post_synaptic_weights)
end
function IFNF(N::Int,sim_type::CuArray,post_synaptic_weights::Vector{Vector{Any}})
fire::CuArray{Bool} = zeros(Bool,N)
u = typeof(sim_type)(zeros(N))
IFNF(N,fire,u,post_synaptic_weights)
end
function IFNF(N::Int,sim_type::Array,post_synaptic_weights::Vector{Vector{Any}})
fire::Array{Bool} = zeros(Bool,N)
u = typeof(sim_type)(zeros(N))
IFNF(N,fire,u,post_synaptic_weights)
end
end
"""
[Uniform parameter: Integrate-And-Fire Neuron](https://neuronaldynamics.epfl.ch/online/Ch1.S3.html)
"""
IFNF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment