Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated GPGPU code #96

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bench.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python nengo_ocl/tests/test_clra_nonlinearities.py
81 changes: 79 additions & 2 deletions nengo_ocl/clra_nonlinearities.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ def plan_direct(queue, code, init, input_names, inputs, output, tag=None):
return rval



def plan_lif(queue, dt, J, V, W, outS, ref, tau, N=None, tau_n=None,
inc_n=None, upsample=1, **kwargs):
adaptive = N is not None
Expand Down Expand Up @@ -869,6 +870,8 @@ def plan_lif(queue, dt, J, V, W, outS, ref, tau, N=None, tau_n=None,
const ${type} dt = ${dt};
% endif
const ${type} V_threshold = 1;
int b1,b2,b3,b4;

"""
# TODO: could precompute -expm1(-dtu / tau)
text = """
Expand All @@ -882,12 +885,86 @@ def plan_lif(queue, dt, J, V, W, outS, ref, tau, N=None, tau_n=None,
% endif
V += dV;
W -= dtu;
b1 = signbit(-V);
//W >= 0
b2 = abs(signbit(W) - 1);

//W > dtu
b3 = signbit(-W + dtu);
//W <= dtu
b4 = abs(b3 - 1);
V = (b1 * b4) * V;

//(W > dtu OR V > 0) OR (W <= dtu AND W >= 0 AND V > 0)
//OR ELSE => V
V = (b2)*(V * (1 - W * dtu_inv))
+ (abs(b2 - 1)) * V;

b1 = signbit(-V + V_threshold);
b2 = abs(b1 - 1);
spiked = min((char)b1 + spiked, 1);
overshoot = b1 * (dtu * (V - V_threshold)/dV) + b2 * overshoot;
W = b1* (ref - overshoot + dtu) + b2 * W;
V *= b2;

% endfor
outV = V;
outW = W;
outS =spiked * dt_inv;
% if adaptive:
outN = N + (dt / tau_n) * (inc_n * outS - N);
% endif
"""
decs = as_ascii(Template(decs, output_encoding='ascii').render(**textconf))
text = as_ascii(Template(text, output_encoding='ascii').render(**textconf))
cl_name = "cl_alif" if adaptive else "cl_lif"
return _plan_template(
queue, cl_name, text, declares=decs,
inputs=inputs, outputs=outputs, parameters=parameters, **kwargs)
def plan_lif_old(queue, dt, J, V, W, outS, ref, tau, N=None, tau_n=None,
inc_n=None, upsample=1, **kwargs):
adaptive = N is not None
assert J.ctype == 'float'
for array in [V, W, outS]:
assert V.ctype == J.ctype

inputs = dict(J=J, V=V, W=W)
outputs = dict(outV=V, outW=W, outS=outS)
parameters = dict(tau=tau, ref=ref)
if adaptive:
assert all(ary is not None for ary in [N, tau_n, inc_n])
assert N.ctype == J.ctype
inputs.update(dict(N=N))
outputs.update(dict(outN=N))
parameters.update(dict(tau_n=tau_n, inc_n=inc_n))

dt = float(dt)
textconf = dict(type=J.ctype, dt=dt, upsample=upsample, adaptive=adaptive,
dtu=dt/upsample, dtu_inv=upsample/dt, dt_inv=1/dt)
decs = """
char spiked;
${type} dV, overshoot;
const ${type} dtu = ${dtu}, dtu_inv = ${dtu_inv}, dt_inv = ${dt_inv};
% if adaptive:
const ${type} dt = ${dt};
% endif
const ${type} V_threshold = 1;
"""
# TODO: could precompute -expm1(-dtu / tau)
text = """
spiked = 0;
% for ii in range(upsample):
% if adaptive:
dV = -expm1(-dtu / tau) * (J - N - V);
% else:
dV = -expm1(-dtu / tau) * (J - V);
% endif
V += dV;
W -= dtu;
if (V < 0 || W > dtu)
V = 0;
else if (W >= 0)
V *= 1 - W * dtu_inv;

if (V > V_threshold) {
overshoot = dtu * (V - V_threshold) / dV;
W = ref - overshoot + dtu;
Expand All @@ -904,7 +981,7 @@ def plan_lif(queue, dt, J, V, W, outS, ref, tau, N=None, tau_n=None,
"""
decs = as_ascii(Template(decs, output_encoding='ascii').render(**textconf))
text = as_ascii(Template(text, output_encoding='ascii').render(**textconf))
cl_name = "cl_alif" if adaptive else "cl_lif"
cl_name = "cl_alif_old" if adaptive else "cl_lif_old"
return _plan_template(
queue, cl_name, text, declares=decs,
inputs=inputs, outputs=outputs, parameters=parameters, **kwargs)
Expand Down
18 changes: 14 additions & 4 deletions nengo_ocl/tests/test_clra_nonlinearities.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from nengo_ocl.clraggedarray import CLRaggedArray as CLRA, to_device

from nengo_ocl.clra_nonlinearities import (
plan_lif, plan_lif_rate, plan_elementwise_inc, plan_reset, plan_slicedcopy,
plan_lif, plan_lif_old, plan_lif_rate, plan_elementwise_inc, plan_reset, plan_slicedcopy,
plan_linearfilter)


Expand Down Expand Up @@ -95,9 +95,9 @@ def test_lif_speed(rng, heterogeneous):
ref = 2e-3
tau = 20e-3

n_iters = 10
n_iters = 1000
if heterogeneous:
n_neurons = [1.0e5] * 50 + [1e3] * 5000
n_neurons = [1.0e5] * 50 + [1e3] * 500
else:
n_neurons = [1.1e5] * 50
n_neurons = list(map(int, n_neurons))
Expand Down Expand Up @@ -127,8 +127,17 @@ def test_lif_speed(rng, heterogeneous):

print("plan %d: blockify = %s, dur = %0.3f"
% (i, blockify, timer.duration))
print "Original LIF impl"
for i, blockify in enumerate([False, True]):
plan = plan_lif_old(queue, dt, clJ, clV, clW, clOS, ref, tau,
blockify=blockify)

with Timer() as timer:
for j in range(n_iters):
plan()

print("plan %d: blockify = %s, dur = %0.3f"
% (i, blockify, timer.duration))
@pytest.mark.parametrize("blockify", [False, True])
def test_lif_rate(blockify):
"""Test the `lif_rate` nonlinearity"""
Expand Down Expand Up @@ -312,4 +321,5 @@ def test_linearfilter(n_per_kind, rng):


if __name__ == '__main__':
pytest.main([__file__, '-v'])
test_lif_speed(np.random.RandomState(1234567890),True)
#pytest.main([__file__, '-v'])
Binary file added setuptools-15.2.zip
Binary file not shown.