Search Unity

Resolved NativeMultiHashMap<TKey, TValue> GetKeyArray returns IndexOutOfRangeException

Discussion in 'Entity Component System' started by esgnn, Jan 17, 2022.

  1. esgnn

    esgnn

    Joined:
    Mar 3, 2020
    Posts:
    38
    Hi.
    I am very new to Burst and Jobs.
    What do you think I am doing wrong?
    Thank you for your time.
    1. I am converting a NativeArray to a NativeMultiHashMap
    Code (CSharp):
    1. NativeMultiHashMap<Vector3, Vector2> r = new NativeMultiHashMap<Vector3, Vector2>(args[0], Allocator.TempJob);
    2. tbThreaded tbJob = new tbThreaded
    3. {
    4.     df = new NativeSlice<dFiltered>(cpData,0,args[0]),
    5.     results = r
    6. };
    7. JobHandle handle = tbJob.Schedule(args[0], 32);
    8. handle.Complete();
    9.  
    using this Job
    Code (CSharp):
    1. [BurstCompile(CompileSynchronously = true)]
    2. public struct tbThreaded: IJobParallelFor
    3. {
    4.     [ReadOnly]
    5.     public NativeSlice<dFiltered> df;
    6.     [NativeDisableParallelForRestriction]
    7.     public NativeMultiHashMap<Vector3, Vector2> results;
    8.     public void Execute(int i)
    9.     {
    10.         results.Add(df[i].dValue,df[i].pPosition);
    11.     }    
    12. }
    dFiltered struct:
    Code (CSharp):
    1. public struct dFiltered
    2. {
    3.     public Vector3 dValue;
    4.     public Vector2 pPosition;
    5. }
    When I call
    r.GetKeyArray(Allocator.TempJob);

    I get
    IndexOutOfRangeException: Index 626 is out of range of '626' Length.
    Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <60a316878f2f47b5ad8b2d4c8c6c52c0>:0)
    Unity.Collections.NativeArray`1[T].CheckElementWriteAccess (System.Int32 index) (at <60a316878f2f47b5ad8b2d4c8c6c52c0>:0)
    Unity.Collections.NativeArray`1[T].set_Item (System.Int32 index, T value) (at <60a316878f2f47b5ad8b2d4c8c6c52c0>:0)
    Unity.Collections.LowLevel.Unsafe.UnsafeHashMapData.GetKeyArray[TKey] (Unity.Collections.LowLevel.Unsafe.UnsafeHashMapData* data, Unity.Collections.NativeArray`1[T] result) (at Library/PackageCache/com.unity.collections@0.15.0-preview.21/Unity.Collections/UnsafeHashMap.cs:330)
    Unity.Collections.LowLevel.Unsafe.UnsafeMultiHashMap`2[TKey,TValue].GetKeyArray (Unity.Collections.Allocator allocator) (at Library/PackageCache/com.unity.collections@0.15.0-preview.21/Unity.Collections/UnsafeMultiHashMap.cs:256)
    Unity.Collections.NativeMultiHashMap`2[TKey,TValue].GetKeyArray (Unity.Collections.Allocator allocator) (at Library/PackageCache/com.unity.collections@0.15.0-preview.21/Unity.Collections/NativeMultiHashMap.cs:314)
    BBTight.Start () (at Assets/Resources/Test Scripts/pass/BBTight.cs:76)
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    You're disabling safety on your hash map then writing to it in parallel? That is completely unsafe and will corrupt your hash map.

    Hash map supports parallel writing, use pass in hashmap.AsParallelWriter instead.

    Until you are comfortable with what you're doing, don't turn off safety. It's there to protect you and stop you doing things that aren't safe, like this.
     
    esgnn likes this.
  3. esgnn

    esgnn

    Joined:
    Mar 3, 2020
    Posts:
    38
    Hey, thank you, it fixed the problem.
    To anyone who stumbles upon this thread, the fixed code:
    Code (CSharp):
    1. NativeMultiHashMap<Vector3, Vector2> r = new NativeMultiHashMap<Vector3, Vector2>(args[0], Allocator.TempJob);
    2. tbThreaded tbJob = new tbThreaded
    3. {
    4.     df = new NativeSlice<dFiltered>(cpData,0,args[0]),
    5.     results = r.AsParallelWriter()
    6. };
    7. JobHandle handle = tbJob.Schedule(args[0], 32);
    8. handle.Complete();
    and
    Code (CSharp):
    1. [BurstCompile(CompileSynchronously = true)]
    2. public struct tbThreaded: IJobParallelFor
    3. {
    4.     [ReadOnly]
    5.     public NativeSlice<dFiltered> df;
    6.     [NativeDisableParallelForRestriction]
    7.     public NativeMultiHashMap<Vector3, Vector2>.ParallelWriter results;
    8.     public void Execute(int i)
    9.     {
    10.         results.Add(df[i].dValue,df[i].pPosition);
    11.     }  
    12. }