Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,15 @@ public enum RuntimeMoniker
/// .NET 11 using MonoVM (not CLR which is the default)
/// </summary>
Mono11_0,

/// <summary>
/// .NET 10 CLR with composite ReadyToRun compilation
/// </summary>
CompositeR2R10_0,

/// <summary>
/// .NET 11 CLR with composite ReadyToRun compilation
/// </summary>
CompositeR2R11_0,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker)
case RuntimeMoniker.Net90:
case RuntimeMoniker.Net10_0:
case RuntimeMoniker.Net11_0:
case RuntimeMoniker.CompositeR2R10_0:
case RuntimeMoniker.CompositeR2R11_0:
return true;
case RuntimeMoniker.NotRecognized:
case RuntimeMoniker.Mono:
Expand Down
2 changes: 2 additions & 0 deletions src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker)
case RuntimeMoniker.Net90:
case RuntimeMoniker.Net10_0:
case RuntimeMoniker.Net11_0:
case RuntimeMoniker.CompositeR2R10_0:
case RuntimeMoniker.CompositeR2R11_0:
return true;
case RuntimeMoniker.NotRecognized:
case RuntimeMoniker.Mono:
Expand Down
22 changes: 21 additions & 1 deletion src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Toolchains.CompositeR2R;
using BenchmarkDotNet.Toolchains.CoreRun;
using BenchmarkDotNet.Toolchains.CsProj;
using BenchmarkDotNet.Toolchains.DotNetCli;
Expand Down Expand Up @@ -641,6 +642,10 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma
case RuntimeMoniker.Mono11_0:
return MakeMonoJob(baseJob, options, MonoRuntime.Mono11_0);

case RuntimeMoniker.CompositeR2R10_0:
case RuntimeMoniker.CompositeR2R11_0:
return CreateCompositeR2RJob(baseJob, options, runtimeMoniker.GetRuntime());

default:
throw new NotSupportedException($"Runtime {runtimeId} is not supported");
}
Expand Down Expand Up @@ -703,6 +708,21 @@ private static Job MakeMonoAOTLLVMJob(Job baseJob, CommandLineOptions options, s
return baseJob.WithRuntime(monoAotLLVMRuntime).WithToolchain(toolChain).WithId(monoAotLLVMRuntime.Name);
}

private static Job CreateCompositeR2RJob(Job baseJob, CommandLineOptions options, Runtime runtime)
{
var toolChain = CompositeR2RToolchain.From(
new NetCoreAppSettings(
targetFrameworkMoniker: runtime.MsBuildMoniker,
runtimeFrameworkVersion: null,
name: $"CompositeR2R {runtime.Name}",
customDotNetCliPath: options.CliPath?.FullName,
packagesPath: options.RestorePath?.FullName,
customRuntimePack: options.CustomRuntimePack,
aotCompilerPath: options.AOTCompilerPath != null ? options.AOTCompilerPath.ToString() : null));

return baseJob.WithRuntime(runtime).WithToolchain(toolChain).WithId("CompositeR2R");
}

private static Job MakeWasmJob(Job baseJob, CommandLineOptions options, string msBuildMoniker, RuntimeMoniker moniker)
{
bool wasmAot = options.AOTCompilerMode == MonoAotCompilerMode.wasm;
Expand Down Expand Up @@ -827,4 +847,4 @@ internal static bool TryParse(string runtime, out RuntimeMoniker runtimeMoniker)
return Enum.TryParse(runtime.Replace('.', '_'), ignoreCase: true, out runtimeMoniker);
}
}
}
}
4 changes: 4 additions & 0 deletions src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker)
return MonoRuntime.Mono10_0;
case RuntimeMoniker.Mono11_0:
return MonoRuntime.Mono11_0;
case RuntimeMoniker.CompositeR2R10_0:
return CoreRuntime.Core10_0;
case RuntimeMoniker.CompositeR2R11_0:
return CoreRuntime.Core11_0;
default:
throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "Runtime Moniker not supported");
}
Expand Down
69 changes: 69 additions & 0 deletions src/BenchmarkDotNet/Templates/CompositeR2RCsProj.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<Project Sdk="Microsoft.NET.Sdk" DefaultTarget="Publish">

<!-- Properties same as standard CsProj.txt template -->
<PropertyGroup>
<ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
<ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>
<AssemblyTitle>$PROGRAMNAME$</AssemblyTitle>
<TargetFrameworks>$TFM$</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PlatformTarget>$PLATFORM$</PlatformTarget>
<AssemblyName>$PROGRAMNAME$</AssemblyName>
<OutputType>Exe</OutputType>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
<!-- Usage of System.Random can cause compilation errors if Code Analysis warnings are treated as Errors -->
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
<!-- disabled due to https://github.com/dotnet/roslyn/issues/59421 -->
<DebugSymbols>false</DebugSymbols>
<UseSharedCompilation>false</UseSharedCompilation>
<CodeAnalysisRuleSet></CodeAnalysisRuleSet>
<RunAnalyzers>false</RunAnalyzers>
<Deterministic>true</Deterministic>
<!-- needed for custom build configurations (only "Release" builds are optimized by default) -->
<Optimize Condition=" '$(Configuration)' != 'Debug' ">true</Optimize>
<!-- we set LangVersion after any copied settings which might contain LangVersion copied from the benchmarks project -->
<LangVersion Condition="'$(LangVersion)' == '' Or ($([System.Char]::IsDigit('$(LangVersion)', 0)) And '$(LangVersion)' &lt; '7.3')">latest</LangVersion>
<!-- fix for NETSDK1150: https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/5.0/referencing-executable-generates-error -->
<ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
<!-- Suppress warning for nuget package used in old (unsupported) tfm. -->
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<StartupObject>BenchmarkDotNet.Autogenerated.UniqueProgramName</StartupObject>
</PropertyGroup>

<PropertyGroup>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>$RUNTIMEIDENTIFIER$</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
<PublishReadyToRunComposite>true</PublishReadyToRunComposite>
</PropertyGroup>
<ItemGroup>
<!-- Temporary fix until https://github.com/dotnet/sdk/pull/52296 is resolved -->
<PublishReadyToRunCompositeExclusions Include="Dia2Lib.dll" />
<PublishReadyToRunCompositeExclusions Include="TraceReloggerLib.dll" />
</ItemGroup>

<ItemGroup>
<Compile Include="$CODEFILENAME$" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$CSPROJPATH$" />
</ItemGroup>

<!-- Begin copied settings from benchmarks project -->
$COPIEDSETTINGS$
<!-- End copied settings -->

<!-- The purpose of this project is to publish the app with r2r composite using a custom runtime pack and a custom crossgen2, built locally -->

<Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
<ItemGroup>
<RuntimePack>
<PackageDirectory>$RUNTIMEPACK$</PackageDirectory>
</RuntimePack>
<Crossgen2Pack>
<PackageDirectory>$CROSSGEN2PACK$</PackageDirectory>
</Crossgen2Pack>
</ItemGroup>
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.IO;
using System.Text;
using System.Xml;
using BenchmarkDotNet.Detectors;
using BenchmarkDotNet.Extensions;
using BenchmarkDotNet.Helpers;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.CsProj;
using BenchmarkDotNet.Toolchains.DotNetCli;

namespace BenchmarkDotNet.Toolchains.CompositeR2R
{
public class CompositeR2RGenerator : CsProjGenerator
{
private readonly string CustomRuntimePack;
private readonly string Crossgen2Pack;

public CompositeR2RGenerator(string targetFrameworkMoniker, string cliPath, string packagesPath, string customRuntimePack, string crossgen2Pack)
: base(targetFrameworkMoniker, cliPath, packagesPath, runtimeFrameworkVersion: null)
{
CustomRuntimePack = customRuntimePack;
Crossgen2Pack = crossgen2Pack;
BenchmarkRunCallType = Code.CodeGenBenchmarkRunCallType.Direct;
}

protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger)
{
BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase;
var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger);

var xmlDoc = new XmlDocument();
xmlDoc.Load(projectFile.FullName);
var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile);

string content = new StringBuilder(ResourceHelper.LoadTemplate("CompositeR2RCsProj.txt"))
.Replace("$PLATFORM$", buildPartition.Platform.ToConfig())
.Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath))
.Replace("$CSPROJPATH$", projectFile.FullName)
.Replace("$TFM$", TargetFrameworkMoniker)
.Replace("$PROGRAMNAME$", artifactsPaths.ProgramName)
.Replace("$COPIEDSETTINGS$", customProperties)
.Replace("$SDKNAME$", sdkName)
.Replace("$RUNTIMEPACK$", CustomRuntimePack)
.Replace("$CROSSGEN2PACK$", Crossgen2Pack)
.Replace("$RUNTIMEIDENTIFIER$", CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier())
.ToString();

File.WriteAllText(artifactsPaths.ProjectFilePath, content);

GatherReferences(buildPartition, artifactsPaths, logger);
}

protected override string GetExecutablePath(string binariesDirectoryPath, string programName)
=> OsDetector.IsWindows()
? Path.Combine(binariesDirectoryPath, $"{programName}.exe")
: Path.Combine(binariesDirectoryPath, programName);

protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration)
=> Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker, CustomDotNetCliToolchainBuilder.GetPortableRuntimeIdentifier(), "publish");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using BenchmarkDotNet.Characteristics;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.CsProj;
using BenchmarkDotNet.Toolchains.DotNetCli;
using BenchmarkDotNet.Validators;
using JetBrains.Annotations;
using System;
using System.Collections.Generic;

namespace BenchmarkDotNet.Toolchains.CompositeR2R
{
[PublicAPI]
public class CompositeR2RToolchain : CsProjCoreToolchain, IEquatable<CompositeR2RToolchain>
{
private readonly string _customDotNetCliPath;
private CompositeR2RToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath)
: base(name, generator, builder, executor, customDotNetCliPath)
{
_customDotNetCliPath = customDotNetCliPath;
}

[PublicAPI]
public static new IToolchain From(NetCoreAppSettings settings)
=> new CompositeR2RToolchain(settings.Name,
new CompositeR2RGenerator(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath, settings.PackagesPath, settings.CustomRuntimePack, settings.AOTCompilerPath),
new DotNetCliPublisher(settings.TargetFrameworkMoniker, settings.CustomDotNetCliPath),
new Executor(),
settings.CustomDotNetCliPath);

public override IEnumerable<ValidationError> Validate(BenchmarkCase benchmarkCase, IResolver resolver)
{
foreach (var validationError in DotNetSdkValidator.ValidateCoreSdks(_customDotNetCliPath, benchmarkCase))
{
yield return validationError;
}
}

public override bool Equals(object obj) => obj is CompositeR2RToolchain typed && Equals(typed);

public bool Equals(CompositeR2RToolchain other) => Generator.Equals(other.Generator);

public override int GetHashCode() => Generator.GetHashCode();
}
}
Loading