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

SPMI no ASMDiff between Checked and Release #61335

Merged
merged 17 commits into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
efc24d4
SPMI no ASMDiff between Checked and Release
JulieLeeMSFT Nov 9, 2021
3a78a69
SuperPMI asmdiff checked and release
JulieLeeMSFT Nov 10, 2021
1959d1d
SuperPmi asmdiff checked release
JulieLeeMSFT Nov 10, 2021
a9bad61
SuperPMI asmdiff checked release
JulieLeeMSFT Nov 10, 2021
d1a6cb6
SuperPMI asmdiff checked release
JulieLeeMSFT Nov 11, 2021
5c6dddf
SuperPMI asmdiffs checked release
JulieLeeMSFT Nov 13, 2021
16fdb6e
SuperPMI asmdiffs checked release: resolve merge conflict
JulieLeeMSFT Nov 25, 2021
3f80738
SuperPMI asmdiffs checked release: Fixed to use a proj and a script f…
JulieLeeMSFT Nov 26, 2021
84a456e
Superpmi asmdiffs checked release: changed to --diff_with_release as …
JulieLeeMSFT Dec 1, 2021
30e8de1
SuperPMI asmdiffs checked release: Add dependency to completed Releas…
JulieLeeMSFT Dec 1, 2021
75b1d60
Superpmi asmdiffs checked release: add diff_with_release back that go…
JulieLeeMSFT Dec 2, 2021
1fc1380
SuperPMI asmdiffs checked release: Do not create asm file for asmdiff…
JulieLeeMSFT Jan 28, 2022
21af7b7
SuperPMI asmdiffs checked release: Report failure asm diffs (return c…
JulieLeeMSFT Jan 28, 2022
77328b6
SuperPMI asmdiffs checked release: Handled code review feedback to re…
JulieLeeMSFT Feb 1, 2022
cf3ecf7
SuperPMI asmdiffs checked release: Changed to checked_directory inste…
JulieLeeMSFT Feb 1, 2022
fd9ad6c
SuperPMI asmdiffs checked release: explictly say checked_directory
JulieLeeMSFT Feb 2, 2022
8537008
SuperPMI asmdiffs checked release: schedule to run on Saturdays and S…
JulieLeeMSFT Feb 16, 2022
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
41 changes: 41 additions & 0 deletions eng/pipelines/coreclr/superpmi-asmdiffs-checked-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
trigger: none

schedules:
- cron: "0 10 * * 6,0"
displayName: Sat and Sun at 2:00 AM (UTC-8:00)
branches:
include:
- main
always: true

jobs:

- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/coreclr/templates/build-jit-job.yml
buildConfig: checked
platforms:
- windows_x64
- windows_x86
jobParameters:
uploadAs: 'pipelineArtifacts'

- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/coreclr/templates/build-jit-job.yml
buildConfig: release
platforms:
- windows_x64
- windows_x86
jobParameters:
uploadAs: 'pipelineArtifacts'

- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/coreclr/templates/superpmi-asmdiffs-checked-release-job.yml
buildConfig: checked
platforms:
- windows_x64
- windows_x86
helixQueueGroup: ci
helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
parameters:
steps: [] # optional -- any additional steps that need to happen before pulling down the jitutils repo and sending the jitutils to helix (ie building your repo)
variables: [] # optional -- list of additional variables to send to the template
jobName: '' # required -- job name
displayName: '' # optional -- display name for the job. Will use jobName if not passed
pool: '' # required -- name of the Build pool
container: '' # required -- name of the container
buildConfig: '' # required -- build configuration
archType: '' # required -- targeting CPU architecture
osGroup: '' # required -- operating system for the job
osSubgroup: '' # optional -- operating system subgroup
continueOnError: 'false' # optional -- determines whether to continue the build if the step errors
dependsOn: '' # optional -- dependencies of the job
timeoutInMinutes: 320 # optional -- timeout for the job
enableTelemetry: false # optional -- enable for telemetry
liveLibrariesBuildConfig: '' # optional -- live-live libraries configuration to use for the run
helixQueues: '' # required -- Helix queues
dependOnEvaluatePaths: false

jobs:
- template: xplat-pipeline-job.yml
parameters:
dependsOn: ${{ parameters.dependsOn }}
buildConfig: ${{ parameters.buildConfig }}
archType: ${{ parameters.archType }}
osGroup: ${{ parameters.osGroup }}
osSubgroup: ${{ parameters.osSubgroup }}
liveLibrariesBuildConfig: ${{ parameters.liveLibrariesBuildConfig }}
enableTelemetry: ${{ parameters.enableTelemetry }}
enablePublishBuildArtifacts: true
continueOnError: ${{ parameters.continueOnError }}
dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }}
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}

${{ if ne(parameters.displayName, '') }}:
displayName: '${{ parameters.displayName }}'
${{ if eq(parameters.displayName, '') }}:
displayName: '${{ parameters.jobName }}'

variables:

- name: PythonScript
value: 'py -3'
- name: PipScript
value: 'py -3 -m pip'
- name: SpmiCollectionLocation
value: '$(Build.SourcesDirectory)\artifacts\spmi\'
- name: SpmiLogsLocation
value: '$(Build.SourcesDirectory)\artifacts\spmi_logs\'
- name: HelixResultLocation
value: '$(Build.SourcesDirectory)\artifacts\helixresults\'

- ${{ each variable in parameters.variables }}:
- ${{insert}}: ${{ variable }}

workspace:
clean: all
pool:
${{ parameters.pool }}
container: ${{ parameters.container }}
steps:
- ${{ parameters.steps }}

- script: |
mkdir -p $(SpmiCollectionLocation)
displayName: Create directory for SPMI collection

- script: $(PythonScript) $(Build.SourcesDirectory)/src/coreclr/scripts/superpmi_asmdiffs_checked_release_setup.py -source_directory $(Build.SourcesDirectory) -checked_directory $(buildProductRootFolderPath) -release_directory $(releaseProductRootFolderPath) -arch $(archType)
displayName: ${{ format('SuperPMI asmdiffs checked release setup ({0} {1})', parameters.osGroup, parameters.archType) }}

# Run superpmi asmdiffs between checked build and release build in helix
- template: /eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
parameters:
displayName: 'Send job to Helix'
helixBuild: $(Build.BuildNumber)
helixSource: $(_HelixSource)
helixType: 'build/tests/'
helixQueues: ${{ join(',', parameters.helixQueues) }}
creator: dotnet-bot
WorkItemTimeout: 4:00 # 4 hours
WorkItemDirectory: '$(WorkItemDirectory)'
CorrelationPayloadDirectory: '$(CorrelationPayloadDirectory)'
helixProjectArguments: '$(Build.SourcesDirectory)/src/coreclr/scripts/superpmi-asmdiffs-checked-release.proj'
BuildConfig: ${{ parameters.buildConfig }}
osGroup: ${{ parameters.osGroup }}
archType: ${{ parameters.archType }}
shouldContinueOnError: true # Run the future step i.e. upload superpmi logs

# Always upload the available logs for diagnostics
- task: CopyFiles@2
displayName: Copying superpmi.log of all partitions
inputs:
sourceFolder: '$(HelixResultLocation)'
contents: '**/superpmi_*.log'
targetFolder: '$(SpmiLogsLocation)'
condition: always()

- task: PublishPipelineArtifact@1
displayName: Publish SuperPMI logs
inputs:
targetPath: $(SpmiLogsLocation)
artifactName: 'SuperPMI_Logs_$(archType)_$(buildConfig)'
condition: always()

- task: PublishPipelineArtifact@1
displayName: Publish SuperPMI build logs
inputs:
targetPath: $(Build.SourcesDirectory)/artifacts/log
artifactName: 'SuperPMI_BuildLogs_$(archType)_$(buildConfig)'
condition: always()
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
parameters:
buildConfig: '' # required -- build configuration
archType: '' # required -- targeting CPU architecture
osGroup: '' # required -- operating system for the job
osSubgroup: '' # optional -- operating system subgroup
pool: ''
timeoutInMinutes: 320 # build timeout
variables: {}
helixQueues: ''
dependOnEvaluatePaths: false
runJobTemplate: '/eng/pipelines/coreclr/templates/run-superpmi-asmdiffs-checked-release-job.yml'

jobs:
- template: ${{ parameters.runJobTemplate }}
parameters:
jobName: ${{ format('superpmi_asmdiffs_checked_release_{0}{1}_{2}', parameters.osGroup, parameters.osSubgroup, parameters.archType) }}
displayName: ${{ format('SuperPMI asmdiffs checked release {0}{1} {2}', parameters.osGroup, parameters.osSubgroup, parameters.archType) }}
pool: ${{ parameters.pool }}
buildConfig: ${{ parameters.buildConfig }}
archType: ${{ parameters.archType }}
osGroup: ${{ parameters.osGroup }}
osSubgroup: ${{ parameters.osSubgroup }}
dependOnEvaluatePaths: ${{ parameters.dependOnEvaluatePaths }}
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
helixQueues: ${{ parameters.helixQueues }}
dependsOn:
- ${{ format('coreclr_jit_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, 'checked') }}
- ${{ format('coreclr_jit_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, 'release') }}

variables:

- ${{ each variable in parameters.variables }}:
- ${{ if ne(variable.name, '') }}:
- name: ${{ variable.name }}
value: ${{ variable.value }}
- ${{ if ne(variable.group, '') }}:
- group: ${{ variable.group }}

- name: releaseProductRootFolderPath
value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).Release'
- name: releaseProductArtifactName
value: 'CoreCLRProduct_${{ parameters.pgoType }}_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_release'

steps:

# Download jit checked builds
- template: /eng/pipelines/common/download-artifact-step.yml
parameters:
unpackFolder: $(buildProductRootFolderPath)
artifactFileName: '$(buildProductArtifactName)$(archiveExtension)'
artifactName: '$(buildProductArtifactName)'
displayName: 'JIT checked build'

#Download jit release builds
- template: /eng/pipelines/common/download-artifact-step.yml
parameters:
unpackFolder: $(releaseProductRootFolderPath)
artifactFileName: '$(releaseProductArtifactName)$(archiveExtension)'
artifactName: '$(releaseProductArtifactName)'
displayName: 'JIT release build'
73 changes: 73 additions & 0 deletions src/coreclr/scripts/superpmi-asmdiffs-checked-release.proj
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<Project Sdk="Microsoft.DotNet.Helix.Sdk" DefaultTargets="Test">
<!--
This is useful for local testing to print the produced helix items
To use this when you are changing how items are produced, uncomment the target
and replace the Project item at the top of the file with this:
<Project DefaultTargets="printItems">

Once you've done that you can run this to see the results:
dotnet msbuild .\superpmi-asmdiffs.proj /v:n
-->

<!-- <PropertyGroup>
<HelixTargetQueues>Some_Queue</HelixTargetQueues>
<Platform>Windows</Platform>
<Architecture>x64</Architecture>
</PropertyGroup>

<Target Name="printItems">
<Message Text="@(HelixWorkItem -> 'name: %(HelixWorkItem.Identity)
dir: %(HelixWorkItem.PayloadDirectory)
pre: %(HelixWorkItem.PreCommands)
command: %(HelixWorkItem.Command)
post: %(HelixWorkItem.PostCommands)
timeout: %(HelixWorkItem.Timeout) '"/>
</Target> -->

<PropertyGroup>
<Python>%HELIX_PYTHONPATH%</Python>
<ProductDirectory>%HELIX_CORRELATION_PAYLOAD%</ProductDirectory>
<SuperpmiLogsLocation>%HELIX_WORKITEM_UPLOAD_ROOT%</SuperpmiLogsLocation>
<!-- Workaround until https://github.com/dotnet/arcade/pull/6179 is not available -->
<HelixResultsDestinationDir>$(BUILD_SOURCESDIRECTORY)\artifacts\helixresults</HelixResultsDestinationDir>
<WorkItemCommand>$(Python) $(ProductDirectory)\superpmi_asmdiffs_checked_release.py --diff_with_release -base_jit_directory $(ProductDirectory)\base -diff_jit_directory $(ProductDirectory)\diff -log_directory $(SuperpmiLogsLocation)</WorkItemCommand>
<WorkItemTimeout>1:00</WorkItemTimeout>
</PropertyGroup>

<PropertyGroup>
<EnableAzurePipelinesReporter>false</EnableAzurePipelinesReporter>
<EnableXUnitReporter>false</EnableXUnitReporter>
<Creator>$(_Creator)</Creator>
<HelixAccessToken>$(_HelixAccessToken)</HelixAccessToken>
<HelixBuild>$(_HelixBuild)</HelixBuild>
<HelixSource>$(_HelixSource)</HelixSource>
<HelixTargetQueues>$(_HelixTargetQueues)</HelixTargetQueues>
<HelixType>$(_HelixType)</HelixType>
</PropertyGroup>

<ItemGroup>
<HelixCorrelationPayload Include="$(CorrelationPayloadDirectory)">
<PayloadDirectory>%(Identity)</PayloadDirectory>
</HelixCorrelationPayload>
</ItemGroup>

<ItemGroup Condition="'$(Architecture)' == 'x64'">
<SPMI_Partition Include="win-x64" Platform="windows" Architecture="x64" />
<SPMI_Partition Include="win-arm64" Platform="windows" Architecture="arm64" />
<SPMI_Partition Include="unix-x64" Platform="Linux" Architecture="x64" />
<SPMI_Partition Include="unix-arm64" Platform="Linux" Architecture="arm64" />
</ItemGroup>

<ItemGroup Condition="'$(Architecture)' == 'x86'">
<SPMI_Partition Include="win-x86" Platform="windows" Architecture="x86" />
<SPMI_Partition Include="unix-arm" Platform="Linux" Architecture="arm" />
</ItemGroup>

<ItemGroup>
<HelixWorkItem Include="@(SPMI_Partition)">
<Command>$(WorkItemCommand) -arch %(HelixWorkItem.Architecture) -platform %(HelixWorkItem.Platform)</Command>
<Timeout>$(WorkItemTimeout)</Timeout>
<DownloadFilesFromResults>superpmi_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log;superpmi_download_%(HelixWorkItem.Platform)_%(HelixWorkItem.Architecture).log</DownloadFilesFromResults>
</HelixWorkItem>
</ItemGroup>
</Project>
26 changes: 17 additions & 9 deletions src/coreclr/scripts/superpmi.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@
asm_diff_parser.add_argument("-tag", help="Specify a word to add to the directory name where the asm diffs will be placed")
asm_diff_parser.add_argument("-metrics", action="append", help="Metrics option to pass to jit-analyze. Can be specified multiple times, or pass comma-separated values.")
asm_diff_parser.add_argument("-retainOnlyTopFiles", action="store_true", help="Retain only top .dasm files with largest improvements or regressions and delete remaining files.")
asm_diff_parser.add_argument("--diff_with_release", action="store_true", help="Specify if this is asmdiff using release binaries.")

# subparser for upload
upload_parser = subparsers.add_parser("upload", description=upload_description, parents=[core_root_parser, target_parser])
Expand Down Expand Up @@ -1492,6 +1493,7 @@ def replay_with_asm_diffs(self):
with ChangeDir(self.coreclr_args.core_root):
command = [self.superpmi_path] + flags + [self.base_jit_path, self.diff_jit_path, mch_file]
return_code = run_and_log(command)
logging.debug("return_code: %s", return_code)

base_metrics = read_csv_metrics(base_metrics_summary_file)
diff_metrics = read_csv_metrics(diff_metrics_summary_file)
Expand All @@ -1501,33 +1503,32 @@ def replay_with_asm_diffs(self):

if return_code != 0:

# Don't report as replay failure asm diffs (return code 2) or missing data (return code 3).
# Don't report as replay failure asm diffs (return code 2) if not checking diffs with Release build or missing data (return code 3).
# Anything else, such as compilation failure (return code 1, typically a JIT assert) will be
# reported as a replay failure.
if return_code != 2 and return_code != 3:
if (return_code != 2 or self.coreclr_args.diff_with_release) and return_code != 3:
result = False
files_with_replay_failures.append(mch_file)

if is_nonzero_length_file(fail_mcl_file):
# Unclean replay. Examine the contents of the fail.mcl file to dig into failures.
if return_code == 0:
logging.warning("Warning: SuperPMI returned a zero exit code, but generated a non-zero-sized mcl file")
print_fail_mcl_file_method_numbers(fail_mcl_file)
repro_base_command_line = "{} {} {}".format(self.superpmi_path, " ".join(altjit_asm_diffs_flags), self.diff_jit_path)
save_repro_mc_files(temp_location, self.coreclr_args, artifacts_base_name, repro_base_command_line)

# This file had asm diffs; keep track of that.
if is_nonzero_length_file(diff_mcl_file):
files_with_asm_diffs.append(mch_file)

# There were diffs. Go through each method that created diffs and
# create a base/diff asm file with diffable asm. In addition, create
# a standalone .mc for easy iteration.
if is_nonzero_length_file(diff_mcl_file):
if is_nonzero_length_file(diff_mcl_file) and not self.coreclr_args.diff_with_release:
# AsmDiffs. Save the contents of the fail.mcl file to dig into failures.

if return_code == 0:
logging.warning("Warning: SuperPMI returned a zero exit code, but generated a non-zero-sized mcl file")

# This file had asm diffs; keep track of that.
files_with_asm_diffs.append(mch_file)

self.diff_mcl_contents = None
with open(diff_mcl_file) as file_handle:
mcl_lines = file_handle.readlines()
Expand Down Expand Up @@ -1711,7 +1712,7 @@ async def create_one_artifact(jit_path: str, location: str, flags) -> str:

# Construct an overall Markdown summary file.

if len(all_md_summary_files) > 0:
if len(all_md_summary_files) > 0 and not self.coreclr_args.diff_with_release:
overall_md_summary_file = create_unique_file_name(self.coreclr_args.spmi_location, "diff_summary", "md")
if not os.path.isdir(self.coreclr_args.spmi_location):
os.makedirs(self.coreclr_args.spmi_location)
Expand Down Expand Up @@ -3310,6 +3311,11 @@ def verify_replay_common_args():
lambda unused: True,
"Unable to set retainOnlyTopFiles.")

coreclr_args.verify(args,
"diff_with_release",
lambda unused: True,
"Unable to set diff_with_release.")

process_base_jit_path_arg(coreclr_args)

jit_in_product_location = False
Expand Down Expand Up @@ -3555,6 +3561,8 @@ def main(args):
base_jit_path = coreclr_args.base_jit_path
diff_jit_path = coreclr_args.diff_jit_path

if coreclr_args.diff_with_release:
logging.info("Diff between Checked and Release.")
logging.info("Base JIT Path: %s", base_jit_path)
logging.info("Diff JIT Path: %s", diff_jit_path)

Expand Down
Loading