mrc-ide / helios

Simulating far UVC for pathogen control
https://mrc-ide.github.io/helios/
Other
5 stars 0 forks source link

Model speedup #121

Closed cwhittaker1000 closed 3 months ago

cwhittaker1000 commented 3 months ago

Currently the model takes a long time to run. I did some basic profiling and it suggested the I$copy() calls in processes.R were taking ages, especially with the households (which are our most numerous location by a large margin.

Spoke to Giovanni who kindly added in a new bitset operator to individual called bitset_count_and() which basically counts the number of values both set to 1 in two bitsets (i.e. what we currently do with a cumbersome $copy() and $and() (which necessitates allocating memory to the heap and takes time). You can see more here: https://github.com/mrc-ide/individual/commit/bcd6d13b6b682f719cd8ddf6bc27e38b45d109e1

I've done some basic benchmarking and for a population of 100,000 I think we get about a 60% speedup. The PR's not quite done (I need to delete some of the code I only commented out before), but this seems promising!

Also fixes this known issue with newest version of individual: https://github.com/mrc-ide/individual/pull/203

Can test with the following code:

library(helios); library(tictoc)

parameters_list <- get_parameters(overrides = list(human_population = 100000,
                                                   number_initial_S = 35000,
                                                   number_initial_E = 10000,
                                                   number_initial_I = 10000,
                                                   number_initial_R = 45000,
                                                   simulation_time = 10))
variables_list <- create_variables(parameters_list)
parameters_list <- variables_list$parameters_list
variables_list <- variables_list$variables_list
events_list <- create_events(variables_list, parameters_list)
renderer <- individual::Render$new(parameters_list$simulation_time / parameters_list$dt)
x <- create_SE_process(variables_list, events_list, parameters_list, renderer)
timesteps <- round(parameters_list$simulation_time/parameters_list$dt)
renderer <- individual::Render$new(timesteps)
processes_list <- create_processes(variables_list = variables_list,
                                   events_list = events_list,
                                   parameters_list = parameters_list,
                                   renderer = renderer)

tic()
individual::simulation_loop(
  variables = variables_list,
  events = unlist(events_list),
  processes = processes_list,
  timesteps = timesteps
)
toc()