Search Unity

Bug Burst executes both branches of if/else, if they are too similar

Discussion in 'Burst' started by Wobbers, Jan 27, 2023.

  1. Wobbers

    Wobbers

    Joined:
    Dec 31, 2017
    Posts:
    55
    Hi,

    I have this if/else branch in a bursted ISystem, where both, the if and the else part are executed simultaneously for the same entity (There is only one matching entity, as also shown by the debug.logs).
    Both branches add an empty (but different) tag component to the entity, and add an element to a DynamicBuffer.

    Code (CSharp):
    1.  
    2. [BurstCompile]
    3. public void OnUpdate(ref SystemState state)
    4. {
    5.     // ...
    6.  
    7.     var ecb = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>()
    8.                    .CreateCommandBuffer(state.WorldUnmanaged);
    9.     foreach (var (buffers, battle, match, e) in
    10.                 SystemAPI.Query<BattleBuffers, RefRW<OngoingBattle>, RefRO<Match>>()
    11.                         .WithAll<BattleState.PerformAction>()
    12.                         .WithEntityAccess())
    13.     {
    14.         // ...
    15.         Debug.Log($"--- before IF/ELSE for E{e.Index}:{e.Version}; buffer isEmpty: {buffers.actionQueue.IsEmpty}");
    16.         if (buffers.actionQueue.IsEmpty)
    17.         {
    18.             ecb.AddComponent<BattleState.WaitForTurn>(e); // empty tag component
    19.             Debug.Log($"--- execute IF branch for E{e.Index}:{e.Version}");
    20.             var stateUpdate = new MatchStateUpdateMessage
    21.             {
    22.                 ActorId = Actor.Invalid.Id,
    23.                 CurrentState = BattleState.State.WaitForTurn,
    24.             };
    25.             foreach(var player in buffers.players)
    26.                 ecb.AppendToBuffer(matchStateBuffer, stateUpdate.For(player.Connection));
    27.         }
    28.         else
    29.         {
    30.             ecb.AddComponent<BattleState.PrepareTurn>(e); // empty tag component
    31.             Debug.Log($"--- execute ELSE branch for E{e.Index}:{e.Version}");
    32.             var stateUpdate = new MatchStateUpdateMessage
    33.             {
    34.                 ActorId = action.CasterId,
    35.                 CurrentState = BattleState.State.PrepareTurn,
    36.             };
    37.             foreach(var player in buffers.players)
    38.                 ecb.AppendToBuffer(matchStateBuffer, stateUpdate.For(player.Connection));
    39.         }
    40.         Debug.Log($"--- after IF/ELSE E{e.Index}:{e.Version}");
    41.         continue;
    42.  
    43.         // ...
    44.     }
    45. }
    46.  
    When this system runs with burst compilation enabled, both if and else branch are executed (however, only one of the
    BattleState
    tags will be present on the entity afterwards).
    upload_2023-1-27_23-12-7.png

    This can be fixed by switching the order of the statements, i.e. moving the
    ecb.AddComponent
    and
    Debug.Log
    to the bottom of the if branch.
    This should not change anything logically, but provides the correct output.
    upload_2023-1-27_23-15-13.png

    EDIT: Burst version 1.7.4, Entities 1.0.0-pre.15, Unity 2022.2.0f1
     
    Last edited: Jan 27, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,979
    Same log if you disable Burst compilation?
     
    MarcoPersson likes this.
  3. MarcoPersson

    MarcoPersson

    Unity Technologies

    Joined:
    Jul 21, 2021
    Posts:
    53
    Hi @Wobbers,
    Yeah as @CodeSmile asked; are you seeing the same results with Burst compilation disabled?
    Assuming it doesn't happen with Burst disabled, are you either able to produce a single-file repro, or file a bug report via 'Help > Report a Bug' and post the report number here? Then I can look further into it
     
  4. Wobbers

    Wobbers

    Joined:
    Dec 31, 2017
    Posts:
    55
    Yes, with Burst compilation disabled, it works as expected, and the else branch never executes. (the condition is always false).

    It reproduced right away in an empty project, which I actually didn't expect. Report number is IN-30517. I added a system that logs the number of items in the buffer that is added each frame with
    ecb.AppendToBuffer
    in both branches, and it always logs 2 when burst is enabled, and 1 when burst is disabled.
     
  5. MarcoPersson

    MarcoPersson

    Unity Technologies

    Joined:
    Jul 21, 2021
    Posts:
    53
    Great, thanks. I'll have a look at it then
     
  6. MarcoPersson

    MarcoPersson

    Unity Technologies

    Joined:
    Jul 21, 2021
    Posts:
    53
    The issue has been fixed and should be a part of the next release of Burst
     
    Kmsxkuse likes this.