Automatic Code Generation with SymPy
Watch the video of the tutorial online
This tutorial will introduce code generation concepts using the SymPy library. SymPy is a pure Python library for symbolic mathematics. Code generation refers to the act of converting a SymPy symbolic expression into equivalent code in some language, typically for numeric evaluation. This allows one to use SymPy to symbolically model a problem and generate fast numerical code for specific platforms that executes that model. This is a powerful tool that is useful to scientists in many domains. Code generation allows users to speed up existing code, to deal only with the high level mathematics of a problem, avoids mathematical errors and typos, makes it possible to deal with expressions that would otherwise be too large to write by hand, and opens possibilities to perform automatic mathematical optimizations of expressions.
You can run this tutorial online with Binder. Otherwise, follow the instructions in the README to install the tutorial materials.
- Björn Dahlgren, KTH Royal Institute of Technology
- Kenneth Lyons, University of California, Davis
- Aaron Meurer, University of South Carolina
- Jason Moore, University of California, Davis
Attendees will be able to:
- write SymPy expressions describing mathematical functions and identify the
function arguments and outputs,
- use the SymPy code printers to transform SymPy expressions representing
common domain specific functions into multiple output languages,
- use the SymPy code generation routines to output compilable C code and use
Cython to access these functions in Python,
- generate custom vectorized functions with the three SymPy functions:
lambdify, ufuncify, and autowrap,
- create both custom code printers that make use of specialized C libraries and
common subexpression elimination (CSE),
- subclass the core SymPy printers and create a printer for a custom language.
Introduction of the topic, speakers, and software.
Writing common domain specific mathematical expressions with SymPy.
Long expressions, Matrix operations, and Loop Fusion from classical mechanics, chemical kinetics, nuclear dynamics, and materials science.
- Reminders on common gotchas
- Floating point representation
- Undefined Functions
- Matrix Symbols
- [15 min] Code printing
- Exercise: Codegen your own function
The Easy Way: High Level Code Generation [55 minutes]¶
Generate python functions from symbolic expressions.
Generate a Jacobian function for a chemical kinetic problem.
- [10 minutes] Refresher on ordinary differential equations
- [5 minutes] Exercise: write an analytic Jacobian function by hand
- [10 minutes] Introduction to
- [5 minutes] Exercise: Create a function from a SymPy expression
- [5 minutes] Governings equations for systems of ODEs in chemical kinetics.
- [5 minutes] Exercise: generate a function evaluating the rhs of an ODE system
- [10 minutes] Exercise: construct SymPy expressions from a simple data structure
- [10 minutes] Exercise: derive a Jacobian symbolically and generate a function evaluating it
10 Minute Break¶
Convert SymPy matrices to a C program and speed up numerical execution by extending the printer with common subexpression elimination.
Evaluate a chemical kinetic ordinary differential equation and its Jacobian using C.
- [5 minutes] Introduction
- [5 minutes] Exercise: Load the ODE expression, compute the Jacobian, and inspect the results.
- [5 minutes] Printing C Code
- [5 minutes] Exercise: Generate C code for the Jacobian expression.
- [5 minutes] Extending and Customizing Printers
- [10 minutes] Exercise: Construct custom exponential printing and symbol names.
- [5 minutes] Common Sub-expression Elimination
- [15 minutes] Exercise: Generate C code (w/ CSE) for the ODE and Jacobian expressions.
- [5 minutes] Bonus: Compile and execute the C code.
Generate C code to evaluate an ordinary differential equation and and its Jacobian and wrap it for use with SciPy’s integrators. Additionally, demonstrate how one might access external C libraries.
Integrating the water radiolysis system of ODEs.
Section 1: Introduction to Cython¶
- [2 minutes] Explanation of Cython
- [3 minutes] Example: writing Cython and compiling in a notebook
Section 2: Generating C Code with SymPy's
- [2 minutes] Review the water radiolysis system
- [2 minutes] First exposure to
- [3 minutes] Exercise generate code with a cleaner function signature
- [3 minutes] Exercise generate an even cleaner function signature
Section 3. Wrapping the Generated Code with Cython¶
- [5 minutes] Overview of the wrapping process
- [3 minutes] Explanation of the build process
- [3 minutes] Explanation of the wrapper code
- [3 minutes] Exercise: use the wrapped function with some random inputs
- [3 minutes] Use
odeint to integrate the ODEs using the wrapped function
Section 4. Generating and Compiling a C Extension Module Automatically¶
- [3 minutes] Overview of the
- [5 minutes] Exercise: explore the
autowrap generated files
- [5 minutes] Exercise: use the wrapped function with some random inputs
- [2 minutes] Writing a wrapper around the wrapper
- [8 minutes] Exercise: generate a function to compute the Jacobian
Section 5. Using a Custom Printer and an External Library with
- [2 minutes] Overview of
- [2 minutes] Explanation of fastapprox library
- [8 minutes] Exercise: implement a custom code printer to use
fastpow instead of
- [3 minutes] Including
- [3 minutes] Using the new function and proving it worked
- [2 minutes] Exercise: compare outputs of the callables using
The attendees will come away with a powerful set of tools that will allow them
to develop high performance numerical code using Python that compliments NumPy
and SciPy. This tutorial will be ideal for users of the SciPy Stack that would
like to increase the performance of their Python code, get into some of the
depths of how low-level languages can interact and be used from Python, or to
learn a new technique for expressing mathematical models in Python.