chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import TypedDict
|
||||
|
||||
# --- Type Aliases ---
|
||||
# "{data_type[::phi::dtype::bfloat16]; data_layout[STRIDED]; place[Place(gpu:0)]; library_type[PLAIN]}"
|
||||
KernelConfig = dict[str, str]
|
||||
# "fused_transpose": [
|
||||
# "{data_type[uint8_t]; data_layout[ONEDNN]; place[Place(cpu)]; library_type[MKLDNN]}",
|
||||
# "{data_type[int8_t]; data_layout[ONEDNN]; place[Place(cpu)]; library_type[MKLDNN]}",
|
||||
# "{data_type[::phi::dtype::bfloat16]; data_layout[ONEDNN]; place[Place(cpu)]; library_type[MKLDNN]}",
|
||||
# "{data_type[float]; data_layout[ONEDNN]; place[Place(cpu)]; library_type[MKLDNN]}"
|
||||
# ]
|
||||
KernelManifest = dict[str, list[KernelConfig]]
|
||||
|
||||
|
||||
class GpuKernelChangeSummary(TypedDict):
|
||||
# New kernel names that contain "gpu".
|
||||
new_kernels_with_gpu: list[str]
|
||||
# Existing kernels that have new GPU configurations added.
|
||||
kernels_with_new_gpu_support: list[str]
|
||||
# Existing GPU kernels that ignore data_type changes.
|
||||
gpu_kernels_with_new_data_types: dict[str, list[str]]
|
||||
|
||||
|
||||
class KernelManifestComparer:
|
||||
def __init__(self, baseline_manifest_data: dict[str, list[str]]) -> None:
|
||||
self.baseline_manifest: KernelManifest = self._process_raw_manifest(
|
||||
baseline_manifest_data
|
||||
)
|
||||
self._preprocessed_baseline = {
|
||||
kernel_name: {
|
||||
"configs_set": {tuple(sorted(cfg.items())) for cfg in configs},
|
||||
"gpu_signatures": {
|
||||
self._create_config_signature_without_dtype(cfg)
|
||||
for cfg in configs
|
||||
if "gpu" in cfg.get("place", "")
|
||||
},
|
||||
}
|
||||
for kernel_name, configs in self.baseline_manifest.items()
|
||||
}
|
||||
|
||||
def _parse_config_string(self, config_str: str) -> KernelConfig:
|
||||
pattern = r"([\w:]+)\[([^\]]+)\]"
|
||||
matches = re.findall(pattern, config_str)
|
||||
return dict(matches)
|
||||
|
||||
def _create_config_signature_without_dtype(
|
||||
self, config: KernelConfig
|
||||
) -> tuple[tuple[str, str], ...]:
|
||||
signature_items = {
|
||||
key: value for key, value in config.items() if key != "data_type"
|
||||
}
|
||||
return tuple(sorted(signature_items.items()))
|
||||
|
||||
def _process_raw_manifest(
|
||||
self, raw_manifest: dict[str, list[str]]
|
||||
) -> KernelManifest:
|
||||
processed_manifest: KernelManifest = {}
|
||||
for kernel_name, config_strings in raw_manifest.items():
|
||||
processed_manifest[kernel_name] = [
|
||||
self._parse_config_string(cs) for cs in config_strings
|
||||
]
|
||||
return processed_manifest
|
||||
|
||||
def compare(
|
||||
self, target_manifest_data: dict[str, list[str]]
|
||||
) -> GpuKernelChangeSummary:
|
||||
target_manifest = self._process_raw_manifest(target_manifest_data)
|
||||
|
||||
new_kernels_with_gpu: set[str] = set()
|
||||
kernels_with_new_gpu_support: set[str] = set()
|
||||
gpu_kernels_with_new_data_types: dict[str, set[str]] = {}
|
||||
|
||||
baseline_kernel_names = set(self._preprocessed_baseline.keys())
|
||||
target_kernel_names = set(target_manifest.keys())
|
||||
|
||||
# 1. Find newly added kernels that are GPU-related.
|
||||
added_kernel_names = target_kernel_names - baseline_kernel_names
|
||||
for kernel_name in added_kernel_names:
|
||||
if any(
|
||||
"gpu" in cfg.get("place", "")
|
||||
for cfg in target_manifest[kernel_name]
|
||||
):
|
||||
new_kernels_with_gpu.add(kernel_name)
|
||||
|
||||
# 2. Find changes within existing kernels.
|
||||
common_kernel_names = baseline_kernel_names.intersection(
|
||||
target_kernel_names
|
||||
)
|
||||
for kernel_name in common_kernel_names:
|
||||
baseline_data = self._preprocessed_baseline[kernel_name]
|
||||
target_configs = target_manifest[kernel_name]
|
||||
|
||||
target_configs_set = {
|
||||
tuple(sorted(cfg.items())) for cfg in target_configs
|
||||
}
|
||||
|
||||
if baseline_data["configs_set"] == target_configs_set:
|
||||
continue
|
||||
|
||||
added_config_tuples = (
|
||||
target_configs_set - baseline_data["configs_set"]
|
||||
)
|
||||
added_configs = [dict(t) for t in added_config_tuples]
|
||||
|
||||
baseline_gpu_signatures = baseline_data["gpu_signatures"]
|
||||
has_baseline_gpu_support = bool(baseline_gpu_signatures)
|
||||
|
||||
for added_cfg in added_configs:
|
||||
if "gpu" in added_cfg.get("place", ""):
|
||||
kernels_with_new_gpu_support.add(kernel_name)
|
||||
added_signature = (
|
||||
self._create_config_signature_without_dtype(added_cfg)
|
||||
)
|
||||
if (
|
||||
has_baseline_gpu_support
|
||||
and added_signature in baseline_gpu_signatures
|
||||
):
|
||||
new_data_type = added_cfg.get("data_type", "N/A")
|
||||
gpu_kernels_with_new_data_types.setdefault(
|
||||
kernel_name, set()
|
||||
).add(new_data_type)
|
||||
|
||||
return {
|
||||
"new_kernels_with_gpu": sorted(new_kernels_with_gpu),
|
||||
"kernels_with_new_gpu_support": sorted(
|
||||
kernels_with_new_gpu_support
|
||||
),
|
||||
"gpu_kernels_with_new_data_types": {
|
||||
k: sorted(v) for k, v in gpu_kernels_with_new_data_types.items()
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def cli():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Compare GPU kernel configurations between two manifests."
|
||||
)
|
||||
parser.add_argument(
|
||||
"baseline_manifest",
|
||||
type=Path,
|
||||
help="Path to the baseline manifest JSON file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"target_manifest",
|
||||
type=Path,
|
||||
help="Path to the target manifest JSON file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ignore-data-type-changes",
|
||||
action="store_true",
|
||||
help="If set, ignore data_type changes in GPU kernel comparisons.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = cli()
|
||||
if not args.baseline_manifest.exists():
|
||||
raise ValueError(
|
||||
f"Baseline manifest file not found: {args.baseline_manifest.resolve()}"
|
||||
)
|
||||
if not args.target_manifest.exists():
|
||||
raise ValueError(
|
||||
f"Target manifest file not found: {args.target_manifest.resolve()}"
|
||||
)
|
||||
|
||||
with args.baseline_manifest.open("r", encoding="utf-8") as f:
|
||||
baseline_data = json.load(f)
|
||||
|
||||
with args.target_manifest.open("r", encoding="utf-8") as f:
|
||||
target_data = json.load(f)
|
||||
|
||||
comparer = KernelManifestComparer(baseline_data)
|
||||
summary = comparer.compare(target_data)
|
||||
|
||||
has_reportable_changes = False
|
||||
if args.ignore_data_type_changes:
|
||||
all_gpu_related_changes = set(summary["new_kernels_with_gpu"]) | set(
|
||||
summary["kernels_with_new_gpu_support"]
|
||||
)
|
||||
kernels_with_only_dtype_changes = set(
|
||||
summary["gpu_kernels_with_new_data_types"].keys()
|
||||
)
|
||||
unignored_changes = (
|
||||
all_gpu_related_changes - kernels_with_only_dtype_changes
|
||||
)
|
||||
if unignored_changes:
|
||||
has_reportable_changes = True
|
||||
else:
|
||||
if (
|
||||
summary["new_kernels_with_gpu"]
|
||||
or summary["kernels_with_new_gpu_support"]
|
||||
):
|
||||
has_reportable_changes = True
|
||||
|
||||
if summary["new_kernels_with_gpu"]:
|
||||
print("New GPU Kernels Added:")
|
||||
for kernel in summary["new_kernels_with_gpu"]:
|
||||
print(f" - {kernel}")
|
||||
|
||||
if summary["kernels_with_new_gpu_support"]:
|
||||
print("\nKernels with New GPU Support:")
|
||||
for kernel in summary["kernels_with_new_gpu_support"]:
|
||||
print(f" - {kernel}")
|
||||
|
||||
if summary["gpu_kernels_with_new_data_types"]:
|
||||
print("\nGPU Kernels with new Data Type:")
|
||||
for kernel, data_types in summary[
|
||||
"gpu_kernels_with_new_data_types"
|
||||
].items():
|
||||
data_types_str = ", ".join(data_types)
|
||||
print(f" - {kernel}: New data types - {data_types_str}")
|
||||
|
||||
if has_reportable_changes:
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user