Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Burst Union/ Exlicit struct layout

Discussion in 'Burst' started by craftsmanbeck, Jan 4, 2020.

  1. craftsmanbeck

    craftsmanbeck

    Joined:
    Nov 20, 2010
    Posts:
    40
    At the moment I have IBufferElementData containing an enum, a float, and an int, and based on the enum's value I use either the float or the int within a job. Because it's either int or float, never both, I would like to have something like a c++ Union, to potentially increase memory efficiency by 33%.
    I tried using System.Runtime.InteropServices' StructLayout to stick the float and int in the same spot, but while it works fine in MonoBehaviours and without Burst, when using Burst it throws an error saying the struct comes from an unaddressable source.
    Are explicit layouts just an unsupported feature or is it a bug? Is there some way of accomplishing what I'm trying with Burst at the moment?
     
  2. Endlord

    Endlord

    Joined:
    Jan 7, 2014
    Posts:
    11
    There's a writeup here (Jackson Dunstan) which deals with using unions with Burst.

    Edit: I tested the code on the site, and it is working for me with Burst (Entities 0.4, Burst 1.2.0)
     
    Last edited: Jan 5, 2020
    craftsmanbeck likes this.
  3. craftsmanbeck

    craftsmanbeck

    Joined:
    Nov 20, 2010
    Posts:
    40
    Thank you for that. I tried it as well, and it works fine for IComponentData, but then tried the same thing but using a DynamicBuffer instead, and got the same error, so it looks like it's a bug. Unsure where to submit bugs about DOTS, as a recent one I submitted through the editor's report bug thing hasn't gotten me a response yet. On the off chance here's the right place to post it, this is the error
    Burst error BC0102: Unexpected internal compiler error while processing function `IL_000e: ldfld [...]System.InvalidOperationException: The struct field Data.Token TestingBuffer::Value's struct comes from an unaddressable source: IL_0004: call !0 Unity.Entities.DynamicBuffer`1<TestingBuffer>::get_Item(System.Int32) args(IL_0001, IL_0003) [...]

    Some more googling found a similar issue that was supposed to be fixed in Burst 1.1, but I guess they didn't catch Dynamic Buffers.
     
  4. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    Thanks for reporting this - I'm having a look at it now, will reply again once I've tracked down where the bug is.
     
  5. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    I've had a go and repro'ing the issue with explicit-layout structs and DynamicBuffer, but no luck so far. @craftsmanbeck please could you submit (another) bug report via Help > Report a Bug? If you mention Burst in the title of the bug report, it should get routed through to our team.
     
    craftsmanbeck likes this.
  6. craftsmanbeck

    craftsmanbeck

    Joined:
    Nov 20, 2010
    Posts:
    40
    Thanks for looking into it. I've submitted the report as "Burst Dynamic Buffer Explicit Struct Layout Error". It seems to happen when reading data of a dynamic buffer containing an explicitly laid out struct without chaching the element of the dynamic buffer in a local variable. The error in the console also doesn't correspond to the actual line the error occurs on it seems, and I added some comments to the code in the submitted project to reflect this.
     
  7. tim_jones

    tim_jones

    Unity Technologies

    Joined:
    May 2, 2019
    Posts:
    287
    Thanks very much - I've located the report. That's indeed a Burst bug, so we'll get that fixed. In the meantime, as you've found, you can workaround it by using an intermediate local variable.
     
    craftsmanbeck likes this.
  8. sebas77

    sebas77

    Joined:
    Nov 4, 2011
    Posts:
    1,641
    I am getting something similar with ComponentDataFromEntity with Burst 1.2.0 out of preview

    with this:

    [ReadOnly] public ComponentDataFromEntity<UECSSveltoEGID> SveltoEgidGroup;

    and this:

    public struct UECSSveltoEGID : IComponentData
    {
    public EGID egid;
    }

    and this:

    [StructLayout(LayoutKind.Explicit, Size = 8)]
    public struct EGID:IEquatable<EGID>,IEqualityComparer<EGID>,IComparable<EGID>
    {
    [FieldOffset(0)] public readonly uint entityID;
    [FieldOffset(4)] public readonly ExclusiveGroupStruct groupID;
    [FieldOffset(0)] ulong _GID;
    }

    I get this:

    E:\RobocraftX\Assets\Code\RobocraftECS\Contexts\Scenes\Character\Camera\Engines\LocalCameraSphereCastEngine.cs(127,25): Burst error BC0102: Unexpected internal compiler error while processing function `IL_0085: ldfld System.UInt32 Svelto.ECS.EGID::entityID args(IL_0080)`: System.InvalidOperationException: The struct field Svelto.ECS.EGID RobocraftX.UECS.UECSSveltoEGID::egid's struct comes from an unaddressable source: IL_007b: call !0 Unity.Entities.ComponentDataFromEntity`1<RobocraftX.UECS.UECSSveltoEGID>::get_Item(Unity.Entities.Entity) args(IL_0074, IL_0079)
    at Burst.Compiler.IL.Transforms.ExplicitLayoutTransform.ForceFieldAccessToAddress (Burst.Compiler.IL.Syntax.ILInstruction inst, System.Boolean forceAddress) [0x000fb] in <5365ccf18ec94235b5e31dbc5844b7eb>:0
    at Burst.Compiler.IL.Transforms.ExplicitLayoutTransform.ForceFieldAccessToAddress (Burst.Compiler.IL.Syntax.ILInstruction inst, System.Boolean forceAddress) [0x000b7] in <5365ccf18ec94235b5e31dbc5844b7eb>:0
    at Burst.Compiler.IL.Transforms.ExplicitLayoutTransform.VisitImpl (Burst.Compiler.IL.Syntax.ILInstruction inst) [0x00010] in <5365ccf18ec94235b5e31dbc5844b7eb>:0
    at Burst.Compiler.IL.ILVisitor.Visit (Burst.Compiler.IL.Syntax.ILInstruction instruction) [0x00007] in <5365ccf18ec94235b5e31dbc5844b7eb>:0
    at RobocraftX.Character.Camera.LocalCameraSphereCastEngine.LocalCameraSphereCastJob.Execute(RobocraftX.Character.Camera.LocalCameraSphereCastEngine.LocalCameraSphereCastJob* this) (at E:\RobocraftX\Assets\Code\RobocraftECS\Contexts\Scenes\Character\Camera\Engines\LocalCameraSphereCastEngine.cs:127)
    at Unity.Jobs.IJobExtensions.JobStruct`1<RobocraftX.Character.Camera.LocalCameraSphereCastEngine.LocalCameraSphereCastJob>.Execute(ref RobocraftX.Character.Camera.LocalCameraSphereCastEngine.LocalCameraSphereCastJob data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, ref Unity.Jobs.LowLevel.Unsafe.JobRanges ranges, int jobIndex)
    While compiling job: System.Void Unity.Jobs.IJobExtensions/JobStruct`1<RobocraftX.Character.Camera.LocalCameraSphereCastEngine/LocalCameraSphereCastJob>::Execute(T&,System.IntPtr,System.IntPtr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,System.Int32)
     
  9. Domas_L

    Domas_L

    Unity Technologies

    Joined:
    Nov 27, 2018
    Posts:
    111
    sebas77 likes this.