Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question BurstCompile and ComponentDataFromEntity + execution from ForEach

Discussion in 'Entity Component System' started by TP-Fab, Feb 9, 2023.

  1. TP-Fab

    TP-Fab

    Joined:
    Jul 10, 2019
    Posts:
    37
    Hi there,

    Trying to figure something out with Entities 0.17 and can't wrap my head around it.

    I'm trying to execute something with a CFE (and with some NativeHashMap too, not included in the example below), but I can't get it to work without using some weird workaround:

    - #1 When trying to use BurstCompile on both the static class and static method I'm trying to burst (using CFE), I get a BC1063 that says the CFE is passed as a ref, although explicitely an in and a local variable rather than a member than the system

    - #2 Trying without BurstCompile on the static class, I observe 2 different behaviours: the direct call to the method is NOT bursted, while calling the method from a fake Entities.ForEach (only one entity in the world has that component), it does burst it properly. Which is definitely a dirty workaround

    Am I missing something that would allow to burst properly the direct call to that method in OnUpdate?

    note: the reason for this method to exist is to execute calculations on some NativeHashMap structure that would be extremely inefficient to reproduce as an Entities.ForEach, hence trying to get a direct call working.

    Code (CSharp):
    1. [BurstCompile]  // #3
    2.     public class ESTest : SystemBase
    3.     {
    4.         [BurstCompile] // #3
    5.         protected override void OnUpdate()
    6.         {
    7.             var cfeTest = GetComponentDataFromEntity< ECCharacter >();
    8.  
    9.             StaticTest.TestMethod( in cfeTest ); // #2
    10.  
    11.             Entities.ForEach( ( in ECOneComponentInWorld someSingleEntity ) =>
    12.                     {
    13.                         StaticTest.TestMethod( in cfeTest ); // #2
    14.                     } )
    15.                     .WithName( "singleEntityTest" )
    16.                     .Run();
    17.         }
    18.     }
    19.  
    20.     // [BurstCompile]    // #1
    21.     public static class StaticTest
    22.     {
    23.         [BurstCompile]
    24.         public static void TestMethod( in ComponentDataFromEntity< ECCharacter > cfeCharacter )
    25.         {
    26.             var a = 0;
    27.             for ( var i = 0; i < 10000000; i++ )
    28.             {
    29.                 a++;
    30.             }
    31.         }
    32.     }
    33.  
    34.     // #1 compile error if BurstCompile on class & method -->  Burst error BC1063: Unsupported parameter `ref Unity.Entities.ComponentDataFromEntity`1<TPC.ECCharacter>
    35.     // #2 with only method BurstCompile, executing TestMethod in a dummy ForEach loop runs as Bursted, while the direct call from OnUpdate is NOT Bursted
    36.     // #3 (as expected) no effect from BurstCompile on the system (no compile error, no change on execution)
     
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Because direct call follows FunctionPointer rules, and you can’t pass CDFE directly as an argument in that case by design. Calling method from the bursted job works differently and makes all calls from that code - burst compiled.
    https://docs.unity3d.com/Packages/com.unity.burst@1.8/manual/csharp-function-pointers.html
    And CDFE is exactly native container
     
  3. TP-Fab

    TP-Fab

    Joined:
    Jul 10, 2019
    Posts:
    37
    I see, thanks!

    Is there in that case any other choice for methods using NativeContainer to be called from anywhere else than a ForEach? A Job type that requires a minimal amount of boilerplate code maybe?
     
    Last edited: Feb 10, 2023