Search Unity

error when using raycast in parallelfor

Discussion in 'Physics for ECS' started by BigRookGames, Oct 31, 2020.

  1. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    I am hitting an error when calling a raycast inside of parallelfor job:

    `IndexOutOfRangeException: Index 3 is out of restricted IJobParallelFor range [0...0] in ReadWriteBuffer.`

    any idea what variable it may be referring to- index3?
    It is triggering at line 16

    Code (CSharp):
    1. JobHandle hoverJob = Entities.WithBurst().ForEach(( Entity entity,
    2.             int entityInQueryIndex, //Used for Concurrent ECB writing
    3.             ref HoverSystem hoverSystem,
    4.             ref PhysicsVelocity _physicsVelocity,
    5.             in PhysicsMass _physicsMass
    6.             ,in Translation translation
    7.             //,ref Rotation rotation
    8.             ) => {
    9.                 RaycastHit raycastHit = new RaycastHit();
    10.                 RaycastInput rayInput = new RaycastInput
    11.                 {
    12.                     Start = translation.Value,
    13.                     End = translation.Value - new float3(0, hoverSystem.hoverHeight, 0),
    14.                     Filter = colFilter
    15.                 };
    16.                 bool hit = collisionWorld.CastRay(rayInput, out raycastHit);
     
    RamType0 and flyingmylove like this.
  2. ryanslikesocool

    ryanslikesocool

    Joined:
    Jul 31, 2016
    Posts:
    49
    I'm having the exact same issue with the new DOTS package updates yesterday. Would love an answer for this.
     
    deus0 and BigRookGames like this.
  3. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    I suspected it might have been from the update, but I made some other changes too so couldn't be sure.
     
  4. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    When I schedule the job normally (not parallel) it seems to work, so for now that may help. I do need it to be parallel so it isn't a solution but maybe a temp fix until we get more info.
     
    ryanslikesocool likes this.
  5. ryanslikesocool

    ryanslikesocool

    Joined:
    Jul 31, 2016
    Posts:
    49
    Yep. That "fix" works for me too. Disappointed I can't use ScheduleParallel, but it works!
     
    BigRookGames likes this.
  6. flyingmylove

    flyingmylove

    Joined:
    Sep 29, 2019
    Posts:
    11
    Same problem.
    I find that there is a readOnly NativeArray m_Bodies in a struct called BvhLeafProcessor in the Broadphase.cs.
    Should be a bug in nativearray stuff.
     
    BigRookGames likes this.
  7. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    I would expect that if you work with readonly CollisionWorld this wouldn't happen. I've seen the same thing before if I remember correctly.
     
    BigRookGames and flyingmylove like this.
  8. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Also depends on how you schedule it, maybe it doesn't complete on time and the next BuildPhysicsWorld jumps in and breaks the data you are working on. I don't see the scheduling code here...
     
    BigRookGames likes this.
  9. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    Thanks for helping.

    As for scheduling, The first job after physics uses export physics as the dependency:

    .Schedule(exportPhysics.GetOutputDependency());

    and the job that is mentioned in the error uses that job as a dependency, so I would think it would be clear of the physics system.
     
  10. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You still need to go before EndFramePhysicsSystem (by using AddInputDependency(), but also the UpdateBefore). Otherwise there is no guarantee that next BuildPhysicsWorld won't override your data.
     
    BigRookGames likes this.
  11. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    Oh yes, I also have that: [UpdateAfter(typeof(EndFramePhysicsSystem)), UpdateBefore(typeof(HoverBotSystem))]

    Should this be done before?
     
  12. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Just make sure your HoverBotSystem waits for the handle of the job you are spawning, that should do it.
     
    BigRookGames likes this.
  13. jtanaka-u

    jtanaka-u

    Joined:
    May 4, 2020
    Posts:
    2
    Are you saying that any raycast system should run inside the FixedStepSimulationSystemGroup and that it has to be always before EndFramePhysicsSystem but never after it?
     
  14. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Just saying that if it is in this group, it needs to be before this system. If it's in a different group it should be fine.
     
    jtanaka-u and BigRookGames like this.
  15. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
  16. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You can also use Entities.WithReadOnly() for CollisionWorld, I think it's simplest.
     
    martinjonsson01 and toomasio like this.
  17. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    Hi... Besides physics which im not using, how do we fix this ScheduleParallel Bug? Do we simply wait for unity to fix it before updating our packages?
     
  18. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    You can schedule an IJob or IJobChunk or IJobParallelFor instead, setting [ReadOnly] on members of the job should work there for now.
     
  19. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    It's not possible to rework 100 systems and then rework them back after unity does a fix haha.. The use of IJobChunk I only use if I have a more complex system with more then one function!
     
  20. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Yeah I get it, it's far from ideal.
     
  21. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    slamming my head against the wall and this finally worked. Thanks!
     
  22. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    Well more like impossible. How long until unity gets the core feature of ECS working again lol
    I thought maybe with 2020.2 that the latest ECS would be working again, but still broken. Maybe related but beta and alpha has been bricked on linux since this year as well. Also annoying that I'm forced to install the particles package if I want to update the hybrid package. I'm just really looking forward to the day when ECS packages become stable and I won't have to update again for it to be bricked!
     
    Last edited: Dec 15, 2020
  23. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    Are you specifically referring to the bug that requires a read-only reference definition?
     
  24. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    '`IndexOutOfRangeException: Index 3 is out of restricted IJobParallelFor range [0...0] in ReadWriteBuffer.`' This error that I receieve this error when using a parallel job in a system.

    Code (CSharp):
    1. var entities = uiQuery.ToEntityArray(Allocator.TempJob);
    2. var uis = GetComponentDataFromEntity<UIElement>(true);
    3. Entities.ForEach((Entity e, int entityInQueryIndex, ref Navigator navigator, in Controller controller) =>
    4. {
    5.     for (int i = 0; i < entities.Length; i++)
    6.     {
    7.         var e2 = entities[i];
    8.         var size = uis[e2].size;
    9.     }
    10. }

    I use this, an iterate through for a simpler mouse raycast system. The new Entities package returns the new error, while the old one works fine. It stops me from upgrading my packages.
     
  25. petarmHavok

    petarmHavok

    Joined:
    Nov 20, 2018
    Posts:
    461
    Can I see the system that runs this code? Most notably the tags above system and any job scheduling code.
     
    deus0 likes this.
  26. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    Totally the script looks like this!
    The issue is it doesn't let me iterate through the entities anymore during the parallel job.
    This code worked prior to the latest entities package.
    The new added error/restriction is this:
    'IndexOutOfRangeException: Index 1 is out of restricted IJobParallelFor range [0...0] in ReadWriteBuffer.
    ReadWriteBuffers are restricted to only read & write the element at the job index. You can use double buffering strategies to avoid race conditions due to reading & writing in parallel to the same elements from a job.'

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Transforms;
    4. using Unity.Burst;
    5. using Unity.Collections;
    6.  
    7. namespace Zoxel.UI
    8. {
    9.     [DisableAutoCreation]
    10.     public class MouseRaycastUISystem : SystemBase
    11.     {
    12.         public EndSimulationEntityCommandBufferSystem commandBufferSystem;
    13.         private EntityQuery uis;
    14.  
    15.         protected override void OnCreate()
    16.         {
    17.             commandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    18.             uis = GetEntityQuery(ComponentType.ReadOnly<UIElement>(), ComponentType.ReadOnly<NavigationUI>(), ComponentType.ReadOnly<Translation>());
    19.         }
    20.  
    21.         [BurstCompile]
    22.         protected override void OnUpdate()
    23.         {
    24.             if (uis.CalculateEntityCount() == 0)
    25.             {
    26.                 return;
    27.             }
    28.             var entities = uis.ToEntityArray(Allocator.TempJob);
    29.             var uiElements = GetComponentDataFromEntity<UIElement>(true);
    30.             var frustrumHeight = Zoxel.Cameras.CameraUIStartSystem.frustrumHeight;
    31.             var frustrumWidth = Zoxel.Cameras.CameraUIStartSystem.frustrumWidth;
    32.             var PostUpdateCommands = commandBufferSystem.CreateCommandBuffer().AsParallelWriter();
    33.             Dependency = Entities.ForEach((Entity e, int entityInQueryIndex, ref Navigator navigator, in Controller controller) =>
    34.             {
    35.                 if (controller.lockState != (int)UnityEngine.CursorLockMode.None ||
    36.                     controller.deviceType != (byte)DeviceType.KeyboardMouse ||
    37.                     controller.mapping == (byte)ControllerMapping.Input)
    38.                 {
    39.                     return;
    40.                 }
    41.                 navigator.mouseOver = 0;
    42.                 var pointer = controller.data.pointer;
    43.                 bool didSelect = false;
    44.                 for (int i = 0; i < entities.Length; i++)
    45.                 {
    46.                     var uiEntity = entities[i];
    47.                     var uiElement = uiElements[uiEntity];
    48.                     var position = uiElement.position;
    49.                     var size = uiElement.size;
    50.                     size = new float2(size.x / frustrumWidth, size.y / frustrumHeight);
    51.                     position = position - size / 2f;
    52.                     if (pointer.x >= position.x && pointer.x <= position.x + size.x &&
    53.                         pointer.y >= position.y && pointer.y <= position.y + size.y)
    54.                     {
    55.                         navigator.mouseOver = 1;
    56.                         if (navigator.selected == uiEntity)
    57.                         {
    58.                             didSelect = true;
    59.                             break;
    60.                         }
    61.                         else if (navigator.selectedIcon != uiEntity)
    62.                         {
    63.                             PostUpdateCommands.AddComponent(entityInQueryIndex, e,
    64.                                 new SelectionEvent
    65.                                 {
    66.                                     newSelected = uiEntity,
    67.                                     character = navigator.character
    68.                                 });
    69.                             didSelect = true;
    70.                             break;
    71.                         }
    72.                     }
    73.                 }
    74.                 if (!didSelect && navigator.selected.Index != 0)
    75.                 {
    76.                     PostUpdateCommands.AddComponent(entityInQueryIndex, e,
    77.                         new SelectionEvent
    78.                         {
    79.                             newSelected = new Entity(),
    80.                             character = navigator.character
    81.                         });
    82.                 }
    83.             })  .WithDisposeOnCompletion(entities)
    84.                 .WithNativeDisableContainerSafetyRestriction(uiElements)
    85.                 .ScheduleParallel(Dependency);
    86.             commandBufferSystem.AddJobHandleForProducer(Dependency);
    87.         }
    88.     }
    89. }
     
    Last edited: Dec 20, 2020
    bb8_1 likes this.
  27. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    what about when you add .WithNativeDisableParallelForRestriction(entities)
     
    deus0 likes this.
  28. deus0

    deus0

    Joined:
    May 12, 2015
    Posts:
    256
    I found a better solution from stack overflow!
    https://stackoverflow.com/questions...n-array-item-within-nativearrrayentity-in-ecs
    Basically just a readonly declaration for the entities I pass through. The missing piece of the puzzle :D
    .WithReadOnly(entities)
    The safety mechanisms improved a lot over the last entities package, so anyone without these declarations should also run into the same issue.
    The only issue now with the new packages is this weird flashing i'm getting with hybrid rendering (rendermesh) models

    Edit: this is happening only for lit shader graphs using hybrid renderer system, switching to unlit shadergraphs for now
    Edit2: Wow this is old, this is why I stopped using Hyrbrid haha.
     
    Last edited: Jun 26, 2022