Search Unity

[SOLVED] Burst tries to compile struct not involved with jobs

Discussion in 'Burst' started by Sylmerria, Nov 23, 2020.

  1. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Hi all,

    Before upgrading to 1.4.1, this setup worked nicely without complains for more than 1 year.

    So the problem is burst tries to compile struct which is not used at all in ECS world.
    He tries to compile "VariableContainerNumericalData" for example which is my class for data authoring before blob conversion.

    An error example :

    Code (CSharp):
    1. M:\Unity\cityBuilder\hmh\Hades - Master of hell\Assets\Scripts\ECS\EventSystem\Data\ConditionData.cs(399,13): Burst error BC1051: Invalid managed type found for the field `_baseData` of the struct `HMH.Data.EventSystem.ECS.VariableContainerNumericalData`.: the type `HMH.Data.BaseData` is a managed type and  is not supported
    2.  
    3. at HMH.ECS.EventSystem.EventCaseConditionEvaluateDay.Evaluate(HMH.ECS.EventSystem.EventCaseConditionEvaluateDay* this) (at M:\Unity\cityBuilder\hmh\Hades - Master of hell\Assets\Scripts\ECS\EventSystem\Data\ConditionData.cs:399)
    4. at HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob.Execute(HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob* this, ref HMH.ECS.Date.NotificationDayChanged notification) (at M:\Unity\cityBuilder\hmh\Hades - Master of hell\Assets\Scripts\ECS\EventSystem\System\ConditionJob\EventCaseSystemEvaluateDay.cs:113)
    5. at Unity.Entities.JobForEachExtensions.JobStruct_Process_C`2<HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob,HMH.ECS.Date.NotificationDayChanged>.ExecuteChunk(ref Unity.Entities.JobForEachExtensions.JobStruct_Process_C`2<HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob,HMH.ECS.Date.NotificationDayChanged> jobData, System.IntPtr bufferRangePatchData, int begin, int end, Unity.Entities.ArchetypeChunk* chunks, int* entityIndices) (at M:\Unity\cityBuilder\hmh\Hades - Master of hell\Library\PackageCache\com.unity.entities@0.16.0-preview.21\Unity.Entities\IJobForEach.gen.cs:2792)
    6. at Unity.Entities.JobForEachExtensions.JobStruct_Process_C`2<HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob,HMH.ECS.Date.NotificationDayChanged>.Execute(ref Unity.Entities.JobForEachExtensions.JobStruct_Process_C`2<HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob,HMH.ECS.Date.NotificationDayChanged> jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex) (at M:\Unity\cityBuilder\hmh\Hades - Master of hell\Library\PackageCache\com.unity.entities@0.16.0-preview.21\Unity.Entities\IJobForEach.gen.cs:2766)
    7.  
    8.  
    9. While compiling job: System.Void Unity.Entities.JobForEachExtensions/JobStruct_Process_C`2<HMH.ECS.EventSystem.EventCaseNotificationEvaluateDayJob,HMH.ECS.Date.NotificationDayChanged>::Execute(Unity.Entities.JobForEachExtensions/JobStruct_Process_C`2<T,T0>&,System.IntPtr,System.IntPtr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,System.Int32)
    10. at M:\Unity\cityBuilder\hmh\Hades - Master of hell\Assets\Scripts\ECS\EventSystem\Data\ConditionData.cs:line 399
    11.  
    ConditionData struct at line 399
    Code (CSharp):
    1.         public bool Evaluate()
    2.         {
    3.             return ConditionData.Value.ComparisonType.CompareWith(CurrentState, TargetState);
    4.         }
    Full code
    Code (CSharp):
    1.     [InternalBufferCapacity(1)]
    2.     public struct EventCaseConditionEvaluateDay : IEventCondition
    3.     {
    4.         public BlobAssetReference<ConditionEvaluateDayBlobData> ConditionData;
    5.  
    6.         public Entity ControlVariableEntity;
    7.  
    8.         public uint CurrentState;
    9.         public uint TargetState;
    10.  
    11.         public EventCaseConditionTarget ConditionTargetData;
    12.  
    13.         #region Properties
    14.  
    15.         /// <inheritdoc />
    16.         public EventCaseConditionTarget ConditionTarget => ConditionTargetData;
    17.  
    18.         #endregion
    19.  
    20.         /// <inheritdoc />
    21.         public bool Evaluate()
    22.         {
    23.             return ConditionData.Value.ComparisonType.CompareWith(CurrentState, TargetState);
    24.         }
    25.     }

    CompareWith extension
    Code (CSharp):
    1.         public static bool CompareWith(this EnumComparison ec, float value, float reference)
    2.         {
    3.             switch (ec)
    4.             {
    5.                 case EnumComparison.Greater:
    6.  
    7.                     return value > reference;
    8.                 case EnumComparison.GreaterEqual:
    9.  
    10.                     return value > reference || AlmostEqual2SComplement(value, reference, 6);
    11.                 case EnumComparison.Equal:
    12.  
    13.                     return AlmostEqual2SComplement(value, reference, 6);
    14.                 case EnumComparison.LowerEqual:
    15.  
    16.                     return value < reference || AlmostEqual2SComplement(value, reference, 6);
    17.                 case EnumComparison.Lower:
    18.  
    19.                     return value < reference;
    20.                 default:
    21.  
    22.                     throw new Exception("EnumComparison unknow : " + ec);
    23.             }
    24.         }

    Job being compiled which throws error
    line 113
    Code (CSharp):
    1.  var newStatus = cond.Evaluate();
    Full code
    Code (CSharp):
    1.     [BurstCompile]
    2.     public struct EventCaseNotificationEvaluateDayJob : IJobForEach<NotificationDayChanged>
    3.     {
    4.         /// <inheritdoc />
    5.         public void Execute(ref NotificationDayChanged notification)
    6.         {
    7.             //using (ProfileMarker.Auto())
    8.             {
    9.                 if (LinkHashmapRO.TryGetFirstValue(Entity.Null, out var listenner, out var it) == false)
    10.                     return;
    11.  
    12.                 do
    13.                 {
    14.                     var bufferDataListenner            = ConditionEvaluateDayBFE[listenner];
    15.                     var bufferEventCaseConditionStatus = EventCaseConditionStatusBFE[listenner];
    16.  
    17.                     for (var i = 0; i < bufferDataListenner.Length; i++)
    18.                     {
    19.                         var cond = bufferDataListenner[i];
    20.  
    21.                         cond.CurrentState = CurrentDay;
    22.  
    23.                         bufferDataListenner[i] = cond;
    24.  
    25.                         var newStatus = cond.Evaluate();
    26.  
    27.                         if (newStatus == bufferEventCaseConditionStatus[cond.ConditionTarget.BufferIndex])
    28.                             continue;
    29.  
    30.                         bufferEventCaseConditionStatus[cond.ConditionTarget.BufferIndex] = newStatus;
    31.  
    32.                         DirtyEntity.Enqueue(listenner);
    33.                     }
    34.                 } while (LinkHashmapRO.TryGetNextValue(out listenner, ref it));
    35.             }
    36.         }
    37.  
    38.         #region Variables
    39.  
    40.         //private static readonly ProfilerMarker ProfileMarker = new ProfilerMarker($"EventCaseSystem.Condition.{nameof(EventCaseNotificationEvaluateDayJob)}");
    41.  
    42.         [ReadOnly]
    43.         public NativeMultiHashMap<Entity, Entity> LinkHashmapRO;
    44.         [ReadOnly]
    45.         public uint CurrentDay;
    46.  
    47.         public BufferFromEntity<EventCaseConditionEvaluateDay> ConditionEvaluateDayBFE;
    48.         public BufferFromEntity<EventCaseConditionStatus>      EventCaseConditionStatusBFE;
    49.  
    50.         public NativeQueue<Entity>.ParallelWriter DirtyEntity;
    51.  
    52.         #endregion
    53.     }

    Code (CSharp):
    1.     public struct EventCaseConditionTarget
    2.     {
    3.         public int BufferIndex;
    4.  
    5.         public static implicit operator EventCaseConditionTarget(int value)
    6.         {
    7.             return new EventCaseConditionTarget { BufferIndex = value };
    8.         }
    9.     }
    Any ideas or I need to submit a bug ?
     
    Last edited: Nov 23, 2020
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,684
    No. And never was. It's main Burst restriction, you can't have managed data inside burst, no matter of using these fields.
     
  3. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Sorry after checking my code ( little tired) I write wrong thing. (I have edit the first message)
     
  4. sheredom

    sheredom

    Unity Technologies

    Joined:
    Jul 15, 2019
    Posts:
    300
    It's not a bug - you are trying to use managed data in that job and Burst doesn't allow it.

    If you want to keep using managed data then remove the [BurstCompile] from the job and it'll run in Mono instead.
     
    nyanpath likes this.
  5. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    That the thing, I don't use at all managed datas in this code :/

    As you can see, all my variables are struct from entities or from blob

    Code (CSharp):
    1.  
    2.         [ReadOnly]
    3.         public NativeMultiHashMap<Entity, Entity> LinkHashmapRO;
    4.         [ReadOnly]
    5.         public uint CurrentDay;
    6.         public BufferFromEntity<EventCaseConditionEvaluateDay> ConditionEvaluateDayBFE;
    7.         public BufferFromEntity<EventCaseConditionStatus>      EventCaseConditionStatusBFE;
    8.         public NativeQueue<Entity>.ParallelWriter DirtyEntity;
    but burst tells me otherwise which is making no sense for me.
    So either error message is wrong or doesn't show me the real problem
     
  6. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    Here's the error from your first message:

    Please can you paste the definition of HMH.Data.EventSystem.ECS.VariableContainerNumericalData and HMH.Data.BaseData? According to that error message, BaseData is a managed type, and it's used in a field in VariableContainerNumericalData.
     
  7. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    So yeah, @eizenhorn was right but the stranger thing is burst complains about my managed field (not use in burst but anyway it's not valid) which takes place in my blob :confused:
    So blob doesn't complained about managed field inside struct ?
    Code (CSharp):
    1.     public struct ConditionEvaluateMonthBlobData
    2.     {
    3.         public OperationTarget OperationTargetType;
    4.         public uint            ComparisonValue;
    5.  
    6.         public VariableContainerNumericalData ComparisonVariable;
    7.  
    8.         public EnumComparison ComparisonType;
    9.     }
    Code (CSharp):
    1.     [Serializable]
    2.     public struct VariableContainerNumericalData : IDataValidation
    3.     {
    4.         #region Variables
    5.  
    6.         [LabelText("Type"), OnValueChanged("TypeHasChanged")]
    7.         public VariableTypeNumerical VariableType;
    8.         [LabelText("Target"), ValueDropdown("GetDropdownValue"), ValidateInput("ValidateInput")]
    9.         public int VariableIndex;
    10.  
    11. #if UNITY_EDITOR
    12.         private BaseData _baseData;
    13. #endif
    14.  
    15.         #endregion
    16.  
    17.         public bool ProcessAndLoadRelativeAsset(EventCaseDataAuthoring eventCaseDataAuthoring)
    18.         {
    19.             if (VariableIndex >= 0)
    20.             {
    21.                 if (eventCaseDataAuthoring != null && eventCaseDataAuthoring.IsSystemCreation == false)
    22.                     eventCaseDataAuthoring.ConvertLocalVariableIDToGlobalVariableID(ref this);
    23.  
    24.                 return true;
    25.             }
    26.  
    27.             int delta;
    28.  
    29.             switch (VariableType)
    30.             {
    31.                 case VariableTypeNumerical.Int:
    32.                     delta = BaseData.InstanceBuildingAgent.LengthVariableIntWithoutSystem();
    33.                     break;
    34.                 case VariableTypeNumerical.Float:
    35.                     delta = BaseData.InstanceBuildingAgent.LengthVariableFloatWithoutSystem();
    36.                     break;
    37.                 default:
    38.                     throw new ArgumentOutOfRangeException();
    39.             }
    40.  
    41.             VariableIndex = delta - VariableIndex + 1;
    42.             return true;
    43.         }
    44.  
    45.         /// <inheritdoc />
    46.         public bool AreDataValids()
    47.         {
    48.             return BaseData.Instance != null && BaseData.InstanceBuildingAgent.ValideVariableIndex(VariableType, VariableIndex);
    49.         }
    50.  
    51. #if UNITY_EDITOR
    52.  
    53.         public void EditorInitialize(BaseData baseData)
    54.         {
    55.             _baseData = baseData;
    56.         }
    57.  
    58.         private void TypeHasChanged()
    59.         {
    60.             VariableIndex = -1;
    61.             UnityEditor.EditorUtility.SetDirty(BaseData.Instance);
    62.             Sirenix.Utilities.Editor.GUIHelper.RequestRepaint(10);
    63.         }
    64.  
    65.         private IEnumerable GetDropdownValue()
    66.         {
    67.             var baseData = _baseData == null ? BaseData.Instance : _baseData;
    68.  
    69.             if (baseData == null)
    70.                 return null;
    71.  
    72.             switch (VariableType)
    73.             {
    74.                 case VariableTypeNumerical.Int:
    75.                     return baseData.GetVariableIntIndexes();
    76.                 case VariableTypeNumerical.Float:
    77.                     return baseData.GetVariableFloatIndexes();
    78.                 case VariableTypeNumerical.InfluencingVariable:
    79.                 default:
    80.                     throw new ArgumentOutOfRangeException();
    81.             }
    82.         }
    83.  
    84.         private bool ValidateInput(int value)
    85.         {
    86.             return ValidateInput();
    87.         }
    88.  
    89.         private bool ValidateInput()
    90.         {
    91.             var baseData = _baseData == null ? BaseData.Instance : _baseData;
    92.  
    93.             if (baseData == null)
    94.                 return true;
    95.  
    96.             ValueDropdownList<int> list;
    97.  
    98.             switch (VariableType)
    99.             {
    100.                 case VariableTypeNumerical.Int:
    101.                     list = (ValueDropdownList<int>)baseData.GetVariableIntIndexes();
    102.                     break;
    103.                 case VariableTypeNumerical.Float:
    104.                     list = (ValueDropdownList<int>)baseData.GetVariableFloatIndexes();
    105.                     break;
    106.                 case VariableTypeNumerical.InfluencingVariable:
    107.                 default:
    108.                     throw new ArgumentOutOfRangeException();
    109.             }
    110.  
    111.             foreach (var item in list)
    112.             {
    113.                 if (item.Value == VariableIndex)
    114.                     return true;
    115.             }
    116.  
    117.             return false;
    118.         }
    119.  
    120. #endif
    121.  
    122.         /// <inheritdoc />
    123.         public override string ToString()
    124.         {
    125.             return $"{nameof(VariableContainerNumericalData)}{{VariableType: {VariableType} - VariableIndex: {VariableIndex}}}";
    126.         }
    127.     }
    Anyway thanks for hints and sorry for your time
     
    sheredom likes this.