Search Unity

Bug ScheduleParallel() crashes computer. Schedule() does not.

Discussion in 'Burst' started by Kmsxkuse, Dec 21, 2021.

  1. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    Executing SystemBase code:
    Code (CSharp):
    1. [DisableAutoCreation]
    2. public class CrashComputer : SystemBase
    3. {
    4.     private NativeArray<UnsafeList<v256>> _deltas, _inventories;
    5.  
    6.     public JobHandle SystemHandle;
    7.  
    8.     protected override void OnCreate()
    9.     {
    10.         _deltas = new NativeArray<UnsafeList<v256>>(2400, Allocator.Persistent,
    11.             NativeArrayOptions.UninitializedMemory);
    12.         _inventories = new NativeArray<UnsafeList<v256>>(_deltas.Length, Allocator.Persistent,
    13.             NativeArrayOptions.UninitializedMemory);
    14.  
    15.         var random = new Random(54321);
    16.  
    17.         const int size = 1000;
    18.         for (var index = 0; index < _deltas.Length; index++)
    19.         {
    20.             var list = new UnsafeList<v256>(size, Allocator.Persistent);
    21.             _inventories[index] = new UnsafeList<v256>(size, Allocator.Persistent, NativeArrayOptions.ClearMemory);
    22.             for (var pop = 0; pop < size; pop++)
    23.             {
    24.                 var target = new v256((sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    25.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    26.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    27.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    28.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    29.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    30.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    31.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    32.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    33.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2),
    34.                     (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2), (sbyte) random.NextInt(-1, 2)
    35. );
    36.                 list.Add(target);
    37.             }
    38.  
    39.             _deltas[index] = list;
    40.         }
    41.     }
    42.  
    43.     protected override void OnUpdate()
    44.     {
    45.         // ------ WARNING ------ WILL CRASH COMPUTER ------
    46.         Dependency = new TestJob
    47.         {
    48.             Deltas = _deltas,
    49.             Inventories = _inventories
    50.         }.ScheduleParallel(_deltas.Length, 1, default);
    51.  
    52.         // THIS DOES NOT CRASH COMPUTER (executes as expected)
    53.         // Dependency = new TestJob
    54.         // {
    55.         //     Deltas = _deltas,
    56.         //     Inventories = _inventories
    57.         // }.Schedule(_deltas.Length, default);
    58.  
    59.         // Note, setting the dependency parameter of both jobs to Dependency
    60.         // seems to prevent the crash? Maybe. It goes from crash 100% to crash
    61.         // maybe 25% for parallel scheduling and restarting Unity after every run.
    62.  
    63.         // Singlethreaded Schedule() works with default
    64.         // or Dependency as expected with no crashing.
    65.  
    66.         SystemHandle = Dependency;
    67.     }
    68.  
    69.     protected override void OnDestroy()
    70.     {
    71.         Dependency.Complete();
    72.  
    73.         foreach (var delta in _deltas)
    74.             delta.Dispose();
    75.         _deltas.Dispose();
    76.  
    77.         foreach (var inventory in _inventories)
    78.             inventory.Dispose();
    79.         _inventories.Dispose();
    80.     }
    81.  
    82.     [BurstCompile]
    83.     private unsafe struct TestJob : IJobFor
    84.     {
    85.         [ReadOnly] public NativeArray<UnsafeList<v256>> Deltas;
    86.  
    87.         public NativeArray<UnsafeList<v256>> Inventories;
    88.  
    89.         public void Execute(int index)
    90.         {
    91.             var deltaPtr = Deltas[index].Ptr;
    92.             var inventoryPtr = Inventories[index].Ptr;
    93.  
    94.             RegularAddition((sbyte*) deltaPtr, (sbyte*) inventoryPtr);
    95.         }
    96.  
    97.         [MethodImpl(MethodImplOptions.NoInlining)]
    98.         private static void RegularAddition([NoAlias] sbyte* deltasPtr, [NoAlias] sbyte* inventoriesPtr)
    99.         {
    100.             for (var index = 0; index < 1000; index++)
    101.             for (var inside = 0; inside < 32; inside++)
    102.                 inventoriesPtr[index * 32 + inside] += deltasPtr[index * 32 + inside];
    103.         }
    104.     }
    105. }
    Code executing on player loop:
    Code (CSharp):
    1. public class WorldUpdateManager : SystemBase
    2. {
    3.     private World _world;
    4.  
    5.     private CrashComputer _crashComputer;
    6.  
    7.     protected override void OnStartRunning()
    8.     {
    9.         _world = new World("Test World");
    10.  
    11.         var simulationGroup = _world.CreateSystem<SimulationSystemGroup>();
    12.  
    13.         _crashComputer = _world.CreateSystem<CrashComputer>();
    14.         simulationGroup.AddSystemToUpdateList(_crashComputer);
    15.     }
    16.  
    17.     protected override void OnUpdate()
    18.     {
    19.         if (!_crashComputer.SystemHandle.IsCompleted)
    20.             return;
    21.  
    22.         _world.Update();
    23.     }
    24. }


    There is no error message. Computer BSOD requiring me to restart.

    Note, this is a standalone job copy of a DOTS Entities version doing the exact same code, which also crashes when using ScheduleParallel().

    All instances of ScheduleParallel results in crashes. Regardless of job type. Tested with IJobFor (found here), IJobParallelFor, IJobEntityBatch, and IJobChunk.

    Code executed on Unity 2022.1 Beta 2. Entities 0.17. Burst 1.7.0 pre-1.
     
    Last edited: Dec 21, 2021
  2. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    Tried the same setup locally, could not get it to fail nor crash the computer. I tried Burst 1.6.3, 1.7.0-pre.1, and our latest internal Burst, all worked.

    If the issue still persists can you submit an actual ticket with a repro for this please?
     
    Kmsxkuse likes this.
  3. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    Damn, wish just putting the code here would allow for reproducing. Now I have to go the long way...

    Just saw the post about y'all going on vacation. Hope y'all have a good time.

    Odd, making a new project and pasting in the code doesnt crash my computer... Well I do have a lot of other stuff going on in the other project, probably a memory overflow or something.

    Edit: Got it to crash my computer in a empty project.

    Key thing: Turn off burst. I dont know if it's relevant for your team now but since Burst cant exist without the job system (well until ISystemBase comes along), I'll leave the ticket here.
     
    Last edited: Dec 21, 2021
  4. Kmsxkuse

    Kmsxkuse

    Joined:
    Feb 15, 2019
    Posts:
    306
    (Case 1390060) ScheduleParallel() crashes computer. Schedule() does not.