Hello, This is a continuation of previous thread multithreading in agents. I have put an example here which overall is weird as a model but gives idea of memory allocation regions in my original model. Please ignore if you feel im collecting same data again and again . Its not the case in original model, all these collections are required. I just wanted to setup example in a way that there are allocations.
Original model is more complex but with this example I have pointed out locations where I feel issue reside.
using Agents, Random, StaticArrays
@agent struct SocialAgent(ContinuousAgent{2, Float64})
mass::Float64
count::Int64
status::Symbol
type::Symbol
end
function ball_model(; speed = 0.002)
space2d = ContinuousSpace((1, 1); spacing = 0.02)
model = StandardABM(SocialAgent, space2d; agent_step!, properties = Dict(:dt => 1.0, :xx => []),
rng = MersenneTwister(42))
# And add some agents to the model
for ind in 1:500
pos = Tuple(rand(abmrng(model), 2))
type = ind β€ 0.5*500 ? :A : :B
status = type == :A ? :yes : :no
count = 0
vel = sincos(2Ο * rand(abmrng(model))) .* speed
add_agent!(pos, model, vel, 1.0, count, status, type)
end
return model
end
function interact!(a1, a2)
### Choosing Interaction based on cell type and status of Cell
if (a2.type == :A) && (a1.type == :B )
a1.status = :blank
a1.vel = @SVector[0.0,0.0]
end
if (a2.type == :B) && (a1.type == :A)
a2.status = :blank
a2.vel = @SVector[0.0,0.0]
end
end
function rule!(agent, model)
if agent.status == :yes
agent.count += 1
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
if agent.count == 5
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
agent.count = 0
end
end
if agent.status == :no
agent.count += 1
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
if agent.count == 5
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
agent.count = 0
agent.status == :blank
end
end
if agent.status == :blank
agent.count += 1
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
if agent.count == 5
push!(model.xx, (agent.id, abmtime(model), agent.count, agent.status))
agent.count = 0
agent.status == :no
end
end
end
function agent_step!(agent, model)
rule!(agent, model)
move_agent!(agent, model, model.dt)
end
function model_step!(model)
for (a1, a2) in interacting_pairs(model, 0.012, :nearest)
interact!(a1, a2)
elastic_collision!(a1, a2, :mass)
end
end
model = ball_model()
function runn(model)
x = zeros(100)
for i in 1:100
model = ball_model()
run!(model, 160)
x[i] = sum(stack(model.xx, dims = 1 )[:,3])
end
return x
end
@time runn(model)
julia> @time runn(model)
4.937694 seconds (63.26 M allocations: 4.141 GiB, 4.96% gc time)
Thank you for help