Skip to content

Commit 439e44f

Browse files
committed
Add support for composite r2r runs
This is achieved by using already existing properties in the sdk: PublishReadyToRun and PublishReadyToRunComposite. The compositer2r toolchain adds these properties to a standar project template. In order to test with custom built runtime, the toolchain reuses the already existing `customruntimepack` and `aotcompilerpath` bdn args. Example command used locally from microbenchmarks project: dotnet run -c Release -f net10.0 --runtimes compositer2r10_0 --filter "System.Tests.Perf_Int32.TryFormat" --customruntimepack /home/vbrezae/runtime3/artifacts/bin/microsoft.netcore.app.runtime.linux-arm64/Release/ --aotcompilerpath /home/vbrezae/runtime3/artifacts/packages/Release/Shipping/crossgen2pack/
1 parent e6644d0 commit 439e44f

File tree

6 files changed

+209
-1
lines changed

6 files changed

+209
-1
lines changed

src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,15 @@ public enum RuntimeMoniker
248248
/// .NET 11 using MonoVM (not CLR which is the default)
249249
/// </summary>
250250
Mono11_0,
251+
252+
/// <summary>
253+
/// .NET 10 CLR with composite ReadyToRun compilation
254+
/// </summary>
255+
CompositeR2R10_0,
256+
257+
/// <summary>
258+
/// .NET 11 CLR with composite ReadyToRun compilation
259+
/// </summary>
260+
CompositeR2R11_0,
251261
}
252262
}

src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@
1818
using BenchmarkDotNet.Loggers;
1919
using BenchmarkDotNet.Portability;
2020
using BenchmarkDotNet.Reports;
21+
using BenchmarkDotNet.Toolchains.CompositeR2R;
2122
using BenchmarkDotNet.Toolchains.CoreRun;
2223
using BenchmarkDotNet.Toolchains.CsProj;
2324
using BenchmarkDotNet.Toolchains.DotNetCli;
2425
using BenchmarkDotNet.Toolchains.InProcess.Emit;
26+
using BenchmarkDotNet.Toolchains.Mono;
2527
using BenchmarkDotNet.Toolchains.MonoAotLLVM;
2628
using BenchmarkDotNet.Toolchains.MonoWasm;
2729
using BenchmarkDotNet.Toolchains.NativeAot;
2830
using CommandLine;
2931
using Perfolizer.Horology;
3032
using Perfolizer.Mathematics.OutlierDetection;
31-
using BenchmarkDotNet.Toolchains.Mono;
3233
using Perfolizer.Metrology;
3334

3435
namespace BenchmarkDotNet.ConsoleArguments
@@ -634,6 +635,10 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma
634635
case RuntimeMoniker.Mono11_0:
635636
return MakeMonoJob(baseJob, options, MonoRuntime.Mono11_0);
636637

638+
case RuntimeMoniker.CompositeR2R10_0:
639+
case RuntimeMoniker.CompositeR2R11_0:
640+
return CreateCompositeR2RJob(baseJob, options, runtimeMoniker.GetRuntime());
641+
637642
default:
638643
throw new NotSupportedException($"Runtime {runtimeId} is not supported");
639644
}
@@ -692,6 +697,21 @@ private static Job MakeMonoAOTLLVMJob(Job baseJob, CommandLineOptions options, s
692697
return baseJob.WithRuntime(monoAotLLVMRuntime).WithToolchain(toolChain).WithId(monoAotLLVMRuntime.Name);
693698
}
694699

700+
private static Job CreateCompositeR2RJob(Job baseJob, CommandLineOptions options, Runtime runtime)
701+
{
702+
var toolChain = CompositeR2RToolchain.From(
703+
new NetCoreAppSettings(
704+
targetFrameworkMoniker: runtime.MsBuildMoniker,
705+
runtimeFrameworkVersion: null,
706+
name: $"CompositeR2R {runtime.Name}",
707+
customDotNetCliPath: options.CliPath?.FullName,
708+
packagesPath: options.RestorePath?.FullName,
709+
customRuntimePack: options.CustomRuntimePack,
710+
aotCompilerPath: options.AOTCompilerPath != null ? options.AOTCompilerPath.ToString() : null));
711+
712+
return baseJob.WithRuntime(runtime).WithToolchain(toolChain).WithId("CompositeR2R");
713+
}
714+
695715
private static Job MakeWasmJob(Job baseJob, CommandLineOptions options, string msBuildMoniker, RuntimeMoniker moniker)
696716
{
697717
bool wasmAot = options.AOTCompilerMode == MonoAotCompilerMode.wasm;

src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker)
7474
return MonoRuntime.Mono10_0;
7575
case RuntimeMoniker.Mono11_0:
7676
return MonoRuntime.Mono11_0;
77+
case RuntimeMoniker.CompositeR2R10_0:
78+
return CoreRuntime.Core10_0;
79+
case RuntimeMoniker.CompositeR2R11_0:
80+
return CoreRuntime.Core11_0;
7781
default:
7882
throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "Runtime Moniker not supported");
7983
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<Project Sdk="Microsoft.NET.Sdk" DefaultTarget="Publish">
2+
3+
<!-- Properties same as standard CsProj.txt template -->
4+
<PropertyGroup>
5+
<ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
6+
<ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
7+
<AssemblyTitle>$PROGRAMNAME$</AssemblyTitle>
8+
<TargetFrameworks>$TFM$</TargetFrameworks>
9+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
10+
<PlatformTarget>$PLATFORM$</PlatformTarget>
11+
<AssemblyName>$PROGRAMNAME$</AssemblyName>
12+
<OutputType>Exe</OutputType>
13+
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
14+
<!-- Usage of System.Random can cause compilation errors if Code Analysis warnings are treated as Errors -->
15+
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
16+
<!-- disabled due to https://github.com/dotnet/roslyn/issues/59421 -->
17+
<DebugSymbols>false</DebugSymbols>
18+
<UseSharedCompilation>false</UseSharedCompilation>
19+
<CodeAnalysisRuleSet></CodeAnalysisRuleSet>
20+
<RunAnalyzers>false</RunAnalyzers>
21+
<Deterministic>true</Deterministic>
22+
<!-- needed for custom build configurations (only "Release" builds are optimized by default) -->
23+
<Optimize Condition=" '$(Configuration)' != 'Debug' ">true</Optimize>
24+
<!-- we set LangVersion after any copied settings which might contain LangVersion copied from the benchmarks project -->
25+
<LangVersion Condition="'$(LangVersion)' == '' Or ($([System.Char]::IsDigit('$(LangVersion)', 0)) And '$(LangVersion)' &lt; '7.3')">latest</LangVersion>
26+
<!-- fix for NETSDK1150: https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/5.0/referencing-executable-generates-error -->
27+
<ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
28+
<!-- Suppress warning for nuget package used in old (unsupported) tfm. -->
29+
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
30+
<StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>
31+
</PropertyGroup>
32+
33+
<PropertyGroup>
34+
<SelfContained>true</SelfContained>
35+
<RuntimeIdentifier>$RUNTIMEIDENTIFIER$</RuntimeIdentifier>
36+
<PublishReadyToRun>true</PublishReadyToRun>
37+
<PublishReadyToRunComposite>true</PublishReadyToRunComposite>
38+
</PropertyGroup>
39+
<ItemGroup>
40+
<!-- Temporary fix until https://github.com/dotnet/sdk/pull/52296 is resolved -->
41+
<PublishReadyToRunCompositeExclusions Include="Dia2Lib.dll" />
42+
<PublishReadyToRunCompositeExclusions Include="TraceReloggerLib.dll" />
43+
</ItemGroup>
44+
45+
<ItemGroup>
46+
<Compile Include="$CODEFILENAME$" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
47+
</ItemGroup>
48+
49+
<ItemGroup>
50+
<ProjectReference Include="$CSPROJPATH$" />
51+
</ItemGroup>
52+
53+
<!-- Begin copied settings from benchmarks project -->
54+
$COPIEDSETTINGS$
55+
<!-- End copied settings -->
56+
57+
<!-- The purpose of this project is to publish the app with r2r composite using a custom runtime pack and a custom crossgen2, built locally -->
58+
59+
<Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
60+
<ItemGroup>
61+
<RuntimePack>
62+
<PackageDirectory>$RUNTIMEPACK$</PackageDirectory>
63+
</RuntimePack>
64+
<Crossgen2Pack>
65+
<PackageDirectory>$CROSSGEN2PACK$</PackageDirectory>
66+
</Crossgen2Pack>
67+
</ItemGroup>
68+
</Target>
69+
</Project>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.IO;
2+
using System.Text;
3+
using System.Xml;
4+
using BenchmarkDotNet.Detectors;
5+
using BenchmarkDotNet.Extensions;
6+
using BenchmarkDotNet.Helpers;
7+
using BenchmarkDotNet.Loggers;
8+
using BenchmarkDotNet.Running;
9+
using BenchmarkDotNet.Toolchains.CsProj;
10+
using BenchmarkDotNet.Toolchains.DotNetCli;
11+
12+
namespace BenchmarkDotNet.Toolchains.CompositeR2R
13+
{
14+
public class CompositeR2RGenerator : CsProjGenerator
15+
{
16+
private readonly string CustomRuntimePack;
17+
private readonly string Crossgen2Pack;
18+
19+
public CompositeR2RGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string customRuntimePack, string crossgen2Pack)
20+
: base(targetFrameworkMoniker, cliPath, packagesPath, runtimeFrameworkVersion: null)
21+
{
22+
CustomRuntimePack = customRuntimePack;
23+
Crossgen2Pack = crossgen2Pack;
24+
}
25+
26+
protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)
27+
{
28+
BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase;
29+
var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);
30+
31+
var xmlDoc = new XmlDocument();
32+
xmlDoc.Load(projectFile.FullName);
33+
var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);
34+
35+
string content = new StringBuilder(ResourceHelper.LoadTemplate("CompositeR2RCsProj.txt"))
36+
.Replace("$PLATFORM$", buildPartition.Platform.ToConfig())
37+
.Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath))
38+
.Replace("$CSPROJPATH$", projectFile.FullName)
39+
.Replace("$TFM$", TargetFrameworkMoniker)
40+
.Replace("$PROGRAMNAME$", artifactsPaths.ProgramName)
41+
.Replace("$COPIEDSETTINGS$", customProperties)
42+
.Replace("$SDKNAME$", sdkName)
43+
.Replace("$RUNTIMEPACK$", CustomRuntimePack)
44+
.Replace("$CROSSGEN2PACK$", Crossgen2Pack)
45+
.Replace("$RUNTIMEIDENTIFIER$", CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier())
46+
.ToString();
47+
48+
File.WriteAllText(artifactsPaths.ProjectFilePath, content);
49+
50+
GatherReferences(projectFile.FullName, buildPartition, artifactsPaths, logger);
51+
}
52+
53+
protected override string GetExecutablePath(string binariesDirectoryPath, string programName)
54+
=> OsDetector.IsWindows()
55+
? Path.Combine(binariesDirectoryPath, $"{programName}.exe")
56+
: Path.Combine(binariesDirectoryPath, programName);
57+
58+
protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)
59+
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier(), "publish");
60+
}
61+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using BenchmarkDotNet.Characteristics;
2+
using BenchmarkDotNet.Running;
3+
using BenchmarkDotNet.Toolchains.CsProj;
4+
using BenchmarkDotNet.Toolchains.DotNetCli;
5+
using BenchmarkDotNet.Validators;
6+
using JetBrains.Annotations;
7+
using System;
8+
using System.Collections.Generic;
9+
10+
namespace BenchmarkDotNet.Toolchains.CompositeR2R
11+
{
12+
[PublicAPI]
13+
public class CompositeR2RToolchain : CsProjCoreToolchain, IEquatable<CompositeR2RToolchain>
14+
{
15+
private readonly string _customDotNetCliPath;
16+
private CompositeR2RToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)
17+
: base(name, generator, builder, executor, customDotNetCliPath)
18+
{
19+
_customDotNetCliPath = customDotNetCliPath;
20+
}
21+
22+
[PublicAPI]
23+
public static new IToolchain From(NetCoreAppSettings settings)
24+
=> new CompositeR2RToolchain(settings.Name,
25+
new CompositeR2RGenerator(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.CustomRuntimePack, settings.AOTCompilerPath),
26+
new DotNetCliPublisher(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath),
27+
new Executor(),
28+
settings.CustomDotNetCliPath);
29+
30+
public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)
31+
{
32+
foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(_customDotNetCliPath, benchmarkCase))
33+
{
34+
yield return validationError;
35+
}
36+
}
37+
38+
public override bool Equals(object obj) => obj is CompositeR2RToolchain typed && Equals(typed);
39+
40+
public bool Equals(CompositeR2RToolchain other) => Generator.Equals(other.Generator);
41+
42+
public override int GetHashCode() => Generator.GetHashCode();
43+
}
44+
}

0 commit comments

Comments
 (0)