Julia vs C++ for computational mechanics - Implicit Material Point Method

TL;DR : Writing an implicit Material Point Method solver. Would it be that much slower in Julia than C++ for a similar time-effort ?

Hello,

I am PhD student working on simulating creeping snow. I am currently planning on writing my own computational mechanics solver : a quasi-static implicit Material Point Method. For this purpose, I am wondering if you just better do it in C++ or in julia for speed reasons. Let me explain the structure and stakes of my solver.

The Material Point Method is a hybrid Eulerian-Lagrangian Method relying on a set of particles which represent the material, and a background mesh. It goes basically like this :

  1. All the material informations and properties is stored on the particles
  2. These infos are interpolated on the back ground mesh. This step implies a small loop (a dozen step to reach the surrouding grid nodes) within a bigger loop (over all the particles).
  3. The equation of momentum is solved on the grid in the fashion of a Finite Element Method. Warning : since I want to simulate an implicit scheme, solving the mechanical equations involve inverting a matrix.
  4. Info is interpolated back to the particles (similar way as step 2)
  5. Particles positions and speeds are updated, grid is reset, ready for next timestep calculation.

So basically, the optimization challenges (to my understanding and knowledge) are the following :

  • managing big data structures (100k to a few million particles)
  • parallelizing as much as I can
  • managing big (parallelized loops)
  • operations on matrixes, including inversion
  • making my multiple dispatch efficient (to switch easily between small variants, 2D/3D, etc)
  • others ?

Here is my issue :
I am a new user to Julia and I love it, the readability, the multiple dispatch, the expressivity, the debugging (vs c++). Which would make my code much faster to implement than in c++ (which I am also rather new to).
However, this project is not just personal but professional. I really need/want to implement the fastest code I can, even if it takes more time. I would accept being up to 20% MAX slower in Julia than what would be reasonably achievable in c++, but cannot accept a 2 times difference (4 hours long vs 8 hours long simulation is a big difference).

Now, I’ve seen many threads saying Julia is 2 times slower, 30% slower, faster sometimes. And I understand it really depends on the situation. From what I understand, while Julia is slower in general, it would be easier for me to optimize the code in “simple” Julia than in “complex” c++.

So for an equivalent time-effort, would you think Julia’s efficiency would be close enough to that of c++ for my purpose ?

Thank you for your time,

Cheers.

Are you aware of

?

Try to search the packages in this organization before starting your own from scratch.

4 Likes

Was about to suggest. This may provide some insights, or even better, give a basis for future developments.

3 Likes

I think the Julia code will probably be faster, because it is easier to profile, measure, and focus the attention of the performance on the bottlenecks (that’s my experience vs. Fortran).

But even better is to take advantage of the available frameworks.

3 Likes

It really depends on your lvl on c++, you can do crazy performance critical decision in both language. However it will be easier to change the code to perf better in julia, c++ would require you to rewrite big parts to get a little perf sometimes.
If you choose julia I can only tell you to follow closely Performance Tips ¡ The Julia Language, make your code the best possible (time wize and allocation wize) before even considering parallel code, and only then you can go for it.
Doing it from scratch can be a good experience, however, don’t think it will add anything to your phd (unless you wanna go back to the engenering path after it), so go for the tools out there and try to understand them.

2 Likes

If you’re not an expert in C++, I think it’s very likely that with 2 weeks of effort your Julia code will be faster than your C++ code. At my company we tried reimplementing a Python pipeline in several different ways, and within two weeks the Julia version was much faster than the others.

Basically, Julia can do most of the optimization-related things C++ can. You can parallelize pretty easily in fine-grained detail with Tasks, code is compiled via LLVM, it’s quite possible to write non-allocating code, you can easily examine generated LLVM or assembly, etc.

So the big difference is that with Julia you will get a working prototype much sooner, and be able to profile it in detail more easily. (You can of course do detailed profiling in C++, but it’s harder to set up and learn, compared to macros like @timeit in Julia.) You’ll be able to find the slow parts of your code sooner, and spend time optimizing them.

4 Likes

Thank you for your input, I will indeed keep the performance tips on an open tab at all times :sweat_smile:.
Contrary to what you said, I think writing my own codebase is extremely relevant for my PhD since it forces me to go back to the equations and derivation of the solver. And writing the code makes that i fully understand it and can modify it easily. All this makes that, in the end, I will have a deeper knowledge of MPM, mechanical models and computational mechanics in general.

3 Likes

Yes deriving the numerical method, do some numerical analysis and such is beneficial for your PhD, however while writing it from scratch is beneficial for you knowledge, I’m not sure it is for the actual quality of the PhD that’s all, I just don’t want you to pass all your PhD coding which happens a lot and isn’t really relevant. If your PhD is on applied math obviously. Coding should be like 60% o think in applied math world. Unless you have an industry behind the PhD wanting a new code.

1 Like

I’d choose Julia for the reasons others have mentioned above. However, the downside of Julia for me has mostly been that while writing working code is fast and it’s pretty easy to come up with elegant code, a lot of time is spent tracking down obscure allocations in performance-critical functions. The issues often come from using high-level language features such as closures etc. I probably should’ve internalized the performance tips earlier to avoid too much headache. However, sometimes the allocations can pop up in pretty mysterious ways, or at least ways that are not easy to reason about. So it’s good to learn all the available tools like Cthulhu.jl and perhaps the new AllocChecks.jl.

Many performance related matters are not specific to Julia though, including issues related to parallelization or memory access.

Regarding using existing toolkits vs. writing your own, one approach is to write a functional implementation by yourself but once your code has reached some level of maturity, start looking into the established toolkits instead going down the path of adding features and improvements to your code. That way, you learn what writing a solver entails but don’t end up spending thousands of hours on a project that’ll end up lying abandoned in Github once you move to other things. Even a minor contribution to an existing project is likely have a larger real world impact than trying to maintain your own.

3 Likes

Thank you @juliohm, @lmiq, @yolhan_mannes, @Satvik, @tverho for your answers.

I will definitely consider writing my solver in Julia, according to you, I will reach similar performance as c++ since optimizing will be easier, while my work will be more comfortable in Julia.

I did not know about MaterialPointSolver.jl. It’s a great bonus, I would be able to follow an example in Julia with its optimization features.

2 Likes

It is still not clear why you would want to write a new solver, instead of using (or contributing to, if necessary) the existing one.

Don’t get me wrong, it will probably be a great learning experience, but what you will be learning is programming which may not be closely related to your PhD topic.

If you topic is an application of this method, then writing a new package if there is an existing one is a rabbit hole and a waste of time you could be spending on research. If you topic is a new refinement of this method, then you may be able to modify existing software. In any case, you may want to talk to your advisor first about priorities.

6 Likes

The reason I want to implement my own solver is that MaterialPointSolver.jl uses an explicit scheme, where I want to use an implicit one. Let me explain…

If we call Q and quantity involved in the momentum equation (speed, density, etc…) and ^n and ^{n+1} designate two successive time steps.
An explicit scheme calculates the state at ^{n+1} only with the state at time ^n : Q^{n+1} = f(Q^n). This method is the most straightforward solution, benefits from fast calculations and is often more precise. However, it is only conditionally stable, the condition being on the maximum size of the time step.
On the other hand, an implicit scheme calculates the state at time ^{n+1} by solving a system involving the states at times ^n and ^{n+1} : Q^{n+1} = g(Q^n, Q^{n+1}). Solving this system involves bigger time and allocation since we need to inverse a matrix. But this method is unconditionally stable, which means we can choose bigger time steps.
Using an implicit scheme is more convenient when dealing with long simulations and rather static or ‘slow’ deformations.

To the best of my knowledge, there does not exist an implicit, quasistatic, Material Point Method scheme for geomechanical purposes, with all recent efficiency and precision improvements of MPM, written in a fast, parallelizable language (Julia, C++, …).

There lies the innovation of what I do, which will be valuable in my PhD. Plus, I also might need to create a new viscoplastic model, which will be easier to implement if I know everything about my code.

5 Likes

Thanks for the explanation. Given that the package is actively developed and appears to contain a lot of code besides the solver, I would still try approaching the maintainer about making a contribution first.

Don’t get me wrong, nothing prevents you from developing your own package. It’s just that you may end up duplicating a lot of effort for no good reason.

6 Likes