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

AOT optimization #99580

Closed
DotNetNext opened this issue Mar 12, 2024 · 43 comments
Closed

AOT optimization #99580

DotNetNext opened this issue Mar 12, 2024 · 43 comments

Comments

@DotNetNext
Copy link

DotNetNext commented Mar 12, 2024

AOT optimization
1.I referenced a dll, but the dll depends on another dll, so I installed only one dll, and the aot release failed(I only use the functionality of a DLL 。 Do not use dependent DLL functionality)
2.AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun

@DotNetNext DotNetNext added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Mar 12, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Mar 12, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Mar 12, 2024
@MichalStrehovsky
Copy link
Member

Can you describe in more detail what this is about? "referenced a dll" -> what kind of DLL (native? managed?). "the aot release failed" -> how? is there an exception with a stack?

"AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun" -> is this related to first point? what do you mean?

@MichalStrehovsky MichalStrehovsky added the needs-author-action An issue or pull request that requires more info or actions from the author. label Mar 12, 2024
@DotNetNext
Copy link
Author

Can you describe in more detail what this is about? "referenced a dll" -> what kind of DLL (native? managed?). "the aot release failed" -> how? is there an exception with a stack?

"AOT requires perfect EMIT support, not through ReadyToRun, you can provide a DLL reference to publish, instead of checked ReadyToRun" -> is this related to first point? what do you mean?


These two points are not related, they are two optimization directions

Let me write a DEMO for the first question

@dotnet-policy-service dotnet-policy-service bot removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Mar 12, 2024
@DotNetNext
Copy link
Author

DotNetNext commented Mar 12, 2024

AOT DEMO.zip

There are two folders in it.

The error folder can run but cannot be published ,

OK folder can be published, NUGET packages all the references

@vcsjones vcsjones removed the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Mar 12, 2024
@MichalStrehovsky
Copy link
Member

Can you reupload the ZIP? It cannot be downloaded and leads to a 404.

@MichalStrehovsky MichalStrehovsky added needs-author-action An issue or pull request that requires more info or actions from the author. and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Mar 13, 2024
@DotNetNext
Copy link
Author

DotNetNext commented Mar 13, 2024

Can you reupload the ZIP? It cannot be downloaded and leads to a 404.

Can download
AOT DEMO.zip

@dotnet-policy-service dotnet-policy-service bot removed the needs-author-action An issue or pull request that requires more info or actions from the author. label Mar 13, 2024
@DotNetNext
Copy link
Author

image

@NCLnclNCL
Copy link

ok

@MichalStrehovsky
Copy link
Member

This is caused by your rd.xml. If you remove the rd.xml file the compilation succeeds. RD.XML files are unsupported.

The problem is that the nuget package you reference has incomplete dependencies (it's basically broken). By rooting it you cause it to hit codepaths within the compiler that are hard to recover from. The compiler generally tries to be resilient to junk input like this, but it's not 100% and rd.xml definitely makes things worse.

@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Mar 19, 2024
MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this issue Mar 19, 2024
Addresses some of the problems seen in dotnet#99580.

We already check methods and types are loadable. Should do the same for fields.
@DotNetNext
Copy link
Author

This is caused by your rd.xml. If you remove the rd.xml file the compilation succeeds. RD.XML files are unsupported.

The problem is that the nuget package you reference has incomplete dependencies (it's basically broken). By rooting it you cause it to hit codepaths within the compiler that are hard to recover from. The compiler generally tries to be resilient to junk input like this, but it's not 100% and rd.xml definitely makes things worse.

rd.xml delete my program can not run, need rd.xml to support aot my program

@jkotas
Copy link
Member

jkotas commented Mar 19, 2024

You should address the AOT warnings in your application and the references libraries instead: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/fixing-warnings . It is the only supported way to make your AOT compiled program work with confidence.

jkotas pushed a commit that referenced this issue Mar 19, 2024
Addresses some of the problems seen in #99580.

We already check methods and types are loadable. Should do the same for fields.
@DotNetNext
Copy link
Author

DotNetNext commented Mar 19, 2024

You should address the AOT warnings in your application and the references libraries instead: https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/fixing-warnings . It is the only supported way to make your AOT compiled program work with confidence.

I hope to support better in the future, AOT is not working very well at present

@DotNetNext
Copy link
Author

The main ones are: publishing speed, EMIT, dependent publishing errors

@jkotas
Copy link
Member

jkotas commented Mar 19, 2024

EMIT

If you application has a strong dependency on generating dynamic code at runtime via Reflection.Emit, native AOT is not the right technology to use for it. We have no plans to fixing that. Use regular CoreCLR w/ JIT instead.

@DotNetNext
Copy link
Author

EMIT

If you application has a strong dependency on generating dynamic code at runtime via Reflection.Emit, native AOT is not the right technology to use for it. We have no plans to fixing that. Use regular CoreCLR w/ JIT instead.

My solution is to provide a DLL that simply references this DLL to solve the problem, which is nothing more than an intermediate conversion problem

@DotNetNext
Copy link
Author

emit was a feature, and you just dropped it

@huoyaoyuan
Copy link
Member

Emit is fundamentally disagreed with NativeAOT. NativeAOT is designed for environments that Emit or equivalents are forbidden, namely UWP and iOS.

There are alternatives like source generators, to implement features in more AOT-friendly way.

If you prefer, you can get in touch with me privately and I can explain more in Chinese.

@DotNetNext
Copy link
Author

DotNetNext commented Mar 20, 2024

Emit is fundamentally disagreed with NativeAOT. NativeAOT is designed for environments that Emit or equivalents are forbidden, namely UWP and iOS.

There are alternatives like source generators, to implement features in more AOT-friendly way.

If you prefer, you can get in touch with me privately and I can explain more in Chinese.

These solutions are not as good as EMIT, Epression can replace a little, but there is no way to dynamically build classes, EMIT is the best,source generators should not be run time

其他方案不行,不能运行时创建类,目前EMIT能做到表达式树也做不到 ,重点是运行时创建

@DotNetNext
Copy link
Author

If something is useful, it should be supported as much as possible, and give up the existing scheme, which will give many developers a headache, and there is no alternative

@huoyaoyuan
Copy link
Member

dynamically build classes

This is strictly not possible for AOT environment. Ordinal CLR is a must. The NativeAOT type system doesn't support this. AOT environments don't allow this either.

@DotNetNext
Copy link
Author

dynamically build classes

This is strictly not possible for AOT environment. Ordinal CLR is a must. The NativeAOT type system doesn't support this. AOT environments don't allow this either.

I know it's hard, but I think it's possible 。We are to solve problems, not to say impossible, there is no impossible。

@jkotas
Copy link
Member

jkotas commented Mar 20, 2024

I know it's hard, but I think it's possible

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Where do you see the difference between regular CoreCLR w/ JIT and the hypothetical native AOT w/ dynamic code generation?

@MichalPetryka
Copy link
Contributor

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Worth noting that there was an experiment with Mono Interpreter for it.

@am11
Copy link
Member

am11 commented Mar 20, 2024

It was mentioned previously in #95841 (comment), but OP is adamant to have it first-class, which seems likely to happen in the future (based on cost/benefit/# of people asking etc.) but clearly not the priority of the project at this very second. :)

@DotNetNext
Copy link
Author

I know it's hard, but I think it's possible

If we were to add dynamic code generation (emit) to native AOT, we would end up with something that looks very much like regular CoreCLR w/ JIT.

Where do you see the difference between regular CoreCLR w/ JIT and the hypothetical native AOT w/ dynamic code generation?

For example, add a tool to monitor the EMIT conversion part required by the current program, generate the EMIT replacement DLL required for the current program.Users download this DLL, reference it and publish it as AOT

@DotNetNext
Copy link
Author

DotNetNext commented Mar 20, 2024

Users will not use much of the EMIT part, only a little conversion is required

@DotNetNext
Copy link
Author

There are so many packages using EMIT on the market that it would be perfect to support it

@jkotas
Copy link
Member

jkotas commented Mar 21, 2024

For example, add a tool to monitor the EMIT conversion part required by the current program, generate the EMIT replacement DLL required for the current program.Users download this DLL, reference it and publish it as AOT

This approach would violate our design principles for runtime form factors - look for "Deliver predictable experience".

We do not mind if somebody out there builds a solution like the one you are suggesting. It is not going to be included it in the .NET product itself. We believe that the predictable experience is more important.

@jkotas
Copy link
Member

jkotas commented Mar 21, 2024

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

@huoyaoyuan
Copy link
Member

generate the EMIT replacement DLL required for the current program

EMIT can do much more than that. It can generate code based on user input, which is often considered as security risk.
The coverage of EMIT paths may not be exhaustive either.

If the generated code can be determined by the application code only, it should be theoretically possible to replace with source generator. That our current suggestion.

@DotNetNext
Copy link
Author

DotNetNext commented Mar 21, 2024

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

I want to do high-end features, there is no way to use AOT, recently engaged in a dynamic API creation project, directly JS to create C# WEB API. I think this type of project is definitely a big trend in the future, and it's a regret not to support AOT

@DotNetNext
Copy link
Author

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

@DotNetNext
Copy link
Author

DotNetNext commented Mar 21, 2024

source generator

source generator

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

@MichalStrehovsky
Copy link
Member

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

@DotNetNext
Copy link
Author

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

@DotNetNext
Copy link
Author

There are so many packages using EMIT on the market that it would be perfect to support it

These packages are supported by regular CoreCLR w/ JIT. If you depend on these packages, do not use native AOT. It is as simple as that.

Just like AI, if AI can't evolve on its own, then it's just a machine. Language is the same, want to achieve this self-evolution of the function, must be supported at the bottom

AOT is not an "evolution" of the JIT form factor. We have no plans to replace JIT with AOT for .NET.

AOT is specifically for the use cases and scenarios listed in the form factors document linked above. In the past, people who had such requirements often had to rewrite their app in a non-.NET language. Now it's possible to achieve their goals without a rewrite in a different language. But some things might need to still be rewritten using source generators, new high-performance reflection APIs, etc. If you want AOT, you can't get Emit functionality even if you go outside the .NET ecosystem (no emit in Go/Rust/Swift/C++/...). It's just fundamentally incompatible.

If your use case falls into the category that native AOT targets and you actually need AOT form factor, you'll need to make changes. We don't have plans to be drop-in compatible. Native AOT makes choices and tradeoffs to achieve startup/size/working set goals that are not compatible with dynamic code generation.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

@huoyaoyuan
Copy link
Member

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

Those environments are purposefully banning dynamic code emitting. Workarounds like scripting languages are invalid indeed.

Compatibility is counted in two directions: for application code and for platform. CLR was made compatible for Unix platforms by splitting Windows-only features to be optional. There's just no way to use Windows-only features on Unix platforms without heavy emulation. So does dynamic features on AOT-only platforms.

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

The famous users of Emit like System.Text.Json are adopting source generators, to replace reflection and dynamic methods.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

I do not know what this mean. AOT has no relationship with NuGet. They are totally different layers of things.


I think it's better to ask some more questions:

  • Why do you need NativeAOT in the first place? Do you need to run on iOS-like platforms or something? Does your code need to be loadable native library from native code?
  • What type of library that uses dynamic feature are you using? Are you actually using such code path?

@DotNetNext
Copy link
Author

EMIT you can not support, the release error, your compatibility is better? This can always be achieved, rd.xml after the release of missing DLL is not good release

Those environments are purposefully banning dynamic code emitting. Workarounds like scripting languages are invalid indeed.

Compatibility is counted in two directions: for application code and for platform. CLR was made compatible for Unix platforms by splitting Windows-only features to be optional. There's just no way to use Windows-only features on Unix platforms without heavy emulation. So does dynamic features on AOT-only platforms.

The source generator is weak and useless. Is to help me write him less a system.io.file.create, nothing useful

The famous users of Emit like System.Text.Json are adopting source generators, to replace reflection and dynamic methods.

Now I have to package all DLLS with NUGET to publish AOT, even if I don't use DLLS

I do not know what this mean. AOT has no relationship with NuGet. They are totally different layers of things.

I think it's better to ask some more questions:

  • Why do you need NativeAOT in the first place? Do you need to run on iOS-like platforms or something? Does your code need to be loadable native library from native code?
  • What type of library that uses dynamic feature are you using? Are you actually using such code path?

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

@DotNetNext
Copy link
Author

DotNetNext commented Mar 21, 2024

  • Why do you need NativeAOT in the first place? Do you need to run on iOS-like platforms or something? Does your code need to be loadable native library from native code?
  • What type of library that uses dynamic feature are you using? Are you actually using such code path?

I'm open source, I make things for others to use, so others want to use AOT that can only give up some features
You tell me not to support, then I can only other users say not to support.

@huoyaoyuan
Copy link
Member

so others want to use AOT that can only give up some features
You tell me not to support

Not all features are orthogonal. They just have no (direct) way to work together. For example you can't use a WPF component on non-Windows platform. It's just the same that you can't use dynamic code on non-JIT platform.

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

rd.xml is outdated. The recommended approach today is using dynamic dependency annotation. Then the AOT compiler can correctly figure out what part of a library will be used.

@DotNetNext
Copy link
Author

so others want to use AOT that can only give up some features
You tell me not to support

Not all features are orthogonal. They just have no (direct) way to work together. For example you can't use a WPF component on non-Windows platform. It's just the same that you can't use dynamic code on non-JIT platform.

The second problem looks at the above record, mainly after rd.xml, all the DLLS that rely on this DLL must be referenced before they can be published, even if they are not needed

rd.xml is outdated. The recommended approach today is using dynamic dependency annotation. Then the AOT compiler can correctly figure out what part of a library will be used.

Is there a tutorial on not using XML?

@jkotas
Copy link
Member

jkotas commented Mar 21, 2024

You tell me not to support, then I can only other users say not to support.

It is a fine answer to give if your package is fundamentally incompatible with native AOT. For example, Newtonsoft.Json that is the most popular nuget package have done that: JamesNK/Newtonsoft.Json#2732

Is there a tutorial on not using XML?

This blog post is a good introduction: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/

@DotNetNext
Copy link
Author

DotNetNext commented Mar 22, 2024

You tell me not to support, then I can only other users say not to support.

It is a fine answer to give if your package is fundamentally incompatible with native AOT. For example, Newtonsoft.Json that is the most popular nuget package have done that: JamesNK/Newtonsoft.Json#2732

Is there a tutorial on not using XML?

This blog post is a good introduction: https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/

error : System.ArgumentNullException: Value cannot be null. (Parameter 'type')
The program can't run away without publishing rd.xml

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<PublishAot>true</PublishAot>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
	</PropertyGroup>

	<ItemGroup>
	  <PackageReference Include="SqlSugarCore" Version="5.1.4.135" />
	</ItemGroup>

	 

</Project>

@DotNetNext
Copy link
Author

DotNetNext commented Mar 22, 2024

//this is OK
<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		<PublishAot>true</PublishAot>
	</PropertyGroup>

	<ItemGroup>
	  <None Remove="rd.xml" />
	</ItemGroup>

	<ItemGroup>
	  <Content Include="rd.xml">
	    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
	  </Content>
	</ItemGroup>

	<ItemGroup>
	  <PackageReference Include="SqlSugarCore" Version="5.1.4.135" />
	</ItemGroup>

	<ItemGroup>
		<RdXmlFile Include="rd.xml" />
	</ItemGroup>

</Project>
//rd.xml
<Directives>
	<Application>
		<Assembly Name="orm_sqlsugar"  Dynamic="Required All">
		</Assembly>
		<Assembly Name="SqlSugar"  Dynamic="Required All">
		</Assembly>
	</Application>
</Directives>

@github-actions github-actions bot locked and limited conversation to collaborators Apr 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

9 participants