I have an Agents.jl simulation that worked fine last summer… I’m back to looking at the code, and it’s deadlocking and sitting there using 0% of cpu.
It’s a script that uses Threads.@spawn to run some threads each of which reads a simulation description from a channel, runs the simulation, and then put! some summary statistics to a statistics channel. In a separate single thread a function reads from the stats channel and writes stats to a SQLite database.
As I said, all of this worked fine last summer on some version like 1.5.2 or something along those lines. Today in 1.7.0-beta3 (or beta2) it gets to the point where the worker threads have each read a simulation description (and print out what it is) and where the SQLite writer says it’s about to grab the next DB result… but at that point, everything deadlocks and 0% CPU usage.
It doesn’t appear that the ABM runs at all. Here is the code the threads are running. One thread is spawned to run sqliteinserter
, and 5 threads are spawned to run runasim
:
function sqliteinserter(dfchannel,dbfile)
db = SQLite.DB(dbfile);
SQLite.drop!(db,"sims";ifexists=true)
SQLite.drop!(db,"stats";ifexists=true)
SQLite.createtable!(db,"sims",Tables.Schema((:simid,:n,:density,:infprob,:testevery,:poolsize,
:quarduration,:costoftest,:limitdet),
(Int,Int,Float64,Float64,Int,Int,Int,Float64,Float64)));
SQLite.createtable!(db,"stats",Tables.Schema((:simid,:day,:ninfected,:nquarantined,:tottestcost),
(Int,Int,Int,Int,Float64)));
while true
println("about to grab next results for DB.")
tup = take!(dfchannel)
if tup === nothing
return
end
iter,adf,mdf,pars = tup;
println("Completed iteration $iter, adding to SQLite database");
cmd = "insert into sims values(" * Printf.@sprintf("%d,%d,%f,%f,%d,%d,%d,%f,%f);",pars...)
DBInterface.execute(db,cmd);
DBInterface.execute(db,"drop table if exists tempstats;")
SQLite.load!(mdf,db,"tempstats",temp=true,ifnotexists=true)
DBInterface.execute(db,"insert into stats select $iter,day,ninfected,nquarantined,tottestcost from tempstats;")
end
end
function runasim(simchannel,dfchannel)
while true
tup = take!(simchannel)
println("Got new sim $tup")
if tup === nothing
println("Done with thread $(Threads.threadid())")
return
end
iter,sim = tup;
testmodel = covid_model(;sim...)
println("About to run model!")
adf,mdf = run!(testmodel,step_covperson!,stepcovmodel!,365; adata=[],mdata=[:day,:ninfected,:nquarantined,:tottestcost])
println("Finished sim $tup")
put!(dfchannel,(iter,adf,mdf,(simid=iter,sim...)))
end
end
I see printed messages like:
Got new sim (1, (n = 10000, density = 7.957747154594767, infprob = 0.008, testevery = 14, poolsize = 1, quarduration = 14, costoftest = 120.0, limitdet = 1000.0))
but I never see
About to run model!
So at some point after it takes the message from its channel, and before it gets to the println for that message… everything halts.
I’m pretty sure that’s not me doing something stupid, and the tasks aren’t printing the exit message. I don’t think I’m doing anything wrong here, so it feels like there’s a bug. Also it all worked a year ago.
WDYT?