Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
551ec17
Added start of metamodel code
rjplevin Sep 1, 2018
6681c98
Merge branch 'master' into meta-model
rjplevin Sep 1, 2018
ab2ffd2
WIP -- thoughs on meta-components
rjplevin Sep 11, 2018
a1ed5b2
Improved @delegate macro
rjplevin Sep 11, 2018
aa43cf0
WIP - Continued design work
rjplevin Sep 12, 2018
13d62e8
WIP - Notes on MetaComponents
rjplevin Sep 12, 2018
b3baf32
Merge branch 'port-0.7' into meta-model
rjplevin Sep 27, 2018
85419a2
WIP - continue design work
rjplevin Sep 28, 2018
0533eb8
WIP - developing new macro
rjplevin Oct 1, 2018
0bc9321
Merge branch 'master' into meta-model
rjplevin Oct 12, 2018
fda38cb
WIP - composite components
rjplevin Oct 22, 2018
aa5b709
Merge branch 'storage' into meta-model
rjplevin Oct 22, 2018
5373dcc
WIP -- Composite components checkpoint
rjplevin Oct 23, 2018
8172cd2
Merge branch 'master' into meta-model
rjplevin Oct 23, 2018
8a012cc
WIP - Composite component checkpoint.
rjplevin Oct 24, 2018
f204ff5
WIP - Composite Component checkpoint
rjplevin Oct 25, 2018
91bf72f
WIP - Composite Components checkpoint
rjplevin Oct 26, 2018
75a814a
Merge branch 'master' into meta-model
rjplevin Nov 14, 2018
3698440
WIP - Saved before switching to alternative approach
rjplevin Nov 14, 2018
f0e6df2
WIP commit
rjplevin Nov 16, 2018
759a33f
WIP - checkpoint
rjplevin Nov 17, 2018
cc1569e
Modified @delegate to handle more cases (kwargs, default values, extr…
rjplevin Nov 19, 2018
8d612f8
WIP - composite comps
rjplevin Nov 28, 2018
e5108b8
Trial version based on Classes.jl.
rjplevin Nov 29, 2018
fd90393
WIP - version using Classes.jl
rjplevin Nov 30, 2018
3802c37
Merge commit '832685110561f51ca63d7bf8ea2fd444505af7d9' into class-based
rjplevin Dec 3, 2018
0bac195
Add type params to ComponentInstance
rjplevin Dec 3, 2018
cd7a3fd
WIP - Checkpoint
rjplevin Dec 7, 2018
0a70826
update .gitignore
rjplevin Dec 7, 2018
d29cfa7
WIP - Checkpoint component comp work, other minor cleanup
rjplevin Dec 14, 2018
fc312e7
Merge branch 'master' into class-based
rjplevin Dec 19, 2018
4b7dad4
Updated abstract class names
rjplevin Dec 20, 2018
0be9e2c
WIP - changes to support class-based version of composites
rjplevin Jan 16, 2019
414e3f1
WIP - debugging composite components implementation
rjplevin Jan 29, 2019
d03f5d7
WIP -- debugging composites
rjplevin Jan 31, 2019
c475db3
WIP commit
rjplevin Feb 1, 2019
4a89d0e
WIP - Passing 436 tests...
rjplevin Feb 1, 2019
0ed47b3
Merge branch 'master' into class-based
rjplevin Feb 1, 2019
05473ae
WIP - Debugging composites
rjplevin Feb 4, 2019
ea37c60
WIP - Composite Components
rjplevin Feb 5, 2019
1a18703
- Temporarily disabled loading of non-core files for debugging
rjplevin Feb 8, 2019
84798e9
- Removed deprecated @method macro
rjplevin Feb 12, 2019
f2aa318
WIP commit.
rjplevin Feb 14, 2019
d7deb33
WIP
rjplevin Feb 15, 2019
576f3e1
Created a file to think about restructuring the "Def" space into "reg…
rjplevin Feb 15, 2019
46ae936
Pass line numbers through for components' run_timestep and init funct…
rjplevin Feb 20, 2019
1328710
WIP check-in - working through tests.
rjplevin Feb 26, 2019
be1d2aa
WIP - Numerous changes to get tests working
rjplevin Feb 28, 2019
c0f0ea9
WIP - debugging
rjplevin Mar 1, 2019
08f23c2
Merge commit 'd553b622ac988e74da9463d1da19262b0991eaf9' into class-based
rjplevin Mar 5, 2019
19f430d
WIP check-in
rjplevin Mar 7, 2019
74641ce
Nearly all tests now working. Still WIP, however.
rjplevin Mar 8, 2019
f242d29
Merge branch 'master' into class-based
rjplevin Mar 9, 2019
da767d0
Add ReshapedDistribution (fixup last merge)
rjplevin Mar 10, 2019
882f277
WIP - debugging composites
rjplevin Mar 25, 2019
50b9db6
WIP -- first working version of @defcomposite. Still missing the "bin…
rjplevin Mar 26, 2019
1f0b6e5
WIP - debugging composites
rjplevin Apr 1, 2019
b6b4d88
WIP - all test passing (except test_dimensions, still excluded.)
rjplevin Apr 1, 2019
2c48082
WIP
rjplevin Apr 4, 2019
ef6edc1
Disabled 'first' and 'last' args on add_comp! and replace_comp!
rjplevin Apr 8, 2019
59986c7
Adjusted tests to disabled first and last parameters to add_comp!.
rjplevin Apr 30, 2019
4cc1a8c
Consolidated some timestep functions
rjplevin May 3, 2019
a2a3c38
WIP - debugging model pkgs
rjplevin May 8, 2019
d8ffd5d
Fix logic in set_leftover_params!
corakingdon May 8, 2019
4eda904
WIP - testing model packages
rjplevin May 8, 2019
7b8b687
Merge branch 'master' into class-based
rjplevin May 8, 2019
1913093
- Added Classes to Project.toml
rjplevin May 8, 2019
fb75404
WIP - Debugging composite Dice. And a bit of a file reorg.
rjplevin May 14, 2019
79719e4
WIP - debugging composite-based MimiDice2013
rjplevin May 17, 2019
7266f07
Merge branch 'master' into class-based
rjplevin May 24, 2019
7c35f77
WIP - Debugging propagation of vars/params through composites
rjplevin May 26, 2019
0a554a1
Removed calls to deprecated reset_compdefs().
rjplevin Jun 4, 2019
2d2ee20
Further updates to tests
rjplevin Jun 4, 2019
31fe7a8
WIP -- Debugged composite model.
rjplevin Jun 4, 2019
0b63413
Added getindex methods for ModelInstance to simplify model interrogat…
rjplevin Jun 5, 2019
29fe5c9
Added methods to use strings representing data elements in a componen…
rjplevin Jun 5, 2019
0a81000
WIP
rjplevin Jun 8, 2019
aa517cd
- Add a combined sub-component/param/var namespace Dict to CompositeC…
rjplevin Jun 13, 2019
ccb2c67
WIP - Support for importing subcomp params and vars in a composite, a…
rjplevin Jun 18, 2019
e6d299f
WIP -- adding namespace support to components
rjplevin Jun 20, 2019
07e9f46
- Add support for component namespaces combining params and vars
rjplevin Aug 5, 2019
a88ef69
Merge branch 'master' into class-based
rjplevin Aug 5, 2019
e5c9ffd
Merge branch 'master' into class-based
rjplevin Aug 6, 2019
a1688e4
WIP: various adjustments to pass tests.
rjplevin Aug 8, 2019
ba78763
WIP:
rjplevin Aug 9, 2019
eaae4ca
WIP - Bug fixing and some cleanup. All tests working currently.
rjplevin Aug 12, 2019
8cd8460
- Removed component def's variables and parameters slots, using a sin…
rjplevin Aug 15, 2019
04f4e99
Replaced 'exports' optional arg to add_comp!() with 'rename', a list …
rjplevin Aug 15, 2019
7fd5be9
- Namespace import propagation is now working, as are connections def…
rjplevin Aug 21, 2019
ade53b0
WIP -- Continue testing composites
rjplevin Aug 22, 2019
602e23e
WIP: Merge branch 'master' into class-based
rjplevin Sep 28, 2019
081ab79
WIP: fix tests in merger of master into class-based
rjplevin Sep 28, 2019
48724ae
WIP: All Mimi tests are passing on the merged 'class-based' branch. N…
rjplevin Sep 28, 2019
07b7b80
Added some extra support for legacy models.
rjplevin Sep 28, 2019
a537915
Make label-checking optional.
rjplevin Sep 30, 2019
43c5f00
Add funcs to smooth over difference between DatumDef and DatumDefRefe…
rjplevin Oct 1, 2019
9fe5472
Update dependency on MimiFUND
rjplevin Oct 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ docs/site/
.DS_Store
benchmark/tune.json
docs/Manifest.toml
types-old.jl
.vscode
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.9.5-DEV"

[deps]
CSVFiles = "5d742f6a-9f54-50ce-8119-2520741973ca"
Classes = "1a9c1350-211b-5766-99cd-4544d885a0d1"
Compose = "a81c6b42-2e10-5240-aca2-a61377ecd94b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
Binary file added docs/src/figs/Mimi-model-schematic-v3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
82 changes: 82 additions & 0 deletions docs/src/internals/composite_components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Composite Components

## Goals

In Mimi v0.4, we have two levels of model elements, (i) `Model` and (ii) `Component`. (For now, we ignore the distinction between model / component "definition" and "instance" types.) The primary goal of the `MetaComponent` construct is to extend this structure recursively to _N_ levels, by allowing a `MetaComponent` to contain other `MetaComponent`s as well as `LeafComponent`s, which cannot contain other components.

## Major elements
This suggests three types of elements:

1. `LeafComponent(Def|Instance)` -- equivalent to the Mimi v0.4 `Component(Def|Instance)` concept.

1. `MetaComponent(Def|Instance)` -- presents the same API as a `LeafComponent(Def|Instance)`, but the variables and parameters it exposes are the aggregated sets of variables and parameters exposed by its components, each of which can be a `MetaComponent` or `LeafComponent`. A `MetaComponentInstance` creates no new storage for variables and parameters; it references the storage in its internal components. By default, the `run_timestep` method of a `MetaComponentInstance` simply calls the `run_timestep` method of each of its internal components in dependency order.

1. `Model` -- Contains a top-level `MetaComponentInstance` that holds all the actual user-defined components, which are instances of `MetaComponentInstance` or `LeafComponentInstance`. The API for `Model` delegates some calls to its top-level `MetaComponentInstance` while providing additional functionality including running a Monte Carlo simulation.

## Implementation Notes

### Model

* A `Model` will be defined using the `@defmodel` macro.

* As with the currently defined (but not exported) `@defmodel`, component ordering will be determined automatically based on defined connections, with loops avoided by referencing timestep `[t-1]`. This simplifies the API for `addcomponent!`.

* We will add support for two optional functions defined inside `@defmodel`:
* `before(m::Model)`, called before the model runs its first timestep
* `after(m:Model)`, called after the model runs its final timestep.

* A `Model` will be implemented as a wrapper around a single top-level `MetaComponent` that handles the ordering and iteration over sub-components. (In an OOP language, `Model` would subclass `MetaComponent`, but in Julia, we use composition.)

![MetaComponent Schematic](../figs/Mimi-model-schematic-v3.png)


### MetaComponent

* Defined using `@defcomp` as with `LeafComponent`. It's "meta" nature is defined by including a new term:

`subcomps = [sc1, sc2, sc3, ...]`, where the referenced sub-components (`sc1`, etc.) refer to previously defined `ComponentId`s.

* A `MetaComponent`'s `run_timestep` function is optional. The default function simply calls `run_timestep(subcomps::Vector)` to iterate over sub-components and calls `run_timestep` on each. If a `MetaComponent` defines its own `run_timestep` function, it should either call `run_timestep` on the vector of sub-components or perform a variant of this function itself.

* The `@defcomp` macro allows definition of an optional `init` method. To this, we will add support for an `after` method as in `@defmodel`. We will allow `before` as an alias for `init` (perhaps with a deprecation) for consistency with `@defmodel`.

## Other Notes

* Currently, `run()` calls `_run_components(mi, clock, firsts, lasts, comp_clocks)` with simple vectors of firsts, lasts, and comp_clocks. To handle this with the recursive component structure:

* Aggregate from the bottom up building `_firsts` and `_lasts` in each `MetaComponentInstance` holding the values for its sub-components.

* Also store the `MetaComponentInstance`'s own summary `first` and `last` which are just `min(firsts)` and `max(lasts)`, respectively.

* Currently, the `run()` function creates a vector of `Clock` instances, corresponding to each model component. I see two options here:

1. Extend the current approach to have each `MetaComponentInstance` hold a vector of `Clock` instances for its sub-components.

2. Store a `Clock` instance with each `MetaComponentInstance` or `LeafComponentInstance` and provide a recursive method to reset all clocks.


### Other stuff

* This might be is a good time to reconsider the implementation of external parameters. The main question is about naming these and whether they need to be globally unique or merely unique within a (meta) component.

* Unit conversion components should be simple "multiplier" components that are bound with specific conversion factors, conceptually like a "closure" on a component.

* An "identity" component takes an input (external input, bound constant) and allows multiple components to access it. One issue is how to handle the type of argument. Could function wrappers be useful here?
* Identity is simply a unit conversion of 1.

* If > 1 component exports parameters of the same name, it's an error. At least one comp must rename.

* David suggested making composite comps immutable, generating a new one each time a change is made. (Why not just have the CompositeComponentInstance be immutable?)

## Notes from 9/21/18 Meeting

```
@defcomp foo begin
Component(bar; export=[var_1, var_2, param_1])
Component(Mimi.adder, comp_1; # rename locally as :comp_1
bind=[par_3 => 5, # set a parameter to a fixed value
par_4 => bar.var_1]) # connect a parameter to a variable


end
```
7 changes: 4 additions & 3 deletions examples/tutorial/02-two-region-model/two-region-model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ function construct_MyModel()

m = Model()

set_dimension!(m, :time, collect(2015:5:2110))
set_dimension!(m, :regions, [:Region1, :Region2, :Region3]) # Note that the regions of your model must be specified here
set_dimension!(m, :time, 2015:5:2110)
# Note that the regions of your model must be specified here
set_dimension!(m, :regions, [:Region1, :Region2, :Region3])

add_comp!(m, grosseconomy)
add_comp!(m, emissions)

set_param!(m, :grosseconomy, :l, l)
set_param!(m, :grosseconomy, :tfp, tfp)
set_param!(m, :grosseconomy, :s, s)
set_param!(m, :grosseconomy, :depk,depk)
set_param!(m, :grosseconomy, :depk, depk)
set_param!(m, :grosseconomy, :k0, k0)
set_param!(m, :grosseconomy, :share, 0.3)

Expand Down
48 changes: 20 additions & 28 deletions src/Mimi.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Mimi

using Classes
using DataFrames
using DataStructures
using Distributions
Expand All @@ -11,9 +12,10 @@ using StringBuilders
export
@defcomp,
@defsim,
@defcomposite,
MarginalModel,
Model,
add_comp!,
add_comp!,
components,
connect_param!,
create_marginal_model,
Expand Down Expand Up @@ -48,47 +50,37 @@ export
variable_dimensions,
variable_names

include("core/types.jl")

# After loading types, the rest can just be alphabetical
include("core/delegate.jl")
include("core/types/includes.jl")
#
# After loading types and delegation macro, the rest can be loaded in any order.
#
include("core/build.jl")
include("core/connections.jl")
include("core/defs.jl")
include("core/defcomp.jl")
include("core/defmodel.jl")
include("core/defcomposite.jl")
include("core/dimensions.jl")
include("core/instances.jl")
include("core/references.jl")
include("core/time.jl")
include("core/time_arrays.jl")
include("core/model.jl")
include("core/order.jl")
include("core/paths.jl")
include("core/show.jl")

include("mcs/mcs.jl") # need mcs types for explorer
include("explorer/explore.jl")
include("utils/graph.jl")
include("utils/plotting.jl")
include("utils/getdataframe.jl")
include("utils/graph.jl")
include("utils/lint_helper.jl")
include("utils/misc.jl")
include("utils/plotting.jl")

"""
load_comps(dirname::String="./components")

Call include() on all the files in the indicated directory `dirname`.
This avoids having modelers create a long list of include()
statements. Just put all the components in a directory.
"""
function load_comps(dirname::String="./components")
files = readdir(dirname)
for file in files
if endswith(file, ".jl")
pathname = joinpath(dirname, file)
include(pathname)
end
end
end

# Components are defined here to allow pre-compilation to work
function __init__()
compdir = joinpath(@__DIR__, "components")
load_comps(compdir)
end
# Load built-in components
include("components/adder.jl")
include("components/connector.jl")

end # module
2 changes: 0 additions & 2 deletions src/components/adder.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Mimi

# When evaluated in the __init__() function, the surrounding module
# is Main rather than Mimi.
@defcomp adder begin
add = Parameter(index=[time])
input = Parameter(index=[time])
Expand Down
42 changes: 42 additions & 0 deletions src/core/_preliminary.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Preliminary file to think through David's suggestion of splitting defs between "registered"
# readonly "templates" and user-constructed models so it's clear which functions operate on
# templates vs defs within a model.

@class ComponentDef <: NamedObj begin
comp_id::Union{Nothing, ComponentId}
variables::OrderedDict{Symbol, VariableDef}
parameters::OrderedDict{Symbol, ParameterDef}
dim_names::Set{Symbol}
end

@class CompositeComponentDef <: ComponentDef begin
comps_dict::OrderedDict{Symbol, AbstractComponentDef}
exports::ExportsDict
internal_param_conns::Vector{InternalParameterConnection}
external_params::Dict{Symbol, ModelParameter}
end

# Define these for building out a ModelDef, which reference the
# central definitions using the classes above.

@class mutable ModelComponentDef <: NamedObj begin
comp_id::ComponentId # references registered component def
comp_path::Union{Nothing, ComponentPath}
dim_dict::OrderedDict{Symbol, Union{Nothing, Dimension}}
first::Union{Nothing, Int}
last::Union{Nothing, Int}
is_uniform::Bool
end

@class mutable ModelCompositeComponentDef <: ModelComponentDef begin
comps_dict::OrderedDict{Symbol, AbstractModelComponentDef}
bindings::Vector{Binding}
exports::ExportsDict
external_param_conns::Vector{ExternalParameterConnection}
external_params::Dict{Symbol, ModelParameter}

# Names of external params that the ConnectorComps will use as their :input2 parameters.
backups::Vector{Symbol}

sorted_comps::Union{Nothing, Vector{Symbol}}
end
Loading