Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Running HH kernel via LLVM backend #653

@georgemitenkov

Description

@georgemitenkov

Running hh.mod:

TITLE hh.mod   squid sodium, potassium, and leak channels

COMMENT
    This is the original Hodgkin-Huxley treatment for the set of sodium,
    potassium, and leakage channels found in the squid giant axon membrane.
    ("A quantitative description of membrane current and its application
    conduction and excitation in nerve" J.Physiol. (Lond.) 117:500-544 (1952).)
    Membrane voltage is in absolute mV and has been reversed in polarity
    from the original HH convention and shifted to reflect a resting potential
    of -65 mV.
    Remember to set celsius=6.3 (or whatever) in your HOC file.
    See squid.hoc for an example of a simulation using this model.
    SW Jaslove  6 March, 1992
ENDCOMMENT

UNITS {
    (mA) = (milliamp)
    (mV) = (millivolt)
    (S) = (siemens)
}

? interface
NEURON {
    SUFFIX hh
    USEION na READ ena WRITE ina
    USEION k READ ek WRITE ik
    NONSPECIFIC_CURRENT il
    RANGE gnabar, gkbar, gl, el, gna, gk
    RANGE minf, hinf, ninf, mtau, htau, ntau
    THREADSAFE : assigned GLOBALs will be per thread
}

PARAMETER {
    gnabar = .12 (S/cm2)	<0,1e9>
    gkbar = .036 (S/cm2)	<0,1e9>
    gl = .0003 (S/cm2)	<0,1e9>
    el = -54.3 (mV)
}

STATE {
    m h n
}

ASSIGNED {
    v (mV)
    celsius (degC)
    ena (mV)
    ek (mV)

    gna (S/cm2)
    gk (S/cm2)
    ina (mA/cm2)
    ik (mA/cm2)
    il (mA/cm2)
    minf hinf ninf
    mtau (ms) htau (ms) ntau (ms)
}

? currents
BREAKPOINT {
    SOLVE states METHOD cnexp
    gna = gnabar*m*m*m*h
    ina = gna*(v - ena)
    gk = gkbar*n*n*n*n
    ik = gk*(v - ek)
    il = gl*(v - el)
}


INITIAL {
    rates(v)
    m = minf
    h = hinf
    n = ninf
}

? states
DERIVATIVE states {
    rates(v)
    m' =  (minf-m)/mtau
    h' = (hinf-h)/htau
    n' = (ninf-n)/ntau
}

:LOCAL q10
? rates
PROCEDURE rates(v(mV)) {  :Computes rate and other constants at current v.
    :Call once from HOC to initialize inf at resting v.
    LOCAL  alpha, beta, sum, q10

UNITSOFF
    q10 = 3^((celsius - 6.3)/10)
    :"m" sodium activation system
    alpha = .1 * vtrap(-(v+40),10)
    beta =  4 * exp(-(v+65)/18)
    sum = alpha + beta
    mtau = 1/(q10*sum)
    minf = alpha/sum
    :"h" sodium inactivation system
    alpha = .07 * exp(-(v+65)/20)
    beta = 1 / (exp(-(v+35)/10) + 1)
    sum = alpha + beta
    htau = 1/(q10*sum)
    hinf = alpha/sum
    :"n" potassium activation system
    alpha = .01*vtrap(-(v+55),10)
    beta = .125*exp(-(v+65)/80)
    sum = alpha + beta
    ntau = 1/(q10*sum)
    ninf = alpha/sum
}

FUNCTION vtrap(x,y) {  :Traps for 0 in denominator of rate eqns.
    if (fabs(x/y) < 1e-6) {
        vtrap = y*(1 - x/y/2)
    } else {
        vtrap = x/(exp(x/y) - 1)
    }
}

UNITSON

currently produces the following NMODL kernel (used passes --inline --const-folding):

VOID nrn_state_hh(INSTANCE_STRUCT *mech){
    INTEGER id
    INTEGER node_id, ena_id, ek_id
    DOUBLE v
    for(id = 0; id<mech->node_count-7; id = id+8) {
        node_id = mech->node_index[id]
        ena_id = mech->ion_ena_index[id]
        ek_id = mech->ion_ek_index[id]
        v = mech->voltage[node_id]
        mech->ena[id] = mech->ion_ena[ena_id]
        mech->ek[id] = mech->ion_ek[ek_id]
        {
            DOUBLE alpha, beta, sum, q10, vtrap_in_0, vtrap_in_1, v_in_1
            v_in_1 = v
            UNITSOFF
            q10 = 3^((mech->celsius-6.3)/10)
            {
                DOUBLE x_in_0, y_in_0
                x_in_0 = -(v_in_1+40)
                y_in_0 = 10
                IF (fabs(x_in_0/y_in_0)<1e-6) {
                    vtrap_in_0 = y_in_0*(1-x_in_0/y_in_0/2)
                } ELSE {
                    vtrap_in_0 = x_in_0/(exp(x_in_0/y_in_0)-1)
                }
            }
            alpha = .1*vtrap_in_0
            beta = 4*exp(-(v_in_1+65)/18)
            sum = alpha+beta
            mech->mtau[id] = 1/(q10*sum)
            mech->minf[id] = alpha/sum
            alpha = .07*exp(-(v_in_1+65)/20)
            beta = 1/(exp(-(v_in_1+35)/10)+1)
            sum = alpha+beta
            mech->htau[id] = 1/(q10*sum)
            mech->hinf[id] = alpha/sum
            {
                DOUBLE x_in_1, y_in_1
                x_in_1 = -(v_in_1+55)
                y_in_1 = 10
                IF (fabs(x_in_1/y_in_1)<1e-6) {
                    vtrap_in_1 = y_in_1*(1-x_in_1/y_in_1/2)
                } ELSE {
                    vtrap_in_1 = x_in_1/(exp(x_in_1/y_in_1)-1)
                }
            }
            alpha = .01*vtrap_in_1
            beta = .125*exp(-(v_in_1+65)/80)
            sum = alpha+beta
            mech->ntau[id] = 1/(q10*sum)
            mech->ninf[id] = alpha/sum
        }
        mech->m[id] = mech->m[id]+(1.0-exp(mech->dt*((((-1.0)))/mech->mtau[id])))*(-(((mech->minf[id]))/mech->mtau[id])/((((-1.0)))/mech->mtau[id])-mech->m[id])
        mech->h[id] = mech->h[id]+(1.0-exp(mech->dt*((((-1.0)))/mech->htau[id])))*(-(((mech->hinf[id]))/mech->htau[id])/((((-1.0)))/mech->htau[id])-mech->h[id])
        mech->n[id] = mech->n[id]+(1.0-exp(mech->dt*((((-1.0)))/mech->ntau[id])))*(-(((mech->ninf[id]))/mech->ntau[id])/((((-1.0)))/mech->ntau[id])-mech->n[id])
    }

  // remainder of the loop
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions