Dear Racketeers, We are glad to present you a new differentiable programming language called Landau.
https://gitlab.iaaras.ru/iaaras/landau # Description Landau is a LANguage for Dynamical systems with AUtomatic differentiation. Landau is a Turing-incomplete statically typed domain-specific differentiable language. The Turing incompleteness allows a sophisticated source code analysis and, as a result, an optimized compiled code. Landau's syntax supports functions, compile-time ranged `for` loops, `if`/`else` branching constructions, integer and real variables and arrays, and the ability to manually `discard` calculations where automatic derivatives values are expected to be negligibly small. Despite the restrictions, the language is rich enough to express and differentiate cumbersome paper-equations with practically no effort. ## Simplest code sample ``` const int k = 3 # some constant parameter[k] x0 # Parameters w.r.t which derivatives should be taken real[k * k] func(real[k] x, real[k * k] dxdx0) { x[:] ' x0[:] = dxdx0[:] # Tell the compiler about dx/dx0 Jacobian real[k] f = 2 * sin(x[:]) + x[:] # Do the actual work func[:] = f[:] ' x0[:] # Return the values of df/dx0 Jacobian } ``` ## More examples `spacecraft.dau` [1] is a Landau program for modeling spacecraft movement around a planet. Spacecraft's initial position and velocity, as well as the gravitational parameter of the planet, are supposed to be determined by an external nonlinear optimization method. Derivatives of the right-hand side of the equation w.r.t. the initial state vector and the planet mass are handled by Landau. As soon as you have installed Landau (see Installation below), generating C code should be as simple as ``` $ racket spacecraft.dau -c -extfl Success. The output is written to [path]/spacecraft.c ``` Other code examples are available at [2]. ## Differentiation method Landau uses a hybrid approach to calculating derivatives: symbolic differentiation at the expression level and automatic (forward mode) at the assignation level. ## Implementation The Landau transpiler is built on top of the Racket platform and consists of two main parts: the syntax analyzer and the code generator. The job of the syntax analyzer is to: - unroll all loops into an assignation sequence; - trace dependencies of variables and their derivatives; - check the program for correctness, e.g. catch out-of-range errors. The code generator is capable to emit Racket and ANSI C code. It is possible to use 80-bit floating-point numbers (extended precision) without changing the Landau source. ## Landau advantages Landau facilitates the development of dynamical models used in celestial mechanics and possibly other areas. Landau: - generates highly-efficient C code (or less efficient Racket syntax objects which are useful if you are programming in Racket); - exempts user of C pointer managing trouble and low-level debugging; - allows easy notation of mathematical equations, while also allowing loops and functions; - and, of course, provides first-class automatic derivatives (while you can use Landau without them, too). The Landau-generated C code is portable to Windows, Linux, and MacOS compilers. ## Key decisions There are AD approaches where an initial program is unrolled into assignation sequences (Wengert list) and AD problem is solved in linear algebra formalism. The initial problem is reduced to a sparse linear equations system. Even though there are known lots of sparse matrix algorithms, it is not obvious whether it is a good idea to unroll all loops to a giant sparse matrix. In Landau, we decided to take another code generation approach which preserves the initial program's loops, i.e. a Landau loop is transformed into a C or Racket loop whose body is augmented with a derivative calculation code if needed. Unlike other AD tools, Landau allows to annotate derivatives inside a program to be able to predict the number of nonzero derivatives and reduce machine resources used for Jacobian computation and storage. Other AD tools often do not use annotations and hence, make it impossible to perform radical compile-time optimizations of array's derivatives computations. We chose to use a compression technique that stores only nonzero Jacobian values row by row. The sparsity is handled by packing useful Jacobian elements into smaller arrays and generating mappings from the packed derivative indexes to the original ones and inverse mappings, which map the original indexes to the packed ones. # Development in Landau The model development consists of three stages: 1. Manual model description in Landau language (`model.dau`) 2. Transpiling to ANSI C (code generation `model.c`) 3. Compiling to a shared library for a specific platform (`model.dll`, `model.so`, `model.dylib`) ## Publications - I. Dolgakov, D. Pavlov. “Landau: language for dynamical systems with automatic differentiation”. Zap. Nauch. Sem. POMI 485 (2019) [3] - I. Dolgakov, D. Pavlov. “Using capabilities of Racket to implement a domain-specific language”. Computer Assisted Mathematics 1 (2019) [4] # Installation 1. Download and install Racket. 2. Clone repository: `git clone https://gitlab.iaaras.ru/iaaras/landau.git`. 3. Link Landau as a package: `cd landau/ && raco link landau`. # Configuraiton `config.json`: ``` { // Language to compile .dau file to "target_language": "racket" | "ansi-c", // Whether to use 80-bit floating point "use_extfloat": true | false, // Where to write output .c file, // in case `target_language` is "ansi-c" "output_directory": DIRECTORY_PATH } ``` # Planned improvements ## Syntax - FFI (calling C functions inside a Landau program); - complex numbers; - syntactic sugar for array operations; - multidimensional arrays. ## Core While being close to optimal in terms of computation time, the chosen AD algorithm is not very memory efficient. The main problem is that inverse mapping of a single array cell takes O(maxidx) in space, where maxidx is a maximal index of nonzero derivative for the array element. So a better Jacobian compression algorithm is under consideration. ## Static analysis Unrolling all loops and evaluating all compile-time computable variables is a simple but inefficient approach. We are looking for better ways of performing static syntax analysis. ## Code generation - Generate AVX intrinsic functions for the C backend; - generate unsafe vector operations for the Racket backend. # References [1] https://gitlab.iaaras.ru/iaaras/landau/blob/master/tests/spacecraft.dau [2] https://gitlab.iaaras.ru/iaaras/landau/tree/master/tests [3] <http://www.mathnet.ru/php/archive.phtml?wshow=paper&jrnid=znsl&paperid=6869&option_lang=eng> http://www.mathnet.ru/php/archive.phtml?wshow=paper&jrnid=znsl&paperid=6869&option_lang=en <http://www.mathnet.ru/php/archive.phtml?wshow=paper&jrnid=znsl&paperid=6869&option_lang=eng> g [4] http://cte.eltech.ru/ojs/index.php/cam/article/view/1625 -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/5322b07f-0a8c-4b5d-b006-1f59b47c5008o%40googlegroups.com.