ammarhakim / gkylzero

Lowest, compiled layer of Gkeyll infrastructure.
MIT License
22 stars 5 forks source link

[DR] Lua Wrappers in G0 #506

Open ammarhakim opened 4 weeks ago

ammarhakim commented 4 weeks ago

Production Branches

This DR is for work done a while ago for the moments App. It is being written up as now we are using the same approach to wrap the Vlasov and GK Apps. See the main gk-g0-app branch. The naming convention is to to use the suffix _lw for files that contain the "Lua Wrapper".

To work on this code one must have the Lua5.1 dev docs available. Please see Lua 5.1 Dev Docs.

Important: We will stick to Lua5.1. This is important as LuaJIT has frozen its API to the older Lua5.1 API.

Introduction

The goal of this DR is to describe the approach we will use to wrap G0 Apps in Lua. The key here is to directly use the Lua-C API to wrap the various Apps directly. Using the Lua-C Api has the disadvantage that the process is tedious and somewhat error prone. However, the main advantage is that this is what Lua supports natively and so no new dependencies are introduced and we can be certain that things will keep working in the future. Further, as the Lua-C Api is a compiled C code errors due to C-side API changes will be caught at compile time. Note that the LuaJIT wrapped code can't ensure correctness of wrappers: they can fail at run time, making it hard or impossible to debug.

Proposed/Implemented Design

The design of the code is straightforward (but tedious). The goal is to create a top-level object that wraps the App struct. For example, the gkyl_moment_app struct in the moments App. Attached to this wrapped object (represented with a userdata with a metatable table attached to it) are all the methods that the C API exposed. Hence, with this API we can essentially do the same thing in Lua as we do in C. However, we would provide a default run() method that would run the main simulation loop that most users would use.

For this design we need to create a userdata for all object we want to make useable from the Lua side. Not all C objects are of this sort. In general, only the main App object and perhaps Equation objects need to be wrapped into a userdata object that is callable from Lua.

To ease the development of the wrappers I have implemented some code in the gkyl_lua_utils.h header file. This has some functions and macros that make life a little easier when working with the low-level Lua-C API.

JonathanGorard commented 4 weeks ago

It is worth nothing here that, at least in the way that the Lua wrappers are set up at the moment, everything works just fine when G0 is built with LuaJIT, but certain aspects of the wrappers (such as the equation objects in moments) fail when G0 is built with bare-metal Lua 5.1. Since, in the long run, we would ideally like to transition away from the LuaJIT dependency altogether, it is important that we get everything working with Lua 5.1 directly.

It is likely that this is relatively simple to fix; I just need to look into it once we're further along.