Search Unity

[Solved]Strange error : Iterator must be marked [ReadOnly] since 0.23P

Discussion in 'Data Oriented Technology Stack' started by Sylmerria, Mar 7, 2019.

  1. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    237
    Hi guys,

    I have a strange bug since I have upgrade to 0.23P

    Code (CSharp):
    1. InvalidOperationException: The NativeArray AssignStorageToStorageManagerJob.Iterator must be marked [ReadOnly] in the job StorageManagerSystem:AssignStorageToStorageManagerJob, because the container itself is marked read only.
    2. Unity.Jobs.LowLevel.Unsafe.JobsUtility.Schedule (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters) <0x1e30826be10 + 0x0006a> in <d10dbed3cf134e85a6671c286d124aac>:0
    3. Unity.Entities.JobProcessComponentDataExtensions.Schedule (System.Void* fullData, System.Int32 length, System.Int32 innerloopBatchCount, System.Boolean isParallelFor, Unity.Entities.JobProcessComponentDataExtensions+JobProcessComponentDataCache& cache, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/IJobProcessComponentData.cs:352)
    4. Unity.Entities.JobProcessComponentDataExtensions.ScheduleInternal_EDD[T] (T& jobData, Unity.Entities.ComponentSystemBase system, Unity.Entities.ComponentGroup componentGroup, System.Int32 innerloopBatchCount, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/IJobProcessComponentData.generated.cs:597)
    5. Unity.Entities.JobProcessComponentDataExtensions.ScheduleGroupSingle[T] (T jobData, Unity.Entities.ComponentGroup componentGroup, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.0.12-preview.24/Unity.Entities/IJobProcessComponentData.generated.cs:277)
    6.  
    which comes from this job

    Code (CSharp):
    1.         //TODO [BurstCompile]
    2.         private struct AssignStorageToStorageManagerJob : IJobProcessComponentDataWithEntity<StorageResum, StorageFlagNeedStorageManagerLink>
    3.         {
    4.             #region Implementation of IJobProcessComponentDataWithEntity<StorageResum>
    5.  
    6.             /// <inheritdoc />
    7.             public void Execute(Entity entity, int index, ref StorageResum resum, ref StorageFlagNeedStorageManagerLink flag)
    8.             {
    9.                 var storageManagerEntity = HashMapRequestToStorageManager[flag.RequestID];
    10.  
    11.                 resum.StorageManager = storageManagerEntity;
    12.  
    13.                 var buffer = StorageManagerEntityStorageBFE[storageManagerEntity];
    14.  
    15.                 while (buffer.Length <= resum.Index)
    16.                     buffer.Add(new StorageManagerEntityStorageElement());
    17.  
    18.                 buffer[resum.Index] = new StorageManagerEntityStorageElement { Storage = entity };
    19.  
    20.                 CommandBuffer.RemoveComponent<StorageFlagNeedStorageManagerLink>(entity);
    21.             }
    22.  
    23.             #endregion
    24.  
    25.             #region Variables
    26.  
    27.             public NativeHashMap<uint, Entity>                          HashMapRequestToStorageManager;
    28.             public BufferFromEntity<StorageManagerEntityStorageElement> StorageManagerEntityStorageBFE;
    29.             public EntityCommandBuffer                                  CommandBuffer;
    30.  
    31.             #endregion
    32.         }
    And the job is called from

    Code (CSharp):
    1.             inputHandle = new AssignStorageToStorageManagerJob
    2.                           {
    3.                               StorageManagerEntityStorageBFE = GetBufferFromEntity<StorageManagerEntityStorageElement>(),
    4.                               CommandBuffer                  = _postUpdateCommands,
    5.                               HashMapRequestToStorageManager = hashmapToStorageManagerEntity
    6.                           }.ScheduleGroupSingle(_storageToLink, inputHandle);
    7.  
    8.  
    I don't succeed to find what can cause that :/

    Any idea ?

    Thanks
     
    Last edited: Mar 7, 2019
    Antypodish likes this.
  2. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    476
    I'm getting this same error on p26 with an empty simple system:
    Code (CSharp):
    1. [ExecuteAlways]
    2. public class TestSystem : JobComponentSystem
    3. {
    4.     public struct Job : IJobProcessComponentData<TestComponent1, TestComponent2>
    5.     {
    6.         public void Execute(ref TestComponent1 test1, ref TestComponent2 test2)
    7.         {
    8.         }
    9.     }
    10.  
    11.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    12.     {
    13.         Job job = new Job
    14.         {
    15.         };
    16.  
    17.         var handle = job.Schedule(this, inputDeps);
    18.  
    19.         return handle;
    20.     }
    21. }
    InvalidOperationException: The NativeArray Job.Iterator must be marked [ReadOnly] in the job TestSystem:Job, because the container itself is marked read only.


    TestComponent1 and TestComponent2 are defined like this:
    Code (CSharp):
    1. public struct TestComponent1 : IComponentData { }
    2.  
    3. public struct TestComponent2 : IComponentData
    4. {
    5.     public int3 Value;
    6. }
    Edit: This is on Unity 2019.1.0b5
     
  3. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    417
    It is related with the UpdateSystemGroup you are updating your system on. I don't know the details of it but i've experienced that and had to change to the update group that was writing (eg. my case was TransformUpdateGroup).
    Didn't dig any deeper because i have not fully moved to p26.
     
  4. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    476
    I have an empty project with the code I posted above, it doesn't matter what update group I set it keeps throwing the same error.

    How in the world do we now do JobComponentSystem then? The HelloCube_02_IJobProcessComponentData is using a setup super close to what I have there and it works, why is mine not working?
     
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,265
    I think I figured something out. Empty component type is considered tag component and in effect a read only. Your TestComponent1 is a zero sized but 2 is not. But in your IJPCD you are telling the iterator of that (the thing giving you ref variable one by one) that it should be RW. (No [ReadOnly] besides ref)

    Normally it would brought things the same type as your attribute, but this time you tell it RW, but the special zero sized component is forcing read only container.

    - Add any field in TestComponent1 fix the issue. You get a container of RW matching iterator RW.
    - If you add [ReadOnly] on only ref TestComponent1 I think it will work. On the other hand [ReadOnly] on only TestComponent2 won't work. Anyways, if tag component is intended you should be using [RequireTagComponent] on top of IJPCD struct and remove TestComponent1 from the execute argument.
    - The error message could be better, something like "tag component cannot be used in Execute, use [RequireTagComponent] instead" because there's nothing to do about its content in the first place.
     
  6. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    918
    I stumbled across this also a while ago and since then use:
    - [RequireTagComponent] as suggested by @5argon OR
    - filter by CG and use .ScheduleGroup (I find this clearer)
     
    GilCat likes this.
  7. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,265
    I have never used ScheduleGroup. Do you have to match CG in ScheduleGroup with generics on the IJobProcessComponentData? What happen when the CG provided has less or more than the types in the job? I'm afraid that it would be difficult to maintain when editing the job. (That normal Schedule kind of make you a CG based on job description is good already, I can't think of a good use case of ScheduleGroup. Could it provide more customization in some way?)
     
    GilCat and Sylmerria like this.
  8. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    237
    @5argon In my case, even if I need to renamed StorageFlagNeedStorageManagerLink , I have any tag in my IJobProcessComponentData :/
     
  9. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    918
    I used it in the context of tag components and have not tested it very much (it just worked) - I am amazed how you always thoroughly analyze everything - love your blog, first thing I look for answers when I get stuck.

    I think there is not automatic checking it the ScheduleGroup types matched what you specify in the Job -> i.e. room for error. I just liked for the clarity, when I want a job to operate on a specific CG (if the CG is a bit complicated, many types, subtractive, tags it get's messy to specify it with IJobProcessComponentData)
     
    5argon likes this.
  10. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    237
    I found that my componentGroup and my IJobProcessComponentData parameters are not matching.
    It's fixed now.
     
  11. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    417
    That also solved my issue above. Seems like it is all connected with Empty components like @5argon mentioned.

    Thanks
     
  12. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    476
    Well that makes sense, I wish the error could at least be more clear. Definitely will be using RequireTagComponent then since that makes more sense than adding it to the execute argument.
     
  13. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    5,417
    Dear @Joachim_Ante, sorry but I need poke you a little :oops:

    The reason is so, that I had reticently same problem, when upgraded from Unity 2018.3 to Unity 2018.2.

    InvalidOperationException: The NativeArray RunJob.Iterator must be marked [ReadOnly] in the job JSEvaluator:RunJob, because the container itself is marked read only.

    Thx to this discussion and suggestion from @5argon, I was able to resolve that issue.


    Just to indicate for my particular case, I had job
    Code (CSharp):
    1. struct RunJob: IJobForEachWithEntity <IsInstanceFunctionActiveTag>
    with execution part
    Code (CSharp):
    1. public void Execute ( Entity parentEntity, int i_parentIndex, ref IsInstanceFunctionActiveTag parentInstanceTag )
    Similarly as per suggestion, I use Tag IsInstanceFunctionActiveTag with 0 data component.
    Hence after adding [ReadOnly] at the front of ref IsInstanceFunctionActiveTag this need to become
    Code (CSharp):
    1. public void Execute ( Entity parentEntity, int i_parentIndex, [ReadOnly] ref IsInstanceFunctionActiveTag parentInstanceTag )
    My thought is, that error need to be much more informative, than what is now. I had to use search engine, to find answer and this post. No big deal, but may be for others.

    Anyway, thx to all for this thread. :)