JuliaCon 2022 (Times are UTC)

Calling Julia from MATLAB using MATDaemon.jl
07-28, 16:40–16:50 (UTC), Red

MATLAB is a proprietary programming language popular for scientific computing. Calling MATLAB code from Julia via the C API has been supported for many years via MATLAB.jl. The reverse direction is more complex. One approach is to compile Julia via the C++ MEX API as in Mex.jl. In MATDaemon.jl (https://bit.ly/3JxTFFU), we instead communicate by writing data to .mat files. This method is robust across Julia and MATLAB versions, and easy to use: just download jlcall.m from the GitHub repository.

MATLAB is a popular programming language in the scientific community. Unfortunately, it is proprietary, closed-source, and expensive. Within academia, purchasing MATLAB licenses can feel like a tax on research development, especially given the growing global trends towards open, reproducible, and transparent science. For this reason, many scientists are switching as much as possible to open software development using open-source programming languages such as Python, R, and Julia.

Transitioning between programming languages can be a daunting task, however. Beyond the obvious requirement of learning a new language, translating and rewriting existing codebases in a new language can be difficult to do in a modular fashion. Modularity is important in order to be able to translate and test as you go. Indeed, it is often not even necessary to translate an entire library to gain nontrivial improvements; for example, by rewriting only performance-critical code paths.

A convenient way to ease such transitions is through language interoperability. From the Julia side, calling out to the MATLAB C API has been possible for many years using the fantastic MATLAB.jl package, made possible by Julia’s support for calling C code. Calling Julia from MATLAB, however, is more complex for several reasons. The first approach one might try is to use Julia’s C API in conjunction with the MATLAB C/C++ MEX API in order to build a MEX – that is, (M)ATLAB (EX)ecutable – function which embeds Julia. This is the approach taken by the Mex.jl Julia package. When this approach works, it is extremely effective: calling Julia is convenient with little overhead. Unfortunately, writing scripts to compile MEX functions across operating systems and MATLAB versions is notoriously fragile. Indeed, the current version of Mex.jl only supports Julia v1.5.

For these reasons, we created MATDaemon.jl (https://github.com/jondeuce/MATDaemon.jl). This package aims to call Julia from MATLAB in as simple a manner as possible while being robust across both Julia and MATLAB versions – it should “just work”. MATDaemon.jl does this by communicating with Julia via writing MATLAB variables to disk as .mat files. These variables are then read by Julia using the MAT.jl package. The Julia function indicated is then called and the output variables are similarly written to .mat files and read back by MATLAB. Naturally, this comes at the cost of some overhead which would not be present when using the MEX approach. In order to alleviate some of the overhead, a Julia daemon is created using the DaemonMode.jl package (https://github.com/dmolina/DaemonMode.jl). This helps to avoid Julia startup time by running Julia code on a persistent server. While this package is still not recommended for use in tight performance critical loops due to overhead on the order of seconds, it is certainly fast enough for use in rewriting larger bottlenecks and for interactive use in the MATLAB REPL.

Due to its simplicity,MATDaemon.jl is easy to use: just download the jlcall.m MATLAB function from the GitHub repository (https://github.com/jondeuce/MATDaemon.jl/blob/master/api/jlcall.m) and call Julia. For example, running jlcall('sort', {rand(2,5)}, struct('dims', int64(2))) will sort a 2x5 MATLAB double array along the second dimension. A temporary workspace folder .jlcall is created containing a local Project.toml and Manifest.toml file in order to not pollute the global Julia environment. And that’s it! See the documentation in the GitHub repository for example usage, including loading local Julia projects, Base modules, running setup scripts, and more.

PhD candidate studying MRI physics at the University of British Columbia.