Tuples NativeContainers with Burst

Unity version: 2020.3.20f1 Personal
Burst version: 1.7.0-pre.1
Jobs version: 0.11.0-preview.6

Hey folks,

I’m trying to use tuples like (int, int) myTuple for key and value in NativeContainers. The error occures in an IJobParallelFor struct with a [BurstCompile]-Attribute where I have a
public NativeHashMap<(int, int), (int, int)>.ParallelWriter pathData;
and I try to
pathData.TryAdd((theTile, theOtherTile), (1, 2));

The following error message appears even though the code runs absolutely fine and wih the expected results:

Error Message in the Unity Console

(0,0): Burst error BC1016: The managed function System.Collections.Generic.EqualityComparer1.get_Default()` is not supported

at System.ValueTuple2<System.Int32,System.Int32>.Equals(System.ValueTuple2<int,int>* this, System.ValueTuple2<int,int> other) at Unity.Collections.LowLevel.Unsafe.UnsafeHashMapBase2<System.ValueTuple2<System.Int32,System.Int32>,System.ValueTuple2<System.Int32,System.Int32>>.TryGetNextValueAtomic(Unity.Collections.LowLevel.Unsafe.UnsafeHashMapData* data, ref System.ValueTuple2<int,int> item, ref Unity.Collections.NativeMultiHashMapIterator1<System.ValueTuple2<int,int>> it) (at C:\Users\JustMe\Desktop\20211101_Prototype\Library\PackageCache\com.unity.collections@1.0.0-pre.5\Unity.Collections\UnsafeHashMap.cs:871) at Unity.Collections.LowLevel.Unsafe.UnsafeHashMapBase2<System.ValueTuple2<System.Int32,System.Int32>,System.ValueTuple2<System.Int32,System.Int32>>.TryGetFirstValueAtomic(Unity.Collections.LowLevel.Unsafe.UnsafeHashMapData* data, System.ValueTuple2<int,int> key, ref System.ValueTuple2<int,int> item, ref Unity.Collections.NativeMultiHashMapIterator1<System.ValueTuple2<int,int>> it) (at C:\Users\JustMe\Desktop\20211101_Prototype\Library\PackageCache\com.unity.collections@1.0.0-pre.5\Unity.Collections\UnsafeHashMap.cs:856)
at Unity.Collections.LowLevel.Unsafe.UnsafeHashMapBase2<System.ValueTuple2<System.Int32,System.Int32>,System.ValueTuple2<System.Int32,System.Int32>>.TryAddAtomic(Unity.Collections.LowLevel.Unsafe.UnsafeHashMapData* data, System.ValueTuple2<int,int> key, System.ValueTuple2<int,int> item, int threadIndex) (at C:\Users\JustMe\Desktop\20211101_Prototype\Library\PackageCache\com.unity.collections@1.0.0-pre.5\Unity.Collections\UnsafeHashMap.cs:612) at Unity.Collections.LowLevel.Unsafe.UnsafeHashMap2.ParallelWriter<System.ValueTuple2<System.Int32,System.Int32>,System.ValueTuple2<System.Int32,System.Int32>>.TryAdd(Unity.Collections.LowLevel.Unsafe.UnsafeHashMap2.ParallelWriter<System.ValueTuple2<int,int>,System.ValueTuple2<int,int>>* this, System.ValueTuple2<int,int> key, System.ValueTuple2<int,int> item) (at C:\Users\JustMe\Desktop\20211101_Prototype\Library\PackageCache\com.unity.collections@1.0.0-pre.5\Unity.Collections\UnsafeHashMap.cs:1333) at Unity.Collections.NativeHashMap2.ParallelWriter<System.ValueTuple2<System.Int32,System.Int32>,System.ValueTuple2<System.Int32,System.Int32>>.TryAdd(Unity.Collections.NativeHashMap2.ParallelWriter<System.ValueTuple2<int,int>,System.ValueTuple2<int,int>>* this, System.ValueTuple2<int,int> key, System.ValueTuple2<int,int> item) (at C:\Users\JustMe\Desktop\20211101_Prototype\Library\PackageCache\com.unity.collections@1.0.0-pre.5\Unity.Collections\NativeHashMap.cs:443) at PathfindingSystemAStar.CalculateNodesAndConnections.CalculateAndStoreL1Nodes(PathfindingSystemAStar.CalculateNodesAndConnections* this, int startAt, int endAt, PathfindingSystemAStar.Dir top_or_right, Unity.Collections.NativeArray1* tileIndexArr) (at C:\Users\JustMe\Desktop\20211101_Prototype\Assets\Scripts\PathfindingSystemAStar.cs:1133)
at PathfindingSystemAStar.CalculateNodesAndConnections.FindAndCalculate(PathfindingSystemAStar.CalculateNodesAndConnections* this, ref Unity.Collections.NativeArray1<int> tileIndexArr, TileFrameIndexes* blockFrame, PathfindingSystemAStar.Dir dir) (at C:\Users\JustMe\Desktop\20211101_Prototype\Assets\Scripts\PathfindingSystemAStar.cs:1110) at PathfindingSystemAStar.CalculateNodesAndConnections.Execute(PathfindingSystemAStar.CalculateNodesAndConnections* this, int index) (at C:\Users\JustMe\Desktop\20211101_Prototype\Assets\Scripts\PathfindingSystemAStar.cs:1051) at Unity.Jobs.IJobParallelForExtensions.ParallelForJobStruct1<PathfindingSystemAStar.CalculateNodesAndConnections>.Execute(ref PathfindingSystemAStar.CalculateNodesAndConnections jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex)

While compiling job:
Unity.Jobs.IJobExtensions+JobStruct1[[PathfindingSystemAStar+PathfindingAStarHeapBidirectional, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystemAStar+PathfindingAStarHeapBidirectional&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) Unity.Jobs.IJobExtensions+JobStruct1[[PathfindingSystemAStar+PathfindingAStar, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystemAStar+PathfindingAStar&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct1[[PathfindingSystem+BuildTileFramesJob, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystem+BuildTileFramesJob&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) Unity.Jobs.IJobExtensions+JobStruct1[[PathfindingFloodFill+InitialFloodFill, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingFloodFill+InitialFloodFill&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct1[[PathfindingSystemAStar+CalculateNodesAndConnections, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystemAStar+CalculateNodesAndConnections&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) Unity.Jobs.IJobExtensions+JobStruct1[[PathfindingSystem+BuildWorldNet, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystem+BuildWorldNet&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct1[[PathfindingSystem+IntraConnectTileFramesInWorldBlock, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystem+IntraConnectTileFramesInWorldBlock&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct1[[PathfindingSystem+FindNeighbourTilesJob, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystem+FindNeighbourTilesJob&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct1[[PathfindingSystem+GetRelevantConnections, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystem+GetRelevantConnections&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089) Unity.Jobs.IJobExtensions+JobStruct1[[PathfindingSystemAStar+CalculateUniqueL1NodeTable, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystemAStar+CalculateUniqueL1NodeTable&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)
Unity.Jobs.IJobExtensions+JobStruct`1[[PathfindingSystemAStar+PathfindingAStarHeap, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null::Execute(PathfindingSystemAStar+PathfindingAStarHeap&, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|System.IntPtr, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089|Unity.Jobs.LowLevel.Unsafe.JobRanges&, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null|System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089)

Would be nice if that could be fixed.

I saw it in the changelog too. I figured out that I could use tuples in native containers such as NativeMultiHashMap as a value but not as a key. I find it hard to tell, why that would “enter or escape the Burst function boundaries”, because tuples are just two or more values put together in one variable. Once I define, say a NativeMultiHashMap<(int, int), (int, int) myMultiHashmap, I could not extend these values as I could, if I would use a multidimensional or nested nativecontainer.
The code gets complied fine even when using burst but there is that annoying error message when I start up unity…

Hmm, i guess to use a struct like

{
int a = 7;
int b = 234;
}```
would not work as a key parameter in a native container aswell, right?

it will, if it will implement IEquatable<Mystruct>

Thanks for your hints. I got it working without having these annoying error messages using this answer: https://stackoverflow.com/questions/1307493/is-there-a-complete-iequatable-implementation-reference

Although I think that should be implemented by default when dealing with tuples. But the knowhow is beyond my knowledge.

Thanks!

Not sure if this would be useful but here is NTuple which only accepts unmanaged values and is blittable. It has implicit casts to and from ValueTuple so you can write ValueTuples to NativeCollections of NTuples. e.g.

static void Foo()
{
    var foo = new NativeArray<NTuple<int, float>>(5, Allocator.Persistent);
    foo[0] = (1, 2.2f);
    ...
}

Haven’t checked this code in a while, but hopefully it’s useful.