Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Deterministic Floats with Burst, IL2CPP and Unity.Mathematics (SLEEF)

Discussion in 'Scripting Dev Blitz Day 2023 - Q&A' started by Iron-Warrior, Feb 23, 2023.

  1. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    I've written a previous thread about determinism in Unity and cross platform deterministic math.

    I also built a repo to test a bunch of float math on a variety of platforms and hardware using IL2CPP; the results were more or less what I expected based off research, in that the basic math operations seem to be cross platform deterministic (provided you are on ARMv8), while System.Math calls are not (as expected, since they point to C runtimes that may differ per platform).

    I figured this was the case with Unity.Mathematics compiled under Burst, since the Deterministic compile mode is still listed as "reserved for the future"...but inspecting the IL that is outputted by Burst under these conditions, it seems it inserts the correct deterministic SLEEF methods.

    So my question is: is Burst compiled code with FloatMode.Deterministic already guaranteed to be deterministic? And if so, would it be possible for Unity to expose the ability to make use of the SLEEF'd Unity.Mathematics functions without using Burst? Since it seems that IL2CPP produces deterministic float math on its own. (I could do this on my own, but compiling SLEEF cross platform is a pretty huge hassle, and figured many more would benefit if Unity has already completed the work.)
     
    FM-Productions likes this.
  2. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    The short answer is no, it's not guaranteed to be deterministic. As you've spotted, some amount of work has been done there, and it may produce the correct results in some situations, but it's not complete enough for us to guarantee anything.

    That's an interesting idea. I don't know what value we could provide there (other than building and packaging it so you don't have to). I think though, our focus (when we get time to work on this feature) is likely to be making floating point determinism work in the context of Burst.
     
  3. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Thanks for the reply Tim!

    Is this an issue with SLEEF, or something deeper? I did find on their doc page they state that Android/iOS support is experimental, and so possible they don't include them in their consistency tests. My assumption is that Burst itself would be able to achieve determinism for the basic arithmetic, as it uses LLVM (like IL2CPP) to produce the native code.

    It'd definitely feel like a niche feature, but I definitely like knowing that all code could be made deterministic/use the same math libraries when committing to a project (I haven't built anything extensive with ECS, and I could imagine using a hybrid setup of some sort). I'm thinking SLEEF would likely beat System.Math in performance when called from C#, but I haven't kept up C#'s native function call performance enough (I remember them introducing the ability to call native code without marshalling).
     
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,921
    I'll also mention that although IL2CPP might seem to be deterministic in this regard, it is not something we support or test for, unfortunately.
     
  5. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Yeah, I figured, and it's not really practical to rely on something like this when it's unsupported, as it'd be too fragile for production (as I believe IL2CPP does generate different code for different platforms, though currently not for math, as it seems).

    ...but it sure would be neat if it was! I'm not an expert on testing math consistency, so I'm really not sure what goes in to proving it out beyond what I have already done above. I'm guessing ensuring the actual compilation of C++ to native is consistent would be in LLVM's domain.

    Interestingly, the VR game Nock was just announced for PSVR, interested to see if it supports crossplay with Quest, as it uses deterministic networking with Burst/ECS/Unity Physics.
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,921
    We strive to keep the generated C++ code the same for all platforms, but the runtime code and C library code does indeed differ.
     
    Iron-Warrior likes this.
  7. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    It's more that we just didn't yet finish the work on our side. One of the outstanding tasks is to setup continuous-integration tests that execute floating point operations on multiple architectures, and compare the results, to verify determinism. What is there currently may be deterministic on some or all platforms, but we really can't guarantee it at this stage, because the feature is not finished.
     
    Iron-Warrior and SF_FrankvHoof like this.
  8. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Gotcha. Has this work been started? I'm curious if your approach differs much from mine in the repo I posted--I just generated a bunch of random floats, plus some predetermined values (subnormals, infinities, etc) and fed them through every possible operation. This felt a bit scattershot to me but I couldn't think of any more rigorous way that didn't involve like...2^32 * N operations. (Though as this was for IL2CPP, I did also inspect the generated C++ to verify that the math code was the same across platforms.)
     
  9. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    We haven't started the work to setup continuous-integration tests on multiple architectures - but I imagine it will look a lot like the approach you outlined.
     
  10. Iron-Warrior

    Iron-Warrior

    Joined:
    Nov 3, 2009
    Posts:
    838
    Okay nice! Thanks for all your replies, really helped to demystify everything around this ✌

    Also re: Unity exposing the SLEEF functions to devs who aren't doing pure Burst gameplay code...I realized you can just do this
    Code (CSharp):
    1.     [BurstCompile(FloatMode = FloatMode.Deterministic)]
    2.     public static float sin(float x)
    3.     {
    4.         return (float)System.Math.Sin(x);
    5.     }
    ...as per the IL the SLEEF function is inserted here, allowing this to be called from non-Burst code (?). No idea the overhead of going from IL2CPP'd C# to a Burst function, I assume fairly minimal as I think Burst functions take in unmanaged objects only?