Skip to content

Commit

Permalink
Merge pull request #1396 from brian-team/long_runs_cpp_standalone
Browse files Browse the repository at this point in the history
Avoid casting timesteps to 32bit in C++ standalone
  • Loading branch information
mstimberg authored Mar 17, 2022
2 parents c2b155f + aff91cb commit 2fc55f1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
10 changes: 5 additions & 5 deletions brian2/devices/cpp_standalone/brianlib/clocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include<math.h>

namespace {
inline int fround(double x)
inline int64_t fround(double x)
{
return (int)(x+0.5);
return (int64_t)(x+0.5);
};
};

Expand All @@ -28,20 +28,20 @@ class Clock
inline bool running() { return timestep[0]<i_end; };
void set_interval(double start, double end)
{
int i_start = fround(start/dt[0]);
int64_t i_start = fround(start/dt[0]);
double t_start = i_start*dt[0];
if(t_start==start || fabs(t_start-start)<=epsilon*fabs(t_start))
{
timestep[0] = i_start;
} else
{
timestep[0] = (int)ceil(start/dt[0]);
timestep[0] = (int64_t)ceil(start/dt[0]);
}
i_end = fround(end/dt[0]);
double t_end = i_end*dt[0];
if(!(t_end==end || fabs(t_end-end)<=epsilon*fabs(t_end)))
{
i_end = (int)ceil(end/dt[0]);
i_end = (int64_t)ceil(end/dt[0]);
}
}
private:
Expand Down
19 changes: 19 additions & 0 deletions brian2/tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,23 @@ def test_both_equal():

assert (M1.v == M2.v).all()

@pytest.mark.standalone_compatible
def test_long_run():
defaultclock.dt = 0.1 * ms
group = NeuronGroup(1, 'x : 1')
group.run_regularly('x += 1')
# Timesteps are internally stored as 64bit integers, but previous versions
# converted them into 32bit integers along the way. We'll make sure that
# this is not the case and everything runs fine. To not actually run such a
# long simulation we manually advance the clock.
net = Network(group, name='network')
start_step = 2**31-5
start_time = start_step*defaultclock.dt_
with catch_logs() as l:
net.t_ = start_time # for runtime
device.insert_code('main', 'network.t = {};'.format(start_time)) # for standalone
net.run(6 * defaultclock.dt)
assert group.x == 6

@pytest.mark.codegen_independent
def test_long_run_dt_change():
Expand Down Expand Up @@ -1571,6 +1588,7 @@ def test_multiple_runs_function_change():
device.build(direct_call=False, **device.build_options)
assert_equal(mon.v[0], [1, 2, 3, 4])


if __name__ == '__main__':
BrianLogger.log_level_warn()
for t in [
Expand Down Expand Up @@ -1635,6 +1653,7 @@ def test_multiple_runs_function_change():
test_runtime_rounding,
test_small_runs,
test_both_equal,
test_long_run,
test_long_run_dt_change,
test_multiple_runs_constant_change,
test_multiple_runs_function_change
Expand Down

0 comments on commit 2fc55f1

Please sign in to comment.