Embedding Julia code in Fortran

Hey everyone,

I am fairly new to Julia and am interested to do machine learning with it. So far I learnt how to code in Julia and how to use the Flux library. Yet, My goal is to use trained neural networks in a fortran code. I saw on the Julia page that it is possible to embed Julia code in C/C++, but I can’t manage to find the way to do it in fortran. Does anyone have an idea?

1 Like

A cleaner way is to bind to ONNXRuntime from Fortran so you don’t need Julia runtime for inference, after some searches, it appears that this doesn’t exist..

It is much easier to interface the other way around. It is conceivable as a workflow to have a main julia code that calls your fortran routines?

In general Julia will be much friendlier for file manipulation, visualization, and the higher-level stuff, and usually one could let some lower level tasks to Fortran if there are nice routines available for one’s purpose.

5 Likes

Thank you very much for your answers, so I agree with the fact of using Julia for higher level stuff, yet I am working on a fortran code that already exists and we want to add some machine learning to replace some operations in the code. In order to use Julia as the main code to use machine learning algorithms, I would have to rewrite most of the existing optimized fortran code, which isn’t really what we want, hence my question of embedding Julia code in fortran.

Since there is no better answer, unfortunately, I would just point that probably you would need “only” a wrapper for the main Fortran program. You could convert the main fortran program into a subroutine, and call it from Julia. Or create a new “main” program in Julia and call all the subroutines of Fortran from it. Of course how hard is that depends a lot on the the complexity of the program.

The alternative, easy one, is just to use each code (Julia and Fortran) as just independent program to execute, and interface them by writing and reading stuff from and to files. Of course that’s only viable if the cost of this slow interface is not important.

3 Likes

One more option would be not embedding Julia, but calling Julia. Meaning you have a Julia server and some ways of communication between your Fortran and Julia programs (e.g. ZMQ).

What are your requirements for throughput and latency?

In Fortran, you call a C function (Interoperability with C (The GNU Fortran Compiler) ). So maybe you can call the jl_init function (and others) by declaring a interface with the bind c attribute in Fortran. The problem would be C macros and potentially C data structures not suppoted by the Fortran’s C binding. So maybe you need some small C wrapper around your Julia code, that you can call from Fortran.

I have never tried this myself, but I would be interested to hear about your approach.

There’s one other option, call some other language from Fortran, I suggest to Python.

I googled a bit, found this, not sure if it’s the best, seems good, see its blog post:

I don’t mean this necessarily as a substitute for Julia and Flux (though would be helpful for e.g. Tensorflow or PyTorch), but rather to then call from Python to Julia, with Pythoncall.jl (it’s also to call from Python, or use pyjulia). Learning to call to or from Python (for Julia and likely any for language) is very useful, likely to be helpful to know, also independently of what you’re trying to do.

This might be the easiest intermediate language, and then you don’t need to code anything for interop, just call a bit differently. And since calling to or from Python is in-process (and I suppose all three), it’s fast, most likely.

There are some issues with coding your own interop infrastructure, that I’m not to up-to-speed on. I just know you get rid of them for some minor inconvenience. If some of the code is multi-threaded, that might be an issue, but likely will be with and without this solution.

There are some other options for the middle language. I wouldn’t recommend e.g. Java (not in-process), Rust should work. It’s possible to call to Julia from it and from C++ (library available to make easier from C++ and another from Rust). Both would be an option to call from, but it’s likely easier to call to Python than them.

It’s not mandatory interacting with the C macros or data structures to embed Julia. The approach in GitHub - GunnarFarneback/DynamicallyLoadedEmbedding.jl: Embed Julia with dynamical loading of libjulia at runtime. uses neither of those and minimizes the number of libjulia functions called.

1 Like

If I remember correctly, @sloede has a working prototype for this.

Thanks for pinging me, @ranocha!

Yes, we do indeed have a working prototype for calling Julia from Fortran. Since Fortran is not nice (some may call it horrible) when playing with others, I found that for me it was much easier to write a small shim library in C that itself is called from Fortran, and then have the C library interact with Julia.

You can fin examples for pure C-to-Julia usage and Fortran-to-C-to-Julia usage in this repository:

Please feel free to ping me here (or better yet, in the repository using an issue) if there are questions/problems.

3 Likes