Cupid as a Framework Specific Modeling Language

Cupid:
A Smart Development Environment
for Earth System Models
Rocky Dunlap
research sponsored by NASA/ROSES
1
ESMF/NUOPC
• A framework for
constructing earth system
models from components
• Hierarchical architecture
• Functions for coupling and
data exchange, including
representing numerical
grids and interpolation
• A layer on top of ESMF
• Standardized way of using
ESMF to promote a
common model
architecture
• Generic components that
can be specialized
2
Adopting a Scientific Framework
• Scientific frameworks provide:
– an overall structure for the application
– reusable, domain-specific functionality
• Adopting a scientific framework requires:
– understanding the framework API
– writing framework completion code to implement
framework concepts
– respecting framework constraints
3
Framework Specific
Modeling Languages
• Explicit encoding of domain-specific concepts
provided by a framework API
• Framework concepts are mapped to code
patterns
• Two-way mapping:
– Reverse engineering of existing code
– Forward engineering - code generation
Antkiewicz, Michał, and Krzysztof Czarnecki. "Framework-specific modeling languages with
round-trip engineering." Model Driven Engineering Languages and Systems (2006): 692-706.
4
source code editor
framework-specific model
5
Framework
Completion Code
Framework
Specific Modeling
Language
NUOPC
Model
Implements
Set Services
Name
Calls Generic Set
Services
Registers Init
Phase 1
Registers Init
Phase 2
Implements
Init Phase 1
6
Structural Mapping Types
Structural Pattern Expression
Structural Elements Matched
module
Matches a Fortran module
m moduleName
Matches the name of the module m
m subroutine
Matches a subroutine defined inside
module m
m subroutine: “name(type1, type2, ...)”
or
m subroutine: “*(*)”
Matches a subroutine defined inside
module m with the given signature. The
wildcard * can be used in place of the
name and/or types.
s subroutineName
Matches the name of subroutine s
s formalParam: i
Matches the ith formal parameter of
subroutine s
7
Structural Mapping Types (cont)
Structural Pattern Expression
Structural Elements Matched
s call
Matches a subroutine call within the
implementation of subroutine s
s call: “name” [definedInModule:
“moduleName”]
Matches a subroutine call within the
implementation of subroutine s to a
subroutine with the given name.
Optionally restricts matches to
subroutines defined in a certain named
module.
c argValByIndex: i
Matches the ith argument value for the
call c
c argValByKeyword: “keyword”
Matches the value of the argument with
the given keyword for the call c
8
Mappings
NUOPC Model
module
Implements Set Services
subroutine: “*(type(ESMF_GridComp), integer)”
subroutineName
Name
Calls Generic Set
Services
...
call: “routine_SetServices”
definedInModule: “NUOPC_Model”
Registers Init Phase 0
call: “ESMF_GridCompSetEntryPoint”
Registers Init Phase 1
call: “ESMF_GridCompSetEntryPoint”
Registers Init Phase 2
call: “ESMF_GridCompSetEntryPoint”
Implements Init
Phase 0
subroutine: “*(type(ESMF_GridComp),
type(ESMF_State), type(ESMF_State),
type(ESMF_Clock), integer)”
Implements Init
Phase 1
subroutine: “*(type(ESMF_GridComp),
type(ESMF_State), type(ESMF_State),
type(ESMF_Clock), integer)”
8
Constraints
NUOPC Model
[1]
module
Implements Set Services
[1]
required by
framework
(violations allowed
required
by
during development)
framework AND
essential to match
set services
(never violated)
optional by
framework
[0..1]
[1]
...
![1]
[0..1]
[1]
[1]
subroutine: “*(type(ESMF_GridComp), integer)”
subroutineName
Name
Calls Generic Set
Services
call: “routine_SetServices”
definedInModule: “NUOPC_Model”
Registers Init Phase 0
call: “ESMF_GridCompSetEntryPoint”
Registers Init Phase 1
call: “ESMF_GridCompSetEntryPoint”
Registers Init Phase 2
call: “ESMF_GridCompSetEntryPoint”
Implements Init
Phase 0
subroutine: “*(type(ESMF_GridComp),
type(ESMF_State), type(ESMF_State),
type(ESMF_Clock), integer)”
Implements Init
Phase 1
subroutine: “*(type(ESMF_GridComp),
type(ESMF_State), type(ESMF_State),
type(ESMF_Clock), integer)”
8
Another Part of the FSML
Implements Init
Phase 1
[1]
[1]
[0..*]
subroutine: “*(type(ESMF_GridComp), type(ESMF_State),
type(ESMF_State), type(ESMF_Clock), integer)”
importStateParam
formalParam: 2
exportStateParam
formalParam: 3
advertisesImportField
[1]
essential
![1]
derived
[1]
call: NUOPC_StateAdvertiseField
addsToState
addsToImportState
standardName
argValByIndex: 1
OCL: self.addsToState ==
self.parent.importStatePa
ram
argValByKeyword:
“StandardName”
path expression
Partial Code for Init Phase 1
12
Making the FSML More Concise
Implements Init
Phase 1
[1]
[1]
[0..*]
subroutine: “*(type(ESMF_GridComp), type(ESMF_State),
type(ESMF_State), type(ESMF_Clock), integer)”
importStateParam
formalParam: 2
exportStateParam
formalParam: 3
advertisesImportField
[1]
![1]
[1]
embedded path
expression
call: NUOPC_StateAdvertiseField
addsToState
argValByIndex: 1
addsToImportState
argValByIndex: 1 sameAs:
(../../ formalParam: 2)
standardName
argValByKeyword:
“StandardName”
Realize Bi-directional Mappings
code
queries
module atm
use ESMF
use NUOPC
use NUOPC_Model
Virtual Program Graph &
Abstract Syntax Tree
subroutine setservices(gcomp, rc)
....
end subroutine
parse
subroutine advance(gcomp, rc)
....
end subroutine
rewrite
....
end module
code
transformations
Photran Eclipse Plugin
14
Status
• FSML concepts:
– NUOPC Model, Set Services, Init Phase 1, Init
Phase 2, Advertise Import/Export Field, Realize
Import/Export Field, Attach Model Advance
method
• Mappings: defined on as “as needed” basis
– Code queries for every mapping (reverse dir.)
– Only a few code transformations (forward dir.)
15
Issues & Opportunities
• Dealing with different versions of the framework,
API releases, etc.
• FSML: Should we take a coarse-grained or finegrained approach?
– coarse-grained: Full architecture of NUOPC
application; Models, Mediators, Connectors, etc.
– fine-grained: Focus on NUOPC Model with high detail
• Limitations of static analysis
– How far will it take us?
– Inclusion of control flow hints for the user:
conditionals and loops
– How would this tool work in a dynamic environment?
16
Old Slides
17
Constraints
NUOPC Model
required by framework
(violations allowed
during development)
[1]
Implements Set Services
[1]
required by framework AND
essential in order to match
parent feature
(never violated)
![1]
[0..1]
[1]
[1]
optional by framework
Name
Calls Generic Set
Services
Registers Init Phase 0
Registers Init Phase 1
Registers Init Phase 2
[0..1]
Implements Init
Phase 0
[1]
Implements Init
Phase 1
...
8
19
Image taken from Figure 2 of:
Antkiewicz, Michał, and Krzysztof Czarnecki. "Framework-specific modeling
languages with round-trip engineering." Model Driven Engineering
Languages and Systems (2006): 692-706.
http://gp.uwaterloo.ca/sites/default/files/models06.pdf
20
Synchronization States and
Reconciliation (Antkiewicz)
• synchronization state: forward addition
– a feature added to the asserted model
– e.g., a new import field is advertised
• reconciliation decision: enforce
– make code consistent with asserted model
– e.g., adds calls to NUOPC_StateAdvertiseField()
21
Synchronization States and
Reconciliation (Antkiewicz)
• synchronization state: reverse removal
– a feature removed from code
– e.g., call to NUOPC_StateRealizeField() removed
• reconciliation decision: update
– make asserted model consistent with code
– e.g., remove realize field feature from asserted model
• key features used to match concepts between
code and model
– e.g., use field short name because they are unique
22
Forward Engineering (Antkiewicz)
• Example feature (variation point):
– advertise import field “sea_surface_temperature”
• Code transformations
– need to add a call to:
NUOPC_StateAdvertiseField(importState,
StandardName=“sea_surface_temperature”, rc=rc)
– where to add the call (initialize phase 1)
• how to determine which subroutine? (e.g., look at SetServices?)
• what if it doesn’t exist? (e.g., add it automatically?)
– name of import state parameter (second parameter of
subroutine)
– add error checking calls? (need to know name of rc
parameter)
23
Reverse Engineering (Antkiewicz)
• Start with existing source code (e.g., a Fortran module)
• Code queries used to build model
– Question: Is the Fortran module a NUOPC Model?
– Does it use ESMF, NUOPC, and NUOPC_Model?
• Is this enough?
– Does it have a SetServices that calls the generic
NUOPC_Model routine_SetServices()
• Keep it mind it could have an alias, e.g.,
model_routine_SetServices()
• Support for partial concepts
– e.g., this is a NUOPC_Model but it fails to call the generic
routine_setServices() method
– required because we are helping the user to build up
implementation incrementally
24
Partial Framework Specific Modeling Language for NUOPC
Maps to a Fortran module
Name of model
True if module uses ESMF,
NUOPC, NUOPC_Model
Reference
Maps to subroutine
True if has correct
parameter types (gcomp, rc)
True if calls routine_SetServices
in NUOPC_Model
True if sets entry point
for init phase 1, 2
25
Code Queries
26
Candidates / False Positives
• Goal: Given code for a (partial) NUOPC
Model, find the SetServices routine
• Initially ALL subroutines in the module are
candidates
• Look for clues:
– parameter types (ESMF_GridComp, Integer)
– calls to routine_SetServices() in NUOPC_Model
– calls to ESMF_GridCompSetServices()
– calls to ESMF_MethodAdd()
27
Has 2 parameters of type
ESMF_Grid and Integer
Calls routine_SetServices()
If there is ONE subroutine
here, it is likely the right one.
BUT, if there are ZERO
subroutines, then we have to
consider other CANDIDATES.
Calls ESMF_GridCompSetServices()
28