This post is equally a “Help Wanted” post as it is a potential bug. The expected behaviour is surprisingly not documented anywhere, but my current setup worked with an older version of burst (1.5.6), but breaks when trying to upgrade to 1.7.0.
High-level goal: Build a managed dll (either externally using visual studio or with Unity) which contains methods and/or jobs that then get burst compiled by a project which uses the dll.
With burst version 1.5.6, I accomplished this by compiling a Unity project that contained the dll’s code, and then importing the generated dll into another project. This approach does not work with burst 1.7.0. First, in editor burst spams a bunch of warnings like:
Compilation was requested for method [...] but it is not a known Burst entry point. This may be because the [BurstCompile] method is defined in a generic class, and the generic class is not instantiated with concrete types anywhere in your code.
Most of the methods that it is failing to find are not generic or contained in a generic type, so I think that is a red herring. Weirdly, the methods appear in the burst inspector, but none of the jobs or methods run bursted.
What is the correct method for creating a managed plugin and ensuring that jobs/methods contained in the plugin get bursted? I’d appreciate any help/insight into this.
Hey there. So unfortunately you’ve ran into a corner case that we never officially supported - Burst has never supported having precompiled assemblies, in 1.6 and prior it was just an artifact of how we discovered methods to Burst compile in the Editor that this would work.
In Burst 1.7+ we’ve integrated Burst compilation into the Unity editor compilation pipeline. What this means is that only the assemblies that the Unity editor tells us are being compiled during a script recompilation will be Burst compiled. We’ve done this for good reason (it allows us to start Burst compiling things much earlier than previously, meaning that we end up with an overall better user experience when using Burst. But the downside is that the feature that you were relying on (Burst in precompiled assemblies) will no longer work.
You are right that the warning is a red herring - I actually didn’t realise that it was possible to have Burst work in precompiled assemblies before your post, and the main problems we were seeing with the 1.6 → 1.7 transition was with BurstCompile’s in open generics (thus the error message).
The reason they appear in the inspector still is that the inspector is using the older codepath (where we reflect through all loaded assemblies).
We’ll update the documentation of the package to make it clear that we do not support this usecase.
I see, that is unfortunate. It’s nice to be able to provide pre-built managed dlls (whether to other teams within the company, publishing assets on the asset store, etc). It’s disappointing that burst now makes this workflow impossible, especially since it used to work and I imagine that there isn’t a hard technical limitation which makes this infeasible.
Though it wasn’t what I was hoping to hear, I appreciate your quick response and explanation.
No to both questions. I did not realize the AssemblyBuilder api existed, but I don’t fully understand how much it would have changed in terms of final output of the assembly. To give more details:
To get this scenario working with the older version of burst, I tried building with two different approaches:
Build externally via Visual Studio. I couldn’t get this working, and I thought the reason might have been that the assembly didn’t contain the delegates, structs, etc. that burst injects (e.g. MethodName_00000678$PostfixBurstDelegate). The issue might have been something else, or there might have been other issue son top of this.
Build with Unity which entailed having a Unity project which contained the code that I wanted to be in the dll. Build the project, and then copy the dll from ProjectName_Data\Managed folder. This worked (with the old version of burst).
To actually use the plugin in a project, I would treat it like any other managed dll (i.e. put it in the Assets folder, a Package, etc).
@sheredom Any ETA on supporting precompiled assemblies?
We are looking into supporting hot reload for burst and this is a hard requirement to make your code changes burst compile on-the-fly.
It works nicely for 2021 LTS but for 2022+ you get warnings that can’t be filtered or ignored.
The hot reload still works because the job just falls back to managed code but the warning persists and is annoying.
We want to give our users a seamless experience and right now we have to tell them that there is no way to fix this warning and they have to deal with it and the performance penalty if they want to hot reload their burst jobs.
More info on our tool here: https://hotreload.net/
Hi @jannysice - no, supporting precompiled assemblies is not on our roadmap, so I can’t give an ETA. It is in our backlog though, and it is something we’d like to support in the future.
What are those warnings? Assuming you’re using the same version of Burst, I’d expect most Burst-related warnings to be the same across Editor versions.
Just for reference: Quiet some people that use our package asked for support to hot reload burst compiled code and many more have mentioned that they would only start using it if we support burst. I spent significant amount of man hours to make this work. In the end we were even considering to not release it like this because a warning every time you make code changes to jobs is below the quality bar that we set for our product.
Just came across this thread as we have updated to 2022 LTS, ECS 1.0, and noticed that our pre-compiled jobs are not being Burst compiled, so I wanted to make sure our use case is heard as well. We do not use AssemblyBuilder or PluginImporter. We use pre-compiled DLLs for a number of reasons. We have shared libraries that we do not want developers modifying, internally. Using DLLs forces changes in these libraries to go through proper channels. Second, we wish to keep projects that we develop open for client modification without freely exposing/sharing our IP.
If you want to access definitions between assemblies with BurstCompile, I have found the solution. Simply add into Assembly Definition References this assembly: Unity.Burst.CodeGen.
I put this list on every assembly which uses Burst: