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

Cannot build NativeAOT 8.0 on Arch Linux #2548

Open
Jisu-Woniu opened this issue Mar 28, 2024 · 6 comments
Open

Cannot build NativeAOT 8.0 on Arch Linux #2548

Jisu-Woniu opened this issue Mar 28, 2024 · 6 comments

Comments

@Jisu-Woniu
Copy link

Jisu-Woniu commented Mar 28, 2024

I wrote a simple benchmark, with NativeAOT enabled:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;

BenchmarkRunner.Run<MyBench>();


[SimpleJob(RuntimeMoniker.NativeAot80)]
public class MyBench
{
    [Benchmark]
    public void Bench() { }
}

But when I run dotnet run -c Release, it fails with:

...
// Build Error: Standard output: 
  
 Standard error: 
 MSBuild version 17.8.5+b5265ef37 for .NET
$HOME/.nuget/packages/microsoft.net.illink.tasks/8.0.3/build/Microsoft.NET.ILLink.targets(210,5): warning : Property 'TrimmerDefaultAction' is deprecated in .NET 7 and higher and will be ignored. Use TrimMode instead. [<PROJECT_DIR>/bin/Release/net8.0/136c2e4d-c592-4318-baf9-67ab64a593fc/BenchmarkDotNet.Autogenerated.csproj]
  Generating native code
EXEC : error : Unrecognized instruction set avx-512f [<PROJECT_DIR>/bin/Release/net8.0/136c2e4d-c592-4318-baf9-67ab64a593fc/BenchmarkDotNet.Autogenerated.csproj]
  System.CommandLine.CommandLineException: Unrecognized instruction set avx-512f
     at System.CommandLine.Helpers.ConfigureInstructionSetSupport(String, Int32, Boolean, TargetArchitecture, TargetOS, String, String, Logger, Boolean) + 0x9d5
     at ILCompiler.Program.Run() + 0x59b
     at ILCompiler.ILCompilerRootCommand.<>c__DisplayClass227_0.<.ctor>b__0(ParseResult result) + 0x310
$HOME/.nuget/packages/microsoft.dotnet.ilcompiler/8.0.3/build/Microsoft.NETCore.Native.targets(308,5): error MSB3073: The command ""$HOME/.nuget/packages/runtime.linux-x64.microsoft.dotnet.ilcompiler/8.0.3/tools/ilc" @"obj/Release/net8.0/linux-x64/native/136c2e4d-c592-4318-baf9-67ab64a593fc.ilc.rsp"" exited with code 1. [<PROJECT_DIR>/bin/Release/net8.0/136c2e4d-c592-4318-baf9-67ab64a593fc/BenchmarkDotNet.Autogenerated.csproj]

// BenchmarkDotNet has failed to build the auto-generated boilerplate code.
// It can be found in <PROJECT_DIR>/bin/Release/net8.0/136c2e4d-c592-4318-baf9-67ab64a593fc
// Please follow the troubleshooting guide: https://benchmarkdotnet.org/articles/guides/troubleshooting.html
...

My dotnet --info output:

.NET SDK:
 Version:           8.0.103
 Commit:            6a90b4b4bc
 Workload version:  8.0.100-manifests.e99a2be4

Runtime Environment:
 OS Name:     arch
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /usr/share/dotnet/sdk/8.0.103/

.NET workloads installed:
 Workload version: 8.0.100-manifests.e99a2be4
There are no installed workloads to display.

Host:
  Version:      8.0.3
  Architecture: x64
  Commit:       9f4b1f5d66

.NET SDKs installed:
  8.0.103 [/usr/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 8.0.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 8.0.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

It was installed from Arch Linux repository.

And my .csproj file:

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

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

  <ItemGroup>
    <PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
  </ItemGroup>

</Project>
@Jisu-Woniu
Copy link
Author

Jisu-Woniu commented Mar 28, 2024

avx512f is supported on my CPU:

LANG=C lscpu | grep 512
Flags:   ... invpcid avx512f avx512dq rdseed adx smap avx512ifma ...

If I remove all avx-512* items from <PROJECT_DIR>/bin/Release/net8.0/<UUID>/BenchmarkDotNet.Autogenerated.csproj, it just compiles.

@adamsitnik
Copy link
Member

Hello @Jisu-Woniu

Could you please go to <PROJECT_DIR>/bin/Release/net8.0/136c2e4d-c592-4318-baf9-67ab64a593fc/BenchmarkDotNet.Autogenerated.csproj and share with us what value was used for the <IlcInstructionSet>$this</IlcInstructionSet> element?

It should be just native and in theory should just work (#2464). I just need to check if it's BenchmarkDotNet or NativeAOT bug.

@Jisu-Woniu
Copy link
Author

Jisu-Woniu commented Mar 30, 2024

I build it again and this is the content of bin/Release/net8.0/f58553a8-0c73-499a-98cc-5ad358f5fe53/BenchmarkDotNet.Autogenerated.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <RuntimeFrameworkVersion></RuntimeFrameworkVersion>
    <AssemblyName>f58553a8-0c73-499a-98cc-5ad358f5fe53</AssemblyName>
    <AssemblyTitle>f58553a8-0c73-499a-98cc-5ad358f5fe53</AssemblyTitle>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <PlatformTarget>x64</PlatformTarget>
    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
    <DebugSymbols>false</DebugSymbols>
    <UseSharedCompilation>false</UseSharedCompilation>
    <Deterministic>true</Deterministic>
    <RunAnalyzers>false</RunAnalyzers>
    <PublishAot Condition=" '$(TargetFramework)' != 'net6.0' ">true</PublishAot>
    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
    <TrimMode>link</TrimMode><TrimmerDefaultAction>link</TrimmerDefaultAction>
    <IlcGenerateCompleteTypeMetadata>True</IlcGenerateCompleteTypeMetadata>
    <IlcGenerateStackTraceData>True</IlcGenerateStackTraceData>
    <EnsureNETCoreAppRuntime>false</EnsureNETCoreAppRuntime> <!-- workaround for 'This runtime may not be supported by.NET Core.' error -->
    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles> <!-- workaround for 'Found multiple publish output files with the same relative path.' error -->
    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
    <IlcInstructionSet>base,sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,avx-512f,avx-512bw,avx-512cd,avx-512dq,avx-512vbmi,aes,bmi,bmi2,fma,lzcnt,pclmul,popcnt</IlcInstructionSet>
  </PropertyGroup>
  <PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
</PropertyGroup>

  <ItemGroup>
    <Compile Include="f58553a8-0c73-499a-98cc-5ad358f5fe53.notcs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
  </ItemGroup>
  <ItemGroup>
    
    <ProjectReference Include="<PROJECT_DIR>/Bench.csproj" />
  </ItemGroup>
  <ItemGroup>
    <RdXmlFile Include="bdn_generated.rd.xml" />
  </ItemGroup>
</Project>

Maybe because the Instruction set should be avx512** instead of avx-512**?

@Jisu-Woniu
Copy link
Author

Jisu-Woniu commented Mar 30, 2024

I could set the IlcInstructionSet field to native using the following code:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.NativeAot;

ManualConfig config = DefaultConfig.Instance.AddJob(
    Job.Default.WithToolchain(
        NativeAotToolchain.CreateBuilder().UseNuGet().IlcInstructionSet("native").ToToolchain()
    )
);

BenchmarkRunner.Run<MyBench>(config);

// Use custom runtime instead of the built-in one:
// [SimpleJob(RuntimeMoniker.NativeAot80)]
public class MyBench
{
    [Benchmark]
    public void Bench() { }
}

Generated .csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
    <ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <RuntimeFrameworkVersion></RuntimeFrameworkVersion>
    <AssemblyName>6bb876b0-44dd-4195-9707-766e8b87018a</AssemblyName>
    <AssemblyTitle>6bb876b0-44dd-4195-9707-766e8b87018a</AssemblyTitle>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <PlatformTarget>x64</PlatformTarget>
    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
    <DebugSymbols>false</DebugSymbols>
    <UseSharedCompilation>false</UseSharedCompilation>
    <Deterministic>true</Deterministic>
    <RunAnalyzers>false</RunAnalyzers>
    <PublishAot Condition=" '$(TargetFramework)' != 'net6.0' ">true</PublishAot>
    <IlcOptimizationPreference>Speed</IlcOptimizationPreference>
    <TrimMode>link</TrimMode><TrimmerDefaultAction>link</TrimmerDefaultAction>
    <IlcGenerateCompleteTypeMetadata>True</IlcGenerateCompleteTypeMetadata>
    <IlcGenerateStackTraceData>True</IlcGenerateStackTraceData>
    <EnsureNETCoreAppRuntime>false</EnsureNETCoreAppRuntime> <!-- workaround for 'This runtime may not be supported by.NET Core.' error -->
    <ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles> <!-- workaround for 'Found multiple publish output files with the same relative path.' error -->
    <ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
    <IlcInstructionSet>native</IlcInstructionSet>
  </PropertyGroup>
  <PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
</PropertyGroup>

  <ItemGroup>
    <Compile Include="6bb876b0-44dd-4195-9707-766e8b87018a.notcs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
  </ItemGroup>
  <ItemGroup>
    
    <ProjectReference Include="<PROJECT_DIR>/Bench.csproj" />
  </ItemGroup>
  <ItemGroup>
    <RdXmlFile Include="bdn_generated.rd.xml" />
  </ItemGroup>
</Project>

It can compile and produce correct result.

@adamsitnik
Copy link
Member

It can compile and produce correct result.

Big thanks for letting me know!

There must be some kind of bug here:

if (platform == RuntimeInformation.GetCurrentPlatform() // "native" does not support cross-compilation (so does BDN for now)
&& runtimeMoniker >= RuntimeMoniker.NativeAot80)
{
yield return "native"; // added in .NET 8 https://github.com/dotnet/runtime/pull/87865

I'll try to fix it after the weekend, I am glad you are unblocked for now.

@Jisu-Woniu
Copy link
Author

And maybe these should be replaced with avx512** too.

if (HardwareIntrinsics.IsX86Avx512FSupported) yield return "avx-512f";
if (HardwareIntrinsics.IsX86Avx512BWSupported) yield return "avx-512bw";
if (HardwareIntrinsics.IsX86Avx512CDSupported) yield return "avx-512cd";
if (HardwareIntrinsics.IsX86Avx512DQSupported) yield return "avx-512dq";
if (HardwareIntrinsics.IsX86Avx512VbmiSupported) yield return "avx-512vbmi";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants