#!/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