Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NativeAOT in .NET 7 #61231

Open
32 tasks
agocke opened this issue Nov 4, 2021 · 44 comments
Open
32 tasks

NativeAOT in .NET 7 #61231

agocke opened this issue Nov 4, 2021 · 44 comments

Comments

Projects
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
@agocke
Copy link
Contributor

@agocke agocke commented Nov 4, 2021

.NET 6 improvements listed here: dotnet/runtimelab#336

We're now planning the following improvements for NativeAOT in the .NET 7 timeframe:

Goals:

Pri 0:

  • Move the NativeAOT project out of dotnet/runtimelab and into dotnet/runtime
    • Building
    • Test integration
    • Packaging
  • Switch to runtime-built NativeAOT packages
  • Onboard first-party dotnet console applications using NativeAOT
    • Crossgen
    • dotnet-monitor
  • Perf:
    • At least as fast as on JSON and Plaintext TechEmpower
    • YARP
      • YARP startup time < 50ms
    • Start tracking build time
    • Introduce AOT compatibility annotations - #61239
  • Diagnostics
    • Event pipe
    • Explore SOS extension subset
  • dotnet/runtimelab#1632
    • CFG
    • CET (Shadow stack)

Pri 1:

  • Improve trimming support for APIs needed by common service Apps
  • Onboard more service-focused apps
    • YARP
  • More platform support
    • Mac x64/ARM64
    • Musl compatibility
  • Share more with the CLR
    • Interop
    • Reflection
  • Roslyn AOT analyzer

There also are some non-goals for .NET 7, particularly in applications that are not well-suited to trimming:

  • Complex reflection-dependent frameworks, like ASP.NET MVC and WPF
  • Apps with plugin models which dynamically load assemblies, like MSBuild
  • Mobile, WASM (already provided by Mono)
@agocke agocke added this to Needs triage in AppModel .NET 7 via automation Nov 4, 2021
@dotnet-issue-labeler
Copy link

@dotnet-issue-labeler dotnet-issue-labeler bot commented Nov 4, 2021

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

Loading

@davidfowl
Copy link
Member

@davidfowl davidfowl commented Nov 5, 2021

I think we can get really far with ASP.NET if user code isn't trimmed but framework code is.

I don't see EF in scope either. How do people do data things? ADO.NET?

Loading

@agocke
Copy link
Contributor Author

@agocke agocke commented Nov 5, 2021

At the moment we're sticking with user code not being trimmed by default.

As for EF, I think it strongly depends on what people use. My impression is that grpc is more important for microservice-type apps, but this really isn't my area of expertise. My hope is we can use apps like YARP to drive some of this investigation.

Loading

@hez2010
Copy link

@hez2010 hez2010 commented Nov 5, 2021

I don't see EF in scope either.

I used to build a demo for using EF with NativeAOT, it requires a bit heavy manual written runtime directives but it works without any problem. However, EF can definitely annotated itself for better trimming support and get rid of the need of runtime directives.

See https://github.com/hez2010/EFCore.NativeAOT

Loading

@davidfowl
Copy link
Member

@davidfowl davidfowl commented Nov 5, 2021

but this really isn't my area of expertise

Luckily, this is my area of expertise 🙃.

I'd like to manifest a document that describes the patterns that are AOT unfriendly. I've spent quite some time with native AOT and ASP.NET Core and it would be nice to have a doc for library authors that want to enable trimming to better understand the rules of the game

Loading

@davidfowl
Copy link
Member

@davidfowl davidfowl commented Nov 5, 2021

@agocke any reason to keep this a package? Why not have it be first class like the other publish experiences?

Loading

@snickler
Copy link
Contributor

@snickler snickler commented Nov 5, 2021

Awesome! Does this also have a line item for ensuring it works well in regards to modern Desktop application support? This is a huge want for those migrating from UWP and .NET Native.

Loading

@agocke
Copy link
Contributor Author

@agocke agocke commented Nov 5, 2021

@davidfowl Thanks for the feedback, much appreciated. So I take it EF is really common? In that case, I think it would be useful to find a representative app to flush out problems. As you know, serializers are probably the most common problem with trimming, so let's see what we can bring into scope.

I'd like to manifest a document that describes the patterns that are AOT unfriendly. I've spent quite some time with native AOT and ASP.NET Core and it would be nice to have a doc for library authors that want to enable trimming to better understand the rules of the game

We've added some documentation for this at https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings. Feedback welcome!

Any reason to keep this a package? Why not have it be first class like the other publish experiences?

That's more a technical description in that we need a "package" to ship it in. It seems like we could integrate this with the publish experience, although we might need a workload for additional dependencies. One thing to also keep in mind is that we have a dependency on certain native toolchain pieces as well, like link.exe or an equivalent linker.

Loading

@agocke
Copy link
Contributor Author

@agocke agocke commented Nov 5, 2021

@snickler No plans for GUI apps yet. There's been some success experimenting with WinForms -- it's very close to trimmable once ComWrappers is integrated. We'll just need to see how much bandwidth we have for .NET 7 and how difficult it is to make some of these things trimmable/AOT compatible.

Loading

@jkotas
Copy link
Member

@jkotas jkotas commented Nov 5, 2021

migrating from UWP and .NET Native.

This depends on microsoft/CsWinRT#373

Loading

@lukemcdo
Copy link

@lukemcdo lukemcdo commented Nov 5, 2021

Is there any way a NativeAOT UWP target could be officially supported (or even experimental/beta status) for app services only? This would be a positive tool to help keep modern tools available for UWP while WinUI goes through its teething issues. It would also give a way to build code against .NET 7 and shuffle things out from a UWP code base in-place.

Obviously this wouldn't include official UI support or anything revolutionary.

Loading

@davidfowl
Copy link
Member

@davidfowl davidfowl commented Nov 5, 2021

Will the AOT compiler support the trimming attributes without configuration OOTB, that is, will it only trim assemblies marked as trimmable by default?

Loading

@hez2010
Copy link

@hez2010 hez2010 commented Nov 5, 2021

will it only trim assemblies marked as trimmable by default?

That's not how NativeAOT work. The NativeAOT compiler generates code at compile-time instead of run-time, and there're no IL code and JIT compiler in compiled artifacts so even if the compiler doesn't trim anything, you still may encounter exception due to missing code at runtime.

For example, for a generic type Foo<T> the compiler need to figure out what Ts are being substituted into before it can generate code for it, so below pattern will results in no code generated for Foo<int>:

private Type innerType;

void Boom(Type t)
{
    typeof(Foo<>).MakeGenericType(new [] { t }); // no generated code for `Foo<int>`
}

void Test()
{
    innerType = typeof(int);
    Test(innerType);
}

Besides, there're lot of even complex patterns that cannot be statically analyzed during compile-time so the compiler can only rely on trimming attributes and runtime directives (rd.xml) and it's hard to be made out-of-the-box.

Loading

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Nov 5, 2021

Will the AOT compiler support the trimming attributes without configuration OOTB, that is, will it only trim assemblies marked as trimmable by default?

If we ignore nuances related to AOT and generics that @hez2010 mentions above for a moment, the trimming experience should match PublishTrimmed in .NET 6 - by default only assemblies marked IsTrimmable are trimmed (pretty much just the framework at this point) and further configuration is possible through MSBuild properties. That configuration will do the same things wrt trimming irrespective of whether trimming is done by IL Linker or the NativeAOT compiler. It should already be like this in the latest NativeAOT packages from runtimelab. Any behavior difference between a JIT-based world and AOT-based world in trimming would be a bug.

Loading

@davidfowl
Copy link
Member

@davidfowl davidfowl commented Nov 5, 2021

@hez2010 thanks for the explain (I know how it works 🙃).

@MichalStrehovsky great!

Loading

@filipnavara
Copy link
Contributor

@filipnavara filipnavara commented Nov 5, 2021

Are there any plans to port generics sharing from ProjectN?

Loading

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Nov 5, 2021

Are there any plans to port generics sharing from ProjectN?

If you mean universal shared code, it's not in scope for now. We want to lean into having predictable performance characteristics as opposed to wider compatibility at the cost of unpredictable perf for now.

(Universal shared code turns the generic problem @hez2010 mentioned above into a non-issue because the compiler pregenerates a universal native method body that works for any T. This comes with costs in terms of runtime performance of such method. It works great if such code runs as rarely as possible. But it fills me with dread if such code were to be in a hot path, such as SixLabors/ImageSharp#1703 where the T represents a pixel in a bitmap and the code is going to do hundreds of millions of operations with it.)

Loading

@dustinmoris
Copy link

@dustinmoris dustinmoris commented Nov 5, 2021

Good to see that .NET is the programming platform for Azure developers only.

I mean the majority of the world runs on AWS but the AWS SDK or GCP SDK is nowhere mentioned here.

This is complete bullshit and I'm sick of being treated like some second class peasant by Microsoft if I'm not using Visual Studio + Azure:

image

Loading

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Nov 5, 2021

I mean the majority of the world runs on AWS but the AWS SDK or GCP SDK is nowhere mentioned here.

@dustinmoris I understand where you're coming from given the past couple of weeks, but to be 100% clear on what that bullet means - we are not going to special case Azure SDK in .NET or NativeAOT. It came to our attention (or my attention, really because I dealt with the bug) that if someone references a lot of the Azure SDK NuGet packages combined with a bunch of other NuGet packages, the app becomes so big that NativeAOT fails to compile it (Azure/azure-sdk-for-net#24238). Azure libraries really stand out with their size. Trimming needs to be enabled for them using the publicly available mechanism. This just tracks the Azure SDK issue on our side. I've updated the top post to link the issue. I hope that clears it up. The mechanism is public, documented, and anyone can use it.

Loading

@dustinmoris
Copy link

@dustinmoris dustinmoris commented Nov 5, 2021

@MichalStrehovsky Thanks for the clarification. From the issue it sounded like "let's focus primarily on ASP.NET Core + Azure SDK apps being super efficiently trimmed first".

It came to our attention (or my attention, really because I dealt with the bug) that if someone references a lot of the Azure SDK NuGet packages combined with a bunch of other NuGet packages, the app becomes so big that NativeAOT fails to compile it

Hopefully the team will test this with other SDKs as well so other issues don't go unnoticed for AWS or GCP users.

Loading

@En3Tho
Copy link

@En3Tho En3Tho commented Nov 5, 2021

Annotating or refactoring all other possible SDKs to be AOT-friendly is not in scope of this issue tbh.

I guess when .Net 7 and native AOT lands MS will have to deal with another wave of "Why Azure works but my beloved XXX SDK not"?

Surely MS have to provide a very careful and thorough guide of how to make libraries AOT friendly. But 1) in a general case this is a library maintainer's duty, not MS. 2) Not all libraries can be refactored to be AOT friendly, especially if they are heavy run-time codegen based.

Loading

@hez2010
Copy link

@hez2010 hez2010 commented Nov 5, 2021

Hopefully the team will test this with other SDKs as well so other issues don't go unnoticed for AWS or GCP users.

The trimming support is done by annotating the library itself for trimming compatibility. AWS and GCP sdk authors should annotate their own libraries for better trimming support and make sure they're AOT-friendly. That's not something can be done on .NET NativeAOT or ILLinker toolchain side.

Loading

@serefarikan
Copy link

@serefarikan serefarikan commented Nov 5, 2021

However, EF can definitely annotated itself for better trimming support and get rid of the need of runtime directives.

@hez2010 thanks a lot for the link to that repo. For others curious about how DB access may work in AOT case, Dapper AOT may also be worth keeping an eye on. https://github.com/DapperLib/DapperAOT/

Loading

@roji
Copy link
Member

@roji roji commented Nov 5, 2021

Re EF, we do intend to work on trimming friendliness for 7.0, and ideally make EF fully compatible (tracked by dotnet/efcore#21894). I'll take a look at going beyond that and looking into NativeAOT compat as well, though no promises as of yet...

Loading

@yekanchi
Copy link

@yekanchi yekanchi commented Nov 5, 2021

Does nativeAOT remove IL from the published output?
so the C# code will be compiled(exported) to machine-specific code somehow like what GO, C++ compilers build?

Loading

@hez2010
Copy link

@hez2010 hez2010 commented Nov 5, 2021

Does nativeAOT remove IL from the published output? so the C# code will be compiled(exported) to machine-specific code somehow like what GO, C++ compilers build?

Yes.

Loading

@galvesribeiro
Copy link
Member

@galvesribeiro galvesribeiro commented Nov 5, 2021

This is complete bullshit and I'm sick of being treated like some second class peasant by Microsoft if I'm not using Visual Studio + Azure:
Hopefully the team will test this with other SDKs as well so other issues don't go unnoticed for AWS or GCP users.

@dustinmoris the tools for trimming are/will be available. Any package author can leverage it. It is not reasonable that the team has to run it across all NuGet.org packages. I believe it would be more productive if you open an issue on their SDK repos asking to play the ball and use the tools that allow trimming.

I understand that we're all upset (with real reasons to be!) with all the drama that happened recently, but that doesn't sounds a reasonable approach to have to test all against every possible package.

If the package authors will have/are having issues with the tools, they should just jump in here and report why the trimming isn't working for them.

Most of us is quite aware for how long both AWS and GCP SDKs are far from optimal, with poorly generated code and tons of memory leaks. They are the ones who were treating .Net as second class peasants. It is just a matter of how other languages were well supported there, while .Net never was. Now it seems that AWS has a dedicated team working on making their SDKs better, so hopefully it will come to a point to treat .Net community the same way as the other ones.

Loading

@dragos-dinulescu
Copy link

@dragos-dinulescu dragos-dinulescu commented Nov 5, 2021

Does going with NativeAOT mean that there is no CLR, nor any other runtime?

Loading

@josephmoresena
Copy link

@josephmoresena josephmoresena commented Nov 5, 2021

Does going with NativeAOT mean that there is no CLR, nor any other runtime?

By itself NativeAOT is a runtime but in compilation process combines it with the application.

Loading

@normj
Copy link

@normj normj commented Nov 5, 2021

Happy to help test scenarios with the AWS .NET SDK. We don't do a lot of reflection in the SDK but I'm sure there are areas we need to add the trimming attributes.

@galvesribeiro Sorry your experience with the SDK hasn't been positive. I don't want to derail this thread but you can reach out to me about your issues via email at normj@ and I'm guessing you can figure out the domain part (hint: amazon.com).

Loading

@saint4eva
Copy link

@saint4eva saint4eva commented Nov 6, 2021

Hopefully the team will test this with other SDKs as well so other issues don't go unnoticed for AWS or GCP users.

So what would the Amazon team and Google team be doing when Microsoft annotates their own SDKs for them?

Loading

@agocke
Copy link
Contributor Author

@agocke agocke commented Nov 6, 2021

@normj Happy to hear it! Trimming compatibility is a .NET 6 scenario, so please feel free to give it a try and reach out with any questions. Instructions and documentation for library authors is available at https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming/prepare-libraries-for-trimming

Loading

@robloo
Copy link

@robloo robloo commented Nov 6, 2021

Best news I've heard in months!

Loading

@ShreyasJejurkar
Copy link
Contributor

@ShreyasJejurkar ShreyasJejurkar commented Nov 6, 2021

Please keep this thread technical oriented only and discuss AOT stuff here instead of ranting.

Thank you.

Loading

@ShreyasJejurkar
Copy link
Contributor

@ShreyasJejurkar ShreyasJejurkar commented Nov 7, 2021

Just to be more clear here, @agocke just posted the list of efforts that they are planning for .NET 7 for making .NET more AOT friendly. This does not mean in .NET 7 we will have full AOT mode.
But for sure it will have significant improvements for it, just like we have major improvements in .NET 6 for assembly trimming because most parts of the BCL are now annotated with the corresponding marker attributes for the IL trimmer.

And moreover, as of now, this issue is not even added to .NET 7 milestone so we cannot consider it as committed for it.

I don't work for .NET or MS, but just wanted to put this here so that people and the community can clearly understand what is planned and don't get surprised if this slips from .NET 7.

Loading

@kant2002
Copy link
Contributor

@kant2002 kant2002 commented Nov 7, 2021

Are there any plans to support WASM in better way then it is currently? Maybe not firm plans, but ability to run experiment in same spirit as it was for NativeAOT.

Loading

@MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Nov 8, 2021

Are there any plans to support WASM in better way then it is currently? Maybe not firm plans, but ability to run experiment in same spirit as it was for NativeAOT.

LLVM-WASM will not be affected by this move - the CI infrastructure, NuGet publishing, etc. will stay in the same runtimelab branch as it is.

Loading

@jonathanperis
Copy link

@jonathanperis jonathanperis commented Nov 9, 2021

This means that when we'll have a Blazor Native AOT compiled project we'll have a "myapplication.wasm" plus a "dotnet.wasm" file on the browser only?

If so, this will be amazing

Loading

@yowl
Copy link
Contributor

@yowl yowl commented Nov 9, 2021

I don't work for Microsoft, but the Blazor story is unaffected by this as it uses Mono (and it's AOT) which is not the same.

Loading

@marek-safar
Copy link
Contributor

@marek-safar marek-safar commented Nov 9, 2021

Are there any plans to support WASM in better way then it is currently?

@kant2002 what would you like to see supported better way in WASM than it's in .NET6?

Loading

@kant2002
Copy link
Contributor

@kant2002 kant2002 commented Nov 9, 2021

@marek-safar I have to play with .NET, but on first sight, still same problems with public websites as previous versions. to slow cold load. Also on unreliable mobile network, operation this app would be a pain.

Need a way how to bundle some DLLs at least.

I would like to have console apps, and WASM modules building and accessing via interop. I may miss something which already implemented. Blazor raise a mixed feeling in me. Would like to have ability to drop it.

A lot of issues with Blazor comes from the fact that WASM specifications is extremely slow moving right now.

Reason why I start NativeAOT, is that long time ago, at the age of Blazor @SteveSandersonMS say that CoreRT can eventually power Blazor and we improve what we have even further.

If you think I can be of any help, or you know some area for C#=>WASM where I can be of any help, let me know. Or even more important if I miss something, so I can change my opiniong.

Loading

@robloo
Copy link

@robloo robloo commented Nov 9, 2021

I don't work for Microsoft, but the Blazor story is unaffected by this as it uses Mono (and it's AOT) which is not the same.

So, we are repeating .NET framework mistakes again? There should not be two different AOT stories: One from "main" .NET and the other from Mono. There should be a generalized AOT infrastructure/tooling that supports all platforms, yes even WASM. Anything less is going to be a long-term maintenance burden and in a few years we'll be talking about the need for another .NET unification.

Loading

@jkotas
Copy link
Member

@jkotas jkotas commented Nov 9, 2021

There should not be two different AOT stories:

AOT is tightly coupled with the core runtime. We have two core runtimes: CoreCLR and Mono, each comes with own variants of AOT.

Yes, we would love to have more unification between CoreCLR and Mono core runtimes, and we are actively working on it too.

Loading

@robloo
Copy link

@robloo robloo commented Nov 9, 2021

There should not be two different AOT stories:

AOT is tightly coupled with the core runtime. We have two core runtimes: CoreCLR and Mono, each comes with own variants of AOT.

Yes, we would love to have more unification between CoreCLR and Mono core runtimes, and we are actively working on it too.

True, I get that, and I did oversimplify things.

That said, there really shouldn't be two runtimes either and I see AOT as a big step in actually unifying the runtimes as well. For example, most apps deploy AOT for various reasons on Android/iOS. Full AOT that supported those platforms would potentially allow using .NET itself -- with no Mono -- on Android/iOS. It does seem, as you said, AOT and the runtimes are tightly coupled and therefore to unify the runtimes, AOT should be unified first.

I'm glad you are actively working on a strategy for this though. I would just hate to see further diverging AOT implementations for both when a single one would (in my mind) also be a big step towards unification of the runtimes -- in other words, bigger upfront investment but lower long term costs. Grand unification theory, I mean .NET unification, is the end goal and all decisions should be leading towards it after .NET 5.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment