runtime: NativeAOT on Graviton2 As `armv8.2-a` Fails to Execute
Description
When NativeAOT-compiling an application for deployment onto AWS Lambda, specifying IlcInstructionSet
with the known, documented supported instruction sets for Graviton2 processors fails to execute with the error message:
The required instruction sets are not supported by the current CPU.
Reproduction Steps
For a minimal reproduction, I’m using the code from maxday’s lambda-perf cold start–testing repository, but targeting .NET 8’s NativeAOT. The meaningful parts of that are:
public class Function
{
private static async Task Main()
{
await LambdaBootstrapBuilder.Create(FunctionHandler, new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>())
.Build()
.RunAsync();
}
public static StatusResponse FunctionHandler()
{
return new StatusResponse(statusCode: 200);
}
}
public record StatusResponse(int statusCode);
[JsonSerializable(typeof(StatusResponse))]
public partial class LambdaFunctionJsonSerializerContext : JsonSerializerContext
{
}
…and for .csproj settings:
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifier>linux-arm64</RuntimeIdentifier>
<PublishAot>true</PublishAot>
<AssemblyName>bootstrap</AssemblyName>
<IlcInstructionSet>armv8.2-a</IlcInstructionSet>
Expected behavior
Because Amazon’s Graviton2 processor is documented as revision 8.2-a with support for features “fp16, rcpc, dotprod, crypto” and ilc
doesn’t support “fp16” or “crypto”, I expected this:
<IlcInstructionSet>armv8.2-a,rcpc,dotprod</IlcInstructionSet>
…to compile and run. It compiled, but did not run. Figuring that maybe I was trying to add too much sauce, I tried:
<IlcInstructionSet>armv8.2-a</IlcInstructionSet>
…expecting this to compile and run. It compiled, but did not run.
Actual behavior
Upon execution, this error message is received:
The required instruction sets are not supported by the current CPU.
Regression?
No response
Known Workarounds
Leave off IlcInstructionSet
, implicitly targeting revision 8.0. This does compile (natch) and run.
Configuration
I am cross-compiling for arm64 in the Docker image mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-2.0-cross-arm64
:
~/.dotnet/dotnet publish -p:SysRoot=/crossrootfs/arm64 -p:LinkerFlavor=lld
dotnet --version
is “8.0.100-rc.1.23402.12”
Other information
I admit that I’m not certain this is a problem with the NativeAOT compiler, since I don’t know how to look into a binary and say “Aha, here is the incorrect instruction.”
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 19 (11 by maintainers)
Commits related to this issue
- Test arm64 build Testing a theory for #89937 — committed to dotnet/runtime by MichalStrehovsky a year ago
- Light up for newer arm64 hardware capabilities Fixes #89937 — committed to jkotas/runtime by jkotas a year ago
- Light up for newer arm64 hardware capabilities (#89991) Fixes #89937 — committed to dotnet/runtime by jkotas a year ago
I confirm that with SDK version 8.0.100-rc.1.23407.1 and:
…the problem is resolved. I don’t know what daily build will incorporate these versions into the SDK, but I can keep working with this. Thanks again.
I did a quick check in #89988 and this is a product-build-time issue. I think this is a general product issue, not Native AOT specific. If this
#define
is not set, we would not generate a check for this at all.Could you run some software that can list out supported CPU features on the machine (like for example https://github.com/google/cpu_features#quickstart)?
@EgorBo, @MichalStrehovsky, what do you think about dumping all the supported instruction sets in this error path:
https://github.com/dotnet/runtime/blob/c6fdf522b3cd07606456c3149488430228b99000/src/coreclr/nativeaot/Runtime/startup.cpp#L186-L190
“Supported instruction sets are: …”