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 what is UNITY_DOTSRUNTIME?

Discussion in 'Entity Component System' started by ueue44, Aug 10, 2022.

  1. ueue44

    ueue44

    Joined:
    Jun 17, 2013
    Posts:
    16
    hi

    I am getting an error when building SetSharedComponent of CommandBuffer in ECS using WithBurst.
    The error is due to the internal use of Delegate.

    I am thinking that if the else side of "#if !UNITY_DOTSRUNTIME" in TypeManager.cs works, the error will not occur in the build.
    What is UNITY_DOTSRUNTIME?
    Do we need to define it ourselves?

    ## Burst Error
    ## Stack Trace
    Code (CSharp):
    1. at Unity.Entities.FastEquality.GetHashCode(void* dataPtr, Unity.Entities.FastEquality.TypeInfo typeInfo)
    2.  
    3. at Unity.Entities.FastEquality.GetHashCode(Unity.Physics.PhysicsWorldIndex lhs, Unity.Entities.FastEquality.TypeInfo typeInfo)
    4.  
    5. at Unity.Entities.TypeManager.GetHashCode(ref Unity.Physics.PhysicsWorldIndex val)
    6.  
    7. at Unity.Entities.EntityCommandBuffer.IsDefaultObject(ref Unity.Physics.PhysicsWorldIndex component, ref int hashCode)
    8.  
    9. at Unity.Entities.EntityCommandBuffer.SetSharedComponent(Unity.Entities.EntityCommandBuffer* this, Unity.Entities.Entity e, Unity.Physics.PhysicsWorldIndex component)
    ## Code
    ### Self Code
    Error Occured => commandBuffer.SetSharedComponent(entity, new PhysicsWorldIndex());
    Code (CSharp):
    1. Entities
    2.   .WithBurst()
    3.   .WithAll<TestComponent>()
    4.   .ForEach((
    5.     Entity entity,
    6.     int entityInQueryIndex,
    7.     ref TestComponent testComponent,
    8.   ) => {
    9.     commandBuffer.SetSharedComponent(entity, new PhysicsWorldIndex());
    10.   }).Schedule();
    ### EntityCommandBuffer.cs:2249 => if (IsDefaultObject(ref component, out hashCode))
    Code (CSharp):
    1. public void SetSharedComponent<T>(Entity e, T component) where T : struct, ISharedComponentData
    2. {
    3.     EnforceSingleThreadOwnership();
    4.     AssertDidNotPlayback();
    5.  
    6.     int hashCode;
    7.     if (IsDefaultObject(ref component, out hashCode))
    8.         m_Data->AddEntitySharedComponentCommand<T>(&m_Data->m_MainThreadChain, MainThreadSortKey, ECBCommand.SetSharedComponentData, e, hashCode, null);
    9.     else
    10.         m_Data->AddEntitySharedComponentCommand<T>(&m_Data->m_MainThreadChain, MainThreadSortKey, ECBCommand.SetSharedComponentData, e, hashCode, component);
    11. }
    ### EntityCommandBuffer.cs:2188 => hashCode = TypeManager.GetHashCode(ref component);
    Code (CSharp):
    1. static bool IsDefaultObject<T>(ref T component, out int hashCode) where T : struct, ISharedComponentData
    2. {
    3.     var defaultValue = default(T);
    4.  
    5.     hashCode = TypeManager.GetHashCode(ref component);
    6.     return TypeManager.Equals(ref defaultValue, ref component);
    7. }
    ### TypeManager.cs:760 => return FastEquality.GetHashCode(val, s_FastEqualityTypeInfoList[GetTypeInfo(typeIndex).FastEqualityIndex]);
    Code (CSharp):
    1. public static int GetHashCode<T>(ref T val) where T : struct
    2. {
    3. #if !UNITY_DOTSRUNTIME
    4.     var typeIndex = GetTypeIndex<T>();
    5.     if(IsSharedComponentType(typeIndex))
    6.         return FastEquality.GetHashCode(val, s_FastEqualityTypeInfoList[GetTypeInfo(typeIndex).FastEqualityIndex]);
    7.  
    8.     return FastEquality.GetHashCode(val);
    9. #else
    10.     return (int)XXHash.Hash32((byte*)UnsafeUtility.AddressOf(ref val), UnsafeUtility.SizeOf<T>());
    11. #endif
    12. }
    ### FastEquality.cs:192 => return GetHashCode(UnsafeUtility.AddressOf(ref lhs), typeInfo);
    Code (CSharp):
    1. public static unsafe int GetHashCode<T>(T lhs, TypeInfo typeInfo) where T : struct
    2. {
    3.     return GetHashCode(UnsafeUtility.AddressOf(ref lhs), typeInfo);
    4. }
    ### FastEquality.cs:202 => if (typeInfo.GetHashFn != null)
    Code (CSharp):
    1. public static unsafe int GetHashCode(void* dataPtr, TypeInfo typeInfo)
    2. {
    3.     if (typeInfo.GetHashFn != null)
    4.     {
    5.         TypeInfo.GetHashCodeDelegate fn = (TypeInfo.GetHashCodeDelegate)typeInfo.GetHashFn;
    6.         return fn(dataPtr);
    7.     }
    8.  
    9.     return Hash32((byte*) dataPtr, typeInfo.TypeSize);
    10. }
    ### FastEquality.cs:152
    Code (CSharp):
    1. public Delegate GetHashFn;
     
  2. bilalakil

    bilalakil

    Joined:
    Jan 28, 2018
    Posts:
    68
    Also curious, but for a different reason :p I found that I cannot schedule jobs inside a
    [BurstCompile]ISystem.OnUpdate
    , and when fishing around I found the following in
    com.unity.entities
    source:

    Code (CSharp):
    1.  
    2.         //disabling burst in dotsrt until burstable scheduling works
    3. #if !UNITY_DOTSRUNTIME
    4.         [BurstCompile]
    5. #endif
    6.         public void OnUpdate(ref SystemState state)
    7.         {
    8.             var localToWorldType = state.GetComponentTypeHandle<LocalToWorld>(true);
    9.             var childType = state.GetBufferTypeHandle<Child>(true);
    10. // ...
    It seems that every
    ISystem.OnUpdate
    with a scheduled job is guarded with that preprocessor condition. The one above (in
    LocalToParentSystem.cs
    ) is the only one I saw with a comment suggesting some reasoning.

    So what's going on here? How does the
    UNITY_DOTSRUNTIME
    protect from this error? AFAIK
    [BurstCompile]
    always needs to be removed in this circumstance.

    But on that note, if you know anything more about this bug (burstable scheduling) or have seen it in another forum post, please point me in that direction :D
     
    ueue44 likes this.
  3. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    263
    ueue44, bilalakil and elliotc-unity like this.
  4. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    ^that. We're still working on the non-tiny portions of it for various purposes, but there's no recommendable way to use it today and there won't be for 1.0 either, for a long list of reasons of variable quality.

    So, you should definitely not define that define yourself. :) And any code that requires it to be defined will not run in any normal usage.
     
    bilalakil and Anthiese like this.
  5. ueue44

    ueue44

    Joined:
    Jun 17, 2013
    Posts:
    16
    Thank you all.

    I also understand that UNITY_DOTSRUNTIME should not be self-defined!

    > @elliotc-unity

    With that in mind, I think "#if !UNITY_DOTSRUNTIME" in "TypeManager.cs:760" should be "#if UNITY_DOTSRUNTIME"!

    To begin with, does SetSharedComponent support Burst?
     
    Last edited: Aug 18, 2022
  6. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    I can't find such a thing on exactly that line in 0.51, so which one do you mean, and why do you think so?

    In 0.50/0.51 no.

    In 1.0 yes, as long as the component itself has no managed references.

    What are you trying to do overall?
     
  7. ueue44

    ueue44

    Joined:
    Jun 17, 2013
    Posts:
    16
    Thank you for your answer.

    I am looking to run the following code

    Code (CSharp):
    1. Entities
    2.   .WithBurst()
    3.   .WithAll<TestComponent>()
    4.   .ForEach((
    5.     Entity entity,
    6.     int entityInQueryIndex,
    7.     ref TestComponent testComponent,
    8.   ) => {
    9.     commandBuffer.SetSharedComponent(entity, new PhysicsWorldIndex());
    10.   }).Schedule();
    11.  
    I want the physics operation to occur at a specific timing.

    ConvertToEntity processing is slow, so I put an invalid unused value in Physics' worldindex beforehand and ConvertToEntity runs at startup.
    I would like to enable the physics operation by putting in a valid value at a specific timing.

    In doing so, I have an error when using WithBurst in SetSharedComponent, which is why I asked the question.
     
  8. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    Yep, stuff like that is why we had to deal with unmanaged shared components for 1.0. That ifdef is not really that relevant though; even if that bit were burstable, nothing else in the shared component code path in 0.51 is burstable anyway.

    All shared components in 0.51 (and in all previous versions of entities) are stored in a single List<object> per world. We had to add a whole separate unmanaged shared component store for it to work with burst.
     
  9. optimise

    optimise

    Joined:
    Jan 22, 2014
    Posts:
    2,029
    Does it means at 1.0 shared component no longer support managed data?
     
  10. elliotc-unity

    elliotc-unity

    Unity Technologies

    Joined:
    Nov 5, 2015
    Posts:
    228
    No, managed and unmanaged both work in 1.0. But, perhaps obviously, you can't talk about managed ones in burst.

    (So the List<object> is still there, but it only holds the managed shared components now, and the unmanaged shared components are in a separate store.)
     
    ueue44 likes this.
  11. ueue44

    ueue44

    Joined:
    Jun 17, 2013
    Posts:
    16
    > All shared components in 0.51 (and in all previous versions of entities) are stored in a single List<object> per world.

    Well, now I understand!
    Thank you very much.
     
    elliotc-unity likes this.