Skip to content

Commit

Permalink
Merge pull request #21 from MRC-CSO-SPHSU/develop
Browse files Browse the repository at this point in the history
Version 0.3
  • Loading branch information
AtiyahElsheikh authored Jan 14, 2023
2 parents 1b45727 + ce6a6b6 commit 40aec54
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 273 deletions.
47 changes: 41 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,45 @@ Releases
- V0.1.3 ( 2.12) : Utilties is a part of the SE* libraries (compatible with SE V0.1.3)

- **V0.2.0 (5.12.2022)** : Unified API of CreateX and Initialize functions (compatible with SE V0.2)
- Remark: main.jl is no longer maintained.

- V0.2.1 (7.12) : New Simulation Interface for 3 functions, doBirths!, doDeaths!, doDivorces, Improved API for parameter accessory functions, compatible with SE* Version 0.2.1
- V0.2.2 (8.12) : doMarriages (SE* V0.2.2)
- V0.2.3 (9.12) : adoptions, workTransitions, socialTransitions, ageTransitions (SE* V0.2.3)
- V0.2.4 (14.12) : adjusting to SimpleABM types of MA Version 0.4, improved model data structure
- V0.2.5 (21.12) : exploits some tuned simulation functions from SE* V0.2.5 and improved performance
- V0.2.6 (27.12) : Improved implementation of allocation algorithms (no temporary arrays), tuned do marriage algorithm (memoization can be avoided) & Improved runtime performance (3x faster & 4x less memory allocation and storage w.r.t. V0.2.5)
- V0.2.7 (6.1.2023) : (MALPM only) Memoization with domarriage alg can be done only externally (if desired). Employing newly tuned and exact API of four simulation functions. Optimized simulation (with deads removal) vs. normal simulation (without deads removal)
- V0.2.8 (8.1.2023) : (MALPM only) employing tuned API of assigning guardians
- **V0.3 (14-01-2022) : Making use of the rest of the fixed API of SE's Simulate function, further code simplification and tuning. Signficant memory allocation reduction and runtime performance improvement

Performance Progress History
============================

The following is the progress history of executing mainMA.jl on

Version | Runtime | # Memory Allocation | Storage used | Comment
0 | ~29 sec. | ~ 400 M | 12.5 GB | The state of LoneParentsModel.jl before starting this repo.
V0.2.3 | 29 sec. | ~ 360 M | ~ 14 GB | execution with main.jl was quite faster but consumed more memory and storage
V0.2.4 | 21.5 sec. | ~ 280 M | ~ 10.5 GB | MA Version 0.4
V0.2.5 | 20 sec. | ~ 155 M | ~ 8 GB |
V0.2.6 | 7.6 sec. | ~ 37 M | ~ 2.2 GB |
V0.2.8 | 6.3 sec. | ~ 24 M | ~ 1.6 GB |
V0.3 | 4.7 sec | ~ 380 K | ~ 90 MB |

Version | Runtime | # Memory Allocation | Storage used | Comment
--- | --- | --- | --- | ---
0 | ~29 sec. | ~ 400 M | 12.5 GB | The state of LoneParentsModel.jl before starting this repo.
V0.2.3 | 29 sec. | ~ 360 M | ~ 14 GB | execution with main.jl was quite faster but consumed more memory and storage
V0.2.4 | 21.5 sec. | ~ 280 M | ~ 10.5 GB | MA Version 0.4
V0.2.5 | 20 sec. | ~ 155 M | ~ 8 GB |
V0.2.6 | 7.6 sec. | ~ 37 M | ~ 2.2 GB |
V0.2.8 | 6.3 sec. | ~ 24 M | ~ 1.6 GB |
V0.3 | 4.7 sec | ~ 380 K | ~ 90 MB |







- V0.2.1 (7.12) : (MALPM only) New Simulation Interface for 3 functions, doBirths!, doDeaths!, doDivorces, Improved API for parameter accessory functions, compatible with SE* Version 0.2.1
- V0.2.2 (8.12) : (MALPM only) doMarriages (SE* V0.2.2)
- V0.2.3 (9.12) : (MALPM only) adoptions, workTransitions, socialTransitions, ageTransitions (SE* V0.2.3)
- V0.2.4 (14.12) : (MALPM only) adjusting to SimpleABM types of MA Version 0.4, improved model data structure
- V0.2.5 (21.12) : (MALPM only) exploits some tuned simulation functions from SE* V0.2.5 and improved performance (3x faster)
- V0.2.6 (27.12) : (MALPM only) Improved implementation of allocation algorithms (no temporary arrays), tuned do marriage algorithm (memoization can be avoided) & Improved runtime performance (3x faster & 4x less memory allocation and storage w.r.t. V0.2.5)
12 changes: 6 additions & 6 deletions mainMA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ include("mainMAHelpers.jl")
using MultiAgents: ABMSimulatorP
using MultiAgents: run!, setup!
using MALPM.Models: MAModel
using MALPM.Demography: LPMUKDemography, LPMUKDemographyOpt
using MALPM.Examples

const mainConfig = Light() # no input files, logging or flags (REPL Exec.)
# mainConfig = WithInputFiles()

lpmExample = LPMUKDemography() # remove deads
# lpmExample = LPMUKDemographyOpt() # don't remove deads
# lpmExample = LPMUKDemography() # don't remove deads
lpmExample = LPMUKDemographyOpt() # remove deads

const simPars, dataPars, pars = loadParameters(mainConfig)

Expand All @@ -28,10 +28,10 @@ const simPars, dataPars, pars = loadParameters(mainConfig)
# useful when executing from REPL
if mainConfig == Light()
simPars.seed = 0; seed!(simPars)
simPars.verbose = false
simPars.verbose = false
simPars.checkassumption = false
simPars.sleeptime = 0
pars.poppars.initialPop = 500
simPars.sleeptime = 0
pars.poppars.initialPop = 5000
end

const model = setupModel(dataPars, pars)
Expand Down
5 changes: 1 addition & 4 deletions mainMAHelpers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ addToLoadPath!("../MultiAgents.jl")

using SocioEconomics: SEVERSION, SEPATH, SESRCPATH

@assert SEVERSION == v"0.2.6"
@assert SEVERSION == v"0.3"

using SocioEconomics.ParamTypes

using SocioEconomics.XAgents

using SocioEconomics.Specification.Create
using SocioEconomics.Specification.Initialize
using SocioEconomics.Specification.Simulate

include("mainHelpers.jl")

Expand Down
4 changes: 3 additions & 1 deletion src/MALPM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Main components of LoneParentsModel simulation based on MultiAgents.jl package
module MALPM

include("./malpm/Models.jl")
include("./malpm/Demography.jl")
include("./malpm/Examples.jl")
include("./malpm/Simulate.jl")
include("./malpm/SimSetup.jl")

end # MALPM
15 changes: 6 additions & 9 deletions src/malpm/Demography.jl → src/malpm/Examples.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module Demography

"""
Example traits to express different models and configurations
"""
module Examples

import MultiAgents.Util: AbstractExample

export DemographyExample, LPMUKDemography, LPMUKDemographyOpt
Expand All @@ -14,10 +17,4 @@ struct LPMUKDemography <: DemographyExample end
"This is an attemp for improved algorthimic translation"
struct LPMUKDemographyOpt <: DemographyExample end


include("./demography/Population.jl")
include("./demography/Simulate.jl")
include("./demography/SimSetup.jl")


end # Demography
end
2 changes: 0 additions & 2 deletions src/malpm/Models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ alivePeople(model::MAModel) =
# Iterators.filter(person->alive(person),people) # Iterators did not show significant value sofar
houses(model::MAModel) = allagents(model.houses)
towns(model::MAModel) = allagents(model.towns)
#dataOf(model) = model.pop.data
dataOf(model) = model.data
add_person!(model, person) = add_agent!(model.pop, person)
remove_person!(model, personidx::Int) = kill_agent_at_opt!(personidx, model.pop)
add_house!(model, house) = add_agent!(model.houses, house)


allParameters(model::MAModel) = model.parameters
populationParameters(model::MAModel) = model.parameters.poppars
birthParameters(model::MAModel) = model.parameters.birthpars
Expand Down
110 changes: 110 additions & 0 deletions src/malpm/SimSetup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
module SimSetup

using Memoization

using MALPM.Models: MAModel, allPeople, birthParameters
using MALPM.Examples
using MALPM.Simulate: dodeaths!, dobirths!,
do_age_transitions!, do_work_transitions!, do_social_transitions!,
dodivorces!, domarriages!, do_assign_guardians!

using MultiAgents: AbstractABMSimulator
using MultiAgents: attach_pre_model_step!, attach_post_model_step!,
attach_agent_step!, currstep
using SocioEconomics.Utilities: setVerbose!, unsetVerbose!, setDelay!,
checkAssumptions!, ignoreAssumptions!, date2yearsmonths
using SocioEconomics.XAgents: age, isMale, isFemale, isSingle, alive, hasDependents
using SocioEconomics.API.Traits: FullPopulation, AlivePopulation
using SocioEconomics.Specification.SimulateNew: death!, birth!, divorce!, marriage!,
assign_guardian!, age_transition!, work_transition!, social_transition!

import SocioEconomics.API.ModelFunc: share_childless_men, eligible_women
import MultiAgents: setup!, verbose
#export setup!

function setupCommon!(sim::AbstractABMSimulator)

verbose(sim) ? setVerbose!() : unsetVerbose!()
setDelay!(sim.parameters.sleeptime)
sim.parameters.checkassumption ? checkAssumptions!() :
ignoreAssumptions!()

attach_post_model_step!(sim,dodeaths!)
attach_post_model_step!(sim,do_assign_guardians!)
attach_post_model_step!(sim,dobirths!)
attach_post_model_step!(sim,domarriages!)

nothing
end

_popfeature(::LPMUKDemography) = FullPopulation()
_popfeature(::LPMUKDemographyOpt) = AlivePopulation()

deathstep!(person, model, sim, example) =
death!(person, currstep(sim),model,_popfeature(example))

birthstep!(person, model, sim, example) =
birth!(person, currstep(sim),model,_popfeature(example))

divorcestep!(person, model, sim, example) =
divorce!(person, currstep(sim), model, _popfeature(example))

marriagestep!(person, model, sim, example) =
marriage!(person, currstep(sim), model, _popfeature(example))

assign_guardian_step!(person, model, sim, example) =
assign_guardian!(person, currstep(sim), model, _popfeature(example))

age_transition_step!(person, model, sim, example) =
age_transition!(person, currstep(sim), model, _popfeature(example))

work_transition_step!(person, model, sim, example) =
work_transition!(person, currstep(sim), model, _popfeature(example))

social_transition_step!(person, model, sim, example) =
social_transition!(person, currstep(sim), model, _popfeature(example))

_ageclass(person) = trunc(Int, age(person)/10)
@memoize Dict function share_childless_men(model::MAModel, ageclass :: Int)
nAll = 0
nNoC = 0
for p in Iterators.filter(x->alive(x) && isMale(x) && _ageclass(x) == ageclass, allPeople(model))
nAll += 1
if !hasDependents(p)
nNoC += 1
end
end
return nNoC / nAll
end

@memoize eligible_women(model::MAModel) =
[f for f in allPeople(model) if isFemale(f) && alive(f) &&
isSingle(f) && age(f) > birthParameters(model).minPregnancyAge]

function reset_cache_marriages(model,sim,::LPMUKDemography)
#@info "cache reset at $(date2yearsmonths(currstep(sim)))"
Memoization.empty_cache!(share_childless_men)
Memoization.empty_cache!(eligible_women)
end

"set up simulation functions where dead people are removed"
function setup!(sim::AbstractABMSimulator, example::LPMUKDemography)
attach_agent_step!(sim,age_transition_step!)
attach_agent_step!(sim,divorcestep!)
attach_agent_step!(sim,work_transition_step!)
attach_agent_step!(sim,social_transition_step!)
# attach_agent_step!(sim,marriagestep!) # does not seem to work properly (may be due to memoization)
setupCommon!(sim)
nothing
end

function setup!(sim::AbstractABMSimulator,example::LPMUKDemographyOpt)
attach_post_model_step!(sim,do_age_transitions!)
attach_post_model_step!(sim,dodivorces!)
attach_post_model_step!(sim,do_work_transitions!)
attach_post_model_step!(sim,do_social_transitions!)
setupCommon!(sim)
nothing
end

end # SimSetup
99 changes: 99 additions & 0 deletions src/malpm/Simulate.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""
Main simulation functions for the demographic aspect of LPM.
"""

module Simulate

using MultiAgents: AbstractMABM, AbstractABMSimulator
using MultiAgents: currstep
using MALPM.Examples
using SocioEconomics
using SocioEconomics.XAgents: Person
using SocioEconomics.API.Traits: FullPopulation, AlivePopulation,
SimProcess, Death, Birth, Marriage,
AssignGuardian, AgeTransition,
WorkTransition, SocialTransition
using SocioEconomics.Utilities: date2yearsmonths
import SocioEconomics.Specification.SimulateNew: dodeaths!, dobirths!,
dodivorces!, domarriages!, do_assign_guardians!,
do_age_transitions!, do_work_transitions!, do_social_transitions!

_popfeature(::LPMUKDemography) = FullPopulation()
_popfeature(::LPMUKDemographyOpt) = AlivePopulation()

_init_return(::LPMUKDemographyOpt,::SimProcess) = 0

const retDeath = Person[]
_init_return(::LPMUKDemography,::Death) = retDeath

function dodeaths!(model, sim, example::DemographyExample)
ret = _init_return(example,Death())
ret = dodeaths!(model,currstep(sim),_popfeature(example),ret)
#=years, months = date2yearsmonths(currstep(sim))
@info "# of deaths $(years) $(months+1) : $(length(ret.people))"=#
nothing
end # function doDeaths!

const retBirth = Person[]
_init_return(::LPMUKDemography,::Birth) = retBirth

function dobirths!(model, sim, example::DemographyExample)
ret = _init_return(example,Birth())
ret = dobirths!(model,currstep(sim),_popfeature(example),ret)
nothing
end

const retBirth = Person[]
_init_return(::LPMUKDemography,::Birth) = retBirth

function dodivorces!(model, sim, example::DemographyExample)
ret = _init_return(example, Birth())
ret = dodivorces!(model,currstep(sim),_popfeature(example),ret)
nothing
end

const retMarriage = Person[]
_init_return(::LPMUKDemography,::Marriage) = retMarriage

function domarriages!(model, sim, example::DemographyExample)
ret = _init_return(example, Marriage())
ret = domarriages!(model,currstep(sim),_popfeature(example),ret)
end

const retAGuarians = Person[]
_init_return(::LPMUKDemography,::AssignGuardian) = retAGuarians

function do_assign_guardians!(model::AbstractMABM, sim::AbstractABMSimulator, example::DemographyExample)
ret = _init_return(example, AssignGuardian())
ret = do_assign_guardians!(model,currstep(sim),_popfeature(example),ret)
nothing
end

_init_return(::LPMUKDemography,pr::AgeTransition) =
_init_return(LPMUKDemographyOpt(),pr)

function do_age_transitions!(model::AbstractMABM, sim::AbstractABMSimulator, example::DemographyExample)
ret = _init_return(example,AgeTransition())
ret = do_age_transitions!(model,currstep(sim),_popfeature(example),ret)
nothing
end

_init_return(::LPMUKDemography,pr::WorkTransition) =
_init_return(LPMUKDemographyOpt(),pr)

function do_work_transitions!(model::AbstractMABM, sim, example::DemographyExample)
ret = _init_return(example,WorkTransition())
ret = do_work_transitions!(model,currstep(sim),_popfeature(example),ret)
nothing
end

_init_return(::LPMUKDemography,pr::SocialTransition) =
_init_return(LPMUKDemographyOpt(),pr)

function do_social_transitions!(model::AbstractMABM, sim, example::DemographyExample)
ret = _init_return(example,SocialTransition())
ret = do_social_transitions!(model,currstep(sim),_popfeature(example),ret)
nothing
end

end # Simulate
Loading

0 comments on commit 40aec54

Please sign in to comment.