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

[ProfiledAOT] Update workflow to profile apps #9267

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
-->
<ImportGroup Condition=" '$(MonoAOTCompilerTasksAssemblyPath)' == '' and '$(AotAssemblies)' == 'true' ">
<Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoAOTCompiler.Task" />
<Import Project="Sdk.props" Sdk="Microsoft.NET.Runtime.MonoTargets.Task" />
<Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x86" />
<Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-x64" />
<Import Project="Sdk.props" Sdk="Microsoft.NETCore.App.Runtime.AOT.Cross.android-arm" />
Expand All @@ -39,7 +40,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).

<Target Name="_AndroidAot"
Condition=" '$(AotAssemblies)' == 'true' and '$(RuntimeIdentifier)' != '' "
DependsOnTargets="_CreatePropertiesCache;_AndroidAotInputs;_AndroidAotCompilation">
DependsOnTargets="_CreatePropertiesCache;_AndroidAotInputs;_AndroidBeforeAotCompilation;_AndroidAotCompilation">
<ReadLinesFromFile File="$(_AndroidStampDirectory)_AndroidAot.stamp">
<Output TaskParameter="Lines" ItemName="_AotCompiledAssemblies" />
</ReadLinesFromFile>
Expand Down Expand Up @@ -71,9 +72,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
</ItemGroup>
</Target>

<Target Name="_AndroidAotCompilation"
Inputs="@(_AndroidAotInputs)"
Outputs="$(_AndroidStampDirectory)_AndroidAot.stamp">
<Target Name="_AndroidGetAotAssemblies">
<ItemGroup>
<AndroidAotProfile Include="$(MSBuildThisFileDirectory)dotnet.aotprofile" Condition=" '$(AndroidEnableProfiledAot)' == 'true' and '$(AndroidUseDefaultAotProfile)' != 'false' " />
</ItemGroup>
Expand All @@ -89,7 +88,6 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
AotOutputDirectory="$(_AndroidAotBinDirectory)"
RuntimeIdentifier="$(RuntimeIdentifier)"
EnableLLVM="$(EnableLLVM)"
Profiles="@(AndroidAotProfile)"
StripLibraries="$(_AndroidAotStripLibraries)"
ZipAlignmentPages="$(AndroidZipAlignment)">
<Output PropertyName="_Triple" TaskParameter="Triple" />
Expand All @@ -102,11 +100,37 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
<ItemGroup Condition=" '$(AndroidExtraAotOptions)' != '' ">
<_MonoAOTAssemblies Update="@(_MonoAOTAssemblies)" ProcessArguments="$(AndroidExtraAotOptions)" />
</ItemGroup>
</Target>

<Target Name="_AndroidPrepareProfiledAot"
Condition="'$(AndroidEnableProfiledAot)' == 'true' and '$(NetTraceFilePath)' != '' and '$(DotnetPgoToolPath)' != '' and '$(AotAssemblies)' == 'true' and '$(AndroidAotMode)' != 'Full'">
<PropertyGroup>
<_ToolPath>$([System.IO.Path]::GetDirectoryName('$(DotnetPgoToolPath)'))</_ToolPath>
</PropertyGroup>

<NetTraceToMibcConverter
ToolPath="$(_ToolPath)"
Assemblies="@(_MonoAOTAssemblies)"
NetTraceFilePath="$(NetTraceFilePath)"
OutputDir="$(IntermediateOutputPath)">
<Output TaskParameter="MibcFilePath" ItemName="ProfiledAOTProfilePaths" />
</NetTraceToMibcConverter>
</Target>

<Target Name="_AndroidBeforeAotCompilation" DependsOnTargets="_AndroidGetAotAssemblies;_AndroidPrepareProfiledAot" />

<Target Name="_AndroidAotCompilation"
Inputs="@(_AndroidAotInputs)"
Outputs="$(_AndroidStampDirectory)_AndroidAot.stamp"
DependsOnTargets="_AndroidBeforeAotCompilation">
<PropertyGroup>
<_MonoAOTCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier', '$(RuntimeIdentifier)'))</_MonoAOTCompilerPath>
<_LLVMPath Condition=" '$(EnableLLVM)' == 'true' ">$([System.IO.Path]::GetDirectoryName ('$(_MonoAOTCompilerPath)'))</_LLVMPath>
</PropertyGroup>
<MakeDir Directories="$(IntermediateOutputPath)aot\" />
<ItemGroup>
<ProfiledAOTProfilePaths Include="$(MibcFilePath)" />
</ItemGroup>
<MonoAOTCompiler
Triple="$(_Triple)"
ToolPrefix="$(_ToolPrefix)"
Expand All @@ -126,6 +150,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
LdFlags="$(_LdFlags)"
CollectTrimmingEligibleMethods="$(AndroidStripILAfterAOT)"
TrimmingEligibleMethodsOutputDirectory="$(IntermediateOutputPath)tokens"
MibcProfilePath="@(ProfiledAOTProfilePaths)"
WorkingDirectory="$(MSBuildProjectDirectory)"
AotArguments="$(AndroidAotAdditionalArguments)">
<Output TaskParameter="CompiledAssemblies" ItemName="_MonoAOTCompiledAssemblies" />
Expand Down
7 changes: 6 additions & 1 deletion src/profiled-aot/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
<Configuration>Release</Configuration>
<AndroidNeedsInternetPermission>true</AndroidNeedsInternetPermission>
<AndroidEnableAotProfiler>true</AndroidEnableAotProfiler>
<RunAOTCompilation>false</RunAOTCompilation>
<!-- We are using culture-aware/default overloads on purpose -->
<NoWarn>$(NoWarn);CA1305</NoWarn>
</PropertyGroup>

<PropertyGroup>
<RunAOTCompilation>false</RunAOTCompilation> <!-- Set to true to run AOT compilation -->
<!-- <NetTraceFilePath>$(MSBuildThisFileDirectory)obj/android/dotnet-dsrouter_20240912_151653.nettrace</NetTraceFilePath> -->
<!-- <DotnetPgoToolPath></DotnetPgoToolPath> -->
</PropertyGroup>

<Import Project="../../Directory.Build.props" />
<Import Project="../../Configuration.props" />
Expand Down
56 changes: 2 additions & 54 deletions src/profiled-aot/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,56 +1,4 @@
<Project>
<PropertyGroup>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidUseDefaultAotProfile>false</AndroidUseDefaultAotProfile>
<MauiUseDefaultAotProfile>false</MauiUseDefaultAotProfile>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)CommonMethods.cs" />
<AndroidAotProfile Include="custom.aprof" />
<PackageReference Include="Mono.AotProfiler.Android" Version="7.0.0-preview1" />
</ItemGroup>
<PropertyGroup>
<RecordDependsOn>
Clean;
_ClearSystemProperties;
BuildAndStartAotProfiling;
_Sleep;
FinishAotProfiling;
_StripAppMethods;
_SaveMethodNames;
</RecordDependsOn>
</PropertyGroup>
<Target Name="Record" DependsOnTargets="$(RecordDependsOn)">
<Message Importance="High" Text="Success! See changes in: $(MSBuildThisFileDirectory)dotnet.aotprofile" />
</Target>
<Target Name="_ClearSystemProperties" DependsOnTargets="_ResolveMonoAndroidSdks">
<!-- Clear debug.mono.log in case it was set -->
<Exec Command="&quot;$(AdbToolPath)adb&quot; shell &quot;setprop debug.mono.log ''&quot;" />
</Target>
<Target Name="_Sleep">
<Sleep Delay="5000" />
</Target>
<UsingTask TaskName="Sleep"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Delay ParameterType="System.Int32" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
System.Threading.Thread.Sleep(this.Delay);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="_StripAppMethods">
<!-- This removes HelloAndroid.dll from the profile, as user's apps will have a different name -->
<Exec Command="&quot;$(DotNetPreviewTool)&quot; &quot;$(AotProfileToolPath)&quot; -sd --filter-module=&quot;^(?!$(App)).+&quot; &quot;$(MSBuildProjectDirectory)/custom.aprof&quot; -o &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile&quot;" />
</Target>
<Target Name="_SaveMethodNames">
<!-- This saves all the method names to a text file, so we can see a diff over time -->
<Exec Command="&quot;$(DotNetPreviewTool)&quot; &quot;$(AotProfileToolPath)&quot; -m &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile&quot; > &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile.txt&quot;" />
</Target>
<Import Project="$(MSBuildThisFileDirectory)old.profiler.targets" />
<Import Project="$(MSBuildThisFileDirectory)new.profiler.targets" />
</Project>
59 changes: 48 additions & 11 deletions src/profiled-aot/build.proj
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
<Project DefaultTargets="Record">
<Project DefaultTargets="LegacyRecordProfile">
<Import Project="Directory.Build.props" />
<PropertyGroup>
<!-- The template name -->
<App Condition=" '$(App)' == '' ">android</App>
<RuntimeIdentifier Condition=" '$(RuntimeIdentifier)' == '' ">android-arm64</RuntimeIdentifier>
<App Condition="'$(App)' == ''">android</App>
<Intermediate>obj/$(App)/</Intermediate>
<CSProj>$(Intermediate)$(App).csproj</CSProj>
<RuntimeIdentifier Condition=" '$(RuntimeIdentifier)' == '' ">android-arm64</RuntimeIdentifier>
<_RecordProfileDependsOnTargets>
_CheckDiagnosticsTools;
_SetupAppForProfiling;
_Restore;
</_RecordProfileDependsOnTargets>
<_LegacyRecordProfileDependsOnTargets>
_SetupAppForProfiling;
_Restore;
</_LegacyRecordProfileDependsOnTargets>
</PropertyGroup>
<Target Name="Record">
<RemoveDir Directories="$(Intermediate)" />
<Exec Command="&quot;$(DotNetPreviewTool)&quot; new $(App) -o $(Intermediate)" EnvironmentVariables="DOTNET_MULTILEVEL_LOOKUP=0" />
<!-- Copy replacement files-->

<Target Name="_CheckDiagnosticsTools">
<Exec Command="$(DotNetPreviewTool) tool list -g | grep dotnet-trace" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="TraceToolInstalled" />
</Exec>
<Error Condition="'$(TraceToolInstalled)' != '0'" Text="dotnet-trace tool is not installed. Please install it using 'dotnet tool install -g dotnet-trace'." />

<Exec Command="$(DotNetPreviewTool) tool list -g | grep dotnet-dsrouter" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="DsRouterToolInstalled" />
</Exec>
<Error Condition="'$(DsRouterToolInstalled)' != '0'" Text="dotnet-dsrouter tool is not installed. Please install it using 'dotnet tool install -g dotnet-dsrouter'." />
</Target>

<Target Name="_SetupAppForProfiling">
<PropertyGroup>
<EnvVars>DOTNET_MULTILEVEL_LOOKUP=0</EnvVars>
</PropertyGroup>
<ItemGroup>
<_FilesToCopy Include="$(App)/*" />
<_FilesToCopy Include="src/$(App)/*" />
</ItemGroup>

<RemoveDir Directories="$(Intermediate)" />

<Exec Command="$(DotNetPreviewTool) new $(App) -o $(Intermediate)" EnvironmentVariables="$(EnvVars)" />

<!-- Copy replacement files-->
<Copy SourceFiles="@(_FilesToCopy)" DestinationFolder="$(Intermediate)" />
<!-- Restore as a separate step due to: https://github.com/dotnet/sdk/issues/21877 -->
</Target>

<!-- Restore as a separate step due to: https://github.com/dotnet/sdk/issues/21877 -->
<Target Name="_Restore" DependsOnTargets="_SetupAppForProfiling">
<MSBuild Projects="$(CSProj)" Targets="Restore" />
<MSBuild Projects="$(CSProj)" Targets="Record" Properties="App=$(App);RuntimeIdentifier=$(RuntimeIdentifier)" />
</Target>

<Target Name="RecordProfile" DependsOnTargets="$(_RecordProfileDependsOnTargets)">
<MSBuild Projects="$(CSProj)" Targets="Record" Properties="App=$(App);RuntimeIdentifier=$(RuntimeIdentifier);AndroidEnableProfiler=true" />
</Target>

<Target Name="LegacyRecordProfile" DependsOnTargets="$(_LegacyRecordProfileDependsOnTargets)">
<MSBuild Projects="$(CSProj)" Targets="LegacyRecord" Properties="App=$(App);RuntimeIdentifier=$(RuntimeIdentifier)" />
</Target>
</Project>
37 changes: 37 additions & 0 deletions src/profiled-aot/new.profiler.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Project>
<PropertyGroup>
<_RecordDependsOnTargets>
Clean;
Build;
Install;
_ProfileApp;
Uninstall;
</_RecordDependsOnTargets>
<_ProfileAppDependsOnTargets>
_ResolveMonoAndroidSdks; <!-- _ResolveMonoAndroidSdks resolves AdbToolPath -->
_SetupDiagnosticsTracingProperties;
StartAndroidActivity;
_StartTracing;
StopAndroidPackage;
</_ProfileAppDependsOnTargets>
<StartProfilingScript>$(MSBuildThisFileDirectory)recordTrace.sh</StartProfilingScript>
</PropertyGroup>

<Target Name="_SetupDiagnosticsTracingProperties">
<Exec Command="$(AdbToolPath)adb reverse tcp:9000 tcp:9001" />
<Exec Command="$(AdbToolPath)adb shell setprop debug.mono.profile '127.0.0.1:9000,suspend,connect'" />
</Target>

<Target Name="_StartTracing" DependsOnTargets="$(_ResolveAndroidTooling)">
<PropertyGroup>
<AndroidSdkRoot Condition="'$(AndroidSdkPath)' != ''">ANDROID_SDK_ROOT=$(AndroidSdkPath)</AndroidSdkRoot>
</PropertyGroup>
<Exec Command="$(StartProfilingScript) $(DotNetToolPath)" EnvironmentVariables="$(AndroidSdkRoot)" />
</Target>

<Target Name="_ProfileApp" DependsOnTargets="$(_ProfileAppDependsOnTargets)" />

<Target Name="Record" DependsOnTargets="$(_RecordDependsOnTargets)">
<Message Importance="High" Text="Success! See changes in: $(_MauiAOTProfileLocation)$(App).aotprofile" />
</Target>
</Project>
56 changes: 56 additions & 0 deletions src/profiled-aot/old.profiler.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<Project>
<PropertyGroup>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<AndroidUseDefaultAotProfile>false</AndroidUseDefaultAotProfile>
<MauiUseDefaultAotProfile>false</MauiUseDefaultAotProfile>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)CommonMethods.cs" />
<AndroidAotProfile Include="custom.aprof" />
<PackageReference Include="Mono.AotProfiler.Android" Version="7.0.0-preview1" />
</ItemGroup>
<PropertyGroup>
<LegacyRecordDependsOn>
Clean;
_ClearSystemProperties;
BuildAndStartAotProfiling;
_Sleep;
FinishAotProfiling;
_StripAppMethods;
_SaveMethodNames;
</LegacyRecordDependsOn>
</PropertyGroup>
<Target Name="LegacyRecord" DependsOnTargets="$(LegacyRecordDependsOn)">
<Message Importance="High" Text="Success! See changes in: $(MSBuildThisFileDirectory)dotnet.aotprofile" />
</Target>
<Target Name="_ClearSystemProperties" DependsOnTargets="_ResolveMonoAndroidSdks">
<!-- Clear debug.mono.log in case it was set -->
<Exec Command="&quot;$(AdbToolPath)adb&quot; shell &quot;setprop debug.mono.log ''&quot;" />
</Target>
<Target Name="_Sleep">
<Sleep Delay="5000" />
</Target>
<UsingTask TaskName="Sleep"
TaskFactory="RoslynCodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<Delay ParameterType="System.Int32" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
System.Threading.Thread.Sleep(this.Delay);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="_StripAppMethods">
<!-- This removes HelloAndroid.dll from the profile, as user's apps will have a different name -->
<Exec Command="&quot;$(DotNetPreviewTool)&quot; &quot;$(AotProfileToolPath)&quot; -sd --filter-module=&quot;^(?!$(App)).+&quot; &quot;$(MSBuildProjectDirectory)/custom.aprof&quot; -o &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile&quot;" />
</Target>
<Target Name="_SaveMethodNames">
<!-- This saves all the method names to a text file, so we can see a diff over time -->
<Exec Command="&quot;$(DotNetPreviewTool)&quot; &quot;$(AotProfileToolPath)&quot; -m &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile&quot; > &quot;$(MSBuildThisFileDirectory)dotnet.aotprofile.txt&quot;" />
</Target>
</Project>
34 changes: 34 additions & 0 deletions src/profiled-aot/recordTrace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
dotnet="$1"

# Get the PID of dotnet-dsrouter
dsrouter_pid=$(pgrep -f "dotnet dsrouter")

if [ -z "$dsrouter_pid" ]; then
dotnet dsrouter android > >(while IFS= read -r line
do
# Print the line to the terminal
echo "$line"
# Check if the line contains 'pid='
if [[ $line == *"pid="* ]]; then
# Extract the PID value
pid_value=$(echo $line | grep -o 'pid=[0-9]*' | cut -d '=' -f2)
echo "Found pid: $pid_value"
# You can add code here to do something with the PID value
echo "$pid_value" > /tmp/pid_value.txt
break # Exit the loop after finding the first value
fi
done) &

dsrouter_pid=$(pgrep -f "dotnet dsrouter")
trap "kill $dsrouter_pid" EXIT
fi

# # Run dotnet trace collect using the obtained PID and specified format
dotnet trace collect --name dotnet-dsrouter --providers Microsoft-Windows-DotNETRuntime:0x1F000080018:5 --duration 00:00:00:05 # --stopping-event-provider-name Microsoft-Windows-DotNETRuntime --stopping-event-event-name Method/JittingStarted --stopping-event-payload-filter MethodName:PrintA

# Check if there were any errors when running the command
if [ $? -ne 0 ]; then
echo "Error occurred while running the command."
exit 1
fi
Loading