spagnuolocarmine / ABM.jl

A Multi Agent Based Simulation engine in Julia language
MIT License
5 stars 0 forks source link

Performance tests #2

Open pszufe opened 5 years ago

pszufe commented 5 years ago

We need to have some performance tests to understand ho changes affect the library.

Here is a plain Julia rewrite of the classic sheep simulation from Netlogo. We need to:

  1. Implement this in ABM.jl
  2. Run the performance tests (using BenchmarkToools.jl of ABM.jl vs plain Julia to have a benchmark level of overhead of the ABM.jl
  3. Perhaps this test could run along the set of other library tests
using Random, Statistics, Distributions, DataFrames

mutable struct Sheep
    angle::Float64
    x::Float64
    y::Float64
    energy::Float64
end

mutable struct Params
    sheep_energ_per_tick::Int64
    food_val_per_tick::Int64
    birth_treshold::Int64
    birth_cost::Int64
    nsheep::Int64
    sizex::Int64
    sizey::Int64
end

const mpars = Params(10,20,2000,1000,700,35,35)

function move(s::Sheep)
    s.angle += rand(Uniform(0,π/2)) + rand(Uniform(-π/2, 0))
    s.x += cos(s.angle)
    s.y += sin(s.angle)
end

function patch(s::Sheep, grid)
    floor(Int, mod(s.y, size(grid, 1))) + 1,
    floor(Int, mod(s.x, size(grid, 2))) + 1
end

function tick(s::Sheep, grid)
    move(s)
    s.energy -= mpars.sheep_energ_per_tick # parameter; in NetLogo we have 10
    x, y = patch(s, grid)
    if grid[x,y] ≥ mpars.food_val_per_tick # parameter
        s.energy += mpars.food_val_per_tick
        grid[x,y] -= mpars.food_val_per_tick
    end
end

function tick(sset::Set{Sheep})
    for s in sset
        if s.energy > mpars.birth_treshold
            s.energy -= mpars.birth_cost # parameter
            push!(sset, Sheep(s.angle, s.x, s.y, mpars.birth_cost))
        end
        if s.energy ≤ 0
            pop!(sset, s)
        end
    end
end

function tick(grid::Matrix{Int})
    grid .= min.(grid .+ 10, 100) # parameter
end

function setup()
    rand(0:100, mpars.sizex, mpars.sizey),
    Set([Sheep(2π*rand(), mpars.sizey*rand(), mpars.sizex*rand(),
               mpars.birth_cost) for i in 1:mpars.nsheep])
end

function stats(grid, sset)
    sheepcount = zeros(Int, size(grid));
    for s in sset
        (x, y) = patch(s, grid)
        sheepcount[x, y] += 1
    end
    sum(grid), length(sset), cor(vec(sheepcount), vec(grid))
end

function tick(grid, sset)
    for s in sset
        tick(s, grid)
    end
    tick(sset)
    tick(grid)
    stats(grid, sset)
end

function runsim()
    grid, sset = setup()
    gs, ss, cs = stats(grid, sset)
    df = DataFrame(gs=gs, ss=ss, cs=cs)
    for i in 1:200 # parameter; change to 10000 for performance testing
        push!(df, tick(grid, sset))
    end
    df, grid, sset
end
spagnuolocarmine commented 5 years ago

Yes I agree. But we have to keep in mind that this kind of model does not support double buffering on the agent memory and on the agent position field.

On of the most attractive feature fo the ABM.jl is the double buffering strategy.

Anyway, I am currently developing the boids.jl, the Flocker simulation in MASOM. For now it is only a sketch simulation (need to be implemented the boids logic). We can use this model to write this new one, in order to understand the ABM.jl workflow.

pszufe commented 5 years ago

the important thing is to have benchmark ABM vs plain Julia to measure the performance loss.

Double buffering is needed for the distributed computing right?

spagnuolocarmine commented 5 years ago

the important thing is to have benchmark ABM vs plain Julia to measure the performance loss.

Double buffering is needed for the distributed computing right?

Not only, the double buffering is an enabling technology for distributed, but in this case we also would like to support the double buffering in simulation. In this way the system ensures that each agent at time i can see the status of the simulation at time i-1, that is a strict requirement for several ABM simulation (such as Game-of-Life, or Network Game).

pszufe commented 5 years ago

OK. Does MASON support double buffering? because this is one thing to consider (all API now is a kind of MASON clone which is think is very good).

spagnuolocarmine commented 5 years ago

OK. Does MASON support double buffering? because this is one thing to consider (all API now is a kind of MASON clone which is think is very good).

No MASON does not support DB, but we think that we need several improvement compared to MASON maintaining the same API.