69 lines
2.9 KiB
Bash
Executable file
69 lines
2.9 KiB
Bash
Executable file
#!/bin/sh
|
|
set -eu
|
|
|
|
[ "$#" -eq 1 ] || [ "$#" -eq 2 ] || {
|
|
echo "usage: $0 COUNTER_INFO_JSON [OUTPUT_JSON]" >&2
|
|
exit 2
|
|
}
|
|
input=$1
|
|
output=${2:-}
|
|
|
|
analyze() {
|
|
jq '
|
|
([.counter_sets[].counters[]] | unique) as $names |
|
|
def named($pattern): any($names[]; test($pattern; "i"));
|
|
if .schema_version != 1 or .workload != "metal-counter-info" or
|
|
.device.has_unified_memory != true or .device.gpu_families.apple9 != true or
|
|
.device.max_threadgroup_memory_bytes < 32768 or
|
|
(.sampling_points.stage_boundary | type) != "boolean" or
|
|
(.sampling_points.dispatch_boundary | type) != "boolean" or
|
|
(.counter_sets | type) != "array" or (.counter_sets | length) == 0 or
|
|
any(.counter_sets[]; (.name | type) != "string" or
|
|
(.counters | type) != "array" or any(.counters[]; type != "string"))
|
|
then error("invalid target Metal counter inventory") else
|
|
(named("timestamp")) as $timestamp |
|
|
(named("occup|active.*thread|thread.*active")) as $occupancy |
|
|
(named("bandwidth|bytes|memory.*read|memory.*write|read.*memory|write.*memory"))
|
|
as $bandwidth |
|
|
(named("limiter|stall")) as $limiter |
|
|
{
|
|
schema_version: 1,
|
|
scope: "target-metal-counter-capability-analysis",
|
|
device: .device,
|
|
sampling_points: .sampling_points,
|
|
counter_set_count: (.counter_sets | length),
|
|
available_counter_names: $names,
|
|
capabilities: {
|
|
timestamp: $timestamp,
|
|
occupancy: $occupancy,
|
|
bandwidth: $bandwidth,
|
|
limiter_or_stall: $limiter
|
|
},
|
|
instrumentation: {
|
|
stage_timestamps_available:
|
|
(.sampling_points.stage_boundary and $timestamp),
|
|
dispatch_performance_counters_available:
|
|
(.sampling_points.dispatch_boundary and
|
|
($occupancy or $bandwidth or $limiter)),
|
|
selected: (
|
|
if .sampling_points.dispatch_boundary and
|
|
($occupancy or $bandwidth or $limiter)
|
|
then "public-dispatch-counter-sampling"
|
|
elif .sampling_points.stage_boundary and $timestamp
|
|
then "stage-timestamps-plus-xcode-gpu-trace"
|
|
else "xcode-gpu-trace-only" end),
|
|
reason: (
|
|
if .sampling_points.dispatch_boundary and
|
|
($occupancy or $bandwidth or $limiter)
|
|
then "target exposes public dispatch-boundary performance counters"
|
|
elif .sampling_points.stage_boundary and $timestamp
|
|
then "public API lacks required performance counters; retain exact stage timestamps and use Xcode for occupancy/bandwidth/limiter evidence"
|
|
else "public counter sampling lacks both required performance counters and stage timestamps"
|
|
end)
|
|
}
|
|
}
|
|
end
|
|
' "$input"
|
|
}
|
|
|
|
if [ -n "$output" ]; then analyze > "$output"; else analyze; fi
|