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 2 A layer on top of ESMF Standardized way of using ESMF to promote a common model architecture Generic components that can be specialized
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 4 Antkiewicz, Michał, and Krzysztof Czarnecki. "Framework-specific modeling languages with round-trip engineering." Model Driven Engineering Languages and Systems (2006):
source code editorframework-specific model 5
6 NUOPC Model Implements Set Services Calls Generic Set Services Registers Init Phase 1 Registers Init Phase 2 Implements Init Phase 1 Framework Completion Code Framework Specific Modeling Language Name
Structural Mapping Types 7 Structural Pattern ExpressionStructural 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 i th formal parameter of subroutine s
Structural Mapping Types (cont) 8 Structural Pattern ExpressionStructural 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 i th argument value for the call c c argValByKeyword: “keyword” Matches the value of the argument with the given keyword for the call c
Mappings 8 NUOPC Model Implements Set Services Calls Generic Set Services Registers Init Phase 1 Registers Init Phase 2 Implements Init Phase 1 module subroutine: “*(type(ESMF_GridComp), integer)” call: “routine_SetServices” definedInModule: “NUOPC_Model” subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)” Name subroutineName Registers Init Phase 0 call: “ESMF_GridCompSetEntryPoint” Implements Init Phase 0... call: “ESMF_GridCompSetEntryPoint” subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)”
Constraints 8 NUOPC Model Implements Set Services Calls Generic Set Services Registers Init Phase 1 Registers Init Phase 2 Implements Init Phase 1 module subroutine: “*(type(ESMF_GridComp), integer)” call: “routine_SetServices” definedInModule: “NUOPC_Model” subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)” Name subroutineName Registers Init Phase 0 call: “ESMF_GridCompSetEntryPoint” Implements Init Phase 0... call: “ESMF_GridCompSetEntryPoint” subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)” [1] ![1] [0..1] [1] [0..1] [1] required by framework (violations allowed during development) optional by framework required by framework AND essential to match set services (never violated)
Another Part of the FSML Implements Init Phase 1 importStateParam exportStateParam advertisesImportField addsToState addsToImportState standardName subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)” formalParam: 2 formalParam: 3 call: NUOPC_StateAdvertiseField argValByIndex: 1 OCL: self.addsToState == self.parent.importStatePa ram argValByKeyword: “StandardName” [1] [0..*] [1] ![1] [1] essential path expression derived
Partial Code for Init Phase 1 12
Making the FSML More Concise Implements Init Phase 1 importStateParam exportStateParam advertisesImportField addsToState addsToImportState standardName subroutine: “*(type(ESMF_GridComp), type(ESMF_State), type(ESMF_State), type(ESMF_Clock), integer)” formalParam: 2 formalParam: 3 call: NUOPC_StateAdvertiseField argValByIndex: 1 argValByIndex: 1 sameAs: (../../ formalParam: 2) argValByKeyword: “StandardName” [1] [0..*] [1] ![1] [1] embedded path expression
14 module atm use ESMF use NUOPC use NUOPC_Model subroutine setservices(gcomp, rc).... end subroutine subroutine advance(gcomp, rc).... end subroutine.... end module parse Virtual Program Graph & Abstract Syntax Tree rewrite code queries code transformations Photran Eclipse Plugin Realize Bi-directional Mappings
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 fine- grained 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 8 NUOPC Model Implements Set Services Calls Generic Set Services Registers Init Phase 1 Registers Init Phase 2 Implements Init Phase 1 Name Registers Init Phase 0 [1] ![1] [0..1] [1] Implements Init Phase 0 [0..1] [1]... [1] required by framework (violations allowed during development) required by framework AND essential in order to match parent feature (never violated) optional by framework
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):
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
25 Partial Framework Specific Modeling Language for NUOPC Name of model True if module uses ESMF, NUOPC, NUOPC_Model Maps to a Fortran module 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
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
28 Has 2 parameters of type ESMF_Grid and Integer Calls routine_SetServices() Calls ESMF_GridCompSetServices() 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.