Pushing the Limits of Small Binary Creation

Hi all, quick story:

It was at a hotel bar the other day that @asinghvi17 , @avik , @mortenpi , Professor Rebecca Killick, and I did an impromptu hackathon for about 5 hours to see what could be possible with the newly landed PR add --trim option for generating smaller binaries by JeffBezanson · Pull Request #55047 · JuliaLang/julia · GitHub about making small binaries in Julia 1.12. Here’s a write-up of some of our findings and experimentation:

juliac Is Really Great! The juliac compiler that is in development is such a great idea! I highly recommend checking out the blog post by @jbytecode here: juliac on a starters guide for getting started with juliac usage! What we uniquely did here was contribute with showing how to make ccallable functions work within juliac.

Language Interoperability Is Possible with Small Binaries. After much tinkering and exploring, we figured out how to make a small binary that could be executed from within C++ (I’ll let Morten comment more on that!) which evaluated as expected. But what was quite exciting is that after a bunch more tinkering, we got the small binaries to be callable (and usable) from within Julia and R languages!

The Future of juliac Is Exciting! I would say right now, it is still a bit tricky to write juliac compatible code (i.e. type stability, how to use the Julia C/C++ interfaces, write the interface to these binaries from different languages) but there is a lot of richness here. I think we are now at a new frontier for a deeper level of language interoperability that will see Julia proliferate across other ecosystems. I’ll let others comment here!


If you want to reproduce my results and experiments, I made a toy repo here for playing around further!

But, here are some teaser photos showing this in action in Julia:

And then in R:

There is so much to be done here! Alas, I am going to be busy for the next week or so so probably won’t be able to get back to this soon, but I wanted to write up my thoughts and findings here before I am sucked into other research and coursework endeavors again.

Cheers and please let me know your thoughts and ideas!

~ tcp :deciduous_tree:

55 Likes

nice. can’t wait.

1 Like

Maybe it’s too early to ask, but what’s a good workflow, when using juliac, to link against a shared library from a JLL package and deploy the compiled binary with proper environments (e.g., LD_LIBARARY_PATH) for the dependencies?

In a complicated projedct with juliac, will you need a build system like Make or CMake? Or will it be more like a usual Julia package workflow with Project.toml and Manifest.toml?

3 Likes

Tagging @droodman who might be interested in this to the extent it simplified using Julia as a Stata/R “backend”

6 Likes
  1. Can we have an example that requires the runtime? add_julia() from simple.jl is too simple, and would work even with StaticCompiler.jl.
  2. I agree that CMake would make it easier to include in larger (e.g. C++) projects. See the last paragraph here for the Common Lisp version.
3 Likes

We were working on kernal smoothing and gibbs examples but the bugs we were getting made us go even simpler to start with. I’m sure we can add an update once we can get back to those.

5 Likes

Thanks for this great post!

I tried using this today, and had to deal with a few issues. Firstly, the juliac.jl file in the repo wouldnt work with the --experimental flag so I used the juliac.jl in the nightly installation ~/.julia/juliaup/julia-nightly/share/julia/juliac.jl instead. That did output simple.so, but then I got the following erros:

In R when run as LD_LIBRARY_PATH=. LD_PRELOAD=simple.so R I get this:

> dyn.load("simple.so")
ERROR: could not load symbol "jl_image_pointers":
dlsym(RTLD_DEFAULT, jl_image_pointers): symbol not found

In julia run as LD_LIBRARY_PATH=. LD_PRELOAD=simple.so julia --startup-file=no, and the same if i use +nightly:

julia> @ccall "simple.so".add_julia(2::Cint, 2::Cint)::Cint
ERROR: could not load library "simple.so"
dlopen(simple.so, 0x0001): Symbol not found: _ijl_gc_small_alloc
  Referenced from: <2E082EC4-2052-3A30-96D2-BE77FF5A4F95> /Users/ajinkya/projects/julia_repos/julia-c-r-interface/simple.so
  Expected in:     <62118962-B36D-3E98-9107-BA557C947AAD> /Users/ajinkya/.julia/juliaup/julia-1.11.3+0.aarch64.apple.darwin14/lib/julia/libjulia-internal.1.11.3.dylib
Stacktrace:
 [1] top-level scope
   @ ./REPL[1]:1

Any idea what might fix this? I am guessing something just changed since this is under rapid development

2 Likes

Hey @ajinkya-k ,

Thanks for testing this out! Two things:

  • Using the repo I posted, make sure to check out your Julia version to that specific commit I referenced if you want to see everything working as I had it. I know things are developing rapidly so I am certain something broke or changed.

  • I would strongly advise opening an issue about this on the Julia repository and cite my repo and this post here as a reference. To me, it does seem like an element in the pipeline has changed but I am uncertain how to address it.

Thanks and good luck here!

~ tcp :deciduous_tree:

2 Likes