#Using Burst in Roslyn Source Generator

1 messages · Page 1 of 1 (latest)

limber rune
#

Is it possible to use Burst in generated code?

This is what I've tried:

namespace ExampleSourceGenerator
{
    [Generator]
    public class BurstedMethodGenerator : ISourceGenerator
    {
        public void Execute(GeneratorExecutionContext context)
        {
            var sourceBuilder = new StringBuilder(
                @"
                using Unity.Burst;
                using System;
                namespace BurstedMethodNamespace
                {
                    public static class BurstedMethodClass
                    {
                        [BurstCompile]
                        public static int MyFunction(int x)
                        {
                            return x * 2;
                        }
                    }
                }"
            );

            context.AddSource("burstedMethodSourceGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }

        public void Initialize(GeneratorInitializationContext context)
        {
        }
    }
}

When I import my custom library I get these error messages:

NetStandard\ExampleSourceGenerator.BurstedMethodGenerator\burstedMethodSourceGenerator.cs(8,21): error CS0246: The type or namespace name 'BurstCompileAttribute' could not be found (are you missing a using directive or an assembly reference?)
NetStandardBlinq\ExampleSourceGenerator.BurstedMethodGenerator\burstedMethodSourceGenerator.cs(8,21): error CS0246: The type or namespace name 'BurstCompile' could not be found (are you missing a using directive or an assembly reference?)```
jagged forum
#

also prefix with global:

limber rune
jagged forum
#

when you are using fully qualified

limber rune
jagged forum
#

source gen just inserts additional file to project

#

that's about it

#

and you are responsible for it to be valid for compilation

#

I also recommend using SyntaxFactory for it

limber rune
#

It's valid for compilation as soon as I remove the BurstCompile attribute :/

jagged forum
#

try without global

#

just do this:

#

create file in your target project

#

with all valid syntax

#

and copy it to your string

limber rune
#

It's valid

#

but not when generated by roslyn

jagged forum
#

🤔

limber rune
#

as soon as I remove the [BurstCompile] attribute everything is fine

jagged forum
#

I feel like

#

your generated file does not belong to assembly

#

with referenced burst

#

thus it's not resolved

#

try to make some partial type

#

and make generated file

#

part of this partial declaration

limber rune
#

So I created this file in my Unity project:

using Unity.Burst;
public static partial class BurstedMethodClass
{
}

And this in the class library:

public void Execute(GeneratorExecutionContext context)
        {
            var sourceBuilder = new StringBuilder(
                @"
                using System;
                    public static partial class BurstedMethodClass
                    {
                        [BurstCompile]
                        public static int MyFunction(int x)
                        {
                            return x * 2;
                        }
                    }"
            );

            context.AddSource("burstedMethodSourceGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }```
#

and I get the same error again

#

Did you ever manage to use burst in generated code yourself?

jagged forum
#

not really, I only codegened managed code

limber rune
#

ChatGPT4 said that it's not possible but I can't find any information on it

jagged forum
#

also

#

try to put them in same namespace

#

might want to take a look at how Unity codegens file

#

maybe there's some sort of pattern

#

naming could be important

#

allthough

#

since you are simply adding it as constant code

#

I'm not sure even in what assembly it drops the code

limber rune
#

yea I'll try to figure it out

#

thanks for the help anyways!

jagged forum
#

@ocean jolt I think it's justified to ask Dani about this

ocean jolt
#

We simply generate [global::Unity.Burst.BurstCompile] (Just make sure that the assembly you're generating based on is referencing Burst :3)

#

Your original post is pretty close (tho be carefull to use ISourceGenerator. You should ideally use IIncrementalGenerator instead)
It was just missing the attribute on BurstedMethodClass itself and full type names think

jagged forum
ocean jolt
#

We do it no different than Roslyn - ISourceGen will have Execute run for each assembly and so context.Compilation will know. IIncremental generator can run its Init once and it works for all projects, but the callbacks themselves will still be separated by compilation 😄

From a setup perspective. Just make sure that the user assembly your SourceGen is generating based on has the references needed for it to emit. If not you should make your generator throw errors at you.

Like what is the case if you forget to add Burst to an Assembly Definition that references Entities

limber rune
#

Hey @ocean jolt , thanks for your help! I'm slowly getting the hang of it.
Do you know if there's a way to set breakpoints to debug a source generator?
When I attach to the Unity process the breakpoints they don't do anything.

jagged forum
#

hmm, lemme find an example

#

You'll need to copy some code from it

limber rune
#

Thank you @jagged forum , I need to learn more about source generators to understand what that code is all about.
It would probably be easier for me to completely write and debug my source generators outside of Unity for now. I have much to learn anyways.

jagged forum
#

it is meant to be outside of unity

#

I don't think there is a way to debug source gen on target projects yet

limber rune
#

yea I mean, of course I wrote my source generators in a class library

jagged forum
#

what I did - just copy code and create dummies

#

empty classes

#

MonoBehaviour/GameObject and etc

ocean jolt
#

Well, we actually have many ways we debug SourceGen. Here are a few:

  1. We have mock-based SourceGen tests. Those we can directly test without opening Unity.
  2. This is my preferred approach. Use CSC to run the compilation. Simply run dotnet "path/to/csc.dll" @path/to/project/library/.../19...DagSomething/assembly.to.run.generator.on.rsp. CSC can be found in RoslynSDK in your Unity installation, and your projects library files contain RSP files for CSC to run. (run the command in ide of choice, and you can breakpoint the editor - simply running that command will give you Console.WriteLine text, run it with your profiler and you have a nice flame graph)
  3. Write Debug.Break() or Debug.Launch() this forces an IDE to launch and attach at that location.

Hopefully that helps a little :3

limber rune
#

Thanks @ocean jolt , I ended up printing my logs to a file for my debugging needs. Because my Roslyn code generator doesn't take long to compile and isn't that complicated I tested everything within Unity.

ocean jolt
#

Awesome! Btw. Lemme know if any parts of the process was difficult, I'm thinking of doing a little series on SourceGen using Unity. And some of the dos and many donts of SourceGen. Just in my spare time :3

dusky junco
#

That'd be awesome and I'm sure well appreciated!

jagged forum
eternal night
limber rune
# ocean jolt Awesome! Btw. Lemme know if any parts of the process was difficult, I'm thinking...

So far the process was alright, it's mainly Roslyn itself I have to get used to. I would look forward to your series!

I just stumbled upon a baffling issue where Roslyn is sometimes using old code which no longer exists. So it causes exceptions I cannot possibly address.

Deleting the library folder doesn't help, the old code must somehow have baked itself into an assembly which isn't part of the library folder. Its the only explanation I could come up with so far.

I'm using the old Roslyn 3.8 without incremental sourcegen, could that somehow be the cause @ocean jolt?

#

Oh and do's and donts would definetly be useful to learn about! My sourcegen code is a mess ^^

jagged forum
#

not compilation

#

generated files are stored somewhere in AppData folder

#

and yeah, I'd recommend learning incremental

#

Roslyn 3.X is pretty much legacy

#

if Unity sticked to it - compilation performance would have been awful

limber rune
#

Roslyn 4.X isn't supported in Unity 2020 LTS though

jagged forum
#

ah, that's true

#

I'm on 2022.2 so... 😅

ocean jolt
#

4 is supported but only the first

#

So 4.0.1

#

If you're starting early in your project, then Incremental generators are definitely the way to go, also make sure to not include 'compilation' in your execute of an incremental generator, try to do everything in your syntax providers instead. That way execute is only for the output .cs writing itself :3

limber rune
jagged forum
#

I miss so many features

ocean jolt
ocean jolt
jagged forum
#

🥲

limber rune
jagged forum
#

and when it bugs out

#

you see errors

#

meanwhile running compilation inside unity works 99% times

ocean jolt
#

Indeed, btw this is why we work with the IDE makers to help them, as their SourceGen support is still very early stages :3

main vigil
#

I get it even if I fix and delete those files, it's coming from (I think) that RandomObjectSpawner<T> from the Physics Samples

#

I just adopted ECS about a week ago, and trying to get at the heart of understanding how it runs my code through. What is the deal with generics?

dusky junco
#

the deal is they cause all sorts of issues with codegen

#

and you mostly can't use them

main vigil
#

How they manage it in the Unity Samples?