BenchmarkDotNet icon indicating copy to clipboard operation
BenchmarkDotNet copied to clipboard

Source Generators based Toolchain

Open adamsitnik opened this issue 4 years ago • 13 comments

From the .NET Team perspective we quite often hit some build-related issues that require us to change BDN source code and update to latest version. This is especially painful with the WASM toolchain which needs to catch up with a very quickly envolving WASM project build requirements. (cc @naricc @radekdoulik @Lxiamail) It's also a problem for early .NET adopters like ASP.NET Team (cc @halter73 @sebastienros @davidfowl) and projects that use a lot of custom MSBuild settings like ML.NET (@eerhardt).

BDN also lacks the possibility to build the benchmarks on one machine, copy it to a different machine that has no .NET SDK installed and run them there (cc @billwert @drewscoggins @ig-sinicyn).

I'be been thinking about it for a while and I believe that we could solve both problems by implementing a toolchain that takes advantage of C# Source Generators. The idea I have is following:

  1. Use source generators to generate the boilerplate code (in theory all custom MSBuild setting works OOTB)
  2. The host process starts new benchmarks by using it's own exe path, but with a different set of arguments that are recognized and translated to "find selected benchmark in the assembly and run it".
  3. Users should be allowed to specify the runner exe path and args without modifying BDN. Example: V8 for WASM, CoreRun for dotnet/runtime builds.

It would defnitely not become the default toolchain (at least for now) because of the following limitations:

  • no F# support (me and @AndreyAkinshin care about F#)
  • no ability to run benchmarks for a different runtime (no --runtimes support)

I am also not sure what would be the performance of C# Source Generators in case of dotnet/performance Microbenchmarks.csproj that contains 3.5k benchmarks (the boilerplate generated with the existing toolchains in dotnet/performance is more than one million lines of source code and Roslyn fails with OOTM for x86 when we try to run all the benchmarks).

cc @jeffhandley @danmoseley

adamsitnik avatar Aug 11 '21 12:08 adamsitnik

Hi Adam,

I believe you wanted to have another David Fowler on this thread.

Regards, Dave

On Aug 11, 2021, at 6:11 AM, Adam Sitnik @.***> wrote:

 From the .NET Team perspective we quite often hit some build-related issues that require us to change BDN source code and update to latest version. This is especially painful with the WASM toolchain which needs to catch up with a very quickly envolving WASM project build requirements. (cc @naricc @radekdoulik @Lxiamail) It's also a problem for early .NET adopters like ASP.NET Team (cc @halter73 @sebastienros @DavidFowler) and projects that use a lot of custom MSBuild settings like ML.NET @.***).

BDN also lacks the possibility to build the benchmarks on one machine, copy it to a different machine that has no .NET SDK installed and run them there (cc @billwert @DrewScoggins @ig-sinicyn).

I'be been thinking about it for a while and I believe that we could solve both problems by implementing a toolchain that takes advantage of C# Source Generators. The idea I have is following:

Use source generators to generate the boilerplate code (in theory all custom MSBuild setting works OOTB) The host process starts new benchmarks by using it's own exe path, but with a different set of arguments that are recognized and translated to "find selected benchmark in the assembly and run it". Users should be allowed to specify the runner exe path and args without modifying BDN. Example: V8 for WASM, CoreRun for dotnet/runtime builds. It would defnitely not become the default toolchain (at least for now) because of the following limitations:

no F# support (me and @AndreyAkinshin care about F#) no ability to run benchmarks for a different runtime (no --runtimes support) I am also not sure what would be the performance of C# Source Generators in case of dotnet/performance Microbenchmarks.csproj that contains 3.5k benchmarks (the boilerplate generated with the existing toolchains in dotnet/performance is more than one million lines of source code and Roslyn fails with OOTM for x86 when we try to run all the benchmarks).

cc @jeffhandley @danmoseley

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

DavidFowler avatar Aug 11 '21 14:08 DavidFowler

@davidfowl

danmoseley avatar Aug 11 '21 14:08 danmoseley

Almost all the trouble I've had around wasm has been around SDK changes or changes to the all the build infrastructure around wasm apps (like, how to use the AOT compiler, how to bundle a wasm app, etc). So I am not sure I understand how source generators help?

naricc avatar Aug 11 '21 17:08 naricc

So I am not sure I understand how source generators help?

Instead of applying the fix in BDN logic that generates project files you would fix the project file in dotnet/performance.

adamsitnik avatar Aug 11 '21 18:08 adamsitnik

@adamsitnik So I am planning to start work on this soon, and am thinking about the design now. I've never done anything with source generators before and want to make sure I understand the idea.

We want to have a tool chain in BDN that calls into generated code, right? With the generated code eventually produced by clients (like the Microbenchmark harness in dotnet/performance).

I am also not sure what you meant in point 2. above:

The host process starts new benchmarks by using it's own exe path, but with a different set of arguments that are recognized and translated to "find selected benchmark in the assembly and run it.

Is that only for remote runs?

naricc avatar Jan 18 '22 21:01 naricc

I think you have the wrong David Fowler. I'm not involved in this project.

Regards, Dave

On Tue, Jan 18, 2022 at 2:16 PM Nathan Ricci @.***> wrote:

@adamsitnik https://github.com/adamsitnik So I am planning to start work on this soon, and am thinking about the design now. I've never done anything with source generators before and want to make sure I understand the idea.

We want to have a tool chain in BDN that calls into generated code, right? With the generated code eventually produced by clients (like the Microbenchmark harness in dotnet/performance).

I am also not sure what you meant in point 2. above:

The host process starts new benchmarks by using it's own exe path, but with a different set of arguments that are recognized and translated to "find selected benchmark in the assembly and run it.

Is that only for remote runs?

— Reply to this email directly, view it on GitHub https://github.com/dotnet/BenchmarkDotNet/issues/1770#issuecomment-1015840810, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGZDZX3LR3AS3424ORODI6TUWXKDJANCNFSM5B6KRJNA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

-- Dave Fowler Partner Solutions Engineering | @.*** | m +1 303 888 5055 Read our Technical blog: blog https://blog.cloudera.com/category/technical/ .cloudera.com/category/technical/ https://blog.cloudera.com/category/technical/

DavidFowler avatar Jan 18 '22 21:01 DavidFowler

Sorry @DavidFowler (but welcome to our project 😉)

@DavidFowl was intended

danmoseley avatar Jan 18 '22 23:01 danmoseley

@DavidFowler as you probably know, you can hit unsubscribe, either on this page on the right side, or using the link in the email you may have gotten.

danmoseley avatar Jan 18 '22 23:01 danmoseley

Adding @radical to the discussion. He is working on the wasm host app prototype, which might provide some of the functionality you are looking for?

radekdoulik avatar Jan 19 '22 11:01 radekdoulik

The host process starts new benchmarks by using it's own exe path, but with a different set of arguments that are recognized and translated to "find selected benchmark in the assembly and run it".

I think we should have an in-process option for that, too.

timcassell avatar Oct 19 '22 12:10 timcassell

Hey, I recently fought quite a bit with custom toolchain and runtime, and I'm also very supportive of a source generator approach! 😊

@adamsitnik one question I was wondering when also looking around about a related issue like #1403: as I understand it, a source generator approach could avoid entirely to generate separate csprojs (and the complication of replicating the build to a different folder as it is suggested in 1403), is that what you had in mind?

xoofx avatar May 14 '23 14:05 xoofx

is that what you had in mind?

Exactly!

adamsitnik avatar May 17 '23 09:05 adamsitnik