To wrap Rust code in Julia, the rust code usually needs to expose a C interface. Then you can ccall it like a C library and it’s relatively easy. You can also build the library in Yggdrasil to get a JLL package to bundle the dependency. However it doesn’t look like that project has a C interface.
For translation, I think the main obstacle there looks like the lack of tests. It will be hard to know if the translation is correct without tests. Maybe you can generate some reference tests (eg save out the outputs on the examples) and use that to verify parity.
If you had good tests, then I think it doesn’t look like too much code to translate in a week, and the code itself looks like fairly straightforward numerical stuff that would translate well. I would use a LLM at least to get started and reduce the busywork.
I took a quick look at the code - it’s fairly simple and can be easily translated using LLM. There are no complex dependencies and complex language constructs (it was probably translated from C or Fortran itself)
Looks like that library was written for a paper which seems to present this code as novel and not a translation of another existing code.
That said, it looks to have on the order of 1000 lines of Rust code. A significant fraction of that could probably be functionally substituted using common Julia libraries like FFTW.jl, HCubature.jl, etc. A lot of the rest seems like it could be represented more compactly in Julia.
The “hard” part would just be getting a handle on the architecture of the code, testing the end results for consistency with the Rust code, etc.
When I ask for code from LLMs, they produce some helpful and useful code, but invariably, eventually, lose the thread, misunderstand the ultimate goal, add logic errors or hallucinate functionality or packages that don’t exist.
While they are frequently helpful, I would be surprised to see a long translation of code (beyond a couple of dozen lines) that does what I want, let alone that I can trust.
I am using paid/enterprise versions of chatGPT/copilot, BTW.
I translated this package from Matlab to Julia. The Julia version has currently 3128 lines of code. It took me about 10 days of work (fulltime). I used LLMs to translate it function-by-function. But some things could not be translated literately, for example the Matlab code was switching the search path at runtime.
In general it worked well. Procedure:
translate a function
run it in Julia
you will get some error, ask the LLM how to fix the error. Most of the time you get a good answer, but sometimes the errors are tricky and you need to think and debug yourself.
ask the LLM to write a unit test for the function
fix the unit test manually
ask the LLM to write a docstring for the function
At the very end, when you have a running code you still need to change the naming convention for variables to match the Julia style. Using an LLM helps with doing that, but naming is always tricky and sometimes you need to decide about names manually.
I still need to figure out how to run Rust functions and how to debug them to get the reference data for my Julia translations.
Hi, thanks for your interest in Jaime’s project It would be super cool to have a good turbulence generator in Julia. I think it’s worth mentioning a couple of alternatives:
I don’t have very much experience using coding agents (only a couple of days of toying around). In my (limited) experience, it depends quite a bit on how you instruct the agent. Just a “translate this to Julia” won’t work here. What I would try is:
Let the agent analyze the rust code to understand it’s structure (possible let it write that to a .md file for persistence)
Let the agent make a plan for how to translate this to Julia (this time written to a .md file for sure)
Then discuss and refine this plan with the agent. E.g. tell it to find places where Julia libraries could be used or directly instruct it what code to replace with a library. Discuss architecture choices of Julia (e.g. what types to create, what type parameters to use) every iteration should be reflected in the file on disk. In these plannings it can be helpful to let the agent generate small snippets of code to illustrate things.
Once the plan is detailed enough and seems sound, then you let the agent generate the code
I did one refactoring of a ~200loc script into a reusable “library” in this way and was surprised that it just worked directly. I found also that having the agent condense its knowledge into .md files both furthers clarity for the agent and helps you should you need to restart it due to some unforseen issues.
I had some free time to spare today and just gave this a shot: After 3hrs of work I have something that seems to work reasonably well although the code is somewhat messy and definitely has room for improvement. You can find the current version on GitHub
I gave you full access to the repo in case you want to continue this I might continue this in 2 weeks when I have another Friday for experiments but no promises.
Current state:
Everything is translated
Tests (AI generated) are green
A good portion of the tests compare output of this Julia code to reference data generated with Mann.rs (the code for generating this reference data is not included though - I’ll need to figure out how to this as currently it was done by adding code onto Mann.rs)
So I’d be cautiously optimistic that this code - though messy - actually could be correct.
I used RooCode’s Orchestrator mode and that really orchestrated the whole thing quite well
Initial prompt
In this folder you find a Rust project Mann.rs which I want to translate to Julia. I already created a new Julia package which you can find in MannTurbulence. These are some of the high-level requirements:
Correctness: It is very important to ensure that the Julia code produces the same results as the Rust code, which might be difficult because randomness is involved. So a good testing strategy is needed. Maybe we even need to add more precise test to the Rust code.
Performance: The Julia implementation should be fast. However, this should not be too difficult, if we follow the Rust code.
Idiomatic code: We want idiomatic Julia code to ensure maintainability. It is very likely that we can replace parts of the Rust code with Julia packages.
Starting analyzing and making the plan now. Ask me one question at a time to clarify details. Write the migration plan to plan.md.
With some help here and there of course. Models used where
Thank you so much! I will have a look at it. My prof said it would be useful for our research. And the original author of the code is now working in industry and quite busy.
Thank you for the interest and discussion about the package. Mann.rs actually does have a C-compatible interface specifically tailored to be coupled with Python using Pyo3. To interface with Julia, I think just some small changes to the library are needed (adding a #no_mangle and an extern "C" to the functions of interest). This would allow you to call the library in Julia using ccall. If this is helpful, I can try to set this up.