Modelica - A Domain-Specific Language Implementation and Overview of the OpenModelica Compiler Martin Sjölund Department of Computer and Information Science Linköping University 2015-11-13 Overview Part I Part II Part III Background Implementation of a Modelica Compiler Conclusion Part I Background Classic Compiler I Very structured. I Translates from one intermediate representation to another. I I I Assumes it is straight-forward to translate code from one representation to another. Usually statement-based code (maybe some object orientation). Taught in courses TDDB44 and TDDD55. The Phases of the Compiler source program sequence of chars: ’IF sum=5 THEN..’ Lexical analysis sequence of tokens: ’IF’ ’sum’ ’=’ ’5’ Syntactic analysis parse tree, derivation tree Table management Semantic analysis and Intermediate code gen Code optimization Error Management internal form, intermediate code internal form Code generation object program TDDD55/B44, P Fritzson, IDA, LIU, 2011. Systems Engineering I I I I Handling large, complex projects. Combining requirements, modeling, simulation, deployment, support, etc. Inter-disciplinary. You often end up with many different tools because different domains traditionally used different tools. Domain-Specific Languages I I I I Many are similar to classic, general-purpose programming languages (e.g. PHP). Examples include HTML, regular expressions, parser generators. Compilers are usually implemented partially using domain-specific languages (grammars, special languages to describe architectures, etc). Why? It is easier to program and maintain such code. Modelica I g Figure: An RC-circuit implemented in Modelica. c C=1e-6 Centered around making it easy for a (mechanical, electrical, etc) engineer to use Modelica. - I Used for simulation and/or control of multi-domain (physical) systems. R=1e6 pv I Modeling using a graphical user interface (or the equivalent textual representation). r + I An equation-based object-oriented modeling language (a DSL). Simulating the RC-circuit 250 Voltage [V] 200 150 100 50 0 0 1 2 3 4 time [s] Figure: Result of simulating the RC-circuit. 5 Equations Physics is described by equations, not statements. Thus, Modelica primarily uses equations instead of imperative programming (like C). I Equations look like V R =I However, code needs to be translated to imperative programming (or similar) in order to run numerical solvers on a CPU. So it could be solved as either of: I V := R ∗ I I I := I R V R := VI Ordinary Differential Equations (ODEs) The numerical solvers we use require an ODE formulation. For example: ∂x =y ∂t d = 2.0 ∗ t (1) (2) ∂y = −d ∗ x (3) ∂t Where these equations can be solved sequentially and the start value for each state variable is known or can be solved during initialization. Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 x 3.00 y 2.00 ∂x ∂t = y d = 2.0 ∗ t ∂y ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 x 3.00 y 2.00 ∂x 2.00 ∂t = y d = 2.0 ∗ t ∂y ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 x 3.00 y 2.00 ∂x 2.00 ∂t = y d = 2.0 ∗ t 0.00 ∂y ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 x 3.00 y 2.00 ∂x 2.00 ∂t = y d = 2.0 ∗ t 0.00 ∂y 0.00 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 x 3.00 3.50 y 2.00 ∂x 2.00 ∂t = y d = 2.0 ∗ t 0.00 ∂y 0.00 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 x 3.00 3.50 y 2.00 2.00 ∂x 2.00 ∂t = y d = 2.0 ∗ t 0.00 ∂y 0.00 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 x 3.00 3.50 y 2.00 2.00 ∂x 2.00 2.00 ∂t = y d = 2.0 ∗ t 0.00 0.50 ∂y 0.00 -1.75 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 0.50 x 3.00 3.50 4.00 y 2.00 2.00 1.5625 ∂x 2.00 2.00 ∂t = y d = 2.0 ∗ t 0.00 0.50 ∂y 0.00 -1.75 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 0.50 x 3.00 3.50 4.00 y 2.00 2.00 1.5625 ∂x 2.00 2.00 1.5625 ∂t = y d = 2.0 ∗ t 0.00 0.50 1.00 ∂y 0.00 -1.75 -4.00 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 0.50 0.75 x 3.00 3.50 4.00 4.390625 y 2.00 2.00 1.5625 0.5625 ∂x 2.00 2.00 1.5625 ∂t = y d = 2.0 ∗ t 0.00 0.50 1.00 ∂y 0.00 -1.75 -4.00 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 0.50 0.75 x 3.00 3.50 4.00 4.390625 y 2.00 2.00 1.5625 0.5625 ∂x 2.00 2.00 1.5625 0.5625 ∂t = y d = 2.0 ∗ t 0.00 0.50 1.00 1.50 ∂y 0.00 -1.75 -4.00 -6.5859375 ∂t = −d ∗ x Solving the Ordinary Differential Equation Solving the ODE from t=0 to t=1 using a step size of 0.25 with explicit (forward) Euler, using x(t = 0) = 3 and y(t = 0) = 2: t 0.00 0.25 0.50 0.75 1.00 x 3.00 3.50 4.00 4.390625 4.53125 y 2.00 2.00 1.5625 0.5625 -1.083984375 ∂x 2.00 2.00 1.5625 0.5625 ∂t = y d = 2.0 ∗ t 0.00 0.50 1.00 1.50 ∂y 0.00 -1.75 -4.00 -6.5859375 ∂t = −d ∗ x Better Solutions for the Ordinary Differential Equation Modelica tools need to know about ODEs, and can solve them better than the explicit Euler. The end values for different solvers: I Euler stepSize=0.25, x=4.531, y=-1.084, 4 rhs calls I Euler stepSize=0.10, x=4.087, y=-1.600, 10 rhs calls I RK4 stepSize=1.00, x=3.667, y=-1.667, 4 rhs calls I RK4 stepSize=0.25, x=3.747, y=-1.841, 16 rhs calls I DASSL, tolerance=1e-3, x=3.745, y=-1.838, 15 rhs calls I DASSL, x=3.747, y=-1.842, 67 rhs calls I Euler stepSize=1e-5, x=3.747, y=-1.842, 10000 rhs calls model ODE Real d=2* time; Real x(start =3.0, fixed =true); Real y(start =2.0, fixed =true); equation der(x) = y; der(y) = -d*x; end ODE; Multi-Domain Approach: Systems Engineering Modelica is a multi-domain approach based on math: I I I It is suitable to simulate different physical domains independently or multiple domains in the same model. Can be used to simulate full systems or synthesize parts of a system (such as digital controllers). The language fulfills the requirements of Systems Engineering. Part II Implementation of a Modelica Compiler User in the Focus Modelica is designed around the user of the language being the focus: I This makes implementation of the compiler harder. I NP-hard problems need to be solved at compile-time. I I Compilation time is unbounded and includes interpretation of arbitrary code. Certain language features are a little weird when you consider the textual representation, but make sense when for the graphical user interface. OpenModelica OpenModelica is an open source Modelica tool I Open Source Modelica Consortium (OSMC) I I I I I I I 46 org members Mar 2014 Founded Dec 4, 2007 Open-source community services Website and Support Forum Development courses Main development at Linköping University Used for research prototypes and industrial products www.openmodelica.org OpenModelica I Version-controlled source base (git) I Bug database (Trac) I I Continuous integration (Hudson) Interactive Modelica compiler (OMC) I I I I I Compiles the Modelica Language Modelica and Python scripting Efficient C-code, simulation run-time system Extensive Modelica test suite Environment for creating models I I I I I I I OMShell – scripting commands OMNotebook – interactive notebook OMOptim parameter optimization tool OpenModelica dynamic optimizer with collocation MDT – Eclipse plug-in ModelicaML UML-Modelica-Requirements Profile OMEdit graphic connection Editor I Debugger – finding model errors OpenModelica I Version-controlled source base (git) I Bug database (Trac) I I Continuous integration (Hudson) Interactive Modelica compiler (OMC) I I I I I Compiles the Modelica Language Modelica and Python scripting Efficient C-code, simulation run-time system Extensive Modelica test suite Environment for creating models I I I I I I I OMShell – scripting commands OMNotebook – interactive notebook OMOptim parameter optimization tool OpenModelica dynamic optimizer with collocation MDT – Eclipse plug-in ModelicaML UML-Modelica-Requirements Profile OMEdit graphic connection Editor I Debugger – finding model errors OpenModelica I Version-controlled source base (git) I Bug database (Trac) I I Continuous integration (Hudson) Interactive Modelica compiler (OMC) I I I I I Compiles the Modelica Language Modelica and Python scripting Efficient C-code, simulation run-time system Extensive Modelica test suite Environment for creating models I I I I I I I OMShell – scripting commands OMNotebook – interactive notebook OMOptim parameter optimization tool OpenModelica dynamic optimizer with collocation MDT – Eclipse plug-in ModelicaML UML-Modelica-Requirements Profile OMEdit graphic connection Editor I Debugger – finding model errors OpenModelica I Version-controlled source base (git) I Bug database (Trac) I I Continuous integration (Hudson) Interactive Modelica compiler (OMC) I I I I I Compiles the Modelica Language Modelica and Python scripting Efficient C-code, simulation run-time system Extensive Modelica test suite Environment for creating models I I I I I I I OMShell – scripting commands OMNotebook – interactive notebook OMOptim parameter optimization tool OpenModelica dynamic optimizer with collocation MDT – Eclipse plug-in ModelicaML UML-Modelica-Requirements Profile OMEdit graphic connection Editor I Debugger – finding model errors User in the Focus – OMEdit Demo The Compiler Design A Modelica compiler needs to have lots of domain knowledge. It also depends on heuristics to translate equations into ODEs (the main job of a Modelica compiler), which are translated to executable code. I I I I The heuristics may fail to create an ODE from the given code when a solution exists. Solutions do not necessarily exist. Numerical solvers may fail solve the model (require infinite resolution). Solution: good error messages and debuggers. In practice, this works very well. OpenModelica Overview I I I I Written in MetaModelica (general-purpose programming extension to Modelica). The code generator uses our own DSL Susan for text generation (which translates Susan code to MetaModelica). Parser which translates code to C-code, and uses the C interface to MetaModelica to create data types. Kernel written in Modelica, MetaModelica, C, C++, Susan, ANTLR. OpenModelica Parts I Parser (using the ANTLR parser generator). I Front-end (semantic analysis, like a traditional compiler). I I I I I Equation back-end (symbolic math, outputs imperative code from equations). Code generator (takes imperative code and generates of C-code, skipping middle-end and back-end of a traditional compiler). Utilities. Front-end + code generator handles MetaModelica (functions). The compiler is also written in Modelica (bootstrapping). Compiler Bootstrapping The compiler needs a working copy of itself in order to compile its code (because there exist no other MetaModelica compilers). This sounds annoying but has some benefits: I I I Can implement language extensions in order to write a more efficient compiler. Performance improvements to the Modelica compiler also improves the MetaModelica compiler. The language looks similar to Modelica. Testing a Modelica Compiler I I I I Testing a C-compiler is easier because the exact translation semantics are specified. In Modelica, a compiler needs to decide by itself how to generate code. Numerical differences depending on how an equation is solved. Compare result-files with a relative+absolute tolerance and some magic to align discrete event times. Testing a Modelica Compiler How is Everything Developed? I I I I I The Modelica language is developed by committee. OpenModelica developers implement new Modelica language features and create pull requests on github. The pull request is reviewed and automatically tested before it is merged into the main repository. Weekly meetings to coordinate between the Swedish and German teams. Infrequent developer weeks for larger changes to the compiler. Part III Conclusion Software used by OpenModelica OpenModelica is a huge project that combines many pieces of software. You need software engineers to manage everything, as well as mathematicians and mechanical engineers to help implementing the symbolic and numerical solvers. The project includes: I I I A lexer/parser generator. Its own symbolic processing libraries. Numerical solvers: I I I I Linear algebra (dense / sparse). Non-linear solvers (optimization/minimization formulations). ODE solvers (euler, RK4, dassl, radau, lobatto). Dynamic optimization. I DSL for code (text) generation. I C compilers. I GUI toolkits. More Reading I https://modelica.org I https://openmodelica.org www.liu.se