Nondeterminism in Bullet?

In another topic, a comment was made that “[B]ullet [physics] isn’t deterministic”.

I don’t claim to know whether it is or not. I’ve always just assumed it was.

I know with a BulletAppState, the number of physics steps simulated depends on the time per frame, but that’s not anything Bullet has control over.

If anyone has a Short, Self Contained, Correct (Compilable), Example of non-determinism in Bullet, or if non-determinism is mentioned somewhere in its official documentation, I’d appreciate a pointer!

4 Likes

Maybe I’m wrong. It has been known, and I’d be happy to be if it meant learning something new.

It is my understanding, see above, that the physics engine itself is deterministic but due to timing and outside interference it doesn’t always yield the same results.

I.e. each time you run it, your cpu doesn’t emulate the same timeframe cycle due to outside calculations or whatever, and result in different calculation results. It’s not the fault of the engine but a Behavior of general cpu action in real life application.

Reasons beyond normal control.

Examples of how to exploit this are beyond me, but that in the vast majority of runs you will yield a “perfect run” and it’s only some times or some reason a single calculation throws the whole thing off, if only slightly, and the severity over time would make this even visually apparent in most cases.

2 Likes

If you are carefully controlling what you provide the physics engine at each step and are stepping with fixed time deltas then it should be consistent and deterministic.

…as far as I know, bullet doesn’t include Brownian motion. :slight_smile:

Edit: note that when we discourage users from relying on determinism in their GAMES it’s because of how hard it is to get all of that consistent in a game. And only one tiny thing can throw the whole bit out of whack.

In my experience, in bullet you can even single step your physics engine and watch things happen in slow motion if you like. Presuming your inputs are consistent forces at consistent frames, you should get the same output every time (and when debugging things, I always was.)

4 Likes

Provided the timestep is correct your only problem might be floating point determinism, because not even that is deterministic across machines, but I dont know how java solves that.

See https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/

3 Likes

Java has the ‘strictfp’ keyword to make floating point arithmetic deterministic. (https://en.wikipedia.org/wiki/Strictfp)
I don’t know whether bullet uses strict floating point arithmetic. Also not sure whether it is even relevant to the scope of the question here.

3 Likes

Fascinating.

90% of computer programmers believe they thoroughly understand floating-point arithmetic, but less than 1% actually do.

2 Likes

Knowledge is the gift that keeps on giving :heart:

1 Like

To me, nondeterminism means you can run the same app with the same inputs in the same environment and get a different result. Portability is an orthogonal issue, IMO.

Strictfp helps ensure portability between platforms for software written in Java. However, most of Minie’s math is in native code, so it might not be sufficient. And Minie uses many different compilers for native code (Gcc 4.7, Gcc 5.4, Clang 902, and Visual C++ 2019), which increases the risk of non-portability.

2 Likes

Hi @sgold

I have a long, self contained, sure incorrect example of non deterministic behavior in Bullet.
I started playing with this project in 2014 and until now I can’t make it to work.
It is some kind of creatures made with bullet blocks, and a brain of neural networks that moves joints. The purpose is trying to train them until they can follow a target.

For sure I am doing something wrong but I can’t figure what is it ( I suspect about the neural network)

I tried everything I could (fixed time step, jbullet, native bullet, less neurons, simplify creatures, migrating to minie, set max accuracy, round everything to Integers, increase solver iterations, use multibody system instead of the default, change joint types, and many more changes that I forget…)

Source code is really really ugly, I didn’t expect to show it to anyone, so I wont get mad If you don’t want to check it.

In resume, It is kind of “Evolved creatures” from Karl Sims
I got a creature that moves, and some other clones that are almost identical but with some mutation on the weights of the neural net. I spawn all in an environment and evaluate who is performing better.
So I choose the best and generate other clones with some new mutations., so on and so forth.
I need the determinism to repeat the same “best” behavior in that iteration, and repeat it with some slight differences.

In the example that I have right now, I only clone creatures, with no modification, over and over again, and in every iteration, the behavior is different.

I upload the source to a tmp repository if you want to check.

All you should need are fixed time steps and submitting the EXACT SAME forces at the EXACT SAME frames every time.

Fortunately, that’s the absolute simplest thing to check. Just log all of the forces that you ever apply and on which frame. I bet you will find that they vary from run to run… then you can figure out where you multiply by tpf or whatever where you shouldn’t… or where you have some other thing that’s out of sync with frames.

And if I’m wrong, you’ll be able to come back and show us the logs where the exact same forces/accelerations/whatever were applied on the exact same frames but then something diverged.

2 Likes

I’m not interested in debugging your app for you, particularly since it crashes after running 19 hours.

However, I see a possible reason why it might give different results on every run: it uses FastMath.nextRandomInt(), which uses System.currentTimeMillis() as its seed.

Totally agree @pspeed : I think I vaguely tried to accomplish what you mention but failed. But I will try again, follow your advice and come back with a win (hopefully)

@sgold no worries, it is not my intention either. If I can’t fix it with @pspeed “log everything” approach I will try to come up with an example at is bare minimum, directly from scratch for you to check.

ps: yes I left the app for 19 hours, but was just to test an evaluation function. Anyways, don’t bother.
ps2: I use nextrandomint functions only for the first time, to generate the neural network, then I am copying the “brain” without modification on each iteration, I still suspect that Is something related with Time steps in the NeuralNet.

Thank you both

1 Like

I guess I never considered that deterministic physics existed beyond over simplified models. I make it a rule of thumb to never rely on physics to behave the same way twice, especially bullet. I have seen too many times where it has acted completely different, like when an object is dropped which direction it bounces.

In around the 3 minute mark - it shows a reason why this might be a problem.

Other than this particular situation, I can’t really see it being a huge issue in a game (i.e. not a scientific or industrial test) considering the server would be authoritative. Everyone would get the same view/result.

I’ve been reading this thread on and off. And my 2 cents example is:

Trackmania is a group of games (any version new or old) which has deterministic physics, see the press forward tracks for an example of it working every time.
I’m pretty sure its a fixed physics step, but its only a guess.

Hi, me again,

Maybe I have a newie error but I still can’t get it.

I followed @pspeed advice and try to log everything. Bad news is that I still unable to find the issue.
The good thing is that I have an example to its bare minimum…
Simple application,
If you press the 1 Key, it will load 4 simple cubes connected with joints.
In simpleUpdate I am checking if bodies are active or not…
If they are not moving (hit floor and stayed there) then I loop all the bodies and save their positions in a log file.

So, It is only gravity there, I am just leaving the bodies free fall until they stop moving and save their positions They are almost identical, not the same. But there is something weird, it seems that the y component is exactly the same on each run, but different xs and zs.

Hopefully this will help @sgold

1 Like

Do you use the load creature part that is triggered by a key? If not then it’s confusing because that would certainly be non-deterministic.

Also, I’m not sure the physics is fixed time-stepping. (Pretty sure it isn’t in fact.) My recollection is that it was nearly impossible to get BulletAppState to step in fixed time… but I could be thinking of something else.

So you said that I need to load the creature at the beginning without using a key?
or I didn’t understand sorry.

Load the models first, then repeat the excercise. I.e. don’t let the loading delay be an indeterminate.

I loaded the model first and remove the key aproach…repeat the test. I still got different positions at the end.