diff --git a/dnn-providers/hip-kernel-provider/README.md b/dnn-providers/hip-kernel-provider/README.md index 9048c27ba437..207e74464608 100644 --- a/dnn-providers/hip-kernel-provider/README.md +++ b/dnn-providers/hip-kernel-provider/README.md @@ -27,6 +27,7 @@ HipKernelEngine - **HIP MLops engine** (`src/engines/hip_mlops_engine/`): Kernel-specific execution logic. Enabled via the compile flag `ENABLE_HIP_MLOPS_ENGINE` (on by default) - **ASM SDPA engine** (`src/engines/asm_sdpa_engine/`): Assembly kernels to do scaled dot-product attention (SDPA). Enabled via `ENABLE_ASM_SDPA_ENGINE` (on by default) - **HIP Flash2 engine** (`src/engines/hip_flash2_engine/`): Flash-Attention 2 V7 SDPA kernel using precompiled `.co` files for gfx942/gfx950 (FP16). Enabled via `ENABLE_HIP_FLASH2_ENGINE` (off by default) + - **Packaged gfx950 convolution** (`hipkernel:Gfx950ConvFwd`): rocKE forward convolution with FP16/BF16 channels-last storage. See the [integration guide](docs/gfx950_conv_fwd/README.md) for catalog scope, packaging flags, and tests. - **HIP Infrastructure** (`src/hip/`): HIPRTC wrapper classes for compilation and execution - **Kernels** (`kernels/`): Device-side kernel source code embedded at build time - **Plugin SDK Integration**: Implements `IPlan`, `IPlanBuilder`, `IEngine` interfaces diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kdp.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kdp.json new file mode 100644 index 000000000000..5dc4de64c376 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kdp.json @@ -0,0 +1,8558 @@ +{ + "version": "1.0", + "id": "a5ca40eb-4f55-4263-8c4a-cd4dd34b9cf2", + "name": "hipkernel:gfx950_conv_fwd", + "matchers": [ + "3aa9f90a-4080-473d-b08a-65d3acc3b05f" + ], + "engine": "29423f05-8c7b-468a-930b-9e88ca7c99ee", + "dispatch": "d71abd4b-3fea-4c48-a3a1-577a5acb34eb", + "provenance": { + "specialization_contract": { + "schema_version": 1, + "consumers": [ + { + "engine_id": "29423f05-8c7b-468a-930b-9e88ca7c99ee", + "kmd_id": "fb2104d3-bae8-40b7-9a6f-4f7bc7ced8c7", + "metadata_fields": [ + "N", + "Hi", + "Wi", + "C", + "K", + "Y", + "X", + "sH", + "sW", + "pH", + "pW", + "dH", + "dW", + "dtype", + "layout", + "groups", + "tile_m", + "tile_n", + "tile_k", + "warp_m", + "warp_n", + "warp_tile_m", + "warp_tile_n", + "warp_tile_k", + "wave_size", + "pipeline", + "epilogue" + ], + "matcher_only_fields": [], + "bindings": { + "N": { + "field": "N" + }, + "Hi": { + "field": "Hi" + }, + "Wi": { + "field": "Wi" + }, + "C": { + "field": "C" + }, + "K": { + "field": "K" + }, + "Y": { + "field": "Y" + }, + "X": { + "field": "X" + }, + "sH": { + "field": "sH" + }, + "sW": { + "field": "sW" + }, + "pH": { + "field": "pH" + }, + "pW": { + "field": "pW" + }, + "dH": { + "field": "dH" + }, + "dW": { + "field": "dW" + }, + "dtype": { + "field": "dtype" + }, + "layout": { + "field": "layout" + }, + "groups": { + "field": "groups" + }, + "tile_m": { + "field": "tile_m" + }, + "tile_n": { + "field": "tile_n" + }, + "tile_k": { + "field": "tile_k" + }, + "warp_m": { + "field": "warp_m" + }, + "warp_n": { + "field": "warp_n" + }, + "warp_tile_m": { + "field": "warp_tile_m" + }, + "warp_tile_n": { + "field": "warp_tile_n" + }, + "warp_tile_k": { + "field": "warp_tile_k" + }, + "wave_size": { + "field": "wave_size" + }, + "pipeline": { + "field": "pipeline" + }, + "epilogue": { + "field": "epilogue" + } + }, + "vocabulary": {} + } + ] + } + }, + "kernelDescriptors": [ + { + "version": "1.0", + "id": "f5654543-c730-4c3d-99ea-d99dd62f821c", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi14_Wi14_C32_K32_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "0e395305-b67d-45c3-ade5-0a8fe538cb4a", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi14_Wi14_C32_K32_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "9bf5cd6c-e19d-4e9b-ac94-22035ccfb709", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi14_Wi14_C32_K32_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a9dd5594-13d7-45e8-a101-4a4f30ba7e02", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi14_Wi14_C32_K32_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a5df856e-b69f-4cde-890f-02fffa75b2f2", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi8_Wi8_C32_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "d9fb371f-d231-447c-bb5b-4ccd661cce1d", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi8_Wi8_C32_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "24e30d59-39a2-46f4-8154-ded057d1c90b", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi8_Wi8_C32_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "af33f525-38a5-4fa2-810e-db3b9abda086", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi8_Wi8_C32_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a3be2440-c7a9-40ed-81d3-05e1d2df535d", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi17_Wi19_C32_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "32adacd0-a101-464c-b123-f827e74635d2", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi17_Wi19_C32_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "6d798cda-db03-4676-b6bf-6e3df363d036", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi17_Wi19_C32_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "e31002b4-8568-48b5-800b-4cb9713a2123", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi17_Wi19_C32_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "26c0dc60-7262-47e8-88f3-6120a85814fc", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi15_Wi17_C32_K32_Y3_X3_sH1_sW1_pH2_pW2_dH2_dW2_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "f6c8c037-b0a7-468a-b0ff-a3aa29362f09", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi15_Wi17_C32_K32_Y3_X3_sH1_sW1_pH2_pW2_dH2_dW2_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "572caa52-2319-47cb-81ea-c555a14539a1", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi15_Wi17_C32_K32_Y3_X3_sH1_sW1_pH2_pW2_dH2_dW2_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2ad352cf-0182-49f6-8574-32463f1ff586", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi15_Wi17_C32_K32_Y3_X3_sH1_sW1_pH2_pW2_dH2_dW2_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 2, + "pW": 2, + "dH": 2, + "dW": 2, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a8f39f38-4ffa-465d-a00a-0ef33f625e76", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi11_Wi17_C32_K64_Y3_X5_sH1_sW2_pH1_pW2_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "cce41de6-b007-4d6c-9aa9-97010e1e6ace", + "name": "gfx950_conv_fwd_dtypefp16_N2_Hi11_Wi17_C32_K64_Y3_X5_sH1_sW2_pH1_pW2_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "301003e5-f0d6-4c7a-8526-705f60b38ebc", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi11_Wi17_C32_K64_Y3_X5_sH1_sW2_pH1_pW2_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "005831a4-9ecc-44fe-a51e-577cd82ebc9b", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi11_Wi17_C32_K64_Y3_X5_sH1_sW2_pH1_pW2_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "sH": 1, + "sW": 2, + "pH": 1, + "pW": 2, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2fcef2ec-508f-4876-81f0-28765a73c0c3", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K768_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "1068ec10-d3ed-47b9-8cc9-f80747a4eb6e", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K768_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "c6471835-657c-4bf6-885e-aef75dcbafea", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi336_Wi336_C3_K1024_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 336, + "Wi": 336, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 336, + "Wi": 336, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "54192c3a-de0f-4d2d-bd41-4b28f8ee82b6", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi336_Wi336_C3_K1024_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 336, + "Wi": 336, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 336, + "Wi": 336, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "254959e9-be7b-4c39-a2e5-c62623e39f29", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K128_Y4_X4_sH4_sW4_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 128, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 128, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a3b4d3db-142b-40a6-82dc-4e9596094176", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K128_Y4_X4_sH4_sW4_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 128, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 128, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "7653c406-b51f-4d6c-857f-97fd86e2e99b", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C768_K3072_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 768, + "K": 3072, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 768, + "K": 3072, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "fe4f49bd-41a1-402b-ae10-2d69c317bfb0", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C768_K3072_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 768, + "K": 3072, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 768, + "K": 3072, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "f3c80a76-9889-4bb9-b9a0-189f0e9dcfb3", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C3072_K768_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 3072, + "K": 768, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 3072, + "K": 768, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2e00c40d-7627-4b7d-b9d7-42a464521fea", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C3072_K768_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 3072, + "K": 768, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 3072, + "K": 768, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "9061681e-a112-4fb0-8f9e-b570d1713fc3", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C384_K768_Y2_X2_sH2_sW2_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 384, + "K": 768, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 384, + "K": 768, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "30cf39e8-2e1f-4c7f-829f-2d29be6b0fd2", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C384_K768_Y2_X2_sH2_sW2_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 384, + "K": 768, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 384, + "K": 768, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b7cf27bf-8272-483f-b412-3bea594632bb", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K192_Y4_X4_sH4_sW4_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 192, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 192, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "6ba8872d-7692-4660-b31e-24682349cb0f", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K192_Y4_X4_sH4_sW4_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 192, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 192, + "Y": 4, + "X": 4, + "sH": 4, + "sW": 4, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "228246a1-2056-49d3-aa79-6d643b580925", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K1536_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1536, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1536, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "74b150b1-50d7-44b5-9249-8feca27a6692", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K1536_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1536, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1536, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b0bfba94-49f6-41a1-aef3-b7f667ea3f51", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi24_Wi24_C80_K480_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 24, + "Wi": 24, + "C": 80, + "K": 480, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 24, + "Wi": 24, + "C": 80, + "K": 480, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "759d8f16-88f4-418f-94a1-2933ad25792c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi24_Wi24_C80_K480_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 24, + "Wi": 24, + "C": 80, + "K": 480, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 24, + "Wi": 24, + "C": 80, + "K": 480, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "ca660f68-39bb-49e6-9b30-85dbcc04ed3d", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi192_Wi192_C24_K48_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 192, + "Wi": 192, + "C": 24, + "K": 48, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 192, + "Wi": 192, + "C": 24, + "K": 48, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "861f9c83-b13a-4b95-b5b6-5ad4e5f8e571", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi192_Wi192_C24_K48_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 192, + "Wi": 192, + "C": 24, + "K": 48, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 192, + "Wi": 192, + "C": 24, + "K": 48, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "12396ae3-2397-4101-a71e-cd221c025146", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C32_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 32, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 32, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "7e9066c3-d8bc-4667-aec7-03f1516ebd6e", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C32_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 32, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 32, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b9accc85-88e7-4f25-b6b0-031a45d07c26", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi448_Wi448_C3_K3200_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 448, + "Wi": 448, + "C": 3, + "K": 3200, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 448, + "Wi": 448, + "C": 3, + "K": 3200, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "35bef927-d90d-4826-a82b-b06ba7d38b72", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi448_Wi448_C3_K3200_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 448, + "Wi": 448, + "C": 3, + "K": 3200, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 448, + "Wi": 448, + "C": 3, + "K": 3200, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "52e89cc6-8985-4af4-ab83-6c33389bc0ae", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C24_K144_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 24, + "K": 144, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 24, + "K": 144, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "8f027ade-0886-4f01-898c-b8cb271dfc29", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C24_K144_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 24, + "K": 144, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 24, + "K": 144, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "7bae8b56-c3f2-48a6-a0d2-80f6573223f9", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C144_K40_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 144, + "K": 40, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 144, + "K": 40, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "17440c11-596d-488f-ae02-fb848d61b929", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C144_K40_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 144, + "K": 40, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 144, + "K": 40, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b64e0a5d-177d-4340-9ceb-43d3cd5b74eb", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi640_Wi640_C3_K32_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 32, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 32, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "cb9514dc-75f6-43a5-8412-6a48d591fb49", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi640_Wi640_C3_K32_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 32, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 32, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "5096b0f1-f158-4dde-9909-55c5e4fa67a5", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b7899cab-94e1-490f-89a6-8521fea1feba", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi28_Wi28_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 28, + "Wi": 28, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "e585662f-30db-477b-9011-ae88686ba167", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "7de7fcb5-9953-4f60-9db0-7653ef8f1b3c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi14_Wi14_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 14, + "Wi": 14, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "0aa4d154-7789-4206-9954-e7c4f7154a81", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C64_K64_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 64, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 64, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "6c009155-3654-482f-9ba9-1f36dbbb95d4", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C64_K64_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 64, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 64, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2e5d34e2-3622-4560-8253-126b33ba6678", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C128_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "0055a692-f9bd-46d6-9773-905397eccfb5", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C128_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a40bfe67-39f9-4710-90a4-44b9dc02ec0c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C64_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "8a4f4b86-19bf-4dc9-9637-9336a5eea34d", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C64_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 64, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "5ae5530c-d35f-4c81-8d38-c3a0491b1d84", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C256_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 256, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 256, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "23c802db-b4a0-4100-b3b5-92b5ea48957c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi56_Wi56_C256_K64_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 256, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 56, + "Wi": 56, + "C": 256, + "K": 64, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2ecdb0d1-7141-4aa2-a05a-4461f19013d3", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi7_Wi7_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 7, + "Wi": 7, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 7, + "Wi": 7, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "390863f4-9628-4981-ac6f-0398ebf1a9bc", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi7_Wi7_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 7, + "Wi": 7, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 7, + "Wi": 7, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b1f21965-d6b8-46c2-9950-f76da5577269", + "name": "gfx950_conv_fwd_dtypebf16_N256_Hi224_Wi224_C3_K64_Y7_X7_sH2_sW2_pH3_pW3_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 256, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 256, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "da159b1e-5a24-4e92-9d1d-462652e10259", + "name": "gfx950_conv_fwd_dtypebf16_N256_Hi224_Wi224_C3_K64_Y7_X7_sH2_sW2_pH3_pW3_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 256, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 256, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "18c12f19-6a1d-4831-aceb-780c6a022830", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi224_Wi224_C3_K64_Y7_X7_sH2_sW2_pH3_pW3_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "1ea61189-72ac-4d66-96e1-469a3511eba0", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi224_Wi224_C3_K64_Y7_X7_sH2_sW2_pH3_pW3_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 64, + "Y": 7, + "X": 7, + "sH": 2, + "sW": 2, + "pH": 3, + "pW": 3, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "3abd0de9-1090-449c-a960-e49f3b0a0d1e", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C3_K1280_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 1280, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 1280, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "3fc2496d-d855-4465-a4d6-9fa61ade339f", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C3_K1280_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 1280, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 1280, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "f736874c-b4fb-4a9e-8a6e-e8c3d3a557c1", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi512_Wi512_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "16567b8b-81d3-4032-afef-d6c27efdbd67", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi512_Wi512_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "322cb612-2594-4d33-a99b-b90220be4612", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi128_Wi128_C16_K1536_Y2_X2_sH2_sW2_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 1536, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 1536, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "35f7301c-f991-46c2-9a88-d70eccd38c01", + "name": "gfx950_conv_fwd_dtypebf16_N2_Hi128_Wi128_C16_K1536_Y2_X2_sH2_sW2_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 2, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 1536, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 2, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 1536, + "Y": 2, + "X": 2, + "sH": 2, + "sW": 2, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "0fa457cc-6d5b-48e8-8125-48d941d068c1", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C16_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "5e307b51-c0fe-43bd-9fe1-5893957ff30a", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C16_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 16, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "cd32d4c2-646f-4e2b-9add-313c3b748765", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "1bc0e5ea-5545-4821-8647-193174f4ad6c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "8a325587-63d3-4881-9cb1-57ac5d61880b", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "5b23f32e-17cc-4948-81ab-f788fcd73d78", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi128_Wi128_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 128, + "Wi": 128, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "e443e54a-4b83-4ff5-ac12-4d5c8e224732", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi512_Wi512_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "350d4411-ec0d-44c6-a6ee-f8da5494d1b4", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi512_Wi512_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "07a889a8-3406-43e7-b97e-d52aa9f0f591", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi256_Wi256_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 256, + "Wi": 256, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 256, + "Wi": 256, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "edbddc08-d145-47b3-819a-6d0aba1e5711", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi256_Wi256_C512_K512_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 256, + "Wi": 256, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 256, + "Wi": 256, + "C": 512, + "K": 512, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2f68c595-cd3f-4bd1-97b0-5cccfb6d247c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C128_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "9285e2cc-b4c1-4b8c-bfca-bb6007d24258", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C128_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "479d2351-7ff4-44f0-b4ce-32c796ebcfd2", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C128_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "83a11316-0123-4986-8238-daa5a638d14f", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1024_Wi1024_C128_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 128, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "733101e2-b12e-4a7c-b441-f21b81431fd2", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi1024_Wi1024_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "f0a145e7-9237-48e5-9f15-0e7f39907e32", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi1024_Wi1024_C3_K128_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1024, + "Wi": 1024, + "C": 3, + "K": 128, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "0f4b75d7-6310-4645-83af-2fe0cde04a61", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi384_Wi384_C3_K1152_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 384, + "Wi": 384, + "C": 3, + "K": 1152, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 384, + "Wi": 384, + "C": 3, + "K": 1152, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "85cd99ce-7688-4890-bdbc-15db10dcf863", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi384_Wi384_C3_K1152_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 384, + "Wi": 384, + "C": 3, + "K": 1152, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 384, + "Wi": 384, + "C": 3, + "K": 1152, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2673ac76-f93f-4784-948a-ade9f5826774", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi512_Wi512_C3_K1536_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 1536, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 1536, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "dd8fb97f-3cb4-46b9-a976-90cf540c9f35", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi512_Wi512_C3_K1536_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 1536, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 512, + "Wi": 512, + "C": 3, + "K": 1536, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "6514c424-5fa1-4404-808a-2d8f83e503bf", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi224_Wi224_C3_K768_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "ae8d93dd-e069-4de0-9f3e-8c027e963975", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi224_Wi224_C3_K768_Y16_X16_sH16_sW16_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 768, + "Y": 16, + "X": 16, + "sH": 16, + "sW": 16, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "56b72555-0d49-4293-9ee4-97b124f8126c", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K1024_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "9644aebb-a23c-46be-bbb6-447fef6ae4d5", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi224_Wi224_C3_K1024_Y14_X14_sH14_sW14_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 224, + "Wi": 224, + "C": 3, + "K": 1024, + "Y": 14, + "X": 14, + "sH": 14, + "sW": 14, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "bc0407c3-bebc-4444-ad7a-8f45282c8d50", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "b88f5563-9e3e-4b6c-b337-62aabe719b11", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "4d3e1d88-f632-46f5-a23c-d3425f1c3631", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C512_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 512, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 512, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "4e9f695f-a569-4e66-aa16-4ac6031c832f", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C512_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 512, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 512, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "05624cec-c905-4d78-aae3-d375a3062a0b", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi80_Wi80_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "00104750-237e-4b73-a24e-f7310be552ec", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi80_Wi80_C256_K256_Y3_X3_sH1_sW1_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 256, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "2d86ada6-e98b-4196-baab-953851bd6edc", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi320_Wi320_C64_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 320, + "Wi": 320, + "C": 64, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 320, + "Wi": 320, + "C": 64, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "c58d99df-306e-4067-8ced-f1429bede064", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi320_Wi320_C64_K128_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 320, + "Wi": 320, + "C": 64, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 320, + "Wi": 320, + "C": 64, + "K": 128, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "6f6dd04e-639f-46fa-af56-ac40cf5286c2", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi160_Wi160_C128_K256_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 160, + "Wi": 160, + "C": 128, + "K": 256, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 160, + "Wi": 160, + "C": 128, + "K": 256, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "a4e22f3d-8504-40af-b461-ee532b602007", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi160_Wi160_C128_K256_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 160, + "Wi": 160, + "C": 128, + "K": 256, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 160, + "Wi": 160, + "C": 128, + "K": 256, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "c8113cd6-5cd6-4b38-8ca2-c760b1ea413e", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi80_Wi80_C256_K512_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 512, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 512, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "1667d24a-1772-49fa-b417-eea17974a99a", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi80_Wi80_C256_K512_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 512, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 80, + "Wi": 80, + "C": 256, + "K": 512, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "616b910c-aa07-40ad-b081-923f395b4b59", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C768_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 768, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 768, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "72f9f08f-c9a9-4663-8530-08efaf254e8a", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi40_Wi40_C768_K256_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 768, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 40, + "Wi": 40, + "C": 768, + "K": 256, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "4f48953d-de58-4207-bda6-75a2b3e832ac", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi20_Wi20_C512_K512_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 20, + "Wi": 20, + "C": 512, + "K": 512, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 20, + "Wi": 20, + "C": 512, + "K": 512, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "820cf12b-16db-4831-8eeb-4f071474c1c0", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi20_Wi20_C512_K512_Y1_X1_sH1_sW1_pH0_pW0_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 20, + "Wi": 20, + "C": 512, + "K": 512, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 20, + "Wi": 20, + "C": 512, + "K": 512, + "Y": 1, + "X": 1, + "sH": 1, + "sW": 1, + "pH": 0, + "pW": 0, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "5d1899ca-731a-4815-aaf3-81d3f5eb69f7", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1280_Wi1280_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1280, + "Wi": 1280, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1280, + "Wi": 1280, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "da74e021-38dd-43f3-aca9-a3b04f5a3155", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi1280_Wi1280_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 1280, + "Wi": 1280, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 1280, + "Wi": 1280, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "522c3531-11d2-40b2-804d-f738d1e505b3", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi640_Wi640_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "525d05b3-2047-4f9b-a731-280813c4daf7", + "name": "gfx950_conv_fwd_dtypebf16_N1_Hi640_Wi640_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "bf16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "7e36fc53-0df2-4ba8-aaf1-15b95d8efcac", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi640_Wi640_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "db81d517-33e9-4c09-96d5-5949f64e64c2", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi640_Wi640_C3_K64_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 64, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "1abf1d92-9f5e-4ade-ac6c-8980d04a3a3c", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi640_Wi640_C3_K16_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k64", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 16, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 16, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 64, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + }, + { + "version": "1.0", + "id": "52e6bff0-0a3e-42a6-b74b-1da86f7f0bcf", + "name": "gfx950_conv_fwd_dtypefp16_N1_Hi640_Wi640_C3_K16_Y3_X3_sH2_sW2_pH1_pW1_dH1_dW1_tile_k128", + "kernel_source": { + "kind": "rocke", + "source": "builders/common/convolution_forward.py", + "builder": "build_gfx950_conv_fwd", + "spec": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 16, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + } + }, + "metadata": { + "N": 1, + "Hi": 640, + "Wi": 640, + "C": 3, + "K": 16, + "Y": 3, + "X": 3, + "sH": 2, + "sW": 2, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, + "dtype": "fp16", + "layout": "NHWC", + "groups": 1, + "tile_m": 64, + "tile_n": 64, + "tile_k": 128, + "warp_m": 2, + "warp_n": 2, + "warp_tile_m": 32, + "warp_tile_n": 32, + "warp_tile_k": 16, + "wave_size": 64, + "pipeline": "mem", + "epilogue": "cshuffle" + }, + "priority": 0 + } + ], + "arch": [ + "gfx950" + ] +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kmd.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kmd.json new file mode 100644 index 000000000000..a8b65b04ec0f --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.kmd.json @@ -0,0 +1,116 @@ +{ + "version": "1.0", + "id": "fb2104d3-bae8-40b7-9a6f-4f7bc7ced8c7", + "name": "Gfx950ConvFwd variant fields", + "fields": [ + { + "name": "N", + "type": "int" + }, + { + "name": "Hi", + "type": "int" + }, + { + "name": "Wi", + "type": "int" + }, + { + "name": "C", + "type": "int" + }, + { + "name": "K", + "type": "int" + }, + { + "name": "Y", + "type": "int" + }, + { + "name": "X", + "type": "int" + }, + { + "name": "sH", + "type": "int" + }, + { + "name": "sW", + "type": "int" + }, + { + "name": "pH", + "type": "int" + }, + { + "name": "pW", + "type": "int" + }, + { + "name": "dH", + "type": "int" + }, + { + "name": "dW", + "type": "int" + }, + { + "name": "dtype", + "type": "string" + }, + { + "name": "layout", + "type": "string" + }, + { + "name": "groups", + "type": "int" + }, + { + "name": "tile_m", + "type": "int" + }, + { + "name": "tile_n", + "type": "int" + }, + { + "name": "tile_k", + "type": "int", + "default_value": 64 + }, + { + "name": "warp_m", + "type": "int" + }, + { + "name": "warp_n", + "type": "int" + }, + { + "name": "warp_tile_m", + "type": "int" + }, + { + "name": "warp_tile_n", + "type": "int" + }, + { + "name": "warp_tile_k", + "type": "int" + }, + { + "name": "wave_size", + "type": "int" + }, + { + "name": "pipeline", + "type": "string" + }, + { + "name": "epilogue", + "type": "string" + } + ] +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.udd.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.udd.json new file mode 100644 index 000000000000..0a4ba804b3d4 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.udd.json @@ -0,0 +1,6 @@ +{ + "version": "1.0", + "id": "d71abd4b-3fea-4c48-a3a1-577a5acb34eb", + "name": "Gfx950ConvFwd dispatch", + "dispatch_symbol": "hipkernel.gfx950_conv_fwd.dispatch" +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.ued.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.ued.json new file mode 100644 index 000000000000..c72023a54e27 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.ued.json @@ -0,0 +1,14 @@ +{ + "version": "1.0", + "id": "29423f05-8c7b-468a-930b-9e88ca7c99ee", + "name": "hipkernel:Gfx950ConvFwd", + "sdk_version": "1.0.0", + "graph_match": { + "native": "hipkernel.gfx950_conv_fwd.graph_match" + }, + "metadata": "fb2104d3-bae8-40b7-9a6f-4f7bc7ced8c7", + "heuristic": "bca15e6d-a06a-41d3-83d8-8d26ccefa7ff", + "knobs": [ + "tile_k" + ] +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.uhd.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.uhd.json new file mode 100644 index 000000000000..87b6f262b7c3 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/gfx950_conv_fwd.uhd.json @@ -0,0 +1,7 @@ +{ + "version": "1.0", + "id": "bca15e6d-a06a-41d3-83d8-8d26ccefa7ff", + "name": "Gfx950ConvFwd selector", + "kind": "native", + "payload": "hipkernel.gfx950_conv_fwd.score" +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/kernel_dtype_matches_graph.umd.json b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/kernel_dtype_matches_graph.umd.json new file mode 100644 index 000000000000..c6fad9455411 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd/kernel_dtype_matches_graph.umd.json @@ -0,0 +1,7 @@ +{ + "version": "1.0", + "id": "3aa9f90a-4080-473d-b08a-65d3acc3b05f", + "name": "kernel dtype matches the graph's dtype", + "scope": "kernel", + "match_symbol": "hipkernel.gfx950_conv_fwd.kernel_match" +} diff --git a/dnn-providers/hip-kernel-provider/descriptor-packaging/tests/test_hkp_pack_layout.py b/dnn-providers/hip-kernel-provider/descriptor-packaging/tests/test_hkp_pack_layout.py index 12f1f708644c..384bb90f4e51 100644 --- a/dnn-providers/hip-kernel-provider/descriptor-packaging/tests/test_hkp_pack_layout.py +++ b/dnn-providers/hip-kernel-provider/descriptor-packaging/tests/test_hkp_pack_layout.py @@ -580,7 +580,11 @@ def test_example_tree_is_self_consistent(): ids = [d.id for d in flat.descriptors] assert len(ids) == len(set(ids)), "duplicate descriptor ids in the example" rel_dirs = {d.rel_dir.as_posix() for d in flat.kdps()} - assert rel_dirs == {"hip/pointwise_add", "rocKE/gfx942_tiled_attention"} + assert rel_dirs == { + "hip/pointwise_add", + "rocKE/gfx942_tiled_attention", + "rocKE/gfx950_conv_fwd", + } # --- F. Toolchain provenance ------------------------------------------------ diff --git a/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/README.md b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/README.md new file mode 100644 index 000000000000..7b6d1270014e --- /dev/null +++ b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/README.md @@ -0,0 +1,169 @@ +# Packaged gfx950 forward convolution + +`hipkernel:Gfx950ConvFwd` runs rocKE's implicit-GEMM forward convolution through +the HIP Kernel Provider. It accepts plain 2D cross-correlation with dense +channels-last storage, groups=1, FP16 or BF16 storage, FP32 accumulation, and +symmetric padding. See [the graph contract](graph_contract.md) for the exact +dimension/stride mapping and rejection rules, and [kernel mining](mining.md) +for the ABI and compile-time constraints. + +The catalog contains 71 compiled variants for 61 distinct requests. Ten small +requests cover both storage types for padded 3x3, pointwise 1x1, strided, +dilated, and non-square convolution, with `tile_k=64` and `tile_k=128` for each. +The remaining 51 requests are the applicable headline convolution workloads, +using the dispatcher's default tuning. This is a specialized catalog, not a +general convolution engine. An otherwise valid request needs a matching +compiled entry. Grouped, 3D, fused, channels-first, and other dtypes are +integration gaps; they are not claims about rocKE's broader capabilities. +The [verification and coverage snapshot](coverage.md) records actual dispatched +counts, independent correctness results, and the remaining catalog gaps. + +## Build and packaging + +The integration is based on ingestor tooling revision +`9285929e1de2ada46cc01e9054ff3ed5fa6c0456`. Use a checkout containing hipDNN, +the HIP Kernel Provider, the shared integration tests, and their dependencies. +The build requires ROCm with gfx950 support, the rocm-kpack C++ package and +its Python sources, and the Python build requirements documented in +[descriptor packaging](../../descriptor-packaging/README.md). + +From the repository root, choose separate build and install directories: + +```bash +export CONV_BUILD="$PWD/build-conv" +export CONV_INSTALL="$PWD/install-conv" +export ROCKE_LLVM_FLAVOR=llvm22 +export ROCKE_COMGR_LIB=/opt/rocm/lib/libamd_comgr.so +export AMD_COMGR_CACHE_DIR="$CONV_BUILD/comgr-cache" + +cmake --preset hip-kernel-provider -B "$CONV_BUILD" \ + -DCMAKE_INSTALL_PREFIX="$CONV_INSTALL" \ + '-DROCM_LIBS_ENABLE_COMPONENTS=hipdnn;hipdnn-python;hipdnn-integration-tests;hip-kernel-provider' \ + -DHIPDNN_ENABLE_KERNEL_INGESTOR=ON \ + -DHIPKERNELPROVIDER_ENABLE_ROCKE=ON \ + -DHIPKERNELPROVIDER_PRODUCTION_ENABLE_ROCKE=ON \ + -DHIPKERNELPROVIDER_PRODUCTION_ENABLE_HIP=ON \ + -DHIPKERNELPROVIDER_ROCKE_COMGR_LIB="$ROCKE_COMGR_LIB" \ + -DHIPKERNELPROVIDER_PRODUCTION_SOURCE_ROOT="$PWD/dnn-providers/hip-kernel-provider/descriptor-packaging/examples/descriptors" \ + -DHIPKERNELPROVIDER_KPACK_PYTHON_DIR="" \ + '-DCMAKE_PREFIX_PATH=;/opt/rocm' \ + -DGPU_TARGETS=gfx950 -DAMDGPU_TARGETS=gfx950 \ + -DENABLE_ASM_SDPA_ENGINE=OFF +cmake --build "$CONV_BUILD" --parallel +cmake --install "$CONV_BUILD" +``` + +Select the LLVM flavor matching the installed compiler; the example uses +LLVM 22. Keep the same flavor and comgr library for direct comparisons. + +The authored descriptors live under +`descriptor-packaging/examples/descriptors/rocKE/gfx950_conv_fwd`. `hkp_pack` +compiles their rocKE builders into GPU code objects, archives those in kpack, +and rewrites the shipped descriptors to `kind: kpack`. The installed engine +loads that archive without Python. These descriptors do not belong in +`HIPDNN_DESCRIPTOR_FILES` or the embedded kernel lists. + +Generator configuration and the tooling profile are under +`projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd*.yaml`. +Regenerate descriptors with the generator before changing the shipped catalog; +retain existing UUIDs when extending it. The adapter derives tuning defaults +from the actual convolution dispatcher and delegates support checks and IR +construction to the original rocKE builder. + +## Correctness and engine attribution + +Run `hipdnn_list_engines --plugin-dir +"$CONV_INSTALL/lib/hipdnn_plugins/engines"` and require the exact name +`hipkernel:Gfx950ConvFwd`. Enumeration alone does not prove dispatch. + +The provider's `*Gfx950ConvFwd*` unit tests cover graph refusal, every baked +constraint, geometry/overflow, output validation, and buffer nonaliasing. +Its GPU tests force both `tile_k` values for FP16 and BF16, compare with the CPU +reference, and verify benchmarking and plan recreation. Use their installed +binaries with `--gtest_filter='*Gfx950ConvFwd*'`. + +The shared bundles are `quick/Gfx950ConvFwd/Smoke` (two cases) and +`standard/Gfx950ConvFwd/Spatial` (eight spatial cases plus a representative +56x56 BF16 headline workload). The registered target pins the engine by name: + +```bash +ctest --test-dir "$CONV_INSTALL/bin/hip_kernel_provider" \ + -R '^hip_kernel_provider_gfx950_conv_fwd_external_integration_tests$' -V + +"$CONV_INSTALL/bin/hipdnn_integration_tests" \ + --test-article "$CONV_INSTALL/lib/hipdnn_plugins/engines/libhip_kernel_provider.so" \ + --test-engine hipkernel:Gfx950ConvFwd \ + --reference-executor gpu --fail-on-unsupported \ + --gtest_filter='quick_Gfx950ConvFwd*:standard_Gfx950ConvFwd*' +``` + +Count dispatched and skipped cases in the output. The direct invocation fails +on an unsupported graph instead of allowing a suite containing only skips to +pass. The external target is enabled when both the ingestor and production +rocKE packaging are enabled. + +Reconfigure CMake after editing bundle JSON: the shared harness copies its +bundle data into the build tree during configuration, then installs that copy. + +## Selection, cache, and timing + +`tile_k` is an integer engine knob with values 64 and 128. Fallback ranking +prefers 64, matching the dispatcher. With `HIPDNN_FORCE_BENCHMARKING=1`, the +existing ingestor benchmarks all applicable candidates on first execution and +persists the measured ranking. A complete cached ranking suppresses a new +search, including after process restart. Use a fresh `HIPDNN_CACHE_DIR` for +each first-search experiment. + +The pinned runtime uses one warmup and seven timed executions per candidate, +reduces those samples with `robustMean`, and delegates subsequent executions to +the fastest measured candidate. This integration uses that implementation and +its persistent winner cache without changing either. + +The integration probe at +`projects/hipdnn/tools/IngestorGenerator/tools/benchmark_conv_integration.py` +checks the exact engine, validates each forced variant against PyTorch, +records the first search separately, and compares steady-state execution with +direct rocKE using the same spec and compiler. Run its `--help` for artifact +paths and forced/automatic/reuse modes. Execute reuse in a separate process +with the same cache. The fastest result means fastest among the valid variants +actually packaged and measured; first-search time is excluded from reported +steady-state timing. Keep raw measurements in private evidence outside Git. + +To compare another shipped workload, save one object from +`configs/gfx950_conv_fwd.requests.json` to a separate request file and pass +`--request-file --tile-k 64`. The probe derives the dimensions, strides, +and convolution attributes from that request, verifies the exact packaged UUID, +and records the source provenance. Custom requests use an independent PyTorch +FP32 GPU reference on the quantized inputs with TF32 disabled; the small smoke +tests use a CPU reference. The probe checks both results before timing. + +Default timing measures HIP graph replay with GPU events. Use +`--timing-mode events` to include ordinary Python submission gaps in a separate +measurement; do not interpret that result as kernel execution time alone. +The probe suspends its synchronous selection-log callback and backend/plugin +logging during warmup, capture, and timing, then restores them for cache checks. +Ordinary submission results include Python bindings and frontend variant-pack +construction on each call; the report also records the frontend logging state. + +## Coverage audit + +`mine_conv_shapes.py` reads rocKE's canonical convolution cases and +dnn-benchmarking graph JSON directories or workload tarballs. It preserves +source hashes/URIs, attributes, every excluded record, and deduplicated requests. +Unknown categorical values fail rather than acquiring guessed defaults. + +```bash +python projects/hipdnn/tools/IngestorGenerator/tools/mine_conv_shapes.py \ + --rocke-cases dnn-providers/hip-kernel-provider/rocke/library/benchmarks/common/grouped_conv/bench_cases_conv.json \ + --graphs '' \ + --graphs '' \ + --arch gfx950 --out '/conv_requests.json' +``` + +Run the actual adapter predicate on the resulting requests, then validate the +graphs through the installed engine using dnn-benchmarking's explicit +`--engine` selection and `--validate pytorch`. Report actual dispatched/declined +counts separately from offline support predictions. A predicate-accepted +request absent from the catalog is missing integration coverage. A family +rejection needs its concrete predicate reason. Neither bucket proves GPU +correctness without an execution against a reference. diff --git a/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/coverage.md b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/coverage.md new file mode 100644 index 000000000000..995d7b565d1e --- /dev/null +++ b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/coverage.md @@ -0,0 +1,116 @@ +# gfx950 forward convolution verification and coverage + +This snapshot records the specialized POC verified on gfx950 on 2026-09-09. +The shipped catalog contains 71 variants for 61 requests: ten verification +requests with two `tile_k` values each, plus 51 distinct headline requests with +the dispatcher's default `tile_k=64`. The [graph contract](graph_contract.md) +defines the accepted operation and storage semantics. + +## Verification + +| Check | Result | +|---|---| +| Adapter, original-builder IR equivalence, library layering, and miner tests | 98 passed (56 adapter/layering and 42 miner). | +| Provider unit tests | 21 passed, zero skipped. | +| Provider GPU integration tests | 24 passed, zero skipped; includes all 20 forced verification variants with two input seeds. | +| Installed shared integration harness | 11 passed, zero skipped, through the exact engine name; both registered CTest and direct `--fail-on-unsupported` invocation passed. | +| Installed descriptor validator | Passed, including all four native symbols and exact engine registration. | +| Catalog checks | 71 unique packaged symbols/TOC entries, complete metadata equality, and 71 reachable forced variants. | +| Native geometry comparison | Agreed with rocKE on 1,093 cases; eight additional default-epilogue cases also checked. | +| Independent corpus correctness | 106 source graphs passed PyTorch comparison; zero failed or skipped. | +| Direct rocKE comparison | Both smoke tuning choices for both dtypes and all 51 headline requests passed independent correctness before timing. | +| Selection and cache | Both dtypes measured two candidates, selected the fastest recorded candidate, and reused the winner on repeated execution, plan recreation, and separate-process restart. | + +Engine attribution is explicit: `hipkernel:Gfx950ConvFwd` +(`0xAD075A5EA86DD563`). Selecting another engine cannot satisfy these checks. +The installed descriptor loader emits its existing warnings for the optional +`provenance` extension; validation reported no errors or unresolved symbols. + +The 106 corpus graphs represent 51 distinct requests. Together with the ten +small verification requests, they exercise every shipped request. Duplicate +source graphs remain separate coverage records so their provenance is retained. + +## External corpus + +The inventory combines rocKE's canonical `bench_cases_conv.json` at +`faf4621de4be118568e30eb8f69f8f743d4eb773` and dnn-benchmarking's headline +convolution and convolution-sweep archives at +`36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc`. The miner preserves source hashes, +URIs, original attributes, exclusions, and deduplicated requests. It follows +tensor attributes when filenames and dtypes disagree. + +| Source | Records | Graphs audited | Dispatched and correct | Declined | Could not be rendered faithfully | +|---|---:|---:|---:|---:|---:| +| rocKE canonical cases | 111 | 96 | 51 | 45 | 15 | +| Headline convolution | 179 | 179 | 55 | 124 | 0 | +| Convolution sweep | 429 | 429 | 0 | 429 | 0 | +| Total | 719 | 704 | 106 | 598 | 15 | + +These are actual installed-runtime counts. All 704 representable graphs passed +frontend construction. The exact engine declined 598 at engine selection; +there were no discrepancies between predicted and observed dispatch and no +audit errors. Every accepted graph then ran against an independent PyTorch +reference, with explicit execution and tolerance-comparison success checked. +The miner also rejects shape-override-enabled graphs as outside this fixed-shape +contract. None of the 704 audited source graphs enables that flag. + +## Remaining coverage + +The 598 runtime declines split into three populations: + +- **349 backward graphs:** 168 input-gradient and 181 weight-gradient graphs. + They request different operations from this forward engine. +- **124 catalog gaps:** these are 124 distinct 2D forward sweep requests within + the integration contract. The real rocKE factory and validity predicate accept + every request, but no matching variant ships. They remain open integration + coverage work; they are not kernel-family limitations. +- **125 forward graphs outside the integration contract:** the graph matcher + rejects their recorded attributes, including grouped, 1D/3D, other layouts or + dtypes, and asymmetric padding. The family comparison below distinguishes + proven support from requests that cannot be projected faithfully. + +For those 125 forward declines, the scoped rocKE comparison reports: + +| Classification | Records | Evidence and interpretation | +|---|---:|---| +| Family accepts an equivalent request | 71 | Additional integration-contract gaps, including grouped and 3D convolution. Acceptance is a capability/predicate result; these declined graphs have not been validated numerically through this engine. | +| Family declines an equivalent request | 13 | Two channels-first requests, seven actual int8 requests, and four FP32 requests fail the forward family's layout or dtype capability gate. | +| No faithful request projection | 41 | Twenty-three asymmetrically padded 3D graphs cannot be represented by the oracle's symmetric-padding request fields; eighteen 1D graphs are outside its 2D/3D projection. Some also mix operand layouts or have asymmetric padding. No rocKE support verdict is claimed. | + +The remaining 15 canonical source records were never submitted as simplified +graphs: two composed sums, one transpose convolution, one deformable convolution, +three streaming/cache-equivalence workloads, and eight causal 1D workloads with +implicit cropping. Preserving those semantics requires additional graph or +state modeling. They are recorded as unrenderable source records, not runtime +declines or successful tests. + +Of 175 distinct eligible requests, the catalog covers 51 and omits 124. The +broader runbook's goal of zero reference-only declines therefore remains open. +The next catalog expansion should start with those 124 requests, followed by +separate contract and reference work for grouped, 3D, and fused operations. +The successful POC checks do not establish those broader capabilities. + +## Performance evidence + +The integration probe checks the installed descriptor UUID and all compiled +spec fields, rebuilds direct rocKE from the equivalent original-builder spec, +and uses the same gfx950 device, LLVM flavor, and COMGR library. Compilation, +plan creation, first execution/search, correctness, capture, and warmup are +excluded from steady-state kernel comparison. HIP graph replay and ordinary +submission timing are reported separately. +Selection-log callbacks and backend/plugin logging are suspended during timing +and restored for subsequent cache assertions. The report checks the logging +state and zero callback invocations within that interval. + +Candidate ranking uses the existing runtime's one warmup and seven timed +executions with `robustMean`; the probe's steady-state report uses the median +of sample batches. These are separate measurements. A winning variant is the +fastest valid candidate measured during that search, with no claim that a close +ordering is invariant across runs. Persistent cache checks compare UUIDs and +ranking hashes across different process IDs. + +Measured performance reports and historical baseline comparisons are retained +as private evidence outside the source tree. The 51 headline requests, the +48-request canonical subset, and historical-baseline matches are reported as +separate populations. Historical timings do not establish integration overhead; +the current same-spec, same-device comparison supplies that evidence. diff --git a/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/graph_contract.md b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/graph_contract.md new file mode 100644 index 000000000000..028944ec0b30 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/graph_contract.md @@ -0,0 +1,102 @@ +# gfx950 forward convolution graph contract + +Integration base: `9285929e1de2ada46cc01e9054ff3ed5fa6c0456`. +Engine: `hipkernel:Gfx950ConvFwd`. Descriptor dialect: `packaged`. + +## 1. Operation match + +Exactly one `ConvolutionFwdAttributes` node implements plain 2D forward +cross-correlation. The node binds three distinct tensor UIDs: input X, filter W, +and output Y. Bias, activation, backward, and other fused graphs decline. +The operation uses FP32 accumulation and uniform FP16 or BF16 input, filter, +and output. There is no workspace. + +## 2. Field audit + +The authority is `flatbuffers_sdk/schemas/convolution_fwd_attributes.fbs`. + +| Field | Treatment | +|---|---| +| `x_tensor_uid` | Bind a nonvirtual, dense, rank-4 input tensor. | +| `w_tensor_uid` | Bind a nonvirtual, dense, rank-4 filter; require input-channel equality, hence groups=1. | +| `y_tensor_uid` | Bind output; validate its inferred dimensions and layout during prepare. | +| `pre_padding` | Require two nonnegative integers; match both compiled values. | +| `post_padding` | Require equality with pre-padding on both axes. | +| `stride` | Require two positive integers; match both compiled values. | +| `dilation` | Require two positive integers; match both compiled values. | +| `conv_mode` | Require `CROSS_CORRELATION`; decline `CONVOLUTION` and `UNSET`. | + +The enclosing node's compute type must be `FLOAT`. Tensors must have positive +extents and valid physical strides. Reject virtual tensors, constant values, +runtime pass-by-value, ragged offsets, incompatible dtypes, and overlapping +runtime buffers. Actual addresses must satisfy the builder's 16-byte alignment +contract. Dense byte counts and kernel index arithmetic must fit signed 32-bit +values. Tensor names and graph names do not affect computation. + +The enclosing graph's `is_override_shape_enabled` field (from `graph.fbs`) +must be false. Each packaged kernel has fixed dimensions and strides, so the +matcher rejects graphs that enable execution-time shape overrides. + +This schema has no alpha/beta, bias, or group-count scalar. Plain convolution +overwrites Y. Groups are inferred from X channels divided by filter channels; +requiring those channel dimensions equal enforces groups=1. Fusions are graph +compositions and are rejected through the single-node requirement. + +## 3. Frontend and reference reading + +`ConvFpropAttributes` defaults to cross-correlation. `set_padding` sets both +padding vectors; separate pre/post setters can express asymmetric padding, +which this engine declines. Logical dimensions remain NCHW even when storage +is channels-last. The GPU reference `GpuRefConvFwd.cpp` indexes logical NCHW +using supplied strides and computes cross-correlation without reversing W. +The equivalent framework operation is `torch.nn.functional.conv2d` with no +bias, `groups=1`, and explicit stride, padding, and dilation. + +No deprecated convolution attribute spelling appears in the pinned schema. +The output is inferred by the frontend and need not be complete during graph +matching, so output layout validation belongs to dispatch preparation. + +## 4. Real graph sources + +The in-tree convolution bundles and the public `ROCm/dnn-benchmarking` +`Workloads/headline/conv` and `Workloads/microbench/conv_sweep` archives carry +logical NCHW tensor dimensions and explicit strides. Both sources include +layouts and operations outside this engine's contract; layout must be derived +from strides, never from a tensor name or the dimensions alone. Published +workloads are substantially broader than the smoke shape and include backward, +grouped, 3D, and fused graphs. + +The convolution miner retains each source graph, its attributes, and its +provenance. Coverage is assessed against that inventory, independently of the +small correctness matrix. A legal rocKE request without a compiled catalog +entry is reported as a catalog gap. + +## 5. Mapping to the compiled kernel + +| rocKE field | hipDNN source / rule | +|---|---| +| `N` | X dimension 0; Y dimension 0 must agree. | +| `C` | X dimension 1; W dimension 1 must agree. | +| `K` | W dimension 0; Y dimension 1 must agree. | +| `Hi`, `Wi` | X dimensions 2 and 3. | +| `Y`, `X` | W dimensions 2 and 3 (filter height and width). | +| `sH`, `sW` | `stride[0]`, `stride[1]`. | +| `pH`, `pW` | `pre_padding[0]`, `pre_padding[1]`, equal to post-padding. | +| `dH`, `dW` | `dilation[0]`, `dilation[1]`. | +| `Ho`, `Wo` | `(input + 2*padding - dilation*(filter-1) - 1)/stride + 1`, with nonnegative numerator. | +| `dtype` | `HALF` maps to `fp16`; `BFLOAT16` maps to `bf16`. | +| `layout`, `groups` | Dense channels-last, groups=1. | +| `tile_m`, `tile_n`, `tile_k` | Compiled KMD fields; only `tile_k` is an exposed engine knob. | +| `warp_m`, `warp_n`, `warp_tile_m`, `warp_tile_n`, `warp_tile_k`, `wave_size` | Resolved compile-time tuning, checked by the builder and native geometry. | +| `pipeline`, `epilogue` | `mem` pipeline; dispatcher-resolved epilogue, carried in metadata. | + +Physical layouts (strides in elements): + +| Tensor | Logical dimensions | Strides | rocKE physical order | +|---|---|---|---| +| X | `[N,C,Hi,Wi]` | `[Hi*Wi*C,1,Wi*C,C]` | NHWC | +| W | `[K,C,Y,X]` | `[Y*X*C,1,X*C,C]` | KYXC | +| Y | `[N,K,Ho,Wo]` | `[Ho*Wo*K,1,Wo*K,K]` | NHWK | + +A unit-extent axis does not participate in address arithmetic, so its declared +stride need not equal the canonical value. All nondegenerate axes must match. diff --git a/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/mining.md b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/mining.md new file mode 100644 index 000000000000..9ca4a4d6bada --- /dev/null +++ b/dnn-providers/hip-kernel-provider/docs/gfx950_conv_fwd/mining.md @@ -0,0 +1,74 @@ +# gfx950 convolution kernel mining + +Builder: `rocke.instances.common.conv_implicit_gemm.build_implicit_gemm_conv`. +Packaging adapter: `builders.common.convolution_forward.build_gfx950_conv_fwd`. +Base: `9285929e1de2ada46cc01e9054ff3ed5fa6c0456`. + +The primary source is `platform/python/rocke/instances/common/conv_implicit_gemm.py`. +Supporting sources are its `_conv_implicit_gemm_common.py`, +`library/dispatch/grouped_convolution.py`, the graph schema and frontend header +named in `graph_contract.md`, and the existing convolution reference tests. + +| Constraint | Verdict | Enforcement | +|---|---|---| +| Architecture | gfx950 only for this integration | Pack architecture, adapter, native matcher. | +| Direction | Plain forward | One `ConvolutionFwdAttributes` node; adapter requires forward request. | +| Dtype | Uniform FP16 or BF16 with FP32 accumulation | Graph match and adapter; per-kernel dtype equality. | +| Layout | Dense channels-last | Graph strides and prepare-time output check. | +| Spatial rank | 2D only in this engine | Rank/attribute vector checks. | +| Group count | 1 in this engine | X and W channels equal; adapter group check. | +| Padding | Nonnegative and symmetric | Both graph padding vectors checked. | +| Stride and dilation | Positive, both dimensions baked | Exact per-kernel metadata match. | +| Shape | Every dimension is baked | Exact per-kernel metadata match. | +| Fusion callbacks | None | Adapter delegates without callbacks; graph declines fusion. | +| Buffer ABI | Three 16-byte-aligned, nonaliasing pointers | Launch validation. | +| Buffer byte counts | Signed i32 | Checked multiplication before narrowing. | +| Grid bounds | All axes at most 65535 | Real `is_valid_spec_for_problem` and native geometry. | +| Pipeline | `mem` | Spec and native matcher. | +| Epilogue | Dispatcher-derived `cshuffle` or `default` | Resolved in factory, serialized, validated. | +| Tune validity | Real rocKE rules for atoms, waves, divisibility and LDS | Delegate to `is_valid_spec_for_problem`; no duplicated permissive oracle. | +| Workspace | Zero | Forward kernel has no scratch argument. | + +Grouped and 3D convolution exist in the upstream family. Their rejection here +is an integration-contract gap, not evidence that rocKE cannot implement them. +Likewise, a supported shape absent from the package is a catalog gap. The +coverage report keeps these distinct from actual family predicate failures. + +## Default tuning and initial candidate pair + +The gfx950 forward dispatcher resolves `tile_m=64`, `tile_n=64`, `tile_k=64`, +`warp_m=2`, `warp_n=2`, atoms `32x32x16`, `wave_size=64`, and `pipeline=mem`. +The smoke shape resolves the `cshuffle` epilogue. Its tuning twin changes only +`tile_k` to 128. Both are real integer engine-knob values. Fallback ranking +prefers 64; runtime benchmarking can select either valid candidate. + +The adapter serializes resolved values. The original builder's name omits dtype, +padding, stride, and dilation; a deterministic digest over the complete adapter +spec prevents distinct compiled kernels from sharing a symbol. + +## Launch contract + +Arguments, in declaration order: + +1. Input A pointer. +2. Filter B pointer. +3. Output D pointer. +4. `A_bytes` (`i32`): `2*N*Hi*Wi*C`. +5. `B_bytes` (`i32`): `2*K*Y*X*C`. +6. `D_bytes` (`i32`): `2*N*Ho*Wo*K`. + +Grid is `(ceil(K/tile_n), ceil(N*Ho*Wo/tile_m), 1)` and block is +`(warp_m*warp_n*wave_size,1,1)`. Dynamic shared memory is zero; static LDS is +part of the compiled code object. The prepared dispatch must retain both the +compiled program and its runnable kernel and copy graph UIDs/scalars, because +match contexts do not outlive plan preparation. + +## Verification obligations + +Compare adapter IR with direct original-builder IR for each initial dtype/tile +pair. Validate descriptors before and after packing. Force both knob values +through the exact engine, check numerical results against an independent +reference, and test all rejection rows. Benchmark using a fresh cache and +explicit benchmarking, then verify plan recreation and process-restart reuse. +Keep the initial search out of steady-state timing and compare against direct +rocKE execution using the same spec, compiler, and GPU. diff --git a/dnn-providers/hip-kernel-provider/rocke/library/builders/common/convolution_forward.py b/dnn-providers/hip-kernel-provider/rocke/library/builders/common/convolution_forward.py new file mode 100644 index 000000000000..69ecd9345007 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/rocke/library/builders/common/convolution_forward.py @@ -0,0 +1,279 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT + +"""Packaging adapter for the gfx950 implicit-GEMM forward convolution. + +The descriptor spec is flat, while the original builder takes nested problem +and data specs plus optional fusion callbacks. This adapter resolves dispatcher +defaults before packaging and calls the original builder without callbacks. +It does not change the kernel body or introduce a runtime Python dependency. + +The initial contract is 2D cross-correlation, dense NHWC input, KYXC filter, +NHWK output, groups=1, uniform fp16/bf16, and fp32 accumulation. Padding is +symmetric. The ABI is ``(A, B, D, A_bytes:i32, B_bytes:i32, D_bytes:i32)``; +pointers must be 16-byte aligned and non-aliasing. Forward needs no workspace. +""" + +from __future__ import annotations + +import hashlib +import json +from dataclasses import asdict, dataclass, replace + +from dispatch.grouped_convolution import ConvGroupedRequest, dispatch_conv_grouped +from rocke.core.ir import KernelDef +from kernels.common import conv_implicit_gemm as _conv + +_ARCH = "gfx950" +_INT32_MAX = (1 << 31) - 1 + + +@dataclass(frozen=True) +class Gfx950ConvFwdSpec: + """Serializable problem and resolved tuning values for one packaged kernel. + + Use :func:`gfx950_conv_fwd_spec_for_request` to obtain the dispatcher's + current defaults. Direct construction is useful for descriptor hydration; + :func:`supports_gfx950_conv_fwd` and the builder validate it before emission. + All geometry is compiled into the kernel and must match the runtime graph. + """ + + N: int + Hi: int + Wi: int + C: int + K: int + Y: int + X: int + sH: int = 1 + sW: int = 1 + pH: int = 0 + pW: int = 0 + dH: int = 1 + dW: int = 1 + dtype: str = "fp16" + layout: str = "NHWC" + groups: int = 1 + tile_m: int = 64 + tile_n: int = 64 + tile_k: int = 64 + warp_m: int = 2 + warp_n: int = 2 + warp_tile_m: int = 32 + warp_tile_n: int = 32 + warp_tile_k: int = 16 + wave_size: int = 64 + pipeline: str = "mem" + epilogue: str = "cshuffle" + + def to_problem(self) -> _conv.ConvProblem: + """Reconstruct the original problem without dropping geometry fields.""" + return _conv.ConvProblem( + N=self.N, + Hi=self.Hi, + Wi=self.Wi, + C=self.C, + K=self.K, + Y=self.Y, + X=self.X, + sH=self.sH, + sW=self.sW, + pH=self.pH, + pW=self.pW, + dH=self.dH, + dW=self.dW, + groups=self.groups, + ) + + def to_instance_spec(self) -> _conv.ImplicitGemmConvSpec: + """Reconstruct the original builder spec; optional fusion stays disabled.""" + # ConvProblem.short() omits stride, padding and dilation, and the + # original kernel name omits dtype. Hash every flat field so otherwise + # identical shape/tile labels cannot collide in the packaged catalog. + payload = json.dumps(asdict(self), sort_keys=True, separators=(",", ":")) + suffix = hashlib.sha256(payload.encode("utf-8")).hexdigest()[:24] + return _conv.ImplicitGemmConvSpec( + problem=self.to_problem(), + name=f"hkp_conv_fwd_gfx950_{suffix}", + data=_conv.ConvDataSpec( + dtype_a=self.dtype, + dtype_b=self.dtype, + dtype_d=self.dtype, + dtype_acc="fp32", + ), + tile_m=self.tile_m, + tile_n=self.tile_n, + tile_k=self.tile_k, + warp_m=self.warp_m, + warp_n=self.warp_n, + warp_tile_m=self.warp_tile_m, + warp_tile_n=self.warp_tile_n, + warp_tile_k=self.warp_tile_k, + wave_size=self.wave_size, + pipeline=self.pipeline, + epilogue=self.epilogue, + groups=self.groups, + ) + + def kernel_name(self) -> str: + """The actual launch symbol emitted by the original builder.""" + return self.to_instance_spec().kernel_name() + + def grid(self) -> tuple[int, int, int]: + """Grid in workgroups, ordered N-tiles, M-tiles, group.""" + return _conv.implicit_gemm_conv_grid(self.to_instance_spec()) + + def block(self) -> tuple[int, int, int]: + return self.warp_m * self.warp_n * self.wave_size, 1, 1 + + +def _problem_error(spec: Gfx950ConvFwdSpec) -> str: + for name in ("N", "Hi", "Wi", "C", "K", "Y", "X", "sH", "sW", "dH", "dW"): + value = getattr(spec, name) + if type(value) is not int or not 0 < value <= _INT32_MAX: + return f"{name} must be a positive signed 32-bit integer" + for name in ("pH", "pW"): + value = getattr(spec, name) + if type(value) is not int or not 0 <= value <= _INT32_MAX: + return f"{name} must be a nonnegative signed 32-bit integer" + if type(spec.groups) is not int or spec.groups != 1: + return "the packaged forward contract requires groups=1" + if spec.layout != "NHWC": + return "the packaged forward contract requires dense NHWC storage" + if spec.dtype not in ("fp16", "bf16"): + return "the packaged forward contract supports fp16 or bf16 only" + + problem = spec.to_problem() + for label, value in ( + ("padded height", spec.Hi + 2 * spec.pH), + ("padded width", spec.Wi + 2 * spec.pW), + ("effective filter height", spec.dH * (spec.Y - 1) + 1), + ("effective filter width", spec.dW * (spec.X - 1) + 1), + ): + if value > _INT32_MAX: + return f"{label} exceeds signed 32-bit descriptor arithmetic" + if problem.Ho <= 0 or problem.Wo <= 0: + return "convolution has nonpositive output spatial dimensions" + for label, elements in ( + ("input", spec.N * spec.Hi * spec.Wi * spec.C), + ("filter", spec.K * spec.Y * spec.X * spec.C), + ("output", spec.N * problem.Ho * problem.Wo * spec.K), + ): + if elements * 2 > _INT32_MAX: + return f"{label} byte count exceeds the signed 32-bit kernel ABI" + return "" + + +def supports_gfx950_conv_fwd( + spec: Gfx950ConvFwdSpec, *, arch: str = _ARCH +) -> tuple[bool, str]: + """Check the integration contract, then rocKE's real problem/arch predicate.""" + if arch != _ARCH: + return False, f"this adapter requires arch={_ARCH}, got {arch!r}" + if not isinstance(spec, Gfx950ConvFwdSpec): + return False, "expected Gfx950ConvFwdSpec" + error = _problem_error(spec) + if error: + return False, error + for name in ( + "tile_m", + "tile_n", + "tile_k", + "warp_m", + "warp_n", + "warp_tile_m", + "warp_tile_n", + "warp_tile_k", + "wave_size", + ): + value = getattr(spec, name) + if type(value) is not int or not 0 < value <= _INT32_MAX: + return False, f"{name} must be a positive signed 32-bit integer" + if spec.pipeline != "mem": + return False, "the packaged forward contract currently requires pipeline='mem'" + if spec.epilogue not in ("default", "cshuffle"): + return False, "epilogue must be 'default' or 'cshuffle'" + try: + instance = spec.to_instance_spec() + instance.validate() + return _conv.is_valid_spec_for_problem(instance, instance.problem, arch=arch) + except (TypeError, ValueError, ZeroDivisionError) as exc: + return False, str(exc) + + +def gfx950_conv_fwd_spec_for_request( + request: ConvGroupedRequest, *, tile_k: int | None = None +) -> Gfx950ConvFwdSpec: + """Resolve the existing dispatcher's defaults and optionally override tile_k. + + The request interface also describes grouped/3D/backward convolution. + Those requests are rejected here as integration gaps, even when another + rocKE dispatcher candidate can serve them. + """ + if not isinstance(request, ConvGroupedRequest): + raise TypeError("expected ConvGroupedRequest") + if request.arch != _ARCH: + raise ValueError(f"this adapter requires arch={_ARCH}") + if request.direction != "fwd": + raise ValueError("the packaged contract supports forward convolution only") + if any( + value is not None + for value in ( + request.Di, + request.Z, + request.stride_d, + request.pad_d, + request.dilation_d, + ) + ): + raise ValueError("the packaged forward contract supports 2D convolution only") + if request.vec_size_c is not None: + raise ValueError("the packaged contract uses the dispatcher's vector defaults") + base = Gfx950ConvFwdSpec( + N=request.N, + Hi=request.Hi, + Wi=request.Wi, + C=request.C, + K=request.K, + Y=request.Y, + X=request.X, + sH=request.stride_h, + sW=request.stride_w, + pH=request.pad_h, + pW=request.pad_w, + dH=request.dilation_h, + dW=request.dilation_w, + groups=request.G, + dtype=request.dtype.lower(), + layout=request.layout.upper(), + ) + error = _problem_error(base) + if error: + raise ValueError(error) + selected = dispatch_conv_grouped(request).spec + spec = replace( + base, + tile_m=selected.tile_m, + tile_n=selected.tile_n, + tile_k=selected.tile_k if tile_k is None else tile_k, + warp_m=selected.warp_m, + warp_n=selected.warp_n, + warp_tile_m=selected.warp_tile_mn, + warp_tile_n=selected.warp_tile_mn, + warp_tile_k=selected.warp_tile_k, + wave_size=selected.to_fwd_spec(base.to_problem()).wave_size, + pipeline=selected.pipeline, + epilogue=selected.epilogue, + ) + ok, reason = supports_gfx950_conv_fwd(spec, arch=request.arch) + if not ok: + raise ValueError(reason) + return spec + + +def build_gfx950_conv_fwd(spec: Gfx950ConvFwdSpec, *, arch: str = _ARCH) -> KernelDef: + """The typed ``(spec, *, arch)`` entry point consumed by hkp_pack.""" + ok, reason = supports_gfx950_conv_fwd(spec, arch=arch) + if not ok: + raise ValueError(f"invalid packaged forward convolution: {reason}") + return _conv.build_implicit_gemm_conv(spec.to_instance_spec(), arch=arch) diff --git a/dnn-providers/hip-kernel-provider/rocke/library/tests/test_convolution_forward_packaging.py b/dnn-providers/hip-kernel-provider/rocke/library/tests/test_convolution_forward_packaging.py new file mode 100644 index 000000000000..508a01bb002c --- /dev/null +++ b/dnn-providers/hip-kernel-provider/rocke/library/tests/test_convolution_forward_packaging.py @@ -0,0 +1,235 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT + +"""CPU tests for descriptor hydration and the unmodified convolution builder ABI.""" + +from __future__ import annotations + +import inspect +import json +import typing +from dataclasses import asdict, fields, replace + +import pytest +from builders.common.convolution_forward import ( + Gfx950ConvFwdSpec, + build_gfx950_conv_fwd, + gfx950_conv_fwd_spec_for_request, + supports_gfx950_conv_fwd, +) +from dispatch.grouped_convolution import ConvGroupedRequest, dispatch_conv_grouped +from rocke.core.ir import BF16, F16, I32, PtrType +from rocke.core.lower_llvm import _lower_kernel_to_llvm_python +from rocke.instances.common.conv_implicit_gemm import ( + ConvProblem, + build_implicit_gemm_conv, +) + + +def _request(**overrides) -> ConvGroupedRequest: + values = { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "pad_h": 1, + "pad_w": 1, + "arch": "gfx950", + } + values.update(overrides) + return ConvGroupedRequest(**values) + + +def _original_problem(request: ConvGroupedRequest) -> ConvProblem: + return ConvProblem( + N=request.N, + Hi=request.Hi, + Wi=request.Wi, + C=request.C, + K=request.K, + Y=request.Y, + X=request.X, + sH=request.stride_h, + sW=request.stride_w, + pH=request.pad_h, + pW=request.pad_w, + dH=request.dilation_h, + dW=request.dilation_w, + ) + + +@pytest.mark.parametrize("dtype", ["fp16", "bf16"]) +def test_factory_preserves_dispatcher_defaults(dtype): + request = _request(dtype=dtype) + packaged = gfx950_conv_fwd_spec_for_request(request) + original = dispatch_conv_grouped(request).spec.to_fwd_spec( + _original_problem(request) + ) + actual = packaged.to_instance_spec() + assert replace(actual, name=original.name) == original + assert packaged.epilogue == "cshuffle" + assert packaged.tile_k == 64 + assert packaged.grid() == (1, 7, 1) + assert packaged.block() == (256, 1, 1) + + +@pytest.mark.parametrize("dtype", ["fp16", "bf16"]) +@pytest.mark.parametrize("tile_k", [64, 128]) +@pytest.mark.parametrize("llvm_flavor", ["llvm20", "llvm22"]) +def test_adapter_emits_original_llvm_and_six_argument_abi(dtype, tile_k, llvm_flavor): + request = _request(dtype=dtype) + spec = gfx950_conv_fwd_spec_for_request(request, tile_k=tile_k) + original_spec = dispatch_conv_grouped(request).spec.to_fwd_spec( + _original_problem(request) + ) + original_spec = replace( + original_spec, tile_k=tile_k, name=spec.to_instance_spec().name + ) + packaged = build_gfx950_conv_fwd(spec, arch="gfx950") + original = build_implicit_gemm_conv(original_spec, arch="gfx950") + assert _lower_kernel_to_llvm_python( + packaged, arch="gfx950", llvm_flavor=llvm_flavor + ) == _lower_kernel_to_llvm_python(original, arch="gfx950", llvm_flavor=llvm_flavor) + assert packaged.name == spec.kernel_name() + assert [p.name for p in packaged.params] == [ + "A", + "B", + "D", + "A_bytes", + "B_bytes", + "D_bytes", + ] + element = F16 if dtype == "fp16" else BF16 + expected_types = [PtrType(element, "global")] * 3 + [I32] * 3 + assert [p.type for p in packaged.params] == expected_types + assert all(p.attrs["align"] == 16 for p in packaged.params[:3]) + assert packaged.max_workgroup_size == 256 + + +@pytest.mark.parametrize( + "overrides", + [ + {"Y": 1, "X": 1, "pad_h": 0, "pad_w": 0}, + {"stride_h": 2, "stride_w": 2}, + {"dilation_h": 2, "dilation_w": 2, "pad_h": 2, "pad_w": 2}, + {"Hi": 15, "Wi": 19, "Y": 3, "X": 5, "pad_h": 1, "pad_w": 2, "stride_w": 2}, + ], +) +def test_geometry_round_trip_for_extended_2d_matrix(overrides): + request = _request(**overrides) + spec = gfx950_conv_fwd_spec_for_request(request) + assert supports_gfx950_conv_fwd(spec) == (True, "ok") + assert spec.to_problem() == _original_problem(request) + assert spec.grid() == dispatch_conv_grouped(request).grid + + +def test_serialized_spec_and_typed_builder_are_packager_compatible(): + spec = gfx950_conv_fwd_spec_for_request(_request(), tile_k=128) + values = json.loads(json.dumps(asdict(spec))) + assert Gfx950ConvFwdSpec(**values) == spec + assert all(type(values[field.name]) in (int, str) for field in fields(spec)) + signature = inspect.signature(build_gfx950_conv_fwd) + assert list(signature.parameters) == ["spec", "arch"] + assert signature.parameters["arch"].kind is inspect.Parameter.KEYWORD_ONLY + assert typing.get_type_hints(build_gfx950_conv_fwd)["spec"] is Gfx950ConvFwdSpec + + +@pytest.mark.parametrize( + "override", + [ + {"dtype": "bf16"}, + {"sH": 2}, + {"sW": 2}, + {"pH": 2}, + {"pW": 2}, + {"dH": 2}, + {"dW": 2}, + {"tile_k": 128}, + ], +) +def test_symbols_include_attributes_missing_from_original_shape_name(override): + spec = gfx950_conv_fwd_spec_for_request(_request()) + changed = replace(spec, **override) + assert changed.kernel_name() != spec.kernel_name() + restored = Gfx950ConvFwdSpec(**json.loads(json.dumps(asdict(changed)))) + assert restored.kernel_name() == changed.kernel_name() + + +@pytest.mark.parametrize( + ("override", "reason"), + [ + ({"N": 0}, "N must be"), + ({"C": True}, "C must be"), + ({"Hi": 14.0}, "Hi must be"), + ({"sH": 0}, "sH must be"), + ({"dW": -1}, "dW must be"), + ({"pH": -1}, "pH must be"), + ({"groups": 2}, "groups=1"), + ({"layout": "NCHW"}, "NHWC"), + ({"dtype": "fp32"}, "fp16 or bf16"), + ({"tile_k": 0}, "tile_k must be"), + ({"warp_m": 0}, "warp_m must be"), + ({"tile_m": 96}, "not divisible"), + ({"wave_size": 32}, "wave_size"), + ({"pipeline": "wavelet"}, "pipeline='mem'"), + ({"epilogue": "unknown"}, "epilogue must be"), + ({"epilogue": "default"}, "vector size c"), + ({"Hi": 1, "Wi": 1, "Y": 7, "X": 7}, "nonpositive output"), + ({"N": 33554432, "Hi": 1, "Wi": 1}, "input byte count"), + ({"dH": (1 << 31) - 1}, "effective filter height"), + ( + { + "N": 1, + "Hi": 4096, + "Wi": 4096, + "C": 1, + "K": 1, + "Y": 1, + "X": 1, + "pH": 0, + "pW": 0, + }, + "grid_m", + ), + ], +) +def test_invalid_specs_decline_before_emission(override, reason): + spec = replace(gfx950_conv_fwd_spec_for_request(_request()), **override) + ok, explanation = supports_gfx950_conv_fwd(spec) + assert not ok + assert reason in explanation + with pytest.raises(ValueError, match="invalid packaged forward convolution"): + build_gfx950_conv_fwd(spec, arch="gfx950") + + +@pytest.mark.parametrize( + ("override", "reason"), + [ + ({"direction": "wgrad"}, "forward convolution only"), + ({"G": 2}, "groups=1"), + ({"layout": "NCHW"}, "NHWC"), + ({"arch": "gfx942"}, "gfx950"), + ({"Di": 4, "Z": 1, "stride_d": 1, "pad_d": 0, "dilation_d": 1}, "2D"), + ({"vec_size_c": 1}, "vector defaults"), + ({"stride_w": 0}, "sW must be"), + ], +) +def test_request_factory_declines_outside_integration_contract(override, reason): + with pytest.raises(ValueError, match=reason): + gfx950_conv_fwd_spec_for_request(_request(**override)) + + +def test_arch_is_checked_at_build_time(): + spec = gfx950_conv_fwd_spec_for_request(_request()) + assert not supports_gfx950_conv_fwd(spec, arch="gfx942")[0] + with pytest.raises(ValueError, match="requires arch=gfx950"): + build_gfx950_conv_fwd(spec, arch="gfx942") + + +def test_odd_output_channels_obtain_dispatcher_scalar_epilogue(): + spec = gfx950_conv_fwd_spec_for_request(_request(K=31)) + assert spec.epilogue == "default" + assert supports_gfx950_conv_fwd(spec) == (True, "ok") diff --git a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/CMakeLists.txt b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/CMakeLists.txt index 90efe6281d66..dd165ac638eb 100644 --- a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/CMakeLists.txt +++ b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/CMakeLists.txt @@ -14,6 +14,7 @@ target_sources(hip_kernel_provider_impl PRIVATE # where the superbuild CI lane points the production source root. ${CMAKE_CURRENT_SOURCE_DIR}/packs/PointwiseNative.cpp ${CMAKE_CURRENT_SOURCE_DIR}/packs/ConvNative.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/packs/Gfx950ConvFwdNative.cpp ) # Sources above are entirely inside `#ifdef HIPDNN_ENABLE_KERNEL_INGESTOR`; the diff --git a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.cpp b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.cpp index adf1f7ebfc96..06f0fae8589a 100644 --- a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.cpp +++ b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.cpp @@ -15,6 +15,7 @@ const std::vector& ingestorPacks() static const std::vector s_packs = { {"hipkernel:Pointwise", ®isterPointwiseSymbols, &resetPointwiseModuleCache}, {"hipkernel:ConvFwd", ®isterConvFwdSymbols, &resetConvFwdModuleCache}, + {"hipkernel:Gfx950ConvFwd", ®isterGfx950ConvFwdSymbols, &resetGfx950ConvFwdModuleCache}, }; return s_packs; } diff --git a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.hpp b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.hpp index 5e154bc78020..6504e43518e6 100644 --- a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.hpp +++ b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/IngestorPacks.hpp @@ -48,6 +48,10 @@ void resetPointwiseModuleCache(); void registerConvFwdSymbols(hipdnn_plugin_sdk::ingestor::SymbolScope& scope); void resetConvFwdModuleCache(); +/// @see packs/Gfx950ConvFwdNative.cpp +void registerGfx950ConvFwdSymbols(hipdnn_plugin_sdk::ingestor::SymbolScope& scope); +void resetGfx950ConvFwdModuleCache(); + /// Drops every pack's cached kpack modules, so the next dispatch re-reads its archive /// from disk. /// diff --git a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp new file mode 100644 index 000000000000..e2edcebf84af --- /dev/null +++ b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp @@ -0,0 +1,169 @@ +// Copyright © Advanced Micro Devices, Inc., or its affiliates. +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include +#include + +namespace hip_kernel_provider::kernel_ingestor_engine::gfx950_conv_fwd +{ + +/// Logical NCHW/KCYX dimensions. The kernel stores A as NHWC, B as KYXC, D as NHWK. +struct Problem +{ + int64_t n; + int64_t c; + int64_t k; + int64_t hi; + int64_t wi; + int64_t y; + int64_t x; + int64_t strideH; + int64_t strideW; + int64_t padH; + int64_t padW; + int64_t dilationH; + int64_t dilationW; +}; + +struct Geometry +{ + int64_t ho; + int64_t wo; + int64_t gemmM; + std::array tensorBytes; // A, B, D, in the rocKE launch ABI order. +}; + +struct LaunchGeometry +{ + unsigned int gridX; + unsigned int gridY; + unsigned int gridZ; + unsigned int blockX; +}; + +/// The compiled pointer arguments are noalias. Check complete storage ranges, +/// including partially overlapping views, before passing them to the kernel. +inline bool bufferRangesDoNotOverlap(const std::array& addresses, + const std::array& bytes) +{ + for(size_t i = 0; i < addresses.size(); ++i) + { + if(bytes[i] <= 0 + || addresses[i] + > std::numeric_limits::max() - static_cast(bytes[i])) + { + return false; + } + for(size_t j = 0; j < i; ++j) + { + // Subtract ordered addresses so even untrusted pointers cannot overflow. + if(addresses[i] >= addresses[j] + ? addresses[i] - addresses[j] < static_cast(bytes[j]) + : addresses[j] - addresses[i] < static_cast(bytes[i])) + { + return false; + } + } + } + return true; +} + +/// The builder's A_bytes/B_bytes/D_bytes arguments and indexing use signed i32. +inline std::optional tensorByteSize(const std::array& dims) +{ + int64_t bytes = 2; // Both supported storage types, fp16 and bf16, occupy two bytes. + for(const auto extent : dims) + { + if(extent <= 0 || extent > std::numeric_limits::max() / bytes) + { + return std::nullopt; + } + bytes *= extent; + } + return static_cast(bytes); +} + +inline std::optional + outputExtent(int64_t input, int64_t filter, int64_t stride, int64_t pad, int64_t dilation) +{ + constexpr auto MAX_INDEX = std::numeric_limits::max(); + if(input <= 0 || input > MAX_INDEX || filter <= 0 || filter > MAX_INDEX || stride <= 0 + || stride > MAX_INDEX || pad < 0 || pad > MAX_INDEX || dilation <= 0 || dilation > MAX_INDEX) + { + return std::nullopt; + } + + // Check before multiplying: both the host arithmetic and the builder's i32 + // coordinate transforms must represent the padded and dilated extents. + if(pad > (MAX_INDEX - input) / 2 || filter - 1 > (MAX_INDEX - 1) / dilation) + { + return std::nullopt; + } + const auto padded = input + 2 * pad; + const auto effectiveFilter = (filter - 1) * dilation + 1; + if(padded < effectiveFilter) + { + return std::nullopt; + } + return (padded - effectiveFilter) / stride + 1; +} + +inline std::optional deriveGeometry(const Problem& problem) +{ + const auto aBytes = tensorByteSize({problem.n, problem.c, problem.hi, problem.wi}); + const auto bBytes = tensorByteSize({problem.k, problem.c, problem.y, problem.x}); + const auto ho + = outputExtent(problem.hi, problem.y, problem.strideH, problem.padH, problem.dilationH); + const auto wo + = outputExtent(problem.wi, problem.x, problem.strideW, problem.padW, problem.dilationW); + if(!aBytes || !bBytes || !ho || !wo) + { + return std::nullopt; + } + const auto dBytes = tensorByteSize({problem.n, problem.k, *ho, *wo}); + if(!dBytes) + { + return std::nullopt; + } + + // dBytes already bounded this product, including its extra factor of K * 2. + return Geometry{*ho, *wo, problem.n * *ho * *wo, {*aBytes, *bBytes, *dBytes}}; +} + +inline std::optional launchGeometry(const Problem& problem, + const Geometry& geometry, + int64_t tileM, + int64_t tileN, + int64_t warpM, + int64_t warpN, + int64_t waveSize) +{ + if(tileM <= 0 || tileN <= 0 || warpM <= 0 || warpN <= 0 || waveSize != 64 + || warpM > 1024 / waveSize || warpN > 1024 / (waveSize * warpM) || problem.k <= 0 + || geometry.gemmM <= 0) + { + return std::nullopt; + } + + // Mirrors implicit_gemm_conv_grid and ImplicitGemmConvSpec.launch_block_size + // in rocke/instances/common/conv_implicit_gemm.py (mem pipeline, groups=1). + // Subtract before division to avoid overflowing even for an untrusted tile size. + const auto gridX = 1 + (problem.k - 1) / tileN; + const auto gridY = 1 + (geometry.gemmM - 1) / tileM; + // Same grid bound as rocKE's is_valid_spec_for_problem. + if(gridX > 65535 || gridY > 65535) + { + return std::nullopt; + } + return LaunchGeometry{static_cast(gridX), + static_cast(gridY), + 1, + static_cast(warpM * warpN * waveSize)}; +} + +} // namespace hip_kernel_provider::kernel_ingestor_engine::gfx950_conv_fwd diff --git a/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp new file mode 100644 index 000000000000..481501d264f1 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp @@ -0,0 +1,495 @@ +// Copyright © Advanced Micro Devices, Inc., or its affiliates. +// SPDX-License-Identifier: MIT + +#ifdef HIPDNN_ENABLE_KERNEL_INGESTOR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compilation/KernelCompileOptions.hpp" +#include "core/Handle.hpp" +#include "engines/hip_mlops_engine/HipMlopsKernelCompiler.hpp" +#include "engines/kernel_ingestor_engine/IngestorKernelCode.hpp" +#include "engines/kernel_ingestor_engine/IngestorPacks.hpp" +#include "engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp" + +namespace hip_kernel_provider::kernel_ingestor_engine +{ + +using namespace hipdnn_plugin_sdk::ingestor; +namespace data_objects = hipdnn_flatbuffers_sdk::data_objects; +namespace conv = gfx950_conv_fwd; + +namespace +{ + +constexpr std::string_view GRAPH_MATCHER_SYMBOL = "hipkernel.gfx950_conv_fwd.graph_match"; +constexpr std::string_view KERNEL_MATCHER_SYMBOL = "hipkernel.gfx950_conv_fwd.kernel_match"; +constexpr std::string_view SCORE_SYMBOL = "hipkernel.gfx950_conv_fwd.score"; +constexpr std::string_view DISPATCH_SYMBOL = "hipkernel.gfx950_conv_fwd.dispatch"; +constexpr std::string_view X_TOKEN = "gfx950_conv_fwd.x.uid"; +constexpr std::string_view W_TOKEN = "gfx950_conv_fwd.w.uid"; +constexpr std::string_view Y_TOKEN = "gfx950_conv_fwd.y.uid"; + +struct Binding +{ + int64_t x; + int64_t w; + int64_t y; +}; + +struct MatchedProblem +{ + Binding binding; + conv::Problem problem; + conv::Geometry geometry; + data_objects::DataType dtype; +}; + +const data_objects::TensorAttributes* findTensor(const MatchContext& context, int64_t uid) +{ + const auto& tensors = context.graph.getTensorMap(); + const auto it = tensors.find(uid); + return it == tensors.end() ? nullptr : it->second; +} + +bool isDeviceTensor(const data_objects::TensorAttributes* tensor) +{ + return tensor != nullptr && !tensor->virtual_() + && !hipdnn_flatbuffers_sdk::utilities::isPassByValueTensor(tensor) + && !tensor->ragged_offset_tensor_uid().has_value() && tensor->alignment() >= 16 + && tensor->alignment() % 16 == 0 + && (tensor->data_type() == data_objects::DataType::HALF + || tensor->data_type() == data_objects::DataType::BFLOAT16); +} + +bool hasPackedNhwcStrides(const data_objects::TensorAttributes* tensor) +{ + if(tensor == nullptr || tensor->dims() == nullptr || tensor->strides() == nullptr + || tensor->dims()->size() != 4 || tensor->strides()->size() != 4) + { + return false; + } + const auto* dims = tensor->dims(); + const std::array extents{dims->Get(0), dims->Get(1), dims->Get(2), dims->Get(3)}; + if(!conv::tensorByteSize(extents)) + { + return false; + } + // hipDNN [N,C,H,W] -> NHWC; filter [K,C,Y,X] -> KYXC; output [N,K,Ho,Wo] -> NHWK. + // The byte-size guard above bounds every multiplication here. + const std::array expected{ + extents[1] * extents[2] * extents[3], 1, extents[1] * extents[3], extents[1]}; + for(flatbuffers::uoffset_t axis = 0; axis < 4; ++axis) + { + // A unit-extent axis never contributes to an address, whatever its stride. + if(extents[axis] != 1 && tensor->strides()->Get(axis) != expected[axis]) + { + return false; + } + } + return true; +} + +bool hasSpatialRankTwo(const flatbuffers::Vector* values) +{ + return values != nullptr && values->size() == 2; +} + +std::optional matchProblem(const MatchContext& context) +{ + if(!context.graph.isValid() || context.graph.getGraph().is_override_shape_enabled() + || !hipdnn_plugin_sdk::archMatches( + context.deviceProperties.gcnArchName, "gfx950", hipdnn_plugin_sdk::ArchMatchMode::PREFIX) + || context.deviceProperties.warpSize != 64 || context.graph.nodeCount() != 1) + { + return std::nullopt; + } + const auto& node = context.graph.getNodeWrapper(0); + if(node.attributesType() != data_objects::NodeAttributes::ConvolutionFwdAttributes + || node.attributes() == nullptr || node.computeDataType() != data_objects::DataType::FLOAT) + { + return std::nullopt; + } + const auto& attributes = node.attributesAs(); + if(attributes.conv_mode() != data_objects::ConvMode::CROSS_CORRELATION + || !hasSpatialRankTwo(attributes.pre_padding()) + || !hasSpatialRankTwo(attributes.post_padding()) || !hasSpatialRankTwo(attributes.stride()) + || !hasSpatialRankTwo(attributes.dilation())) + { + return std::nullopt; + } + for(flatbuffers::uoffset_t axis = 0; axis < 2; ++axis) + { + if(attributes.pre_padding()->Get(axis) != attributes.post_padding()->Get(axis)) + { + return std::nullopt; + } + } + + const Binding binding{ + attributes.x_tensor_uid(), attributes.w_tensor_uid(), attributes.y_tensor_uid()}; + const auto* x = findTensor(context, binding.x); + const auto* w = findTensor(context, binding.w); + const auto* y = findTensor(context, binding.y); + if(binding.x == binding.w || binding.x == binding.y || binding.w == binding.y + || !isDeviceTensor(x) || !isDeviceTensor(w) || !isDeviceTensor(y) || !hasPackedNhwcStrides(x) + || !hasPackedNhwcStrides(w) || x->data_type() != w->data_type() + || x->data_type() != y->data_type()) + { + return std::nullopt; + } + // Output dims/strides may not yet be inferred. Validate them in prepare(), before + // loading any code or computing device addresses; they do not define this problem. + const auto* xDims = x->dims(); + const auto* wDims = w->dims(); + if(xDims->Get(1) != wDims->Get(1)) + { + return std::nullopt; // A smaller filter channel count encodes grouped convolution. + } + const conv::Problem problem{xDims->Get(0), + xDims->Get(1), + wDims->Get(0), + xDims->Get(2), + xDims->Get(3), + wDims->Get(2), + wDims->Get(3), + attributes.stride()->Get(0), + attributes.stride()->Get(1), + attributes.pre_padding()->Get(0), + attributes.pre_padding()->Get(1), + attributes.dilation()->Get(0), + attributes.dilation()->Get(1)}; + const auto geometry = conv::deriveGeometry(problem); + if(!geometry) + { + return std::nullopt; + } + return MatchedProblem{binding, problem, *geometry, x->data_type()}; +} + +std::optional graphMatches(const MatchContext& context) +{ + const auto matched = matchProblem(context); + if(!matched) + { + return std::nullopt; + } + return BoundTokens{{std::string(X_TOKEN), matched->binding.x}, + {std::string(W_TOKEN), matched->binding.w}, + {std::string(Y_TOKEN), matched->binding.y}}; +} + +template +bool metadataEquals(const KernelDefinition& kernel, const char* field, const T& expected) +{ + const auto it = kernel.metadata.find(field); + if(it == kernel.metadata.end()) + { + return false; + } + const auto* value = std::get_if(&it->second); + return value != nullptr && *value == expected; +} + +bool kernelFits(const MatchedProblem& matched, const KernelDefinition& kernel) +{ + if(kernel.source.kind != KernelSourceKind::KPACK) + { + return false; + } + const auto& p = matched.problem; + const std::array, 13> fields{{{"N", p.n}, + {"C", p.c}, + {"K", p.k}, + {"Hi", p.hi}, + {"Wi", p.wi}, + {"Y", p.y}, + {"X", p.x}, + {"sH", p.strideH}, + {"sW", p.strideW}, + {"pH", p.padH}, + {"pW", p.padW}, + {"dH", p.dilationH}, + {"dW", p.dilationW}}}; + for(const auto& field : fields) + { + if(!metadataEquals(kernel, field.first, field.second)) + { + return false; + } + } + const std::string dtype = matched.dtype == data_objects::DataType::HALF ? "fp16" : "bf16"; + // These are the two packaged dispatcher configurations. Keep the complete tuning + // contract explicit: a new pipeline or atom needs its launch/ABI reviewed here. + // rocKE's default_vector_sizes picks vec_c > 1 for even K in both storage types; + // is_valid_spec permits the default epilogue only with scalar output stores. + return metadataEquals(kernel, "dtype", dtype) + && metadataEquals(kernel, "layout", std::string("NHWC")) + && metadataEquals(kernel, "groups", int64_t{1}) + && metadataEquals(kernel, "tile_m", int64_t{64}) + && metadataEquals(kernel, "tile_n", int64_t{64}) + && (metadataEquals(kernel, "tile_k", int64_t{64}) + || metadataEquals(kernel, "tile_k", int64_t{128})) + && metadataEquals(kernel, "warp_m", int64_t{2}) + && metadataEquals(kernel, "warp_n", int64_t{2}) + && metadataEquals(kernel, "warp_tile_m", int64_t{32}) + && metadataEquals(kernel, "warp_tile_n", int64_t{32}) + && metadataEquals(kernel, "warp_tile_k", int64_t{16}) + && metadataEquals(kernel, "wave_size", int64_t{64}) + && metadataEquals(kernel, "pipeline", std::string("mem")) + && (metadataEquals(kernel, "epilogue", std::string("cshuffle")) + || (p.k % 2 != 0 && metadataEquals(kernel, "epilogue", std::string("default")))) + && conv::launchGeometry(p, matched.geometry, 64, 64, 2, 2, 64).has_value(); +} + +bool kernelMatches(const MatchContext& context, + const BoundTokens& /*bound*/, + const KernelDefinition& kernel) +{ + const auto matched = matchProblem(context); + return matched && kernelFits(*matched, kernel); +} + +double score(const MatchContext& /*context*/, + const BoundTokens& /*bound*/, + const KernelDefinition& kernel) +{ + // Deterministic fallback only. BenchmarkPlan replaces this order with measurements + // when benchmarking is enabled. tile_k=64 is the gfx950 dispatcher's default. + return metadataEquals(kernel, "tile_k", int64_t{64}) ? 1.0 : 0.0; +} + +void requireBindings(const BoundTokens& bound, const Binding& binding) +{ + if(tryGetBoundInt(bound, X_TOKEN) != std::optional(binding.x) + || tryGetBoundInt(bound, W_TOKEN) != std::optional(binding.w) + || tryGetBoundInt(bound, Y_TOKEN) != std::optional(binding.y)) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, + "gfx950_conv_fwd dispatch requires this graph matcher's tensor bindings"); + } +} + +void requireOutput(const MatchContext& context, const MatchedProblem& matched) +{ + const auto* output = findTensor(context, matched.binding.y); + if(!hasPackedNhwcStrides(output) || output->dims()->Get(0) != matched.problem.n + || output->dims()->Get(1) != matched.problem.k + || output->dims()->Get(2) != matched.geometry.ho + || output->dims()->Get(3) != matched.geometry.wo) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, + "gfx950_conv_fwd requires packed NHWK output with the inferred convolution dimensions"); + } +} + +/// The kernel ABI buildIngestorKernelCode verifies the loaded symbol against: +/// build_implicit_gemm_conv emits (A*, B*, D*, A_bytes:i32, B_bytes:i32, D_bytes:i32). +/// Names and offsets are unused for this comparison; see requireSignatureMatch. +const std::vector& gfx950ConvFwdKernelSignature() +{ + static const KernelArgument s_buffer{ + "global_buffer", static_cast(sizeof(void*)), 0, ""}; + static const KernelArgument s_bytes{"by_value", static_cast(sizeof(int32_t)), 0, ""}; + static const std::vector s_signature{ + s_buffer, s_buffer, s_buffer, s_bytes, s_bytes, s_bytes}; + return s_signature; +} + +class PreparedConvFwd : public PreparedDispatch +{ +public: + PreparedConvFwd(IngestorKernelCode code, Binding binding, std::array bytes) + : _code(std::move(code)) + , _binding(binding) + , _bytes(bytes) + { + } + + /// A hipModule_t belongs to the device it loaded on, so the kernel is resolved per + /// launch stream rather than held as one pointer. + compilation::IRunnableKernel& kernelForStream(hipStream_t stream) const + { + return _code.kernelForStream(stream); + } + const Binding& binding() const + { + return _binding; + } + const std::array& bytes() const + { + return _bytes; + } + +private: + // Holds both the program/module and its kernel view; owns no MatchContext data. + IngestorKernelCode _code; + Binding _binding; + std::array _bytes; +}; + +class ConvFwdDispatchHandler : public IKernelDispatchHandler +{ +public: + ConvFwdDispatchHandler(const compilation::IKernelCompiler& compiler, + const compilation::KpackKernelLoader& loader) + : _compiler(compiler) + , _loader(loader) + { + } + + size_t workspaceBytes(const MatchContext& /*context*/, + const BoundTokens& /*bound*/, + const KernelDefinition& /*kernel*/) const override + { + return 0; // The kernel uses registers and statically allocated LDS only. + } + + std::unique_ptr prepare(const MatchContext& context, + const BoundTokens& bound, + const KernelDefinition& kernel) const override + { + const auto matched = matchProblem(context); + if(!matched || !kernelFits(*matched, kernel)) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, + "gfx950_conv_fwd graph or packaged kernel does not satisfy the convolution " + "contract"); + } + requireBindings(bound, matched->binding); + requireOutput(context, *matched); + + // KPACK ignores compile options. Use a canonical stand-in because arbitrary + // strides on unit-extent axes are valid here but confuse the NCHW/NHWC sorter + // in KernelCompileOptions. The real tensor has already passed our layout check. + flatbuffers::FlatBufferBuilder builder; + const std::vector dims{2, 2, 2, 2}; + const std::vector strides{8, 1, 4, 2}; + builder.Finish(data_objects::CreateTensorAttributesDirect( + builder, 0, nullptr, matched->dtype, &strides, &dims)); + const compilation::KernelCompileOptions options( + flatbuffers::GetRoot(builder.GetBufferPointer()), + context.deviceProperties.gcnArchName); + auto code = buildIngestorKernelCode( + _compiler, _loader, context, kernel, options, gfx950ConvFwdKernelSignature()); + const auto launch = conv::launchGeometry(matched->problem, + matched->geometry, + kernel.getIntMetadata("tile_m"), + kernel.getIntMetadata("tile_n"), + kernel.getIntMetadata("warp_m"), + kernel.getIntMetadata("warp_n"), + kernel.getIntMetadata("wave_size")); + // kernelFits checked this exact geometry before loading the archive. + code.setBlockSize(launch->blockX, 1, 1); + code.setGridSize(launch->gridX, launch->gridY, launch->gridZ); + code.setSharedMemBytes(0); + return std::make_unique( + std::move(code), matched->binding, matched->geometry.tensorBytes); + } + + void launch(const Handle& handle, + const PreparedDispatch& prepared, + const hipdnnPluginDeviceBuffer_t* deviceBuffers, + uint32_t numDeviceBuffers, + void* /*workspace*/) const override + { + const auto& convPrepared = dynamic_cast(prepared); + if(deviceBuffers == nullptr) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, "gfx950_conv_fwd requires device buffers"); + } + const auto& binding = convPrepared.binding(); + const auto a + = hipdnn_plugin_sdk::findDeviceBuffer(binding.x, deviceBuffers, numDeviceBuffers); + const auto b + = hipdnn_plugin_sdk::findDeviceBuffer(binding.w, deviceBuffers, numDeviceBuffers); + const auto d + = hipdnn_plugin_sdk::findDeviceBuffer(binding.y, deviceBuffers, numDeviceBuffers); + for(const auto* ptr : {a.ptr, b.ptr, d.ptr}) + { + if(ptr == nullptr || reinterpret_cast(ptr) % 16 != 0) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, + "gfx950_conv_fwd requires non-null device pointers aligned to 16 bytes"); + } + } + const auto& bytes = convPrepared.bytes(); + if(!conv::bufferRangesDoNotOverlap({reinterpret_cast(a.ptr), + reinterpret_cast(b.ptr), + reinterpret_cast(d.ptr)}, + bytes)) + { + throw hipdnn_plugin_sdk::HipdnnPluginException( + HIPDNN_PLUGIN_STATUS_BAD_PARAM, + "gfx950_conv_fwd requires nonoverlapping input, filter, and output storage"); + } + // build_implicit_gemm_conv, conv_implicit_gemm.py: A*, B*, D*, A_bytes:i32, + // B_bytes:i32, D_bytes:i32. These are storage byte sizes, not element counts. + convPrepared.kernelForStream(handle.getStream()) + .launch(handle.getStream(), a.ptr, b.ptr, d.ptr, bytes[0], bytes[1], bytes[2]); + } + +private: + const compilation::IKernelCompiler& _compiler; + const compilation::KpackKernelLoader& _loader; +}; + +compilation::KpackModuleCache& moduleCache() +{ + static compilation::KpackModuleCache s_cache; + return s_cache; +} + +const ConvFwdDispatchHandler& dispatchHandler() +{ + // The registries retain non-owning pointers; all three dependencies live for the + // process, including across provider handle destruction and recreation. + static const HipMlopsKernelCompiler s_compiler; + static const compilation::KpackKernelLoader s_loader(moduleCache()); + static const ConvFwdDispatchHandler s_handler(s_compiler, s_loader); + return s_handler; +} + +} // namespace + +void registerGfx950ConvFwdSymbols(SymbolScope& scope) +{ + scope.add(std::string(GRAPH_MATCHER_SYMBOL), &graphMatches); + scope.add(std::string(KERNEL_MATCHER_SYMBOL), &kernelMatches); + scope.add(std::string(SCORE_SYMBOL), &score); + scope.add(std::string(DISPATCH_SYMBOL), &dispatchHandler()); +} + +void resetGfx950ConvFwdModuleCache() +{ + moduleCache().clear(); +} + +} // namespace hip_kernel_provider::kernel_ingestor_engine + +#endif // HIPDNN_ENABLE_KERNEL_INGESTOR diff --git a/dnn-providers/hip-kernel-provider/src/integration_tests/CMakeLists.txt b/dnn-providers/hip-kernel-provider/src/integration_tests/CMakeLists.txt index d432a6a2a5f7..6d5efad83029 100644 --- a/dnn-providers/hip-kernel-provider/src/integration_tests/CMakeLists.txt +++ b/dnn-providers/hip-kernel-provider/src/integration_tests/CMakeLists.txt @@ -86,6 +86,7 @@ if(HIPDNN_ENABLE_KERNEL_INGESTOR) kernel_ingestor_engine/IntegrationGpuKernelIngestor.cpp kernel_ingestor_engine/IntegrationGpuKernelIngestorKpack.cpp kernel_ingestor_engine/IntegrationGraphVerificationContext.cpp + kernel_ingestor_engine/IntegrationGpuGfx950ConvFwd.cpp ) # This target links only the SDKs, not hip_kernel_provider_private, so it does not # inherit the provider's gate and needs the definition set directly. @@ -167,6 +168,20 @@ if(NOT COMMAND add_external_integration_test_target) find_package(hipdnn_integration_tests CONFIG QUIET) endif() +if(HIPDNN_ENABLE_KERNEL_INGESTOR AND HIPKERNELPROVIDER_PRODUCTION_ENABLE_ROCKE + AND TARGET hipdnn_integration_tests AND COMMAND add_external_integration_test_target) + add_external_integration_test_target( + TARGET_NAME hip_kernel_provider_gfx950_conv_fwd_external_integration_tests + PLUGIN_TARGET hip_kernel_provider + ENGINE_NAME hipkernel:Gfx950ConvFwd + INSTALL_SUBDIR hip_kernel_provider + REFERENCE_EXECUTOR gpu + GTEST_FILTER + quick_Gfx950ConvFwd* + standard_Gfx950ConvFwd* + ) +endif() + if(ENABLE_ASM_SDPA_ENGINE AND HIPDNN_ENABLE_SDPA AND TARGET hipdnn_integration_tests AND COMMAND add_external_integration_test_target) set(_synthetic_root "/__hipdnn_install_root__") diff --git a/dnn-providers/hip-kernel-provider/src/integration_tests/kernel_ingestor_engine/IntegrationGpuGfx950ConvFwd.cpp b/dnn-providers/hip-kernel-provider/src/integration_tests/kernel_ingestor_engine/IntegrationGpuGfx950ConvFwd.cpp new file mode 100644 index 000000000000..f36c4246fba6 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/src/integration_tests/kernel_ingestor_engine/IntegrationGpuGfx950ConvFwd.cpp @@ -0,0 +1,435 @@ +// Copyright © Advanced Micro Devices, Inc., or its affiliates. +// SPDX-License-Identifier: MIT + +#ifdef HIPDNN_ENABLE_KERNEL_INGESTOR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../IntegrationGraphVerificationHarness.hpp" + +namespace hip_kernel_provider::kernel_ingestor_engine::integration +{ + +using namespace hipdnn_frontend; +using namespace hipdnn_frontend::graph; +using namespace hipdnn_test_sdk::utilities; +namespace ingestor = hipdnn_plugin_sdk::ingestor; + +namespace +{ + +constexpr const char* ENGINE_NAME = "hipkernel:Gfx950ConvFwd"; +constexpr const char* TILE_K_KNOB = "tile_k"; + +struct ConvProblem +{ + int64_t n = 2; + int64_t c = 32; + int64_t k = 32; + int64_t hi = 14; + int64_t wi = 14; + int64_t y = 3; + int64_t x = 3; + int64_t strideH = 1; + int64_t strideW = 1; + int64_t padH = 1; + int64_t padW = 1; + int64_t dilationH = 1; + int64_t dilationW = 1; +}; + +struct Variant +{ + std::string name; + DataType dtype; + int64_t tileK; + ConvProblem problem{}; +}; + +std::vector correctnessVariants() +{ + // Same five spatial cases, two dtypes and two tile sizes as the initial + // verification requests in gfx950_conv_fwd.requests.json. + const std::vector> problems{ + {"Smoke", {}}, + {"Pointwise", {1, 32, 64, 8, 8, 1, 1, 1, 1, 0, 0, 1, 1}}, + {"Strided", {2, 32, 64, 17, 19, 3, 3, 2, 2, 1, 1, 1, 1}}, + {"Dilated", {1, 32, 32, 15, 17, 3, 3, 1, 1, 2, 2, 2, 2}}, + {"Nonsquare", {2, 32, 64, 11, 17, 3, 5, 1, 2, 1, 2, 1, 1}}}; + std::vector variants; + for(const auto& [name, problem] : problems) + { + for(const auto dtype : {DataType::HALF, DataType::BFLOAT16}) + { + for(const auto tileK : {int64_t{64}, int64_t{128}}) + { + const auto dtypeName = dtype == DataType::HALF ? "Fp16" : "Bf16"; + variants.push_back( + {name + dtypeName + "TileK" + std::to_string(tileK), dtype, tileK, problem}); + } + } + } + return variants; +} + +std::shared_ptr + buildConvGraph(DataType dtype, const ConvProblem& problem = {}, bool channelsLast = true) +{ + auto graph = std::make_shared(); + graph->set_name("gfx950_conv_fwd") + .set_io_data_type(dtype) + .set_intermediate_data_type(dtype) + .set_compute_data_type(DataType::FLOAT); + + auto x = std::make_shared(); + x->set_uid(1) + .set_name("X") + .set_dim({problem.n, problem.c, problem.hi, problem.wi}) + .set_stride(channelsLast ? std::vector{problem.c * problem.hi * problem.wi, + 1, + problem.wi * problem.c, + problem.c} + : std::vector{problem.c * problem.hi * problem.wi, + problem.hi * problem.wi, + problem.wi, + 1}) + .set_data_type(dtype); + auto w = std::make_shared(); + w->set_uid(2) + .set_name("W") + .set_dim({problem.k, problem.c, problem.y, problem.x}) + .set_stride({problem.c * problem.y * problem.x, 1, problem.x * problem.c, problem.c}) + .set_data_type(dtype); + + ConvFpropAttributes attributes; + attributes.set_name("gfx950_conv_fwd") + .set_padding({problem.padH, problem.padW}) + .set_stride({problem.strideH, problem.strideW}) + .set_dilation({problem.dilationH, problem.dilationW}) + .set_convolution_mode(ConvolutionMode::CROSS_CORRELATION); + auto y = graph->conv_fprop(x, w, attributes); + // The frontend infers output dims/strides from the channels-last input. + y->set_uid(3).set_name("Y").set_output(true).set_data_type(dtype); + return graph; +} + +KnobSetting enableBenchmarkingKnob() +{ + return KnobSetting(hipdnn_plugin_sdk::BENCHMARKING_KNOB_NAME, int64_t{1}); +} + +size_t selectionCount(const LogRecorderBase& recorder) +{ + const auto logs = recorder.getRecordedLogs(); + return static_cast(std::count_if(logs.begin(), logs.end(), [](const auto& log) { + return log.message.find("benchmarking selected kernel") != std::string::npos; + })); +} + +class ScopedPluginLogCapture +{ +public: + explicit ScopedPluginLogCapture(void* userHandle) + : _userHandle(userHandle) + { + const auto read = getGlobalLogLevel(_previousLevel); + EXPECT_EQ(read.code, ErrorCode::OK) << read.err_msg; + const auto registered = setCallback(HIPDNN_SEV_INFO); + EXPECT_EQ(registered.code, ErrorCode::OK) << registered.err_msg; + _registered = registered.code == ErrorCode::OK; + const auto level = setGlobalLogLevel(HIPDNN_SEV_INFO); + EXPECT_EQ(level.code, ErrorCode::OK) << level.err_msg; + } + + ~ScopedPluginLogCapture() + { + if(_registered) + { + static_cast(setCallback(HIPDNN_SEV_OFF)); + } + static_cast(setGlobalLogLevel(_previousLevel)); + } + + ScopedPluginLogCapture(const ScopedPluginLogCapture&) = delete; + ScopedPluginLogCapture& operator=(const ScopedPluginLogCapture&) = delete; + + IsolatedLogRecorder& recorder() const + { + return _recorder; + } + +private: + Error setCallback(hipdnnSeverity_t level) const + { + return setUserLogCallback(IsolatedLogRecorder::getIsolatedUserRecordingCallback(), + level, + LogCallbackMode::SYNC, + _userHandle); + } + + hipdnnSeverity_t _previousLevel = HIPDNN_SEV_OFF; + void* _userHandle; + bool _registered = false; + mutable IsolatedLogRecorder _recorder = IsolatedLogRecorder::withOverrideLevel(HIPDNN_SEV_INFO); +}; + +} // namespace + +class IntegrationGpuGfx950ConvFwd + : public test_utilities::IntegrationGraphVerificationHarness +{ +protected: + using Base = test_utilities::IntegrationGraphVerificationHarness; + + void SetUp() override + { + Base::SetUp(); + if(HasFatalFailure() || IsSkipped()) + { + return; + } + hipDeviceProp_t properties{}; + ASSERT_EQ(hipGetDeviceProperties(&properties, _deviceId), hipSuccess); + _arch = properties.gcnArchName; + if(!hipdnn_plugin_sdk::archMatches( + _arch, "gfx950", hipdnn_plugin_sdk::ArchMatchMode::PREFIX)) + { + GTEST_SKIP() << "The packaged convolution family requires gfx950"; + } + } + + static int64_t engineId() + { + return hipdnn_data_sdk::utilities::engineNameToId(ENGINE_NAME); + } + + void buildAndCompile(Graph& graph, const std::vector& knobs) + { + auto result = graph.build_operation_graph(_handle); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + std::vector engineIds; + result = graph.get_ranked_engine_ids(engineIds); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + ASSERT_NE(std::find(engineIds.begin(), engineIds.end(), engineId()), engineIds.end()) + << "The installed plugin did not offer " << ENGINE_NAME; + + // Hard selection: a preferred-engine hint can fall back silently to another + // provider. This path must execute this engine even when other engines match. + result = graph.create_execution_plan_ext(engineId(), knobs); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + result = graph.check_support(); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + result = graph.build_plans(); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + int64_t selected = 0; + result = graph.get_execution_plan_engine_id(selected); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + ASSERT_EQ(selected, engineId()); + int64_t workspaceSize = -1; + result = graph.get_workspace_size(workspaceSize); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + ASSERT_EQ(workspaceSize, 0); + } + + void executeAndVerifyStorage(Graph& graph, DataType dtype, unsigned int seed) + { + auto [serialized, serializationError] = graph.to_binary(); + ASSERT_TRUE(serializationError.is_good()) << serializationError.get_message(); + const auto wrapper + = hipdnn_flatbuffers_sdk::flatbuffer_utilities::GraphWrapper::fromSerializedBlob( + serialized.data(), serialized.size()); + GraphTensorBundle gpu(wrapper.getTensorMap()); + GraphTensorBundle cpu(wrapper.getTensorMap()); + for(const auto uid : {int64_t{1}, int64_t{2}}) + { + const auto tensorSeed = seed + static_cast(uid); + gpu.randomizeTensor(uid, -1.0F, 1.0F, tensorSeed); + cpu.randomizeTensor(uid, -1.0F, 1.0F, tensorSeed); + } + gpu.getTensor(3).fillWithSentinelValue(); + cpu.getTensor(3).fillWithSentinelValue(); + auto buffers = gpu.toDeviceVariantPack(); + const auto result = graph.execute(_handle, buffers, nullptr); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + ASSERT_EQ(hipStreamSynchronize(_stream), hipSuccess); + CpuReferenceGraphExecutor().execute( + serialized.data(), serialized.size(), cpu.toHostVariantPack()); + gpu.getTensor(3).markDeviceModified(); + + // FP32 accumulation followed by a low-precision store. Absolute slack covers + // cancellation/order differences in accumulation; relative slack covers + // two output ulps. Inputs are bounded to [-1,1] and the reference uses FP32. + const float relativeTolerance = dtype == DataType::HALF ? 0.002F : 0.016F; + const auto validator + = createAllCloseValidator(frontendToSdkDataType(dtype), 0.001F, relativeTolerance); + EXPECT_TRUE(validator->allClose(cpu.getTensor(3), gpu.getTensor(3))); + } + + std::optional persistedRanking() const + { + const auto path = ingestor::winnerCacheShardPath(ENGINE_NAME, _arch); + std::ifstream stream(path); + std::string line; + std::optional ranking; + while(std::getline(stream, line)) + { + if(const auto entry = ingestor::decodeWinnerRecordLine(line)) + { + // Every parameterized test owns a fresh cache and benchmarks one + // graph only. A second record here indicates leaked test state. + EXPECT_FALSE(ranking.has_value()); + ranking = entry->second; + } + } + return ranking; + } + + // The inherited harness opens the plugin relative to the running binary. No + // descriptor override is set: installed tests must load installed kpack archives. + ScopedTestCacheDir _cacheDir{"gfx950-conv", ScopedTestCacheDir::Scope::TEST}; + ScopedEnvironmentVariableSetter _forceBenchmarking{"HIPDNN_FORCE_BENCHMARKING", ""}; + ScopedEnvironmentVariableSetter _cacheEnabled{"HIPDNN_DISABLE_CACHE", ""}; + std::string _arch; +}; + +TEST_P(IntegrationGpuGfx950ConvFwd, ForcedVariantMatchesCpuReference) +{ + const auto& variant = GetParam(); + auto graph = buildConvGraph(variant.dtype, variant.problem); + const std::vector knobs{ + KnobSetting(TILE_K_KNOB, variant.tileK), + KnobSetting(hipdnn_plugin_sdk::BENCHMARKING_KNOB_NAME, int64_t{0})}; + ASSERT_NO_FATAL_FAILURE(buildAndCompile(*graph, knobs)); + ASSERT_NO_FATAL_FAILURE(executeAndVerifyStorage(*graph, variant.dtype, 3)); + ASSERT_NO_FATAL_FAILURE(executeAndVerifyStorage(*graph, variant.dtype, 11)); +} + +TEST_F(IntegrationGpuGfx950ConvFwd, CatalogExposesBothTileKVariantsAndDefault) +{ + auto graph = buildConvGraph(DataType::HALF); + auto result = graph->build_operation_graph(_handle); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + std::vector knobs; + result = graph->get_knobs_for_engine(engineId(), knobs); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + const auto tileK = std::find_if( + knobs.begin(), knobs.end(), [](const auto& knob) { return knob.knobId() == TILE_K_KNOB; }); + ASSERT_NE(tileK, knobs.end()); + const auto* constraint = dynamic_cast(tileK->constraint()); + ASSERT_NE(constraint, nullptr); + EXPECT_EQ(constraint->getValidValues(), (std::unordered_set{64, 128})); + const auto* defaultValue = std::get_if(&tileK->defaultValue()); + ASSERT_NE(defaultValue, nullptr); + EXPECT_EQ(*defaultValue, 64); +} + +TEST_F(IntegrationGpuGfx950ConvFwd, DeclinesChannelsFirstStorage) +{ + auto graph = buildConvGraph(DataType::HALF, {}, false); + const auto result = graph->build_operation_graph(_handle); + ASSERT_EQ(result.code, ErrorCode::OK) << result.err_msg; + std::vector engineIds; + const auto ranked = graph->get_ranked_engine_ids(engineIds); + EXPECT_TRUE(ranked.code == ErrorCode::OK || ranked.code == ErrorCode::GRAPH_NOT_SUPPORTED) + << ranked.err_msg; + EXPECT_EQ(std::find(engineIds.begin(), engineIds.end(), engineId()), engineIds.end()); +} + +class IntegrationGpuGfx950ConvFwdBenchmark : public IntegrationGpuGfx950ConvFwd +{ +}; + +TEST_P(IntegrationGpuGfx950ConvFwdBenchmark, MeasuresTwoCandidatesAndReusesFastestRecordedWinner) +{ + const auto dtype = GetParam().dtype; + // Exercise both the public knob and the process override requested by the runbook. + _forceBenchmarking.setValue("1"); + ASSERT_FALSE(_cacheDir.path().empty()); + const ScopedPluginLogCapture capture(this); + auto& recorder = capture.recorder(); + auto graph = buildConvGraph(dtype); + ASSERT_NO_FATAL_FAILURE(buildAndCompile(*graph, {enableBenchmarkingKnob()})); + EXPECT_TRUE(recorder.hasLogContaining("will benchmark 2 candidate(s)")) + << recorder.getRecordedLogsAsString(); + ASSERT_NO_FATAL_FAILURE(executeAndVerifyStorage(*graph, dtype, 19)); + ASSERT_EQ(selectionCount(recorder), 1U) << recorder.getRecordedLogsAsString(); + + const auto ranking = persistedRanking(); + ASSERT_TRUE(ranking) << "Benchmarking did not persist its measured candidate ranking"; + ASSERT_EQ(ranking->size(), 2U); + EXPECT_NE((*ranking)[0].kernelId, (*ranking)[1].kernelId); + for(const auto& candidate : *ranking) + { + EXPECT_TRUE(std::isfinite(candidate.timeMs)); + EXPECT_GT(candidate.timeMs, 0.0); + } + EXPECT_LE((*ranking)[0].timeMs, (*ranking)[1].timeMs); + const std::string winner = ingestor::toString(ranking->front().kernelId); + EXPECT_TRUE(recorder.hasLogContaining("benchmarking selected kernel " + winner)) + << recorder.getRecordedLogsAsString(); + + ASSERT_NO_FATAL_FAILURE(executeAndVerifyStorage(*graph, dtype, 23)); + EXPECT_EQ(selectionCount(recorder), 1U); + + graph.reset(); + recorder.clearLogs(); + auto recreated = buildConvGraph(dtype); + ASSERT_NO_FATAL_FAILURE(buildAndCompile(*recreated, {enableBenchmarkingKnob()})); + EXPECT_TRUE(recorder.hasLogContaining("served kernel " + winner + " at rank 0")) + << recorder.getRecordedLogsAsString(); + EXPECT_TRUE( + recorder.hasLogContaining("from a benchmarked record of 2 entry(s) for 2 candidate(s)")) + << recorder.getRecordedLogsAsString(); + EXPECT_FALSE(recorder.hasLogContaining("will benchmark")); + ASSERT_NO_FATAL_FAILURE(executeAndVerifyStorage(*recreated, dtype, 29)); + EXPECT_EQ(selectionCount(recorder), 0U); +} + +INSTANTIATE_TEST_SUITE_P(Correctness, + IntegrationGpuGfx950ConvFwd, + ::testing::ValuesIn(correctnessVariants()), + [](const ::testing::TestParamInfo& info) { + return info.param.name; + }); + +INSTANTIATE_TEST_SUITE_P(Autotuning, + IntegrationGpuGfx950ConvFwdBenchmark, + ::testing::Values(Variant{"Fp16", DataType::HALF, 64}, + Variant{"Bf16", DataType::BFLOAT16, 64}), + [](const ::testing::TestParamInfo& info) { + return info.param.name; + }); + +} // namespace hip_kernel_provider::kernel_ingestor_engine::integration + +#endif // HIPDNN_ENABLE_KERNEL_INGESTOR diff --git a/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/CMakeLists.txt b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/CMakeLists.txt index d627040bf25e..1852ec83c997 100644 --- a/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/CMakeLists.txt +++ b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/CMakeLists.txt @@ -9,4 +9,6 @@ target_sources(hip_kernel_provider_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/packs/TestPointwiseAddMatchers.cpp ${CMAKE_CURRENT_SOURCE_DIR}/packs/TestPointwisePacks.cpp ${CMAKE_CURRENT_SOURCE_DIR}/packs/TestConvFwdPack.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestGfx950ConvFwdPack.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestGfx950ConvFwdGeometry.cpp ) diff --git a/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp new file mode 100644 index 000000000000..9bb478d758c7 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp @@ -0,0 +1,138 @@ +// Copyright © Advanced Micro Devices, Inc., or its affiliates. +// SPDX-License-Identifier: MIT + +#ifdef HIPDNN_ENABLE_KERNEL_INGESTOR + +#include + +#include + +#include "engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp" + +namespace +{ + +using namespace hip_kernel_provider::kernel_ingestor_engine::gfx950_conv_fwd; + +constexpr Problem SMOKE{2, 32, 32, 14, 14, 3, 3, 1, 1, 1, 1, 1, 1}; + +TEST(TestGfx950ConvFwdGeometry, RejectsAliasedAndPartiallyOverlappingStorage) +{ + // Adjacent storage is legal, independent of argument address order. + EXPECT_TRUE(bufferRangesDoNotOverlap({0x1000, 0x1100, 0x1300}, {256, 512, 128})); + EXPECT_TRUE(bufferRangesDoNotOverlap({0x1300, 0x1100, 0x1000}, {128, 512, 256})); + EXPECT_FALSE(bufferRangesDoNotOverlap({0x1000, 0x1000, 0x2000}, {256, 512, 128})); + EXPECT_FALSE(bufferRangesDoNotOverlap({0x1000, 0x10F0, 0x2000}, {256, 512, 128})); + EXPECT_FALSE(bufferRangesDoNotOverlap({0x1000, 0x2000, 0x1010}, {256, 512, 128})); + EXPECT_FALSE(bufferRangesDoNotOverlap({0x2000, 0x1000, 0x1010}, {256, 512, 128})); + EXPECT_FALSE(bufferRangesDoNotOverlap({0x1000, 0x2000, 0x3000}, {0, 512, 128})); + EXPECT_FALSE(bufferRangesDoNotOverlap( + {0x1000, 0x2000, std::numeric_limits::max() - 63}, {256, 512, 128})); +} + +TEST(TestGfx950ConvFwdGeometry, PaddedSmokeUsesByteCountsAndPartialMTile) +{ + const auto geometry = deriveGeometry(SMOKE); + ASSERT_TRUE(geometry); + EXPECT_EQ(geometry->ho, 14); + EXPECT_EQ(geometry->wo, 14); + EXPECT_EQ(geometry->gemmM, 392); + EXPECT_EQ(geometry->tensorBytes[0], 25088); + EXPECT_EQ(geometry->tensorBytes[1], 18432); + EXPECT_EQ(geometry->tensorBytes[2], 25088); + + const auto launch = launchGeometry(SMOKE, *geometry, 64, 64, 2, 2, 64); + ASSERT_TRUE(launch); + EXPECT_EQ(launch->gridX, 1U); + EXPECT_EQ(launch->gridY, 7U); + EXPECT_EQ(launch->gridZ, 1U); + EXPECT_EQ(launch->blockX, 256U); +} + +TEST(TestGfx950ConvFwdGeometry, NonSquareStrideAndDilationUseFloorOutputShape) +{ + const Problem problem{2, 32, 96, 15, 19, 3, 2, 2, 3, 1, 0, 2, 1}; + const auto geometry = deriveGeometry(problem); + ASSERT_TRUE(geometry); + EXPECT_EQ(geometry->ho, 7); + EXPECT_EQ(geometry->wo, 6); + EXPECT_EQ(geometry->gemmM, 84); + EXPECT_EQ(geometry->tensorBytes[0], 36480); + EXPECT_EQ(geometry->tensorBytes[1], 36864); + EXPECT_EQ(geometry->tensorBytes[2], 16128); + + const auto launch = launchGeometry(problem, *geometry, 64, 64, 2, 2, 64); + ASSERT_TRUE(launch); + EXPECT_EQ(launch->gridX, 2U); + EXPECT_EQ(launch->gridY, 2U); +} + +TEST(TestGfx950ConvFwdGeometry, RefusesNonpositiveExtentAndEmptyOutput) +{ + auto problem = SMOKE; + problem.c = 0; + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.n = -1; + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.y = 20; + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.strideH = 0; + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.dilationW = -1; + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.padH = -1; + EXPECT_FALSE(deriveGeometry(problem)); +} + +TEST(TestGfx950ConvFwdGeometry, RefusesSignedByteCountOverflowForEveryOperand) +{ + EXPECT_EQ(tensorByteSize({1, 1, 1, 1073741823}), 2147483646); + EXPECT_FALSE(tensorByteSize({1, 1, 1, 1073741824})); + EXPECT_FALSE(tensorByteSize({std::numeric_limits::max(), 1, 1, 1})); + + auto problem = SMOKE; + problem.n = 100000000; + EXPECT_FALSE(deriveGeometry(problem)); // A bytes. + problem = SMOKE; + problem.y = 100000000; + EXPECT_FALSE(deriveGeometry(problem)); // B bytes. + problem = Problem{1, 1, 32768, 256, 256, 1, 1, 1, 1, 0, 0, 1, 1}; + EXPECT_FALSE(deriveGeometry(problem)); // D bytes; A and B each fit. +} + +TEST(TestGfx950ConvFwdGeometry, RefusesOverflowInPaddedAndDilatedCoordinates) +{ + auto problem = SMOKE; + problem.padH = std::numeric_limits::max(); + EXPECT_FALSE(deriveGeometry(problem)); + problem = SMOKE; + problem.dilationW = std::numeric_limits::max(); + EXPECT_FALSE(deriveGeometry(problem)); +} + +TEST(TestGfx950ConvFwdGeometry, EnforcesTheBuildersGridAndWorkgroupLimits) +{ + const auto geometry = deriveGeometry(SMOKE); + ASSERT_TRUE(geometry); + EXPECT_FALSE(launchGeometry(SMOKE, *geometry, 0, 64, 2, 2, 64)); + EXPECT_FALSE(launchGeometry(SMOKE, *geometry, 64, -1, 2, 2, 64)); + EXPECT_FALSE(launchGeometry(SMOKE, *geometry, 64, 64, 0, 2, 64)); + EXPECT_FALSE(launchGeometry(SMOKE, *geometry, 64, 64, 2, 2, 32)); + EXPECT_FALSE(launchGeometry(SMOKE, *geometry, 64, 64, 16, 2, 64)); + EXPECT_FALSE( + launchGeometry(SMOKE, *geometry, 64, 64, std::numeric_limits::max(), 2, 64)); + + const Problem tooManyTiles{1, 1, 1, 2048, 2048, 1, 1, 1, 1, 0, 0, 1, 1}; + const auto largeGeometry = deriveGeometry(tooManyTiles); + ASSERT_TRUE(largeGeometry); + EXPECT_FALSE(launchGeometry(tooManyTiles, *largeGeometry, 64, 64, 2, 2, 64)); +} + +} // namespace + +#endif // HIPDNN_ENABLE_KERNEL_INGESTOR diff --git a/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp new file mode 100644 index 000000000000..f21c4ffb2a03 --- /dev/null +++ b/dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp @@ -0,0 +1,510 @@ +// Copyright © Advanced Micro Devices, Inc., or its affiliates. +// SPDX-License-Identifier: MIT + +#ifdef HIPDNN_ENABLE_KERNEL_INGESTOR + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "packs/PointwiseTestGraphs.hpp" + +namespace +{ + +using namespace hip_kernel_provider::kernel_ingestor_engine::testing; +using namespace hipdnn_plugin_sdk::ingestor; +namespace data_objects = hipdnn_flatbuffers_sdk::data_objects; + +constexpr PackSymbols GFX950_CONV_FWD{"hipkernel:Gfx950ConvFwd", + "hipkernel.gfx950_conv_fwd.graph_match", + "", + "hipkernel.gfx950_conv_fwd.kernel_match", + "hipkernel.gfx950_conv_fwd.score", + "hipkernel.gfx950_conv_fwd.dispatch", + "gfx950_conv_fwd.x.uid", + "gfx950_conv_fwd.w.uid", + "gfx950_conv_fwd.y.uid"}; + +struct TensorSpec +{ + std::vector dims; + std::vector strides; + data_objects::DataType dtype = data_objects::DataType::HALF; + bool isVirtual = false; + bool passByValue = false; + bool constant = false; + bool omitDims = false; + bool omitStrides = false; + std::optional raggedOffset{}; + int64_t alignment = 16; +}; + +struct GraphSpec +{ + std::array tensors{{{{2, 32, 14, 14}, {6272, 1, 448, 32}}, + {{32, 32, 3, 3}, {288, 1, 96, 32}}, + {{2, 32, 14, 14}, {6272, 1, 448, 32}}}}; + std::vector stride{1, 1}; + std::vector dilation{1, 1}; + std::vector prePadding{1, 1}; + std::vector postPadding{1, 1}; + data_objects::DataType computeType = data_objects::DataType::FLOAT; + data_objects::ConvMode mode = data_objects::ConvMode::CROSS_CORRELATION; + bool omitStride = false; + bool omitTensor = false; + bool overrideShapes = false; + unsigned int nodeCount = 1; + int64_t xUid = 1; + int64_t wUid = 2; + int64_t yUid = 3; +}; + +DeviceProperties gfx950Properties(std::string arch = "gfx950") +{ + // Deliberately by value: matcher tests must run on CPU-only and non-gfx950 hosts. + DeviceProperties properties; + properties.gcnArchName = std::move(arch); + properties.warpSize = 64; + return properties; +} + +flatbuffers::FlatBufferBuilder buildGraph(const GraphSpec& spec = {}) +{ + flatbuffers::FlatBufferBuilder builder; + std::vector> tensors; + for(size_t i = 0; i < spec.tensors.size(); ++i) + { + if(spec.omitTensor && i == 0) + { + continue; + } + const auto& tensor = spec.tensors[i]; + const auto dims = tensor.omitDims ? flatbuffers::Offset>() + : builder.CreateVector(tensor.dims); + const auto strides = tensor.omitStrides + ? flatbuffers::Offset>() + : builder.CreateVector(tensor.strides); + const auto value = tensor.constant + ? builder.CreateStruct(data_objects::Float16Value(1.0F)).Union() + : flatbuffers::Offset(); + data_objects::TensorAttributesBuilder tensorBuilder(builder); + tensorBuilder.add_uid(static_cast(i + 1)); + tensorBuilder.add_data_type(tensor.dtype); + tensorBuilder.add_dims(dims); + tensorBuilder.add_strides(strides); + tensorBuilder.add_virtual_(tensor.isVirtual); + tensorBuilder.add_is_runtime_pass_by_value(tensor.passByValue); + tensorBuilder.add_alignment(tensor.alignment); + if(tensor.constant) + { + tensorBuilder.add_value_type(data_objects::TensorValue::Float16Value); + tensorBuilder.add_value(value); + } + if(tensor.raggedOffset) + { + tensorBuilder.add_ragged_offset_tensor_uid(*tensor.raggedOffset); + } + tensors.push_back(tensorBuilder.Finish()); + } + const auto attributes = data_objects::CreateConvolutionFwdAttributesDirect( + builder, + spec.xUid, + spec.wUid, + spec.yUid, + &spec.prePadding, + &spec.postPadding, + spec.omitStride ? nullptr : &spec.stride, + &spec.dilation, + spec.mode); + std::vector> nodes; + for(unsigned int i = 0; i < spec.nodeCount; ++i) + { + nodes.push_back( + data_objects::CreateNodeDirect(builder, + "gfx950_conv_fwd_test", + spec.computeType, + data_objects::NodeAttributes::ConvolutionFwdAttributes, + attributes.Union())); + } + const auto tensorVector = builder.CreateVector(tensors); + const auto nodeVector = builder.CreateVector(nodes); + data_objects::GraphBuilder graphBuilder(builder); + graphBuilder.add_tensors(tensorVector); + graphBuilder.add_nodes(nodeVector); + graphBuilder.add_is_override_shape_enabled(spec.overrideShapes); + builder.Finish(graphBuilder.Finish()); + return builder; +} + +KernelDefinition smokeKernel(int64_t tileK = 64, const std::string& dtype = "fp16") +{ + KernelDefinition kernel; + kernel.source.kind = KernelSourceKind::KPACK; + kernel.metadata = {{"N", int64_t{2}}, + {"C", int64_t{32}}, + {"K", int64_t{32}}, + {"Hi", int64_t{14}}, + {"Wi", int64_t{14}}, + {"Y", int64_t{3}}, + {"X", int64_t{3}}, + {"sH", int64_t{1}}, + {"sW", int64_t{1}}, + {"pH", int64_t{1}}, + {"pW", int64_t{1}}, + {"dH", int64_t{1}}, + {"dW", int64_t{1}}, + {"dtype", dtype}, + {"tile_m", int64_t{64}}, + {"tile_n", int64_t{64}}, + {"tile_k", tileK}, + {"warp_m", int64_t{2}}, + {"warp_n", int64_t{2}}, + {"warp_tile_m", int64_t{32}}, + {"warp_tile_n", int64_t{32}}, + {"warp_tile_k", int64_t{16}}, + {"wave_size", int64_t{64}}, + {"pipeline", std::string("mem")}, + {"epilogue", std::string("cshuffle")}, + {"layout", std::string("NHWC")}, + {"groups", int64_t{1}}}; + return kernel; +} + +TEST(TestGfx950ConvFwdGraphMatcher, AcceptsBothStorageTypesAndBindsActualTensorUids) +{ + for(const auto dtype : {data_objects::DataType::HALF, data_objects::DataType::BFLOAT16}) + { + GraphSpec spec; + for(auto& tensor : spec.tensors) + { + tensor.dtype = dtype; + } + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + const auto bound = matchesGraph(GFX950_CONV_FWD, fixture.context()); + ASSERT_TRUE(bound); + EXPECT_EQ(tryGetBoundInt(*bound, GFX950_CONV_FWD.inputAToken), 1); + EXPECT_EQ(tryGetBoundInt(*bound, GFX950_CONV_FWD.inputBToken), 2); + EXPECT_EQ(tryGetBoundInt(*bound, GFX950_CONV_FWD.outputToken), 3); + } +} + +TEST(TestGfx950ConvFwdGraphMatcher, ArchGateUnderstandsFeatureSuffixes) +{ + const GraphFixture accepted(buildGraph(), gfx950Properties("gfx950:sramecc+:xnack-")); + EXPECT_TRUE(matchesGraph(GFX950_CONV_FWD, accepted.context())); + for(const auto* arch : {"gfx942", "gfx9500", "gfx95", "", "prefix-gfx950"}) + { + SCOPED_TRACE(arch); + const GraphFixture refused(buildGraph(), gfx950Properties(arch)); + EXPECT_FALSE(matchesGraph(GFX950_CONV_FWD, refused.context())); + } + auto properties = gfx950Properties(); + properties.warpSize = 32; + const GraphFixture refused(buildGraph(), properties); + EXPECT_FALSE(matchesGraph(GFX950_CONV_FWD, refused.context())); +} + +TEST(TestGfx950ConvFwdGraphMatcher, AcceptsUnitExtentAxesWithArbitraryStrides) +{ + GraphSpec spec; + spec.tensors[0].dims = {1, 1, 14, 14}; + spec.tensors[0].strides = {0, 196, 14, 1}; + spec.tensors[1].dims = {1, 1, 3, 3}; + spec.tensors[1].strides = {9, 9, 3, 1}; + spec.tensors[2].dims = {1, 1, 14, 14}; + spec.tensors[2].strides = {196, 196, 14, 1}; + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + EXPECT_TRUE(matchesGraph(GFX950_CONV_FWD, fixture.context())); +} + +TEST(TestGfx950ConvFwdGraphMatcher, AllowsOneByOneStridedDilatedAndNonSquareProblems) +{ + const std::vector> cases{ + [](auto& s) { + s.tensors[1].dims = {32, 32, 1, 1}; + s.tensors[1].strides = {32, 1, 32, 32}; + }, + [](auto& s) { s.stride = {2, 3}; }, + [](auto& s) { s.dilation = {2, 1}; }, + [](auto& s) { + s.tensors[0].dims = {2, 32, 15, 19}; + s.tensors[0].strides = {9120, 1, 608, 32}; + }}; + for(const auto& change : cases) + { + GraphSpec spec; + change(spec); + // The frontend will infer the changed output dimensions before preparation. + spec.tensors[2].omitDims = true; + spec.tensors[2].omitStrides = true; + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + EXPECT_TRUE(matchesGraph(GFX950_CONV_FWD, fixture.context())); + } +} + +struct RefusalCase +{ + const char* name; + std::function change; +}; + +TEST(TestGfx950ConvFwdGraphMatcher, RefusesUnsupportedGraphsBeforeReadingTheirGeometry) +{ + const std::vector cases{ + {"fused graph", [](auto& s) { s.nodeCount = 2; }}, + {"empty graph", [](auto& s) { s.nodeCount = 0; }}, + {"runtime shape overrides", [](auto& s) { s.overrideShapes = true; }}, + {"convolution mode", [](auto& s) { s.mode = data_objects::ConvMode::CONVOLUTION; }}, + {"half accumulation", [](auto& s) { s.computeType = data_objects::DataType::HALF; }}, + {"unset accumulation", [](auto& s) { s.computeType = data_objects::DataType::UNSET; }}, + {"missing tensor", [](auto& s) { s.omitTensor = true; }}, + {"dangling tensor", [](auto& s) { s.xUid = 999; }}, + {"aliased output uid", [](auto& s) { s.yUid = s.xUid; }}, + {"groups", [](auto& s) { s.tensors[1].dims[1] = 16; }}, + {"NCHW input", [](auto& s) { s.tensors[0].strides = {6272, 196, 14, 1}; }}, + {"KCYX filter", [](auto& s) { s.tensors[1].strides = {288, 9, 3, 1}; }}, + {"nonpacked input", [](auto& s) { s.tensors[0].strides[0] += 32; }}, + {"negative stride", [](auto& s) { s.tensors[0].strides[2] = -448; }}, + {"rank three input", [](auto& s) { s.tensors[0].dims.pop_back(); }}, + {"rank three filter", [](auto& s) { s.tensors[1].dims.pop_back(); }}, + {"rank five input", [](auto& s) { s.tensors[0].dims.push_back(1); }}, + {"missing input dims", [](auto& s) { s.tensors[0].omitDims = true; }}, + {"missing filter strides", [](auto& s) { s.tensors[1].omitStrides = true; }}, + {"zero extent", [](auto& s) { s.tensors[0].dims[2] = 0; }}, + {"negative extent", [](auto& s) { s.tensors[1].dims[3] = -1; }}, + {"overflow extent", + [](auto& s) { s.tensors[0].dims[0] = std::numeric_limits::max(); }}, + {"missing stride", [](auto& s) { s.omitStride = true; }}, + {"wrong stride rank", [](auto& s) { s.stride = {1}; }}, + {"zero stride", [](auto& s) { s.stride[0] = 0; }}, + {"negative dilation", [](auto& s) { s.dilation[1] = -1; }}, + {"wrong dilation rank", [](auto& s) { s.dilation = {1, 1, 1}; }}, + {"negative padding", [](auto& s) { s.prePadding[0] = s.postPadding[0] = -1; }}, + {"asymmetric padding", [](auto& s) { s.postPadding[0] = 2; }}, + {"empty padding", [](auto& s) { s.prePadding.clear(); }}, + {"empty output extent", [](auto& s) { s.dilation = {100, 100}; }}}; + for(const auto& test : cases) + { + SCOPED_TRACE(test.name); + GraphSpec spec; + test.change(spec); + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + EXPECT_FALSE(matchesGraph(GFX950_CONV_FWD, fixture.context())); + } + const GraphFixture pointwise(buildPointwiseGraph(), gfx950Properties()); + EXPECT_FALSE(matchesGraph(GFX950_CONV_FWD, pointwise.context())); +} + +TEST(TestGfx950ConvFwdGraphMatcher, RejectsUnsupportedStorageOnEveryOperand) +{ + const std::vector> changes{ + [](auto& t) { t.dtype = data_objects::DataType::FLOAT; }, + [](auto& t) { t.dtype = data_objects::DataType::BFLOAT16; }, + [](auto& t) { t.isVirtual = true; }, + [](auto& t) { t.passByValue = true; }, + [](auto& t) { t.constant = true; }, + [](auto& t) { t.raggedOffset = 7; }, + [](auto& t) { t.alignment = 8; }}; + for(size_t operand = 0; operand < 3; ++operand) + { + SCOPED_TRACE(operand); + for(const auto& change : changes) + { + GraphSpec spec; + change(spec.tensors[operand]); + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + EXPECT_FALSE(matchesGraph(GFX950_CONV_FWD, fixture.context())); + } + } +} + +TEST(TestGfx950ConvFwdKernelMatcher, BothTileKVariantsMatchOnlyTheirStorageType) +{ + for(const auto dtype : {data_objects::DataType::HALF, data_objects::DataType::BFLOAT16}) + { + GraphSpec spec; + for(auto& tensor : spec.tensors) + { + tensor.dtype = dtype; + } + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + const std::string name = dtype == data_objects::DataType::HALF ? "fp16" : "bf16"; + const std::string otherName = name == "fp16" ? "bf16" : "fp16"; + for(const auto tileK : {64, 128}) + { + EXPECT_TRUE( + matchesKernel(GFX950_CONV_FWD, fixture.context(), smokeKernel(tileK, name))); + EXPECT_FALSE( + matchesKernel(GFX950_CONV_FWD, fixture.context(), smokeKernel(tileK, otherName))); + } + } +} + +TEST(TestGfx950ConvFwdKernelMatcher, EveryBakedShapeAttributeMustMatch) +{ + const GraphFixture fixture(buildGraph(), gfx950Properties()); + for(const auto* field : + {"N", "C", "K", "Hi", "Wi", "Y", "X", "sH", "sW", "pH", "pW", "dH", "dW"}) + { + SCOPED_TRACE(field); + auto kernel = smokeKernel(); + kernel.metadata[field] = kernel.getIntMetadata(field) + 1; + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + } +} + +TEST(TestGfx950ConvFwdKernelMatcher, MissingOrWronglyTypedMetadataDeclinesCleanly) +{ + const GraphFixture fixture(buildGraph(), gfx950Properties()); + const auto original = smokeKernel(); + for(const auto& field : original.metadata) + { + SCOPED_TRACE(field.first); + auto kernel = original; + kernel.metadata.erase(field.first); + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + kernel.metadata[field.first] = std::vector{1}; + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + } +} + +TEST(TestGfx950ConvFwdKernelMatcher, DeclinesUnreviewedTuningAndUnpackagedCode) +{ + const GraphFixture fixture(buildGraph(), gfx950Properties()); + for(const auto* field : {"tile_m", + "tile_n", + "tile_k", + "warp_m", + "warp_n", + "warp_tile_m", + "warp_tile_n", + "warp_tile_k", + "wave_size"}) + { + SCOPED_TRACE(field); + auto kernel = smokeKernel(); + kernel.metadata[field] = kernel.getIntMetadata(field) + 1; + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + } + auto kernel = smokeKernel(); + kernel.metadata["pipeline"] = std::string("wavelet"); + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + kernel = smokeKernel(); + kernel.metadata["epilogue"] = std::string("relu"); + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + kernel = smokeKernel(); + kernel.metadata["groups"] = int64_t{2}; + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + kernel = smokeKernel(); + kernel.metadata["layout"] = std::string("NCHW"); + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + kernel = smokeKernel(); + for(const auto kind : {KernelSourceKind::EMBEDDED_SOURCE, + KernelSourceKind::ROCKE_BUILDER, + KernelSourceKind::HSACO_FILE}) + { + kernel.source.kind = kind; + EXPECT_FALSE(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel)); + } +} + +TEST(TestGfx950ConvFwdKernelMatcher, DefaultEpilogueRequiresScalarOutputStores) +{ + // is_valid_spec_for_problem accepts K=31 (auto vec_c=1) and rejects K=32 + // (auto vec_c=8) for default epilogues, for both dtypes and tile_k choices. + for(const auto dtype : {data_objects::DataType::HALF, data_objects::DataType::BFLOAT16}) + { + const std::string name = dtype == data_objects::DataType::HALF ? "fp16" : "bf16"; + SCOPED_TRACE(name); + for(const auto k : {int64_t{31}, int64_t{32}}) + { + SCOPED_TRACE(k); + GraphSpec spec; + for(auto& tensor : spec.tensors) + { + tensor.dtype = dtype; + } + spec.tensors[1].dims[0] = k; + spec.tensors[2].dims[1] = k; + spec.tensors[2].strides = {14 * 14 * k, 1, 14 * k, k}; + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + for(const auto tileK : {64, 128}) + { + SCOPED_TRACE(tileK); + auto kernel = smokeKernel(tileK, name); + kernel.metadata["K"] = k; + kernel.metadata["epilogue"] = std::string("default"); + EXPECT_EQ(matchesKernel(GFX950_CONV_FWD, fixture.context(), kernel), k == 31); + } + } + } +} + +TEST(TestGfx950ConvFwdScore, FallbackPrefersDispatcherDefault) +{ + const GraphFixture fixture(buildGraph(), gfx950Properties()); + EXPECT_GT(scoreKernel(GFX950_CONV_FWD, fixture.context(), smokeKernel(64)), + scoreKernel(GFX950_CONV_FWD, fixture.context(), smokeKernel(128))); +} + +TEST(TestGfx950ConvFwdDispatch, RegisteredHandlerNeedsNoWorkspaceAndChecksBindings) +{ + const GraphFixture fixture(buildGraph(), gfx950Properties()); + const auto bound = matchesGraph(GFX950_CONV_FWD, fixture.context()); + ASSERT_TRUE(bound); + const auto& handler = dispatchHandler(GFX950_CONV_FWD); + EXPECT_EQ(handler.workspaceBytes(fixture.context(), *bound, smokeKernel()), 0U); + EXPECT_THROW(handler.prepare(fixture.context(), {}, smokeKernel()), + hipdnn_plugin_sdk::HipdnnPluginException); + auto wrongBound = *bound; + wrongBound[std::string(GFX950_CONV_FWD.outputToken)] = int64_t{1}; + EXPECT_THROW(handler.prepare(fixture.context(), wrongBound, smokeKernel()), + hipdnn_plugin_sdk::HipdnnPluginException); +} + +TEST(TestGfx950ConvFwdDispatch, OutputValidationWaitsForPreparationAndPrecedesCodeLoading) +{ + const std::vector> cases{ + [](auto& t) { + t.omitDims = true; + t.omitStrides = true; + }, + [](auto& t) { t.strides = {6272, 196, 14, 1}; }, + [](auto& t) { t.dims = {2, 32, 14}; }, + [](auto& t) { t.dims[2] = 0; }, + [](auto& t) { t.dims[0] = 1; }, + [](auto& t) { + t.dims[1] = 16; + t.strides = {3136, 1, 224, 16}; + }}; + for(const auto& change : cases) + { + GraphSpec spec; + change(spec.tensors[2]); + const GraphFixture fixture(buildGraph(spec), gfx950Properties()); + const auto bound = matchesGraph(GFX950_CONV_FWD, fixture.context()); + ASSERT_TRUE(bound); + const auto& handler = dispatchHandler(GFX950_CONV_FWD); + try + { + // An empty archive path must never be reached in any of these cases. + handler.prepare(fixture.context(), *bound, smokeKernel()); + FAIL() << "Preparation accepted an invalid output tensor"; + } + catch(const hipdnn_plugin_sdk::HipdnnPluginException& error) + { + EXPECT_NE(std::string(error.what()).find("packed NHWK output"), std::string::npos); + } + } +} + +} // namespace + +#endif // HIPDNN_ENABLE_KERNEL_INGESTOR diff --git a/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/graph.template.json b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/graph.template.json new file mode 100644 index 000000000000..4e5ac895dbd1 --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/graph.template.json @@ -0,0 +1,54 @@ +{ + "compute_data_type": "float", + "intermediate_data_type": "${case.intermediate_data_type}", + "io_data_type": "${case.io_data_type}", + "is_override_shape_enabled": false, + "name": "Gfx950ConvFwd", + "nodes": [ + { + "compute_data_type": "float", + "inputs": { + "w_tensor_uid": 1, + "x_tensor_uid": 2 + }, + "name": "convolution", + "outputs": { + "y_tensor_uid": 0 + }, + "parameters": { + "conv_mode": "CROSS_CORRELATION", + "dilation": "${case.attributes.parameters__dilation}", + "post_padding": "${case.attributes.parameters__post_padding}", + "pre_padding": "${case.attributes.parameters__pre_padding}", + "stride": "${case.attributes.parameters__stride}" + }, + "type": "ConvolutionFwdAttributes" + } + ], + "tensors": [ + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "Y", + "strides": "${case.strides}", + "uid": 0, + "virtual": false + }, + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "W", + "strides": "${case.strides}", + "uid": 1, + "virtual": false + }, + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "X", + "strides": "${case.strides}", + "uid": 2, + "virtual": false + } + ] +} diff --git a/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/support.json b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/support.json new file mode 100644 index 000000000000..7a3e2b9a9d86 --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/support.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "claims": { + "hipkernel:Gfx950ConvFwd": [ + { + "cases": [ + "smoke_half", + "smoke_bfloat16" + ], + "support": { + "gfx950": [ + "linux" + ] + } + } + ] + } +} diff --git a/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/sweep.json b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/sweep.json new file mode 100644 index 000000000000..60f8d4ac30ad --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/quick/Gfx950ConvFwd/Smoke/sweep.json @@ -0,0 +1,171 @@ +{ + "version": 1, + "cases": [ + { + "id": "smoke_half", + "values": { + "io_data_type": "half", + "intermediate_data_type": "half", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 32, + 14, + 14 + ], + "strides": [ + 6272, + 1, + 448, + 32 + ], + "data_type": "half" + }, + { + "uid": 1, + "dims": [ + 32, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "half" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 14, + 14 + ], + "strides": [ + 6272, + 1, + 448, + 32 + ], + "data_type": "half" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 1 + ], + "parameters__pre_padding": [ + 1, + 1 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "smoke_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 32, + 14, + 14 + ], + "strides": [ + 6272, + 1, + 448, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [ + 32, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 14, + 14 + ], + "strides": [ + 6272, + 1, + 448, + 32 + ], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 1 + ], + "parameters__pre_padding": [ + 1, + 1 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + } + ] +} diff --git a/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/graph.template.json b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/graph.template.json new file mode 100644 index 000000000000..4e5ac895dbd1 --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/graph.template.json @@ -0,0 +1,54 @@ +{ + "compute_data_type": "float", + "intermediate_data_type": "${case.intermediate_data_type}", + "io_data_type": "${case.io_data_type}", + "is_override_shape_enabled": false, + "name": "Gfx950ConvFwd", + "nodes": [ + { + "compute_data_type": "float", + "inputs": { + "w_tensor_uid": 1, + "x_tensor_uid": 2 + }, + "name": "convolution", + "outputs": { + "y_tensor_uid": 0 + }, + "parameters": { + "conv_mode": "CROSS_CORRELATION", + "dilation": "${case.attributes.parameters__dilation}", + "post_padding": "${case.attributes.parameters__post_padding}", + "pre_padding": "${case.attributes.parameters__pre_padding}", + "stride": "${case.attributes.parameters__stride}" + }, + "type": "ConvolutionFwdAttributes" + } + ], + "tensors": [ + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "Y", + "strides": "${case.strides}", + "uid": 0, + "virtual": false + }, + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "W", + "strides": "${case.strides}", + "uid": 1, + "virtual": false + }, + { + "data_type": "${case.data_type}", + "dims": "${case.dims}", + "name": "X", + "strides": "${case.strides}", + "uid": 2, + "virtual": false + } + ] +} diff --git a/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/support.json b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/support.json new file mode 100644 index 000000000000..78c504fdb52b --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/support.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "claims": { + "hipkernel:Gfx950ConvFwd": [ + { + "cases": [ + "pointwise_half", + "pointwise_bfloat16", + "strided_half", + "strided_bfloat16", + "dilated_half", + "dilated_bfloat16", + "nonsquare_half", + "nonsquare_bfloat16", + "workload_56x56_bfloat16" + ], + "support": { + "gfx950": [ + "linux" + ] + } + } + ] + } +} diff --git a/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/sweep.json b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/sweep.json new file mode 100644 index 000000000000..1c8eef217c04 --- /dev/null +++ b/dnn-providers/integration-tests/integration-test-bundles/standard/Gfx950ConvFwd/Spatial/sweep.json @@ -0,0 +1,710 @@ +{ + "version": 1, + "cases": [ + { + "id": "pointwise_half", + "values": { + "io_data_type": "half", + "intermediate_data_type": "half", + "tensors": [ + { + "uid": 0, + "dims": [ + 1, + 64, + 8, + 8 + ], + "strides": [ + 4096, + 1, + 512, + 64 + ], + "data_type": "half" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 1, + 1 + ], + "strides": [ + 32, + 1, + 32, + 32 + ], + "data_type": "half" + }, + { + "uid": 2, + "dims": [ + 1, + 32, + 8, + 8 + ], + "strides": [ + 2048, + 1, + 256, + 32 + ], + "data_type": "half" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 0, + 0 + ], + "parameters__pre_padding": [ + 0, + 0 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "pointwise_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [ + 1, + 64, + 8, + 8 + ], + "strides": [ + 4096, + 1, + 512, + 64 + ], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 1, + 1 + ], + "strides": [ + 32, + 1, + 32, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [ + 1, + 32, + 8, + 8 + ], + "strides": [ + 2048, + 1, + 256, + 32 + ], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 0, + 0 + ], + "parameters__pre_padding": [ + 0, + 0 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "strided_half", + "values": { + "io_data_type": "half", + "intermediate_data_type": "half", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 64, + 9, + 10 + ], + "strides": [ + 5760, + 1, + 640, + 64 + ], + "data_type": "half" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "half" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 17, + 19 + ], + "strides": [ + 10336, + 1, + 608, + 32 + ], + "data_type": "half" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 1 + ], + "parameters__pre_padding": [ + 1, + 1 + ], + "parameters__stride": [ + 2, + 2 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "strided_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 64, + 9, + 10 + ], + "strides": [ + 5760, + 1, + 640, + 64 + ], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 17, + 19 + ], + "strides": [ + 10336, + 1, + 608, + 32 + ], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 1 + ], + "parameters__pre_padding": [ + 1, + 1 + ], + "parameters__stride": [ + 2, + 2 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "dilated_half", + "values": { + "io_data_type": "half", + "intermediate_data_type": "half", + "tensors": [ + { + "uid": 0, + "dims": [ + 1, + 32, + 15, + 17 + ], + "strides": [ + 8160, + 1, + 544, + 32 + ], + "data_type": "half" + }, + { + "uid": 1, + "dims": [ + 32, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "half" + }, + { + "uid": 2, + "dims": [ + 1, + 32, + 15, + 17 + ], + "strides": [ + 8160, + 1, + 544, + 32 + ], + "data_type": "half" + } + ], + "attributes": { + "parameters__dilation": [ + 2, + 2 + ], + "parameters__post_padding": [ + 2, + 2 + ], + "parameters__pre_padding": [ + 2, + 2 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "dilated_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [ + 1, + 32, + 15, + 17 + ], + "strides": [ + 8160, + 1, + 544, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [ + 32, + 32, + 3, + 3 + ], + "strides": [ + 288, + 1, + 96, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [ + 1, + 32, + 15, + 17 + ], + "strides": [ + 8160, + 1, + 544, + 32 + ], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [ + 2, + 2 + ], + "parameters__post_padding": [ + 2, + 2 + ], + "parameters__pre_padding": [ + 2, + 2 + ], + "parameters__stride": [ + 1, + 1 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "nonsquare_half", + "values": { + "io_data_type": "half", + "intermediate_data_type": "half", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 64, + 11, + 9 + ], + "strides": [ + 6336, + 1, + 576, + 64 + ], + "data_type": "half" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 3, + 5 + ], + "strides": [ + 480, + 1, + 160, + 32 + ], + "data_type": "half" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 11, + 17 + ], + "strides": [ + 5984, + 1, + 544, + 32 + ], + "data_type": "half" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 2 + ], + "parameters__pre_padding": [ + 1, + 2 + ], + "parameters__stride": [ + 1, + 2 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "nonsquare_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [ + 2, + 64, + 11, + 9 + ], + "strides": [ + 6336, + 1, + 576, + 64 + ], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [ + 64, + 32, + 3, + 5 + ], + "strides": [ + 480, + 1, + 160, + 32 + ], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [ + 2, + 32, + 11, + 17 + ], + "strides": [ + 5984, + 1, + 544, + 32 + ], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [ + 1, + 1 + ], + "parameters__post_padding": [ + 1, + 2 + ], + "parameters__pre_padding": [ + 1, + 2 + ], + "parameters__stride": [ + 1, + 2 + ] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Plain channels-last convolution for the packaged gfx950 engine.", + "operation": "ConvolutionFwd", + "seed": 1 + } + }, + { + "id": "workload_56x56_bfloat16", + "values": { + "io_data_type": "bfloat16", + "intermediate_data_type": "bfloat16", + "tensors": [ + { + "uid": 0, + "dims": [1, 64, 56, 56], + "strides": [200704, 1, 3584, 64], + "data_type": "bfloat16" + }, + { + "uid": 1, + "dims": [64, 64, 3, 3], + "strides": [576, 1, 192, 64], + "data_type": "bfloat16" + }, + { + "uid": 2, + "dims": [1, 64, 56, 56], + "strides": [200704, 1, 3584, 64], + "data_type": "bfloat16" + } + ], + "attributes": { + "parameters__dilation": [1, 1], + "parameters__post_padding": [1, 1], + "parameters__pre_padding": [1, 1], + "parameters__stride": [1, 1] + } + }, + "metadata": { + "format_version": 1, + "generator": "manual", + "generator_version": "1.0.0", + "notes": "Representative 56x56 channels-last convolution from the packaged headline catalog.", + "operation": "ConvolutionFwd", + "seed": 1 + } + } + ] +} diff --git a/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.profile.yaml b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.profile.yaml new file mode 100644 index 000000000000..7c0c1ba1f955 --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.profile.yaml @@ -0,0 +1,166 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +# Run these tools from the repository root. This profile describes the same +# adapter, metadata and native hooks as gfx950_conv_fwd.yaml. + +slug: gfx950_conv_fwd +bundle: gfx950_conv_fwd +pack: gfx950_conv_fwd +arch: gfx950 +provider_root: dnn-providers/hip-kernel-provider +dialect: packaged +authored_subpath: rocKE/gfx950_conv_fwd +source: builders/common/convolution_forward.py +builder: build_gfx950_conv_fwd +kernel_source_kind: rocke +workspace_policy: none +delegates_to_existing_plan: false + +engine: + name: hipkernel:Gfx950ConvFwd + sdk_version: "1.0.0" + knobs: [tile_k] + heuristic: native + +request: + module: dispatch.grouped_convolution + class: ConvGroupedRequest + defaults: + direction: fwd + layout: NHWC + G: 1 + algorithm: implicit_gemm_fwd +dispatch: + module: builders.common.convolution_forward + function: gfx950_conv_fwd_spec_for_request +predicate: + module: builders.common.convolution_forward + function: supports_gfx950_conv_fwd +arch_spec: + module: builders.common.convolution_forward + class: Gfx950ConvFwdSpec + +# Consult the real forward candidate, including its capability gate. Grouped +# and 3D cases the reference accepts remain visible as integration scope gaps. +reference_candidates: + module: dispatch.grouped_convolution + function: conv_grouped_candidates + match: algorithm + family: implicit_gemm_fwd +reference_request: + module: dispatch.grouped_convolution + class: ConvGroupedRequest + defaults: + direction: fwd + layout: NHWC + G: 1 + algorithm: implicit_gemm_fwd + +metadata_fields: &metadata_fields + [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, + tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, + warp_tile_k, wave_size, pipeline, epilogue] +kmd_fields: + - {name: N, type: int} + - {name: Hi, type: int} + - {name: Wi, type: int} + - {name: C, type: int} + - {name: K, type: int} + - {name: Y, type: int} + - {name: X, type: int} + - {name: sH, type: int} + - {name: sW, type: int} + - {name: pH, type: int} + - {name: pW, type: int} + - {name: dH, type: int} + - {name: dW, type: int} + - {name: dtype, type: string} + - {name: layout, type: string} + - {name: groups, type: int} + - {name: tile_m, type: int} + - {name: tile_n, type: int} + - {name: tile_k, type: int, default_value: 64} + - {name: warp_m, type: int} + - {name: warp_n, type: int} + - {name: warp_tile_m, type: int} + - {name: warp_tile_n, type: int} + - {name: warp_tile_k, type: int} + - {name: wave_size, type: int} + - {name: pipeline, type: string} + - {name: epilogue, type: string} + +# Metadata uses the adapter's lowercase dtype names. Every tuning value is +# resolved before emission; there are no policy-owned optional fields here. +vocabulary: + dtype: {fp16: fp16, bf16: bf16} + layout: {NHWC: NHWC} + pipeline: {mem: mem} + epilogue: {cshuffle: cshuffle, default: default} +policies: {} +field_map: + G: groups + stride_h: sH + stride_w: sW + pad_h: pH + pad_w: pW + dilation_h: dH + dilation_w: dW +# Partial tiles are masked. tile_k need not divide Y*X*C. +divides: {} +# This models native fallback ordering only. Forced knobs and BenchmarkPlan +# can select either arm; an unforced host corpus will prefer tile_k=64. +score: {field: tile_k, prefer: min} +sweep: + tile_k: + values: [64, 128] + hazard: Keep the mem pipeline and dispatcher geometry fixed; validate every compiled arm. + +launch_surface: + - name: applicability_and_baked_constants + python_source: builders/common/convolution_forward.py:supports_gfx950_conv_fwd + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp:kernelFits + kmd_fields: *metadata_fields + guard: matchProblem checks the unfused forward graph and storage contract; kernelFits compares every compiled shape and tuning value before loading code. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp + - name: problem_geometry_and_byte_counts + python_source: builders/common/convolution_forward.py:_problem_error + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp:deriveGeometry + kmd_fields: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype] + guard: deriveGeometry and outputExtent reject nonpositive outputs, signed byte-count overflow and unrepresentable padded or dilated coordinates. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp + - name: grid + python_source: builders/common/convolution_forward.py:grid + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp:launchGeometry + kmd_fields: [N, Hi, Wi, K, Y, X, sH, sW, pH, pW, dH, dW, groups, tile_m, tile_n] + guard: launchGeometry bounds both workgroup axes and uses ceiling division for the masked partial tiles. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp + - name: block + python_source: builders/common/convolution_forward.py:block + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp:launchGeometry + kmd_fields: [warp_m, warp_n, wave_size, pipeline] + guard: launchGeometry requires wave64 and bounds the thread count; kernelFits admits only the mem pipeline and the packaged warp geometry. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp + - name: kernargs_and_execution + python_source: ../platform/python/rocke/instances/common/conv_implicit_gemm.py:build_implicit_gemm_conv + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp:launch + kmd_fields: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype] + guard: prepare preserves tensor bindings and validated i32 byte counts; launch checks device pointers, 16-byte alignment and non-overlap, then passes A, B, D, A_bytes, B_bytes, D_bytes. + test: dnn-providers/hip-kernel-provider/src/integration_tests/kernel_ingestor_engine/IntegrationGpuGfx950ConvFwd.cpp + - name: pointer_nonalias + python_source: ../platform/python/rocke/instances/common/conv_implicit_gemm.py:build_implicit_gemm_conv + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdGeometry.hpp:bufferRangesDoNotOverlap + kmd_fields: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype] + guard: launch requires disjoint byte ranges for A, B and D, matching the original builder's noalias pointer contract. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdGeometry.cpp + - name: workspace + python_source: ../platform/python/rocke/instances/common/conv_implicit_gemm.py:build_implicit_gemm_conv + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp:workspaceBytes + kmd_fields: [pipeline] + guard: The mem forward builder has no global workspace argument; workspaceBytes returns zero and prepare requests zero dynamic shared-memory bytes. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp + - name: fallback_selection + python_source: builders/common/convolution_forward.py:gfx950_conv_fwd_spec_for_request + cpp_mirror: dnn-providers/hip-kernel-provider/src/engines/kernel_ingestor_engine/packs/Gfx950ConvFwdNative.cpp:score + kmd_fields: [tile_k] + guard: Native score prefers the dispatcher's tile_k=64 default; BenchmarkPlan can replace that ranking with measurements. + test: dnn-providers/hip-kernel-provider/src/tests/engines/kernel_ingestor_engine/TestGfx950ConvFwdPack.cpp diff --git a/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.requests.json b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.requests.json new file mode 100644 index 000000000000..5f81b790fb8c --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.requests.json @@ -0,0 +1,2200 @@ +[ + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "dtype": "fp16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/smoke/fp16", + "sources": [ + { + "source": "verification_matrix", + "case": "smoke" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "dtype": "bf16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/smoke/bf16", + "sources": [ + { + "source": "verification_matrix", + "case": "smoke" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "dtype": "fp16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/pointwise/fp16", + "sources": [ + { + "source": "verification_matrix", + "case": "pointwise" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "N": 1, + "Hi": 8, + "Wi": 8, + "C": 32, + "K": 64, + "Y": 1, + "X": 1, + "dtype": "bf16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/pointwise/bf16", + "sources": [ + { + "source": "verification_matrix", + "case": "pointwise" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "dtype": "fp16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/strided/fp16", + "sources": [ + { + "source": "verification_matrix", + "case": "strided" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 17, + "Wi": 19, + "C": 32, + "K": 64, + "Y": 3, + "X": 3, + "dtype": "bf16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/strided/bf16", + "sources": [ + { + "source": "verification_matrix", + "case": "strided" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 2, + "pad_w": 2, + "dilation_h": 2, + "dilation_w": 2, + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "dtype": "fp16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/dilated/fp16", + "sources": [ + { + "source": "verification_matrix", + "case": "dilated" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 2, + "pad_w": 2, + "dilation_h": 2, + "dilation_w": 2, + "N": 1, + "Hi": 15, + "Wi": 17, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "dtype": "bf16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/dilated/bf16", + "sources": [ + { + "source": "verification_matrix", + "case": "dilated" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 2, + "pad_h": 1, + "pad_w": 2, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "dtype": "fp16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/nonsquare/fp16", + "sources": [ + { + "source": "verification_matrix", + "case": "nonsquare" + } + ] + } + }, + { + "arch": "gfx950", + "direction": "fwd", + "layout": "NHWC", + "G": 1, + "stride_h": 1, + "stride_w": 2, + "pad_h": 1, + "pad_w": 2, + "dilation_h": 1, + "dilation_w": 1, + "N": 2, + "Hi": 11, + "Wi": 17, + "C": 32, + "K": 64, + "Y": 3, + "X": 5, + "dtype": "bf16", + "_catalog_tile_k": [ + 64, + 128 + ], + "_provenance": { + "graph": "verification/nonsquare/bf16", + "sources": [ + { + "source": "verification_matrix", + "case": "nonsquare" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 768, + "Hi": 224, + "Wi": 224, + "Y": 16, + "X": 16, + "G": 1, + "stride_h": 16, + "stride_w": 16, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/CLIP-ViT-B_16__bf16_nhwc_patchify16_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/CLIP-ViT-B_16__bf16_nhwc_patchify16_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/CLIP-ViT-B_16__bf16_nhwc_patchify16_bf16.json", + "sha256": "1a09f2292992532b491932953e87b470023e0bb06417bf4f773bd2b0c2b28121", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1024, + "Hi": 336, + "Wi": 336, + "Y": 14, + "X": 14, + "G": 1, + "stride_h": 14, + "stride_w": 14, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/CLIP-ViT-L_14__bf16_nhwc_patchify14_336_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/CLIP-ViT-L_14__bf16_nhwc_patchify14_336_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/CLIP-ViT-L_14__bf16_nhwc_patchify14_336_bf16.json", + "sha256": "faeab8e62e53dbd987c7d95582358037a8bfcdcabac2fc28cde21079e49a2663", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 128, + "Hi": 224, + "Wi": 224, + "Y": 4, + "X": 4, + "G": 1, + "stride_h": 4, + "stride_w": 4, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ConvNeXt-V2-B__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ConvNeXt-V2-B__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ConvNeXt-V2-B__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "sha256": "7afa5d79cf40369237cd4124857151b74c1ae15797ffc7ab161c9c4822275f1c", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 768, + "K": 3072, + "Hi": 14, + "Wi": 14, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_expand_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_expand_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_expand_1x1_bf16.json", + "sha256": "271f60b121d856572d771d5fcc55eb32eac844c3f713acef439bffef96bd8d3c", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3072, + "K": 768, + "Hi": 14, + "Wi": 14, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_project_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_project_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ConvNeXt-V2-L__bf16_nhwc_block_pw_project_1x1_bf16.json", + "sha256": "ac8a9d81bcaef947e0218f036e7a3b0102e4b7fc860fb2779a197a0519b5a386", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 384, + "K": 768, + "Hi": 28, + "Wi": 28, + "Y": 2, + "X": 2, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_downsample_2x2_s2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_downsample_2x2_s2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ConvNeXt-V2-L__bf16_nhwc_downsample_2x2_s2_bf16.json", + "sha256": "0fd0b31ff8fe2d120052917a30d1293b7a36634e6e3fee734de3475ca75e62fa", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 192, + "Hi": 224, + "Wi": 224, + "Y": 4, + "X": 4, + "G": 1, + "stride_h": 4, + "stride_w": 4, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ConvNeXt-V2-L__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ConvNeXt-V2-L__bf16_nhwc_stem_patchify_4x4_s4_bf16.json", + "sha256": "b79f1bbafb6af1962795f459fd6c7851e3b4137ec2bb74f8ab11218a6a3cfa1a", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1536, + "Hi": 224, + "Wi": 224, + "Y": 14, + "X": 14, + "G": 1, + "stride_h": 14, + "stride_w": 14, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/DINOv2-ViT-g_14__bf16_nhwc_patchify14_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/DINOv2-ViT-g_14__bf16_nhwc_patchify14_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/DINOv2-ViT-g_14__bf16_nhwc_patchify14_bf16.json", + "sha256": "2bfcb6d275a17eb701123fbbdca1774a28823c94811dc853f83112826830cd68", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 80, + "K": 480, + "Hi": 24, + "Wi": 24, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/EfficientNetV2-M__bf16_nhwc_ib_expand_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/EfficientNetV2-M__bf16_nhwc_ib_expand_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/EfficientNetV2-M__bf16_nhwc_ib_expand_1x1_bf16.json", + "sha256": "2d9dc138f3b956b9873167ea2401a8081a13bc1586c4310fd6bc51bfc7231312", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 24, + "K": 48, + "Hi": 192, + "Wi": 192, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/EfficientNetV2-S__bf16_nhwc_fused_mbconv_3x3_s2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/EfficientNetV2-S__bf16_nhwc_fused_mbconv_3x3_s2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/EfficientNetV2-S__bf16_nhwc_fused_mbconv_3x3_s2_bf16.json", + "sha256": "3b88242b48d5858305e0f882c0da957b88a57ca70cc26f5667f879555cd8b885", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 32, + "K": 512, + "Hi": 128, + "Wi": 128, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/Flux.2-VAE__bf16_nhwc_dec_conv_in_32ch_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/Flux.2-VAE__bf16_nhwc_dec_conv_in_32ch_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/Flux.2-VAE__bf16_nhwc_dec_conv_in_32ch_3x3_bf16.json", + "sha256": "971e0b662289299a6165956d95642b3263238dbadf838f9ba2c3b0d73cb70604", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 3200, + "Hi": 448, + "Wi": 448, + "Y": 14, + "X": 14, + "G": 1, + "stride_h": 14, + "stride_w": 14, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/InternViT-6B__bf16_nhwc_patchify14_448_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/InternViT-6B__bf16_nhwc_patchify14_448_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/InternViT-6B__bf16_nhwc_patchify14_448_bf16.json", + "sha256": "ffd6c1b57b614356db8bdc06926b9d900101d3b8dd2fe3e485f76629a782812a", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 24, + "K": 144, + "Hi": 56, + "Wi": 56, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_expand_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_expand_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_expand_1x1_bf16.json", + "sha256": "a426c82f1af7b060e0ad8d0c4aa903237aac9d7aaa2bae0347e1ae4b5c5c45e6", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 144, + "K": 40, + "Hi": 28, + "Wi": 28, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_project_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_project_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/MobileNetV4-Conv-L__bf16_nhwc_ib_project_1x1_bf16.json", + "sha256": "6f89e6cec5f1aba78a69ded81d9ab189b2ccc905694803b371f824c8a13de045", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 32, + "Hi": 640, + "Wi": 640, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/RT-DETR-R50__bf16_nhwc_hgnet_stem_3x3_s2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/RT-DETR-R50__bf16_nhwc_hgnet_stem_3x3_s2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/RT-DETR-R50__bf16_nhwc_hgnet_stem_3x3_s2_bf16.json", + "sha256": "c65b2861d1b9ca0c82a81ba1c4f366fe312ed1ea5ec81fd7f46be7c8765719a5", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 256, + "Hi": 28, + "Wi": 28, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/RepVGG-B2__bf16_nhwc_reparam_dense_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/RepVGG-B2__bf16_nhwc_reparam_dense_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/RepVGG-B2__bf16_nhwc_reparam_dense_3x3_bf16.json", + "sha256": "923b2b76f12d5ca337e3a1f9773fe30c8de9d0eebb81cd1a64cd80ff89fcd8c3", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 256, + "Hi": 14, + "Wi": 14, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-152__bf16_nhwc_bottleneck_3x3_s1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-152__bf16_nhwc_bottleneck_3x3_s1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-152__bf16_nhwc_bottleneck_3x3_s1_bf16.json", + "sha256": "0902386617b7221bfaf76460f3604a6321a12d563e7cb15c632094e77e6c9d1a", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 64, + "K": 64, + "Hi": 56, + "Wi": 56, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_bottleneck_3x3_s1_nhwc_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_bottleneck_3x3_s1_nhwc_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_bottleneck_3x3_s1_nhwc_bf16.json", + "sha256": "4757b00f7d8fc6350b458f804c356f942da7b98eaae9583b3c1c6ad4a18d7e41", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 128, + "K": 128, + "Hi": 56, + "Wi": 56, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_downsample_3x3_s2_nhwc_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_downsample_3x3_s2_nhwc_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_downsample_3x3_s2_nhwc_bf16.json", + "sha256": "38515937997806d4c2713f2791eb28ae33212af2bab86983fb72df6b26275fa7", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 64, + "K": 256, + "Hi": 56, + "Wi": 56, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_expand_1x1_nhwc_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_expand_1x1_nhwc_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_expand_1x1_nhwc_bf16.json", + "sha256": "667d5dfa45076c69fdc78d05b1651bb248290cfec02f8f97fcf62e2aeae6cb2a", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 64, + "Hi": 56, + "Wi": 56, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_reduce_1x1_nhwc_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_reduce_1x1_nhwc_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_reduce_1x1_nhwc_bf16.json", + "sha256": "82ed4d27dbca6d7731a4e4f453d5768e5e4cdff5b86fb4ee3dd67ec76d0a57fb", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 512, + "K": 512, + "Hi": 7, + "Wi": 7, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_stage4_3x3_512_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_stage4_3x3_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_stage4_3x3_512_bf16.json", + "sha256": "c80ae57cf0bd26d0f454424f23bfd1df7079a260692da61b6ca56719eb52eba3", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 256, + "C": 3, + "K": 64, + "Hi": 224, + "Wi": 224, + "Y": 7, + "X": 7, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 3, + "pad_w": 3, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__bf16_nhwc_stem_7x7_s2_train_n256_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__bf16_nhwc_stem_7x7_s2_train_n256_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__bf16_nhwc_stem_7x7_s2_train_n256_bf16.json", + "sha256": "1127b3bd29cfe11e17a73b82e992834c6c2377444446a6a3d0cd925ef40daa43", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 64, + "Hi": 224, + "Wi": 224, + "Y": 7, + "X": 7, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 3, + "pad_w": 3, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ResNet-50__fp16_nhwc_stem_7x7_s2_nhwc_fp16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__fp16_nhwc_stem_7x7_s2_nhwc_fp16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__fp16_nhwc_stem_7x7_s2_nhwc_fp16.json", + "sha256": "71f52bc447ae0a17e08db8278d4b6d6c30eb0567d9d594facbb436c9e2eabca8", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + }, + { + "source": "graphs", + "path": "conv/fprop/ResNet-50__int8_nhwc_stem_7x7_s2_int8.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ResNet-50__int8_nhwc_stem_7x7_s2_int8.json", + "sha256": "66ec8b358a11cc8cfa8052d87f83c44ce4564d6055962f4377d013c11b0f0b27", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1280, + "Hi": 1024, + "Wi": 1024, + "Y": 16, + "X": 16, + "G": 1, + "stride_h": 16, + "stride_w": 16, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SAM-ViT-H__bf16_nhwc_patchify16_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SAM-ViT-H__bf16_nhwc_patchify16_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SAM-ViT-H__bf16_nhwc_patchify16_bf16.json", + "sha256": "cea84642ca8652fc74829e66f039663bf3281ddf446717c3893dc1294f560faf", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 128, + "Hi": 512, + "Wi": 512, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SD1.5-VAE__fp16_nhwc_enc_conv_in_3x3_512_fp16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SD1.5-VAE__fp16_nhwc_enc_conv_in_3x3_512_fp16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SD1.5-VAE__fp16_nhwc_enc_conv_in_3x3_512_fp16.json", + "sha256": "b5811006d4556b7032d4e958db7eb9c1c5a7f07b2f54da3ea52bcd1896ba4689", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 2, + "C": 16, + "K": 1536, + "Hi": 128, + "Wi": 128, + "Y": 2, + "X": 2, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SD3-MMDiT__bf16_nhwc_latent_patchify_2x2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SD3-MMDiT__bf16_nhwc_latent_patchify_2x2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SD3-MMDiT__bf16_nhwc_latent_patchify_2x2_bf16.json", + "sha256": "27455a9e6bc675396da60fe369fd23801ed34b26cea53e24e09f3ddbfcedfb65", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 16, + "K": 512, + "Hi": 128, + "Wi": 128, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SD3-VAE__bf16_nhwc_dec_conv_in_16ch_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SD3-VAE__bf16_nhwc_dec_conv_in_16ch_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SD3-VAE__bf16_nhwc_dec_conv_in_16ch_3x3_bf16.json", + "sha256": "323bd4e459affcf06551c76762d0c1fe9df715e36dd241b5722472121a9dc39e", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 128, + "Hi": 1024, + "Wi": 1024, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SD3-VAE__bf16_nhwc_enc_conv_in_3x3_1024_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SD3-VAE__bf16_nhwc_enc_conv_in_3x3_1024_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SD3-VAE__bf16_nhwc_enc_conv_in_3x3_1024_bf16.json", + "sha256": "e8bed3e767763cedd5bcbfa25ef7e222dc4a3c8f3c3f30b5200f62017d3c03d0", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 512, + "K": 512, + "Hi": 128, + "Wi": 128, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_resnet_3x3_512_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_resnet_3x3_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_dec_resnet_3x3_512_bf16.json", + "sha256": "2798799ac05f3650827be9d978a5f9f6d18a75cf5426afe35c38d45464780048", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + }, + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_mid_3x3_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_mid_3x3_512_bf16.json", + "sha256": "692d5a748df83301d4eb0e34ebac3fb953b43db5d8a5eb8b35dae13e600ce7cb", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 256, + "Hi": 512, + "Wi": 512, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_512_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_512_bf16.json", + "sha256": "faab4ee426286c903f59974a2da9b32385946e92587478a66c756fd43ff7af22", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + }, + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_enc_3x3_256_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_enc_3x3_256_512_bf16.json", + "sha256": "7a88b9c48e57c37dd1a4cf89c6a2fa974bd06c2cf411a7273c7a21d6c1c062d4", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 512, + "K": 512, + "Hi": 256, + "Wi": 256, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_dec_upsample_conv_3x3_bf16.json", + "sha256": "d105987c0d031bd926eeb85b2c6c6fb90ae3e6a650c6b18b0753e413e6638926", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 128, + "K": 128, + "Hi": 1024, + "Wi": 1024, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__bf16_nhwc_enc_downsample_3x3_s2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_enc_downsample_3x3_s2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_enc_downsample_3x3_s2_bf16.json", + "sha256": "ef9a443dd209abd45461d249e3f3d31de6beda13a6d303cbeedfec9f9ec1e92d", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 128, + "K": 128, + "Hi": 1024, + "Wi": 1024, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__bf16_nhwc_enc_resnet_3x3_128_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__bf16_nhwc_enc_resnet_3x3_128_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__bf16_nhwc_enc_resnet_3x3_128_bf16.json", + "sha256": "686dc0b695269e0bd7883608f79592eb9479048e3fad02090a3b96e1733d796d", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 128, + "Hi": 1024, + "Wi": 1024, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SDXL-VAE__fp16_nhwc_enc_conv_in_3x3_fp16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SDXL-VAE__fp16_nhwc_enc_conv_in_3x3_fp16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SDXL-VAE__fp16_nhwc_enc_conv_in_3x3_fp16.json", + "sha256": "6e067fe3ddb7b5f2fca5205576fa9b0a095a52bbdaac1225990e3cead2ced6aa", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1152, + "Hi": 384, + "Wi": 384, + "Y": 14, + "X": 14, + "G": 1, + "stride_h": 14, + "stride_w": 14, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SigLIP-so400m__bf16_nhwc_patchify14_384_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SigLIP-so400m__bf16_nhwc_patchify14_384_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SigLIP-so400m__bf16_nhwc_patchify14_384_bf16.json", + "sha256": "da8376cc94e8fe0e89a7b9c399e78d7ccd7e5c7c8b7341e3f415ed0291c3b934", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1536, + "Hi": 512, + "Wi": 512, + "Y": 16, + "X": 16, + "G": 1, + "stride_h": 16, + "stride_w": 16, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/SigLIP2-g__bf16_nhwc_patchify16_512_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/SigLIP2-g__bf16_nhwc_patchify16_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/SigLIP2-g__bf16_nhwc_patchify16_512_bf16.json", + "sha256": "711b8c9723261d358f8eed63fa7ba4ba57ea934b9d65d25324c775342e60792f", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 768, + "Hi": 224, + "Wi": 224, + "Y": 16, + "X": 16, + "G": 1, + "stride_h": 16, + "stride_w": 16, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ViT-B_16-edge__int8_nhwc_patchify16_int8.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ViT-B_16-edge__int8_nhwc_patchify16_int8.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ViT-B_16-edge__int8_nhwc_patchify16_int8.json", + "sha256": "8eb2de81c681eecd32a62970f1b11ae093e9daeedad41f9ac447d0501e8d752d", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 1024, + "Hi": 224, + "Wi": 224, + "Y": 14, + "X": 14, + "G": 1, + "stride_h": 14, + "stride_w": 14, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/ViT-L_14__bf16_nhwc_patchify_conv2d_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/ViT-L_14__bf16_nhwc_patchify_conv2d_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/ViT-L_14__bf16_nhwc_patchify_conv2d_bf16.json", + "sha256": "ece54fe6ca730960458b357b5b62e13228d082a1be6fd45f844b335b8208bb42", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 256, + "Hi": 40, + "Wi": 40, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_c3k2_bottleneck_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_c3k2_bottleneck_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_c3k2_bottleneck_3x3_bf16.json", + "sha256": "29a76f733cd9d6419df4f3120e56cd6484c90000976c048d92e113a3cfb13f62", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + }, + { + "source": "graphs", + "path": "conv/fprop/YOLOv12-L__bf16_nhwc_a2c2f_conv_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLOv12-L__bf16_nhwc_a2c2f_conv_3x3_bf16.json", + "sha256": "f7fadabd551f4495757326c55b634fee0801076cb5df58eebe74aba2e1286d54", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 512, + "K": 256, + "Hi": 40, + "Wi": 40, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_c3k2_pw_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_c3k2_pw_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_c3k2_pw_1x1_bf16.json", + "sha256": "eadd99b454171d1e150ad10f94b33c30e43a53332d412223947d22f754c0d442", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 256, + "Hi": 80, + "Wi": 80, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_detect_head_3x3_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_detect_head_3x3_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_detect_head_3x3_bf16.json", + "sha256": "8759a0a4f894d9be6bb6192e34f290eea3fa78c0f4923bd5eddb20291af2fafd", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 64, + "K": 128, + "Hi": 320, + "Wi": 320, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_128_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_128_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_128_bf16.json", + "sha256": "5c8bc09e72960f22d168a1bc6f9e2d09de26a1586a49fa244e6b6a836e354172", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 128, + "K": 256, + "Hi": 160, + "Wi": 160, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_256_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_256_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_256_bf16.json", + "sha256": "921c4ca959ce9f6f387836c7f9e3203ebfcc8c62680b6b915b0a172157a39a22", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 256, + "K": 512, + "Hi": 80, + "Wi": 80, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_512_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_512_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_down_3x3_s2_512_bf16.json", + "sha256": "4cd8ecef1fccad53ca0dbabbc1130049dc571965f4a395950231bae3f9f1366e", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 768, + "K": 256, + "Hi": 40, + "Wi": 40, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_neck_c3k2_pw_1x1_p4_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_neck_c3k2_pw_1x1_p4_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_neck_c3k2_pw_1x1_p4_bf16.json", + "sha256": "4121c5ee3e68d8022fcae8fdc6c499bbd63871f885a6a7a6de126aea5f7bfa7d", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 512, + "K": 512, + "Hi": 20, + "Wi": 20, + "Y": 1, + "X": 1, + "G": 1, + "stride_h": 1, + "stride_w": 1, + "pad_h": 0, + "pad_w": 0, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_sppf_pw_1x1_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_sppf_pw_1x1_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_sppf_pw_1x1_bf16.json", + "sha256": "1877e4decff92d470427b6a588cdb9e7869e32f5188f15f005a3738bfed948d3", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 64, + "Hi": 1280, + "Wi": 1280, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_1280_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_1280_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_1280_bf16.json", + "sha256": "50b3b1843ea6c9a4e59601e3a7a8a7a0ce8b20be507dacbb833ed40ae81ee0bc", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 64, + "Hi": 640, + "Wi": 640, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "bf16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_bf16.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_bf16.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__bf16_nhwc_stem_3x3_s2_bf16.json", + "sha256": "ce3d6c0a30fb1ff3351bb97dddd4bf4c8a7a6df56498489f2fd3bff11138096c", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 64, + "Hi": 640, + "Wi": 640, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-L__int8_nhwc_stem_3x3_s2_int8.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-L__int8_nhwc_stem_3x3_s2_int8.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-L__int8_nhwc_stem_3x3_s2_int8.json", + "sha256": "80e65f72b7f4ce9a49fef13dc1a4d20db9e1a5f7efcd213db634d4b8a8069700", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + }, + { + "N": 1, + "C": 3, + "K": 16, + "Hi": 640, + "Wi": 640, + "Y": 3, + "X": 3, + "G": 1, + "stride_h": 2, + "stride_w": 2, + "pad_h": 1, + "pad_w": 1, + "dilation_h": 1, + "dilation_w": 1, + "dtype": "fp16", + "layout": "NHWC", + "direction": "fwd", + "arch": "gfx950", + "_catalog_tile_k": [ + 64 + ], + "_provenance": { + "graph": "conv/fprop/YOLO11-N__int8_nhwc_stem_3x3_s2_int8.json", + "sources": [ + { + "source": "graphs", + "path": "conv/fprop/YOLO11-N__int8_nhwc_stem_3x3_s2_int8.json", + "uri": "https://therock-dvc.s3.amazonaws.com/dnn-benchmarking/files/md5/b8/e7d9105a49d3e9c566bf26a0f87451#conv/fprop/YOLO11-N__int8_nhwc_stem_3x3_s2_int8.json", + "sha256": "9bdd2293a09261e9d6afaa2c5f29568a377b0b0b6c29d9a7efd424ee96535b13", + "archive_sha256": "0055a017febaa82f3ddd7d54aa8755d6a94e903d14246a8a2c9235cfcbc49560", + "repository_revision": "36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc" + } + ] + } + } +] diff --git a/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.yaml b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.yaml new file mode 100644 index 000000000000..a316a13d32dc --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd.yaml @@ -0,0 +1,208 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +# Dispatcher-derived catalog: five verification shapes in FP16/BF16, each +# with tile_k=64/128, plus the default variant for every supported unique +# request in dnn-benchmarking's headline convolution corpus. +# Requests and public source hashes: gfx950_conv_fwd.requests.json. +# Each request's _catalog_tile_k records the arms admitted to this catalog. +# Source revision: 36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc; headline DVC object: +# b8e7d9105a49d3e9c566bf26a0f87451 (Workloads/headline/conv.tar.gz.dvc). +# Regenerate descriptors with generate.py --config this-file --output-dir DIR. + +dialect: packaged +authored_subpath: rocKE/gfx950_conv_fwd +engine: + name: hipkernel:Gfx950ConvFwd + sdk_version: 1.0.0 + knobs: + - tile_k + heuristic: native +kmd_fields: +- name: N + type: int +- name: Hi + type: int +- name: Wi + type: int +- name: C + type: int +- name: K + type: int +- name: Y + type: int +- name: X + type: int +- name: sH + type: int +- name: sW + type: int +- name: pH + type: int +- name: pW + type: int +- name: dH + type: int +- name: dW + type: int +- name: dtype + type: string +- name: layout + type: string +- name: groups + type: int +- name: tile_m + type: int +- name: tile_n + type: int +- name: tile_k + type: int + default_value: 64 +- name: warp_m + type: int +- name: warp_n + type: int +- name: warp_tile_m + type: int +- name: warp_tile_n + type: int +- name: warp_tile_k + type: int +- name: wave_size + type: int +- name: pipeline + type: string +- name: epilogue + type: string +kernel_source_kind: rocke +workspace_policy: none +graph_match: + shape: shared_shape + discriminator: none +# Every metadata field is baked into the kernel at compile time: the builder's +# Gfx950ConvFwdSpec consumes all 27, so the whole geometry and every tuning value +# is part of the specialization contract and none of them are matcher-only. +specialization: + metadata_fields: + [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + matcher_only_fields: [] + bindings: + N: {field: N} + Hi: {field: Hi} + Wi: {field: Wi} + C: {field: C} + K: {field: K} + Y: {field: Y} + X: {field: X} + sH: {field: sH} + sW: {field: sW} + pH: {field: pH} + pW: {field: pW} + dH: {field: dH} + dW: {field: dW} + dtype: {field: dtype} + layout: {field: layout} + groups: {field: groups} + tile_m: {field: tile_m} + tile_n: {field: tile_n} + tile_k: {field: tile_k} + warp_m: {field: warp_m} + warp_n: {field: warp_n} + warp_tile_m: {field: warp_tile_m} + warp_tile_n: {field: warp_tile_n} + warp_tile_k: {field: warp_tile_k} + wave_size: {field: wave_size} + pipeline: {field: pipeline} + epilogue: {field: epilogue} + +packs: +- name: gfx950_conv_fwd + arch: + - gfx950 + kernel_defaults: + kind: rocke + source: builders/common/convolution_forward.py + builder: build_gfx950_conv_fwd + variants: + - name: gfx950_conv_fwd_{tag}_N{N}_Hi{Hi}_Wi{Wi}_C{C}_K{K}_Y{Y}_X{X}_sH{sH}_sW{sW}_pH{pH}_pW{pW}_dH{dH}_dW{dW}_tile_k{tile_k} + metadata: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + spec_order: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + vocabulary: + dtype: + fp16: fp16 + bf16: bf16 + layout: + NHWC: NHWC + pipeline: + mem: mem + epilogue: + cshuffle: cshuffle + default: default + spec_defaults: {layout: NHWC, groups: 1, tile_m: 64, tile_n: 64, warp_m: 2, warp_n: 2, warp_tile_m: 32, warp_tile_n: 32, warp_tile_k: 16, wave_size: 64, pipeline: mem, epilogue: cshuffle} + knob_sets: + knobs0: + - {tile_k: 64, tag: 'dtype{md_dtype}'} + - {tile_k: 128, tag: 'dtype{md_dtype}'} + knobs1: + - {tile_k: 64, tag: 'dtype{md_dtype}'} + shapes: + - {N: 2, Hi: 14, Wi: 14, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 14, Wi: 14, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 8, Wi: 8, C: 32, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 8, Wi: 8, C: 32, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 2, Hi: 17, Wi: 19, C: 32, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 17, Wi: 19, C: 32, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 15, Wi: 17, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 2, pW: 2, dH: 2, dW: 2, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 15, Wi: 17, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 2, pW: 2, dH: 2, dW: 2, dtype: bf16, knobs: knobs0} + - {N: 2, Hi: 11, Wi: 17, C: 32, K: 64, Y: 3, X: 5, sH: 1, sW: 2, pH: 1, pW: 2, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 11, Wi: 17, C: 32, K: 64, Y: 3, X: 5, sH: 1, sW: 2, pH: 1, pW: 2, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 768, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 336, Wi: 336, C: 3, K: 1024, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 128, Y: 4, X: 4, sH: 4, sW: 4, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 14, Wi: 14, C: 768, K: 3072, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 14, Wi: 14, C: 3072, K: 768, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 28, Wi: 28, C: 384, K: 768, Y: 2, X: 2, sH: 2, sW: 2, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 192, Y: 4, X: 4, sH: 4, sW: 4, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 1536, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 24, Wi: 24, C: 80, K: 480, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 192, Wi: 192, C: 24, K: 48, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 128, Wi: 128, C: 32, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 448, Wi: 448, C: 3, K: 3200, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 56, Wi: 56, C: 24, K: 144, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 28, Wi: 28, C: 144, K: 40, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 32, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 28, Wi: 28, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 14, Wi: 14, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 56, Wi: 56, C: 64, K: 64, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 56, Wi: 56, C: 128, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 56, Wi: 56, C: 64, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 56, Wi: 56, C: 256, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 7, Wi: 7, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 256, Hi: 224, Wi: 224, C: 3, K: 64, Y: 7, X: 7, sH: 2, sW: 2, pH: 3, pW: 3, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 64, Y: 7, X: 7, sH: 2, sW: 2, pH: 3, pW: 3, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 1280, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 512, Wi: 512, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} + - {N: 2, Hi: 128, Wi: 128, C: 16, K: 1536, Y: 2, X: 2, sH: 2, sW: 2, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 128, Wi: 128, C: 16, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 128, Wi: 128, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 512, Wi: 512, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 256, Wi: 256, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 1024, Wi: 1024, C: 128, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 1024, Wi: 1024, C: 128, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} + - {N: 1, Hi: 384, Wi: 384, C: 3, K: 1152, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 512, Wi: 512, C: 3, K: 1536, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 768, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 1024, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 40, Wi: 40, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 40, Wi: 40, C: 512, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 80, Wi: 80, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 320, Wi: 320, C: 64, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 160, Wi: 160, C: 128, K: 256, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 80, Wi: 80, C: 256, K: 512, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 40, Wi: 40, C: 768, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 20, Wi: 20, C: 512, K: 512, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 1280, Wi: 1280, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs1} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 16, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs1} diff --git a/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd_wide.yaml b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd_wide.yaml new file mode 100644 index 000000000000..642f651159e7 --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/configs/gfx950_conv_fwd_wide.yaml @@ -0,0 +1,212 @@ +# WIDENED CATALOG: every request carries both tile_k arms so the engine's +# benchmarked selection has a real choice on every request. Derived from +# gfx950_conv_fwd.yaml by moving every shape from knobs1 (tile_k=64 only) +# to knobs0 (tile_k=64 and 128). Shapes and provenance are unchanged. +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +# Dispatcher-derived catalog: five verification shapes in FP16/BF16, each +# with tile_k=64/128, plus the default variant for every supported unique +# request in dnn-benchmarking's headline convolution corpus. +# Requests and public source hashes: gfx950_conv_fwd.requests.json. +# Each request's _catalog_tile_k records the arms admitted to this catalog. +# Source revision: 36f95cc7a8b8b3ee5ba82b195a8e51a7cd47f6cc; headline DVC object: +# b8e7d9105a49d3e9c566bf26a0f87451 (Workloads/headline/conv.tar.gz.dvc). +# Regenerate descriptors with generate.py --config this-file --output-dir DIR. + +dialect: packaged +authored_subpath: rocKE/gfx950_conv_fwd +engine: + name: hipkernel:Gfx950ConvFwd + sdk_version: 1.0.0 + knobs: + - tile_k + heuristic: native +kmd_fields: +- name: N + type: int +- name: Hi + type: int +- name: Wi + type: int +- name: C + type: int +- name: K + type: int +- name: Y + type: int +- name: X + type: int +- name: sH + type: int +- name: sW + type: int +- name: pH + type: int +- name: pW + type: int +- name: dH + type: int +- name: dW + type: int +- name: dtype + type: string +- name: layout + type: string +- name: groups + type: int +- name: tile_m + type: int +- name: tile_n + type: int +- name: tile_k + type: int + default_value: 64 +- name: warp_m + type: int +- name: warp_n + type: int +- name: warp_tile_m + type: int +- name: warp_tile_n + type: int +- name: warp_tile_k + type: int +- name: wave_size + type: int +- name: pipeline + type: string +- name: epilogue + type: string +kernel_source_kind: rocke +workspace_policy: none +graph_match: + shape: shared_shape + discriminator: none +# Every metadata field is baked into the kernel at compile time: the builder's +# Gfx950ConvFwdSpec consumes all 27, so the whole geometry and every tuning value +# is part of the specialization contract and none of them are matcher-only. +specialization: + metadata_fields: + [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + matcher_only_fields: [] + bindings: + N: {field: N} + Hi: {field: Hi} + Wi: {field: Wi} + C: {field: C} + K: {field: K} + Y: {field: Y} + X: {field: X} + sH: {field: sH} + sW: {field: sW} + pH: {field: pH} + pW: {field: pW} + dH: {field: dH} + dW: {field: dW} + dtype: {field: dtype} + layout: {field: layout} + groups: {field: groups} + tile_m: {field: tile_m} + tile_n: {field: tile_n} + tile_k: {field: tile_k} + warp_m: {field: warp_m} + warp_n: {field: warp_n} + warp_tile_m: {field: warp_tile_m} + warp_tile_n: {field: warp_tile_n} + warp_tile_k: {field: warp_tile_k} + wave_size: {field: wave_size} + pipeline: {field: pipeline} + epilogue: {field: epilogue} + +packs: +- name: gfx950_conv_fwd + arch: + - gfx950 + kernel_defaults: + kind: rocke + source: builders/common/convolution_forward.py + builder: build_gfx950_conv_fwd + variants: + - name: gfx950_conv_fwd_{tag}_N{N}_Hi{Hi}_Wi{Wi}_C{C}_K{K}_Y{Y}_X{X}_sH{sH}_sW{sW}_pH{pH}_pW{pW}_dH{dH}_dW{dW}_tile_k{tile_k} + metadata: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + spec_order: [N, Hi, Wi, C, K, Y, X, sH, sW, pH, pW, dH, dW, dtype, layout, groups, tile_m, tile_n, tile_k, warp_m, warp_n, warp_tile_m, warp_tile_n, warp_tile_k, wave_size, pipeline, epilogue] + vocabulary: + dtype: + fp16: fp16 + bf16: bf16 + layout: + NHWC: NHWC + pipeline: + mem: mem + epilogue: + cshuffle: cshuffle + default: default + spec_defaults: {layout: NHWC, groups: 1, tile_m: 64, tile_n: 64, warp_m: 2, warp_n: 2, warp_tile_m: 32, warp_tile_n: 32, warp_tile_k: 16, wave_size: 64, pipeline: mem, epilogue: cshuffle} + knob_sets: + knobs0: + - {tile_k: 64, tag: 'dtype{md_dtype}'} + - {tile_k: 128, tag: 'dtype{md_dtype}'} + knobs1: + - {tile_k: 64, tag: 'dtype{md_dtype}'} + shapes: + - {N: 2, Hi: 14, Wi: 14, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 14, Wi: 14, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 8, Wi: 8, C: 32, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 8, Wi: 8, C: 32, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 2, Hi: 17, Wi: 19, C: 32, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 17, Wi: 19, C: 32, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 15, Wi: 17, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 2, pW: 2, dH: 2, dW: 2, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 15, Wi: 17, C: 32, K: 32, Y: 3, X: 3, sH: 1, sW: 1, pH: 2, pW: 2, dH: 2, dW: 2, dtype: bf16, knobs: knobs0} + - {N: 2, Hi: 11, Wi: 17, C: 32, K: 64, Y: 3, X: 5, sH: 1, sW: 2, pH: 1, pW: 2, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 11, Wi: 17, C: 32, K: 64, Y: 3, X: 5, sH: 1, sW: 2, pH: 1, pW: 2, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 768, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 336, Wi: 336, C: 3, K: 1024, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 128, Y: 4, X: 4, sH: 4, sW: 4, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 14, Wi: 14, C: 768, K: 3072, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 14, Wi: 14, C: 3072, K: 768, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 28, Wi: 28, C: 384, K: 768, Y: 2, X: 2, sH: 2, sW: 2, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 192, Y: 4, X: 4, sH: 4, sW: 4, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 1536, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 24, Wi: 24, C: 80, K: 480, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 192, Wi: 192, C: 24, K: 48, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 128, Wi: 128, C: 32, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 448, Wi: 448, C: 3, K: 3200, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 56, Wi: 56, C: 24, K: 144, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 28, Wi: 28, C: 144, K: 40, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 32, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 28, Wi: 28, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 14, Wi: 14, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 56, Wi: 56, C: 64, K: 64, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 56, Wi: 56, C: 128, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 56, Wi: 56, C: 64, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 56, Wi: 56, C: 256, K: 64, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 7, Wi: 7, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 256, Hi: 224, Wi: 224, C: 3, K: 64, Y: 7, X: 7, sH: 2, sW: 2, pH: 3, pW: 3, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 64, Y: 7, X: 7, sH: 2, sW: 2, pH: 3, pW: 3, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 1280, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 512, Wi: 512, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 2, Hi: 128, Wi: 128, C: 16, K: 1536, Y: 2, X: 2, sH: 2, sW: 2, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 128, Wi: 128, C: 16, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 128, Wi: 128, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 512, Wi: 512, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 256, Wi: 256, C: 512, K: 512, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 1024, Wi: 1024, C: 128, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 1024, Wi: 1024, C: 128, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 1024, Wi: 1024, C: 3, K: 128, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 384, Wi: 384, C: 3, K: 1152, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 512, Wi: 512, C: 3, K: 1536, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 768, Y: 16, X: 16, sH: 16, sW: 16, pH: 0, pW: 0, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 224, Wi: 224, C: 3, K: 1024, Y: 14, X: 14, sH: 14, sW: 14, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 40, Wi: 40, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 40, Wi: 40, C: 512, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 80, Wi: 80, C: 256, K: 256, Y: 3, X: 3, sH: 1, sW: 1, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 320, Wi: 320, C: 64, K: 128, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 160, Wi: 160, C: 128, K: 256, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 80, Wi: 80, C: 256, K: 512, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 40, Wi: 40, C: 768, K: 256, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 20, Wi: 20, C: 512, K: 512, Y: 1, X: 1, sH: 1, sW: 1, pH: 0, pW: 0, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 1280, Wi: 1280, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: bf16, knobs: knobs0} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 64, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} + - {N: 1, Hi: 640, Wi: 640, C: 3, K: 16, Y: 3, X: 3, sH: 2, sW: 2, pH: 1, pW: 1, dH: 1, dW: 1, dtype: fp16, knobs: knobs0} diff --git a/projects/hipdnn/tools/IngestorGenerator/tests/test_mine_conv_shapes.py b/projects/hipdnn/tools/IngestorGenerator/tests/test_mine_conv_shapes.py new file mode 100644 index 000000000000..a902cf84549f --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/tests/test_mine_conv_shapes.py @@ -0,0 +1,418 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT + +"""Protect source semantics and coverage denominators at the mining boundary.""" + +from __future__ import annotations + +import copy +import importlib.util +import io +import json +import subprocess +import sys +import tarfile +from pathlib import Path + +import pytest + +_SCRIPT = Path(__file__).resolve().parents[1] / "tools" / "mine_conv_shapes.py" +_SPEC = importlib.util.spec_from_file_location("mine_conv_shapes", _SCRIPT) +miner = importlib.util.module_from_spec(_SPEC) +_SPEC.loader.exec_module(miner) + + +def _case(**overrides): + return { + "case_id": "F001", + "model": "example", + "op": "conv2d", + "layout": "NHWC", + "N": 2, + "Cin": 32, + "Cout": 32, + "H": 14, + "W": 14, + "Kh": 3, + "Kw": 3, + "stride": 1, + "pad": 1, + "dilation": 1, + "groups": 1, + "dtype": "fp16", + **overrides, + } + + +def _dense(dims, *, channels_last=True): + order = [0, *range(2, len(dims)), 1] if channels_last else list(range(len(dims))) + strides = [0] * len(dims) + stride = 1 + for axis in reversed(order): + strides[axis] = stride + stride *= dims[axis] + return strides + + +def _graph( + *, + groups=1, + spatial=(14, 14), + kernel=(3, 3), + pre=(1, 1), + post=None, + stride=(1, 1), + dilation=(1, 1), + channels_last=True, +): + post = pre if post is None else post + out = [ + (i + p + q - d * (f - 1) - 1) // s + 1 + for i, f, p, q, s, d in zip(spatial, kernel, pre, post, stride, dilation) + ] + dims = ([2, 32, *spatial], [32, 32 // groups, *kernel], [2, 32, *out]) + tensors = [ + { + "uid": uid, + "name": name, + "dims": shape, + "strides": _dense(shape, channels_last=channels_last), + "data_type": "half", + "virtual": False, + } + for uid, name, shape in zip( + (11, 22, 33), ("arbitrary_a", "arbitrary_b", "arbitrary_c"), dims + ) + ] + return { + "name": "misleading_nchw_stride7", + "compute_data_type": "float", + "io_data_type": "half", + "metadata": {"source": "recorded model graph", "model": "model-a"}, + "tensors": tensors, + "nodes": [ + { + "name": "conv", + "type": "ConvolutionFwdAttributes", + "compute_data_type": "float", + "inputs": {"x_tensor_uid": 11, "w_tensor_uid": 22}, + "outputs": {"y_tensor_uid": 33}, + "parameters": { + "conv_mode": "CROSS_CORRELATION", + "pre_padding": list(pre), + "post_padding": list(post), + "stride": list(stride), + "dilation": list(dilation), + }, + } + ], + } + + +def _read_cases(tmp_path, rows): + path = tmp_path / "cases.json" + path.write_text(json.dumps(rows)) + return miner.from_rocke_cases( + path, source_uri="https://example.org/rev/bench_cases_conv.json" + ) + + +def _read_graph(tmp_path, graph): + path = tmp_path / "graph.json" + path.write_text(json.dumps(graph)) + return miner.from_graph_corpus(path)[0] + + +def test_graph_and_case_resolve_same_request_without_tensor_name_or_filename_heuristics( + tmp_path, +): + case = _read_cases(tmp_path, [_case()])[0] + graph = _read_graph(tmp_path, _graph()) + assert graph["oracle_request"] == case["oracle_request"] + assert graph["oracle_request"]["layout"] == "NHWC" + assert graph["oracle_request"]["stride_h"] == 1 + assert graph["kernel_support"] == "pending" + + +@pytest.mark.parametrize( + "fields", [{}, {"is_override_shape_enabled": False}], ids=["absent", "disabled"] +) +def test_static_graph_shape_flag_keeps_the_exact_request(tmp_path, fields): + graph = {**_graph(), **fields} + record = _read_graph(tmp_path, graph) + expected = _read_cases(tmp_path, [_case()])[0]["oracle_request"] + assert record["status"] == "request" + assert record["oracle_request"] == expected + assert record["reasons"] == [] + assert record["provenance"]["attributes"] == graph + + +def test_shape_overrides_cannot_become_a_fixed_shape_catalog_request(tmp_path): + graph = {**_graph(), "is_override_shape_enabled": True} + record = _read_graph(tmp_path, graph) + assert record["status"] == "outside_contract" + assert record["oracle_request"] is None + assert record["kernel_support"] == "not_representable" + assert any("shape overrides" in reason for reason in record["reasons"]) + assert record["provenance"]["attributes"] == graph + requests, report = miner.build_corpus([record]) + assert requests == [] + assert report["counts"]["source_records"] == 1 + assert report["counts"]["outside_contract"] == 1 + assert report["counts"]["unique_requests"] == 0 + + +@pytest.mark.parametrize("value", [None, 0, 1, 0.0, "false", [], {}]) +def test_nonboolean_shape_override_flags_fail_with_source(tmp_path, value): + graph = {**_graph(), "is_override_shape_enabled": value} + with pytest.raises( + miner.MiningError, match="graph.json.*is_override_shape_enabled.*boolean" + ): + _read_graph(tmp_path, graph) + + +def test_rectangular_stride_dilation_and_padding_are_not_collapsed(tmp_path): + record = _read_graph( + tmp_path, + _graph( + spatial=(19, 17), kernel=(3, 5), stride=(2, 3), dilation=(2, 1), pre=(2, 1) + ), + ) + req = record["oracle_request"] + assert { + k: req[k] + for k in ( + "Hi", + "Wi", + "Y", + "X", + "stride_h", + "stride_w", + "dilation_h", + "dilation_w", + "pad_h", + "pad_w", + ) + } == { + "Hi": 19, + "Wi": 17, + "Y": 3, + "X": 5, + "stride_h": 2, + "stride_w": 3, + "dilation_h": 2, + "dilation_w": 1, + "pad_h": 2, + "pad_w": 1, + } + + +@pytest.mark.parametrize( + "field,value", + [ + ("dtype", "f16_typo"), + ("layout", "CHNW"), + ("op", "conv2d_unknown"), + ("conv_mode", "transpose"), + ], +) +def test_unknown_case_categories_fail_with_source(tmp_path, field, value): + with pytest.raises(miner.MiningError, match="cases.json.*unknown"): + _read_cases(tmp_path, [_case(**{field: value})]) + + +@pytest.mark.parametrize("dtype", ["fp16", "half", "float16", "torch.float16"]) +def test_known_dtype_aliases_normalize_without_changing_source_attributes( + tmp_path, dtype +): + record = _read_cases(tmp_path, [_case(dtype=dtype)])[0] + assert record["oracle_request"]["dtype"] == "fp16" + assert record["provenance"]["attributes"]["dtype"] == dtype + + +def test_groups_are_inferred_from_filter_channels_and_retained_for_family_oracle( + tmp_path, +): + record = _read_graph(tmp_path, _graph(groups=4)) + assert record["status"] == "outside_contract" + assert record["oracle_request"]["G"] == 4 + assert record["kernel_support"] == "pending" + assert "integration contract covers groups=1" in record["reasons"][0] + shapes, report = miner.build_corpus([record]) + assert shapes == [] + assert report["counts"]["source_records"] == 1 + + +def test_3d_channels_last_maps_to_dispatcher_depth_fields_without_claiming_unsupported( + tmp_path, +): + record = _read_graph( + tmp_path, + _graph( + spatial=(5, 14, 14), + kernel=(3, 3, 3), + pre=(1, 1, 1), + stride=(1, 1, 1), + dilation=(1, 1, 1), + ), + ) + assert record["status"] == "outside_contract" + assert record["oracle_request"]["Di"] == 5 + assert record["oracle_request"]["Z"] == 3 + assert record["oracle_request"]["layout"] == "NHWC" + assert record["kernel_support"] == "pending" + assert record["provenance"]["attributes"]["tensors"][0]["dims"] == [ + 2, + 32, + 5, + 14, + 14, + ] + + +def test_nchw_layout_is_observed_from_strides_and_not_transposed(tmp_path): + record = _read_graph(tmp_path, _graph(channels_last=False)) + assert record["status"] == "outside_contract" + assert record["oracle_request"]["layout"] == "NCHW" + + +def test_asymmetric_padding_does_not_become_symmetric_request(tmp_path): + graph = _graph(pre=(0, 1), post=(2, 1)) + record = _read_graph(tmp_path, graph) + assert record["status"] == "outside_contract" + assert record["oracle_request"] is None + assert record["provenance"]["attributes"]["nodes"][0]["parameters"][ + "post_padding" + ] == [2, 1] + + +@pytest.mark.parametrize( + "mutate,reason", + [ + (lambda g: g["tensors"][1].update(data_type="bfloat16"), "uniform"), + (lambda g: g["tensors"][0]["strides"].__setitem__(2, 500), "layouts cannot"), + (lambda g: g["nodes"][0]["parameters"].update(alpha=2), "uninterpreted"), + (lambda g: g["nodes"][0].update(compute_data_type="half"), "fp32 accumulation"), + (lambda g: g["tensors"][2].update(virtual=True), "non-virtual"), + ( + lambda g: g["tensors"][0].update(ragged_offset=99), + "uninterpreted tensor attributes", + ), + ( + lambda g: g["nodes"][0]["inputs"].update(bias_tensor_uid=22), + "uninterpreted convolution tensor bindings", + ), + ], +) +def test_semantics_not_expressible_by_request_remain_explicit_exclusions( + tmp_path, mutate, reason +): + graph = _graph() + mutate(graph) + record = _read_graph(tmp_path, graph) + assert record["status"] == "outside_contract" + assert record["oracle_request"] is None + assert any(reason in text for text in record["reasons"]) + + +def test_fused_and_backward_graphs_are_counted_without_mining_plain_forward_requests( + tmp_path, +): + fused = _graph() + fused["nodes"].append({"name": "relu", "type": "PointwiseAttributes"}) + backward = _graph() + backward["nodes"][0]["type"] = "ConvolutionBwdAttributes" + records = [_read_graph(tmp_path, graph) for graph in (fused, backward)] + shapes, report = miner.build_corpus(records) + assert shapes == [] + assert report["counts"]["outside_contract"] == 1 + assert report["counts"]["non_forward"] == 1 + + +def test_all_duplicate_provenance_survives_and_inputs_are_not_mutated(tmp_path): + records = _read_cases( + tmp_path, [_case(case_id="F001", model="a"), _case(case_id="F002", model="b")] + ) + records.append(_read_graph(tmp_path, _graph())) + original = copy.deepcopy(records) + shapes, report = miner.build_corpus(records) + assert len(shapes) == 1 + assert report["counts"]["merged_request_records"] == 2 + provenance = shapes[0]["_provenance"] + assert provenance["uri"] == "https://example.org/rev/bench_cases_conv.json" + assert provenance["also"][0]["case_id"] == "F002" + assert provenance["also"][1]["attributes"]["metadata"]["model"] == "model-a" + assert len(provenance["sha256"]) == 64 + assert records == original + + +@pytest.mark.parametrize( + "field,value", [("stride", 0), ("N", 2.5), ("groups", True), ("dilation", [1])] +) +def test_invalid_dimensions_and_attributes_are_not_coerced(tmp_path, field, value): + with pytest.raises(miner.MiningError): + _read_cases(tmp_path, [_case(**{field: value})]) + + +def test_output_dimensions_are_checked_against_attributes(tmp_path): + graph = _graph() + graph["tensors"][2]["dims"][2] = 13 + with pytest.raises(miner.MiningError, match="output tensor dims disagree"): + _read_graph(tmp_path, graph) + + +def test_equivalent_scalar_and_vector_aliases_are_allowed_but_conflicts_fail(tmp_path): + record = _read_cases(tmp_path, [_case(strides=[1, 1], pads_before=[1, 1])])[0] + assert record["status"] == "request" + with pytest.raises(miner.MiningError, match="conflicting aliases"): + _read_cases(tmp_path, [_case(strides=[1, 2])]) + + +def test_workload_tarball_is_read_without_extracting_and_keeps_member_provenance( + tmp_path, +): + path = tmp_path / "conv.tar.gz" + blob = json.dumps(_graph()).encode() + with tarfile.open(path, "w:gz") as archive: + member = tarfile.TarInfo("conv/fprop/recorded.json") + member.size = len(blob) + archive.addfile(member, io.BytesIO(blob)) + record = miner.from_graph_corpus(path, source_uri="https://example.org/dvc/object")[ + 0 + ] + assert record["provenance"]["path"] == "conv/fprop/recorded.json" + assert ( + record["provenance"]["uri"] + == "https://example.org/dvc/object#conv/fprop/recorded.json" + ) + assert len(record["provenance"]["archive_sha256"]) == 64 + assert not (tmp_path / "conv").exists() + + +def test_cli_always_writes_complete_inventory_beside_request_list(tmp_path): + cases = tmp_path / "cases.json" + cases.write_text(json.dumps([_case(), _case(case_id="F002", groups=4)])) + out = tmp_path / "requests.json" + result = subprocess.run( + [sys.executable, str(_SCRIPT), "--rocke-cases", str(cases), "--out", str(out)], + check=False, + capture_output=True, + text=True, + ) + assert result.returncode == 0, result.stderr + assert len(json.loads(out.read_text())) == 1 + report = json.loads(out.with_name("requests.report.json").read_text()) + assert report["counts"]["source_records"] == 2 + assert report["records"][1]["oracle_request"]["G"] == 4 + assert "Kernel support pending" in result.stdout + + +def test_cli_no_source_is_an_error(tmp_path): + result = subprocess.run( + [sys.executable, str(_SCRIPT), "--out", str(tmp_path / "out.json")], + check=False, + capture_output=True, + text=True, + ) + assert result.returncode != 0 + assert "at least one source" in result.stderr diff --git a/projects/hipdnn/tools/IngestorGenerator/tools/benchmark_conv_integration.py b/projects/hipdnn/tools/IngestorGenerator/tools/benchmark_conv_integration.py new file mode 100755 index 000000000000..d504bfdbae0b --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/tools/benchmark_conv_integration.py @@ -0,0 +1,1156 @@ +#!/usr/bin/env python3 +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +"""Validate and measure the packaged gfx950 convolution against direct rocKE. + +Run once per dtype and mode, writing reports and logs to a private directory. +The caller supplies the installed plugin, the compiler used for packaging, and +the cache directory; this tool neither packages kernels nor deletes cache data. + +For each dtype, run ``--tile-k 64`` and ``--tile-k 128`` for forced correctness +and timing. Then use a fresh cache with ``--mode auto`` and start another Python +process with ``--mode reuse`` and the same cache. Auto requires an uncached graph; +reuse requires an existing complete ranking and fails if another search occurs. +Every mode checks the exact engine, selected descriptor UUID, and tuning metadata. + +Use ``--request-file`` with ``--tile-k`` for a different packaged convolution. +The file contains one ConvGroupedRequest JSON object, optionally including the +catalog's underscore-prefixed provenance annotations. These runs require forced +mode and default to an independent PyTorch FP32 GPU reference; the smoke modes +retain their CPU reference and two-candidate selection/cache checks. Override +the reference location with ``--reference-device cpu|gpu``. Every run validates +both integrated and direct outputs before timing; correctness cannot be skipped. + +Example (all paths are caller-supplied):: + + python benchmark_conv_integration.py --plugin-path "$PLUGIN" \\ + --descriptor-root "$DESCRIPTORS" --backend-library "$BACKEND" \\ + --comgr-library "$COMGR" --cache-dir "$PRIVATE_CACHE" \\ + --log-file "$PRIVATE_LOG" --output "$PRIVATE_REPORT" \\ + --dtype fp16 --mode auto --timing-mode graph + +The default timing captures repeated executions in a HIP graph and measures its +replays with GPU events. This removes Python submission gaps from the kernel +comparison. ``--timing-mode events`` measures a stream of ordinary submissions, +including gaps caused by host enqueue overhead. Both modes exclude compilation, +plan creation, first execution/search, correctness checks, capture, and warmup. +Timing also removes the synchronous selection-log callback and sets the backend +global log level to OFF through its public API. Both are restored before checking +recreated-plan evidence. The report records and verifies these logging states. +Dependencies are imported only when running; ``--help`` works without ROCm. +""" + +from __future__ import annotations + +import argparse +import ctypes +import ctypes.util +import hashlib +import json +import math +import os +import re +import statistics +import sys +import time +import traceback +from contextlib import contextmanager +from dataclasses import asdict +from pathlib import Path + +ENGINE_NAME = "hipkernel:Gfx950ConvFwd" +BENCHMARK_KNOB = "global.benchmarking" +LOG_LEVELS = ("INFO", "WARN", "ERROR", "FATAL", "OFF") +UUID_PATTERN = r"[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}" +SMOKE = { + "N": 2, + "Hi": 14, + "Wi": 14, + "C": 32, + "K": 32, + "Y": 3, + "X": 3, + "sH": 1, + "sW": 1, + "pH": 1, + "pW": 1, + "dH": 1, + "dW": 1, +} + + +def require(condition: bool, message: str) -> None: + if not condition: + raise RuntimeError(message) + + +def check(error, operation: str) -> None: + require(error.is_good(), f"{operation}: {error.get_message()}") + + +def arguments(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "--plugin-path", + type=Path, + required=True, + help="Installed provider library or plugin search directory.", + ) + parser.add_argument( + "--descriptor-root", + type=Path, + help="Installed descriptor tree, read only for UUID/metadata verification.", + ) + parser.add_argument( + "--backend-library", + type=Path, + help="The loaded libhipdnn_backend library (for its public log callback API).", + ) + parser.add_argument( + "--comgr-library", + type=Path, + default=os.environ.get("ROCKE_COMGR_LIB"), + help="Same libamd_comgr used by hkp_pack; defaults to ROCKE_COMGR_LIB.", + ) + parser.add_argument( + "--llvm-flavor", + choices=("llvm20", "llvm22"), + default=os.environ.get("ROCKE_LLVM_FLAVOR", "llvm22"), + help="Same lowering flavor used for packaging; defaults to ROCKE_LLVM_FLAVOR or llvm22.", + ) + parser.add_argument( + "--rocke-root", + type=Path, + help="Source rocke/ tree; otherwise discover it beside this tool.", + ) + parser.add_argument("--cache-dir", type=Path, required=True) + parser.add_argument("--log-file", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument( + "--request-file", + type=Path, + help="One ConvGroupedRequest JSON object; auto/reuse need both packaged tiles.", + ) + parser.add_argument( + "--dtype", + choices=("fp16", "bf16"), + help="Default: fp16 for smoke, otherwise the request dtype; must agree with the file.", + ) + parser.add_argument( + "--reference-device", + choices=("cpu", "gpu"), + help="Independent PyTorch FP32 reference; defaults to CPU for smoke, GPU for requests.", + ) + parser.add_argument("--tile-k", type=int, choices=(64, 128)) + parser.add_argument( + "--mode", + choices=("forced", "auto", "reuse"), + help="Default: forced when tile-k is given, otherwise auto.", + ) + parser.add_argument("--timing-mode", choices=("graph", "events"), default="graph") + parser.add_argument("--iterations", type=int, default=100) + parser.add_argument("--samples", type=int, default=7) + parser.add_argument("--warmup", type=int, default=10) + parser.add_argument("--seed", type=int, default=2026) + parser.add_argument("--device", type=int, default=0) + args = parser.parse_args(argv) + args.mode = args.mode or ("forced" if args.tile_k is not None else "auto") + if (args.mode == "forced") != (args.tile_k is not None): + parser.error( + "--mode forced requires --tile-k; auto/reuse require it to be omitted" + ) + if args.request_file is not None and args.request_file.resolve() in { + args.log_file.resolve(), + args.output.resolve(), + }: + parser.error("--request-file must differ from --log-file and --output") + if args.request_file is None: + args.dtype = args.dtype or "fp16" + args.reference_device = args.reference_device or ( + "gpu" if args.request_file is not None else "cpu" + ) + if args.iterations < 1 or args.samples < 1 or args.warmup < 1 or args.device < 0: + parser.error( + "iterations, samples and warmup must be positive; device must be nonnegative" + ) + if args.comgr_library is None: + parser.error( + "pass --comgr-library or ROCKE_COMGR_LIB to pin the packaging compiler" + ) + if args.llvm_flavor not in ("llvm20", "llvm22"): + parser.error("ROCKE_LLVM_FLAVOR must be llvm20 or llvm22") + return args + + +def configure(args: argparse.Namespace) -> None: + if args.rocke_root is None: + for parent in Path(__file__).resolve().parents: + candidate = parent / "dnn-providers" / "hip-kernel-provider" / "rocke" + if (candidate / "platform" / "python" / "rocke").is_dir(): + args.rocke_root = candidate + break + if args.rocke_root is not None: + root = args.rocke_root.resolve() + for path in (root / "library", root / "platform" / "python"): + require(path.is_dir(), f"Missing rocKE source directory: {path}") + sys.path.insert(0, str(path)) + args.plugin_path = args.plugin_path.resolve() + require( + args.plugin_path.exists(), f"Plugin path does not exist: {args.plugin_path}" + ) + if args.descriptor_root is None: + parent = ( + args.plugin_path if args.plugin_path.is_dir() else args.plugin_path.parent + ) + args.descriptor_root = parent / "arch_content" / "hip-kernel-provider" + args.descriptor_root = args.descriptor_root.resolve() + require( + args.descriptor_root.is_dir(), + f"Missing descriptor tree: {args.descriptor_root}", + ) + require( + not os.environ.get("HIPDNN_DESCRIPTOR_DIR"), + "Unset HIPDNN_DESCRIPTOR_DIR so the installed plugin resolves its own descriptors", + ) + args.comgr_library = args.comgr_library.resolve() + require( + args.comgr_library.is_file(), f"Missing COMGR library: {args.comgr_library}" + ) + for name in ("cache_dir", "log_file", "output"): + setattr(args, name, getattr(args, name).resolve()) + require(args.log_file != args.output, "Log and report paths must differ") + if args.request_file is not None: + args.request_file = args.request_file.resolve() + require( + args.request_file.is_file(), f"Missing request file: {args.request_file}" + ) + require( + args.request_file not in (args.log_file, args.output), + "Request, log, and report paths must differ", + ) + args.cache_dir.mkdir(parents=True, exist_ok=True) + args.log_file.parent.mkdir(parents=True, exist_ok=True) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.log_file.write_text("", encoding="utf-8") + os.environ["HIPDNN_CACHE_DIR"] = str(args.cache_dir) + os.environ["HIPDNN_DISABLE_CACHE"] = "0" + os.environ["HIPDNN_FORCE_BENCHMARKING"] = "0" if args.mode == "forced" else "1" + os.environ["HIPDNN_LOG_LEVEL"] = "info" + os.environ["HIPDNN_LOG_FILE"] = str(args.log_file) + os.environ["ROCKE_COMGR_LIB"] = str(args.comgr_library) + os.environ["ROCKE_LLVM_FLAVOR"] = args.llvm_flavor + os.environ["ROCKE_BACKEND"] = "python" + + +class LogCapture: + """Synchronous public backend callback; the normal file sink is asynchronous. + + The Python bindings do not yet expose this API. Keep the ctypes callback and + user token alive until explicit unregistration. Only retain matching strings; + file I/O remains in hipDNN's normal asynchronous sink outside this callback. + """ + + def __init__(self, library: Path | None): + name = ( + str(library.resolve()) + if library + else ( + ctypes.util.find_library("hipdnn_backend") + or ("hipdnn_backend.dll" if os.name == "nt" else "libhipdnn_backend.so") + ) + ) + self.library = ctypes.CDLL(name) + self.stage = "build" + self.messages: list[dict] = [] + self.received_count = 0 + self._callback_registered = False + callback_type = ctypes.CFUNCTYPE( + None, ctypes.c_void_p, ctypes.c_int, ctypes.c_char_p + ) + self.callback = callback_type(self._receive) + self.token = ctypes.c_int(0) + self.pointer = ctypes.cast(ctypes.pointer(self.token), ctypes.c_void_p) + self.setter = self.library.hipdnnSetUserLogCallback_ext + self.setter.argtypes = [ + callback_type, + ctypes.c_int, + ctypes.c_int, + ctypes.c_void_p, + ] + self.setter.restype = ctypes.c_int + self.level_setter = self.library.hipdnnBackendSetGlobalLogLevel_ext + self.level_setter.argtypes = [ctypes.c_int] + self.level_setter.restype = ctypes.c_int + self.level_getter = self.library.hipdnnBackendGetGlobalLogLevel_ext + self.level_getter.argtypes = [ctypes.POINTER(ctypes.c_int)] + self.level_getter.restype = ctypes.c_int + + def _receive(self, _user, severity, message): + self.received_count += 1 + text = message.decode("utf-8", errors="replace") if message else "" + if "ingestor:" in text: + self.messages.append( + {"stage": self.stage, "severity": severity, "message": text} + ) + + def _set_callback(self, enabled: bool) -> None: + if enabled == self._callback_registered: + return + # Mode SYNC=0, INFO=0, OFF=4, SUCCESS=0 (public ABI). + # OFF waits for in-flight callbacks before removing this registration. + require( + self.setter(self.callback, 0 if enabled else 4, 0, self.pointer) == 0, + f"Failed to {'register' if enabled else 'unregister'} the synchronous log callback", + ) + self._callback_registered = enabled + + def _global_level(self) -> int: + level = ctypes.c_int() + require( + self.level_getter(ctypes.byref(level)) == 0, + "Failed to query the backend's global log level", + ) + require(level.value in range(len(LOG_LEVELS)), "Unknown backend log level") + return level.value + + def _set_global_level(self, level: int) -> None: + require( + self.level_setter(level) == 0, + f"Failed to set the backend's global log level to {LOG_LEVELS[level]}", + ) + + @contextmanager + def suspend_for_timing(self, state: dict): + require( + self._callback_registered, + "Timing log suspension requires an active selection-log capture", + ) + previous_level = self._global_level() + state.update( + { + "scope": "warmup, graph capture/replays, and event sampling", + "control_api": [ + "hipdnnSetUserLogCallback_ext", + "hipdnnBackendSetGlobalLogLevel_ext", + "hipdnnBackendGetGlobalLogLevel_ext", + ], + "backend_global_level_before": LOG_LEVELS[previous_level], + "sync_callback_registered_before": True, + "restored": False, + "frontend_logging": ( + "The frontend has a separate severity cache without a Python setter; " + "its INFO message may be formatted but is dropped by the backend OFF gate." + ), + } + ) + self._set_callback(False) + callback_count = self.received_count + try: + # The public setter updates the backend and all loaded engine plugins. + # Changing HIPDNN_LOG_LEVEL here would not update their initialized caches. + self._set_global_level(4) + during_level = self._global_level() + state["backend_global_level_during"] = LOG_LEVELS[during_level] + state["sync_callback_registered_during"] = self._callback_registered + require(during_level == 4, "Backend logging remained enabled for timing") + yield + require( + self.received_count == callback_count, + "The selection-log callback ran during timing", + ) + finally: + pending_error = sys.exc_info()[1] + state["callbacks_during_timing"] = self.received_count - callback_count + restoration_errors = [] + try: + self._set_global_level(previous_level) + restored_level = self._global_level() + state["backend_global_level_after"] = LOG_LEVELS[restored_level] + require( + restored_level == previous_level, + "The backend's global log level was not restored", + ) + except Exception as error: # noqa: BLE001 - Preserve the timing failure. + restoration_errors.append( + f"Global logging: {type(error).__name__}: {error}" + ) + try: + self._set_callback(True) + state["sync_callback_registered_after"] = self._callback_registered + except Exception as error: # noqa: BLE001 - Preserve the timing failure. + restoration_errors.append( + f"Selection callback: {type(error).__name__}: {error}" + ) + state["restored"] = not restoration_errors + if restoration_errors: + state["restoration_errors"] = restoration_errors + if pending_error is None: + raise RuntimeError("; ".join(restoration_errors)) + + def __enter__(self): + self._set_callback(True) + return self + + def __exit__(self, _kind, error, _traceback): + # OFF=4 atomically unregisters; after this returns, Python may release callback state. + try: + self._set_callback(False) + except Exception as cleanup_error: # noqa: BLE001 - Preserve the failure. + message = f"Failed to unregister the backend log callback: {cleanup_error}" + self.messages.append( + {"stage": "cleanup", "severity": 3, "message": message} + ) + if error is None: + raise RuntimeError(message) + + def text(self, stage: str | None = None) -> str: + return "\n".join( + entry["message"] + for entry in self.messages + if stage is None or entry["stage"] == stage + ) + + +def kernel_objects(value): + if isinstance(value, dict): + if "kernel_source" in value and "metadata" in value and "id" in value: + yield value + for child in value.values(): + yield from kernel_objects(child) + elif isinstance(value, list): + for child in value: + yield from kernel_objects(child) + + +def packaged_candidates(root: Path, specs: dict) -> dict: + found: dict[int, dict] = {} + for path in sorted(root.rglob("*.json")): + value = json.loads(path.read_text(encoding="utf-8")) + for kernel in kernel_objects(value): + metadata = kernel["metadata"] + tile_k = metadata.get("tile_k") + if tile_k not in specs or any( + metadata.get(k) != v for k, v in asdict(specs[tile_k]).items() + ): + continue + source = kernel["kernel_source"] + require( + source.get("kind") == "kpack", f"Descriptor is not packaged: {path}" + ) + require( + source.get("symbol") == specs[tile_k].kernel_name(), + f"Packaged symbol disagrees with the adapter for tile_k={tile_k}", + ) + item = { + "id": kernel["id"].lower(), + "name": kernel.get("name"), + "metadata": metadata, + "source": source, + "descriptor": str(path), + "descriptor_sha256": hashlib.sha256(path.read_bytes()).hexdigest(), + } + require( + tile_k not in found or found[tile_k]["id"] == item["id"], + f"Multiple packaged descriptors have the same requested configuration: {tile_k}", + ) + found[tile_k] = item + require( + set(found) == set(specs), + f"Installed catalog is missing requested tile_k variants: {sorted(set(specs) - set(found))}", + ) + require( + len({item["id"] for item in found.values()}) == len(found), + "Variants must have distinct descriptor UUIDs", + ) + return found + + +def cached_ranking(cache_dir: Path, candidate_ids: set[str]) -> dict | None: + result = None + for path in sorted(cache_dir.rglob("winners.jsonl")): + for line in path.read_text(encoding="utf-8").splitlines(): + try: + record = json.loads(line) + except json.JSONDecodeError: + continue + if not isinstance(record, dict) or not isinstance( + record.get("entries"), list + ): + continue + ids = {entry.get("kernel_id", "").lower() for entry in record["entries"]} + if candidate_ids.issubset(ids): + result = { + "path": str(path), + "record": record, + "record_sha256": hashlib.sha256(line.encode()).hexdigest(), + } + return result + + +def load_request(args: argparse.Namespace, request_type): + if args.request_file is None: + return request_type( + N=2, + C=32, + K=32, + Hi=14, + Wi=14, + Y=3, + X=3, + pad_h=1, + pad_w=1, + dtype=args.dtype, + arch="gfx950", + ), {"kind": "smoke"} + + raw = args.request_file.read_bytes() + value = json.loads(raw) + require(isinstance(value, dict), "Request file must contain one JSON object") + parameters = {key: item for key, item in value.items() if not key.startswith("_")} + request = request_type(**parameters) + request = request_type(**request.normalized()) + require( + args.dtype is None or args.dtype == request.dtype, + f"Explicit dtype {args.dtype!r} disagrees with request dtype {request.dtype!r}", + ) + args.dtype = request.dtype + return request, { + "kind": "request_file", + "path": str(args.request_file.resolve()), + "sha256": hashlib.sha256(raw).hexdigest(), + "provenance": value.get("_provenance"), + "annotations": { + key: item + for key, item in value.items() + if key.startswith("_") and key != "_provenance" + }, + } + + +def tensor_geometry(problem) -> dict: + geometry = { + "x_dims": [problem.N, problem.C, problem.Hi, problem.Wi], + "w_dims": [problem.K, problem.C, problem.Y, problem.X], + "y_dims": [problem.N, problem.K, problem.Ho, problem.Wo], + "stride": [problem.sH, problem.sW], + "padding": [problem.pH, problem.pW], + "dilation": [problem.dH, problem.dW], + } + for operand in ("x", "w", "y"): + _, channels, height, width = geometry[f"{operand}_dims"] + geometry[f"{operand}_strides"] = [ + height * width * channels, + 1, + width * channels, + channels, + ] + return geometry + + +def build_graph( + hipdnn, + handle, + dtype, + capture, + stage: str, + tile_k: int | None, + geometry: dict, + *, + smoke: bool, +): + capture.stage = stage + graph = hipdnn.Graph() + graph.set_name("gfx950_conv_fwd_probe") + graph.set_io_data_type(dtype) + graph.set_intermediate_data_type(dtype) + graph.set_compute_data_type(hipdnn.DataType.FLOAT) + x = hipdnn.Tensor.create(geometry["x_dims"], dtype) + x.set_uid(1) + x.set_stride(geometry["x_strides"]) + w = hipdnn.Tensor.create(geometry["w_dims"], dtype) + w.set_uid(2) + w.set_stride(geometry["w_strides"]) + attrs = hipdnn.ConvFpropAttributes() + attrs.set_padding(geometry["padding"]) + attrs.set_stride(geometry["stride"]) + attrs.set_dilation(geometry["dilation"]) + attrs.set_compute_data_type(hipdnn.DataType.FLOAT) + attrs.set_convolution_mode(hipdnn.ConvolutionMode.CROSS_CORRELATION) + y = graph.conv_fprop(x, w, attrs) + y.set_uid(3) + y.set_output(True) + y.set_data_type(dtype) + if not smoke: + # A unit input channel makes NCHW/NHWC order ambiguous to stride inference. + y.set_stride(geometry["y_strides"]) + check(graph.validate(), "graph validation") + check(graph.build_operation_graph(handle), "operation graph build") + engine_ids = graph.get_ranked_engine_ids() + ids = [ + engine_id + for engine_id in engine_ids + if handle.engine_id_to_name(engine_id) == ENGINE_NAME + ] + require( + len(ids) == 1, + f"Exact engine {ENGINE_NAME!r} is not uniquely offered: {engine_ids}", + ) + engine_id = ids[0] + knobs = {knob.knob_id: knob for knob in graph.get_knobs_for_engine(engine_id)} + require( + "tile_k" in knobs and BENCHMARK_KNOB in knobs, + "Required engine knobs are missing", + ) + choices = set(knobs["tile_k"].constraint.valid_values) + if smoke: + require( + choices == {64, 128}, + "Catalog does not expose exactly the two packaged tile_k choices", + ) + elif tile_k is None: + require( + choices == {64, 128}, + f"Auto/reuse need both packaged tile_k variants; this request offers {sorted(choices)}", + ) + else: + require( + tile_k in choices, f"Requested tile_k={tile_k} is not offered: {choices}" + ) + settings = [hipdnn.KnobSetting(BENCHMARK_KNOB, 0 if tile_k is not None else 1)] + if tile_k is not None: + setting = hipdnn.KnobSetting("tile_k", tile_k) + check(knobs["tile_k"].validate(setting), "tile_k validation") + settings.append(setting) + check( + graph.create_execution_plan_ext(engine_id, settings), + "exact engine/knob selection", + ) + check(graph.check_support(), "plan support") + check(graph.build_plans(), "plan build") + require( + graph.get_execution_plan_engine_id() == engine_id, + "Plan selected a different engine", + ) + require( + graph.get_plan_name(handle) == ENGINE_NAME, + "Plan reports a different engine name", + ) + require( + graph.get_workspace_size() == 0, + "This packaged convolution must not need workspace", + ) + require( + y.get_dim() == geometry["y_dims"] and y.get_stride() == geometry["y_strides"], + "Frontend inferred a different output shape or layout", + ) + return graph, { + "engine_id": engine_id, + "engine_name": ENGINE_NAME, + "requested_knobs": {s.knob_id: s.value for s in settings}, + "tile_k_default": knobs["tile_k"].default_value, + "tile_k_choices": sorted(choices), + } + + +def make_reference(torch, torch_nn, x, w, geometry: dict): + kwargs = { + "stride": geometry["stride"], + "padding": geometry["padding"], + "dilation": geometry["dilation"], + "groups": 1, + } + info = { + "function": "torch.nn.functional.conv2d", + "device": str(x.device), + "accumulation_dtype": "float32", + "rounded_to_dtype": str(x.dtype), + } + if x.device.type == "cuda": + previous_matmul_tf32 = torch.backends.cuda.matmul.allow_tf32 + try: + torch.backends.cuda.matmul.allow_tf32 = False + with torch.backends.cudnn.flags( + enabled=True, benchmark=False, allow_tf32=False + ): + result = torch_nn.conv2d(x.float(), w.float(), **kwargs) + info.update( + { + "matmul_allow_tf32": torch.backends.cuda.matmul.allow_tf32, + "cudnn_allow_tf32": torch.backends.cudnn.allow_tf32, + "cudnn_enabled": torch.backends.cudnn.enabled, + "cudnn_benchmark": torch.backends.cudnn.benchmark, + } + ) + finally: + torch.backends.cuda.matmul.allow_tf32 = previous_matmul_tf32 + else: + result = torch_nn.conv2d(x.float(), w.float(), **kwargs) + return result.to(x.dtype).float(), info + + +def validate_output(torch, output, reference, dtype: str) -> dict: + # Large workloads stay on the GPU; smoke retains its independent CPU comparison. + actual = output.detach().to(device=reference.device, dtype=torch.float32) + require( + bool(torch.isfinite(actual).all()), + "Output contains NaN/Inf or an unwritten element", + ) + atol, rtol = 0.001, (0.002 if dtype == "fp16" else 0.016) + difference = (actual - reference).abs() + reference_location = "HIP GPU" if reference.device.type == "cuda" else "CPU" + require( + bool((difference <= atol + rtol * reference.abs()).all()), + f"Convolution differs from independent torch {reference_location} FP32 reference; max_abs={difference.max().item()}", + ) + return { + "passed": True, + "reference": f"torch.nn.functional.conv2d on {reference_location}, FP32 accumulation", + "max_abs_error": difference.max().item(), + "atol": atol, + "rtol": rtol, + } + + +def measure(torch, launch, stream, args, release) -> dict: + for _ in range(args.warmup): + launch() + stream.synchronize() + release(int(stream.cuda_stream)) + replay = launch + divisor = args.iterations + graph = None + if args.timing_mode == "graph": + graph = torch.cuda.CUDAGraph() + with torch.cuda.graph(graph, stream=stream): + for _ in range(args.iterations): + launch() + replay = graph.replay + for _ in range(2): + replay() + stream.synchronize() + samples = [] + for _ in range(args.samples): + start = torch.cuda.Event(enable_timing=True) + stop = torch.cuda.Event(enable_timing=True) + start.record(stream) + if graph is None: + for _ in range(args.iterations): + replay() + else: + replay() + stop.record(stream) + stop.synchronize() + elapsed = start.elapsed_time(stop) / divisor + require( + math.isfinite(elapsed) and elapsed > 0, + "GPU event timer returned an invalid duration", + ) + samples.append(elapsed) + release(int(stream.cuda_stream)) + return { + "method": ( + "HIP graph replay with GPU events" + if graph is not None + else "GPU events around Python submissions (includes host enqueue gaps)" + ), + "iterations_per_sample": args.iterations, + "samples_ms_per_call": samples, + "median_ms": statistics.median(samples), + "min_ms": min(samples), + "max_ms": max(samples), + "warmup": args.warmup, + "first_execution_and_search_excluded": True, + } + + +def selected_uuid(text: str, *, benchmark: bool = False) -> str: + prefix = ( + "benchmarking selected kernel " + if benchmark + else re.escape(f"engine '{ENGINE_NAME}' ") + r"(?:selected|served) kernel " + ) + matches = re.findall(prefix + f"({UUID_PATTERN})", text) + require(len(matches) == 1, f"Expected one selected kernel UUID in {text!r}") + return matches[0].lower() + + +def run(args: argparse.Namespace, report: dict) -> dict: + # Import torch before rocKE so both use the same initialized HIP runtime. + # isort: off + import torch + import torch.nn.functional as torch_nn + + # isort: on + + import hipdnn_frontend as hipdnn + from builders.common.convolution_forward import ( + build_gfx950_conv_fwd, + gfx950_conv_fwd_spec_for_request, + ) + from dispatch.grouped_convolution import ConvGroupedRequest + from rocke import compile_kernel + from rocke.core.ir_print import print_ir + from rocke.helpers.manifest import conv_args_signature + from kernels.common.conv_implicit_gemm import build_implicit_gemm_conv + from rocke.runtime.comgr import resolved_lib_path + from rocke.runtime.launcher import ( + KernelLauncher, + LaunchConfig, + release_retained_for_stream, + ) + + require( + torch.version.hip is not None and torch.cuda.is_available(), + "A ROCm PyTorch GPU is required", + ) + torch.cuda.set_device(args.device) + properties = torch.cuda.get_device_properties(args.device) + arch = getattr(properties, "gcnArchName", "") + require(arch.split(":")[0] == "gfx950", f"Expected gfx950, got {arch!r}") + request, source = load_request(args, ConvGroupedRequest) + report.update( + { + "dtype": args.dtype, + "request": request.normalized(), + "request_source": source, + "reference_device": args.reference_device, + "seed": args.seed, + } + ) + smoke = args.request_file is None + # A forced request builds only its own spec; auto/reuse rank every packaged variant. + tiles = (64, 128) if (smoke or args.tile_k is None) else (args.tile_k,) + specs = { + tile: gfx950_conv_fwd_spec_for_request(request, tile_k=tile) for tile in tiles + } + report["requested_specs"] = {tile: asdict(spec) for tile, spec in specs.items()} + problem = next(iter(specs.values())).to_problem() + geometry = tensor_geometry(problem) + candidates = packaged_candidates(args.descriptor_root, specs) + candidate_ids = {candidate["id"] for candidate in candidates.values()} + before = cached_ranking(args.cache_dir, candidate_ids) + report.update( + { + "engine_name": ENGINE_NAME, + "mode": args.mode, + "dtype": args.dtype, + "pid": os.getpid(), + "arch": arch, + "device": args.device, + "gpu_name": properties.name, + "torch_version": torch.__version__, + "rocm_version": torch.version.hip, + "problem": {key: getattr(problem, key) for key in SMOKE}, + "tensor_geometry": geometry, + "cache_before": before, + "catalog": candidates, + "toolchain": { + "lowering_backend": "python", + "llvm_flavor": args.llvm_flavor, + "requested_comgr": str(args.comgr_library), + }, + "plugin_path": str(args.plugin_path), + "descriptor_root": str(args.descriptor_root), + "cache_dir": str(args.cache_dir), + "log_file": str(args.log_file), + } + ) + require( + args.mode != "auto" or before is None, + "Auto mode requires a fresh cache for this graph", + ) + require( + args.mode != "reuse" or before is not None, + "Reuse mode requires a complete earlier ranking", + ) + dtype = {"fp16": torch.float16, "bf16": torch.bfloat16}[args.dtype] + frontend_dtype = ( + hipdnn.DataType.HALF if args.dtype == "fp16" else hipdnn.DataType.BFLOAT16 + ) + generator = torch.Generator().manual_seed(args.seed) + x_cpu = ( + torch.empty(geometry["x_dims"]).uniform_(-1, 1, generator=generator).to(dtype) + ) + w_cpu = ( + torch.empty(geometry["w_dims"]).uniform_(-1, 1, generator=generator).to(dtype) + ) + reference = None + if args.reference_device == "cpu": + reference, report["reference"] = make_reference( + torch, torch_nn, x_cpu, w_cpu, geometry + ) + stream = torch.cuda.Stream(device=args.device) + hipdnn.set_engine_plugin_paths( + [str(args.plugin_path)], hipdnn.PluginLoadingMode.ABSOLUTE + ) + handle = hipdnn.create_handle() + graph = recreated = launcher = None + try: + hipdnn.set_stream(handle, int(stream.cuda_stream)) + with torch.cuda.stream(stream), LogCapture(args.backend_library) as capture: + # Keep this list in the shared report even if a later check fails. + report["selection_evidence"] = capture.messages + x = x_cpu.to(device="cuda", memory_format=torch.channels_last) + w = w_cpu.to(device="cuda", memory_format=torch.channels_last) + if args.reference_device == "gpu": + reference, report["reference"] = make_reference( + torch, torch_nn, x, w, geometry + ) + output = torch.empty( + geometry["y_dims"], + device="cuda", + dtype=dtype, + memory_format=torch.channels_last, + ) + output.fill_(float("nan")) + buffers = {1: x.data_ptr(), 2: w.data_ptr(), 3: output.data_ptr()} + build_start = time.perf_counter() + graph, plan = build_graph( + hipdnn, + handle, + frontend_dtype, + capture, + "build", + args.tile_k, + geometry, + smoke=smoke, + ) + report["plan_build_wall_ms"] = (time.perf_counter() - build_start) * 1000 + report["plan"] = plan + + def integrated(): + check(graph.execute(handle, buffers, 0), "hipDNN execute") + + stream.synchronize() + capture.stage = "first_execute" + first_start = time.perf_counter() + integrated() + stream.synchronize() + report["first_execute_wall_ms"] = (time.perf_counter() - first_start) * 1000 + report["integrated_correctness"] = validate_output( + torch, output, reference, args.dtype + ) + if args.mode == "auto": + require( + "will benchmark 2 candidate(s)" in capture.text("build"), + "The first plan did not prepare exactly two benchmark candidates", + ) + winner = selected_uuid(capture.text("first_execute"), benchmark=True) + else: + winner = selected_uuid(capture.text("build")) + require( + "benchmarking selected kernel" not in capture.text(), + "Unexpected new search", + ) + matching = [ + tile + for tile, candidate in candidates.items() + if candidate["id"] == winner + ] + require( + len(matching) == 1, + "Selected UUID does not identify an installed requested variant", + ) + winner_tile = matching[0] + require( + args.tile_k is None or winner_tile == args.tile_k, + "The selected descriptor does not implement the forced tile_k", + ) + report["selected_kernel_id"] = winner + report["selected_tile_k"] = winner_tile + after = cached_ranking(args.cache_dir, candidate_ids) + if args.mode != "forced": + require(after is not None, "No complete measured ranking was persisted") + entries = after["record"]["entries"] + require( + len(entries) == 2 and entries[0]["kernel_id"].lower() == winner, + "Selected kernel differs from the cached winner", + ) + times = [entry["time_ms"] for entry in entries] + require( + all(math.isfinite(t) and t > 0 for t in times) + and times == sorted(times), + "The winner is not the fastest measured valid candidate", + ) + if args.mode == "reuse": + require( + after["record_sha256"] == before["record_sha256"], + "Reuse changed the persisted measurements", + ) + require( + "from a benchmarked record" in capture.text("build"), + "The restarted process did not reuse its stored winner", + ) + report["cache_after"] = after + capture.stage = "repeat_execute" + output.fill_(float("nan")) + integrated() + stream.synchronize() + report["repeat_correctness"] = validate_output( + torch, output, reference, args.dtype + ) + require( + "benchmarking selected kernel" not in capture.text("repeat_execute"), + "The same plan benchmarked again on its second execution", + ) + capture.stage = "direct_compile" + spec = specs[winner_tile] + direct_kernel = build_implicit_gemm_conv( + spec.to_instance_spec(), arch="gfx950" + ) + adapter_ir = print_ir(build_gfx950_conv_fwd(spec, arch="gfx950")) + require( + print_ir(direct_kernel) == adapter_ir, + "Adapter changed the original builder's IR", + ) + artifact = compile_kernel(direct_kernel, arch="gfx950", backend="python") + report["toolchain"]["resolved_comgr"] = resolved_lib_path() + require( + Path(resolved_lib_path()).resolve() == args.comgr_library, + "Direct rocKE used a different COMGR library than requested", + ) + launcher = KernelLauncher( + hsaco=artifact.hsaco, + kernel_name=artifact.kernel_name, + signature=conv_args_signature(args.dtype), + ) + direct_output = torch.empty_like(output) + direct_output.fill_(float("nan")) + values = { + "A": x, + "B": w, + "D": direct_output, + "A_bytes": x.numel() * x.element_size(), + "B_bytes": w.numel() * w.element_size(), + "D_bytes": direct_output.numel() * direct_output.element_size(), + } + config = LaunchConfig( + grid=spec.grid(), + block=spec.block(), + stream=int(stream.cuda_stream), + fence=False, + ) + + def direct(): + launcher(values, config=config) + + direct() + done = torch.cuda.Event() + done.record(stream) + done.synchronize() + release_retained_for_stream(int(stream.cuda_stream)) + report["direct_correctness"] = validate_output( + torch, direct_output, reference, args.dtype + ) + report["direct"] = { + "spec": asdict(spec), + "symbol": artifact.kernel_name, + "adapter_ir_matches_original": True, + "llvm_sha256": hashlib.sha256(artifact.llvm_text.encode()).hexdigest(), + "hsaco_sha256": hashlib.sha256(artifact.hsaco).hexdigest(), + "grid": spec.grid(), + "block": spec.block(), + } + # Finish both compilation paths and correctness checks before timing either. + capture.stage = "steady_state" + report["timing_logging"] = {} + with capture.suspend_for_timing(report["timing_logging"]): + report["integrated_timing"] = measure( + torch, integrated, stream, args, release_retained_for_stream + ) + report["direct_timing"] = measure( + torch, direct, stream, args, release_retained_for_stream + ) + integrated_ms = report["integrated_timing"]["median_ms"] + direct_ms = report["direct_timing"]["median_ms"] + report["comparison"] = { + "same_spec": True, + "same_gpu": True, + "integrated_over_direct": integrated_ms / direct_ms, + "integrated_minus_direct_ms": integrated_ms - direct_ms, + "order": ["integrated", "direct"], + "compilation_before_timing": True, + "timing_mode": args.timing_mode, + } + + if args.mode != "forced": + recreated, recreated_plan = build_graph( + hipdnn, + handle, + frontend_dtype, + capture, + "recreated_plan", + None, + geometry, + smoke=smoke, + ) + require( + selected_uuid(capture.text("recreated_plan")) == winner, + "A recreated plan selected a different winner", + ) + require( + "from a benchmarked record" in capture.text("recreated_plan") + and "will benchmark" not in capture.text("recreated_plan"), + "A recreated plan did not reuse the complete ranking", + ) + output.fill_(float("nan")) + check(recreated.execute(handle, buffers, 0), "recreated-plan execute") + stream.synchronize() + report["recreated_plan"] = recreated_plan + report["recreated_correctness"] = validate_output( + torch, output, reference, args.dtype + ) + finally: + pending_error = sys.exc_info()[1] + cleanup_errors = [] + try: + stream.synchronize() + release_retained_for_stream(int(stream.cuda_stream)) + except Exception as error: # noqa: BLE001 - Preserve failures during cleanup. + cleanup_errors.append(f"Stream cleanup: {type(error).__name__}: {error}") + # Drop plan and launcher references before destroying their backend handle. + graph = recreated = launcher = None + try: + hipdnn.destroy_handle(handle) + except Exception as error: # noqa: BLE001 - Preserve failures during cleanup. + cleanup_errors.append(f"Handle cleanup: {type(error).__name__}: {error}") + if cleanup_errors: + report["cleanup_errors"] = cleanup_errors + if pending_error is None: + raise RuntimeError("; ".join(cleanup_errors)) + report["status"] = "passed" + return report + + +def main(argv: list[str] | None = None) -> int: + args = arguments(argv) + report = { + "status": "failed", + "mode": args.mode, + "dtype": args.dtype, + "requested_tile_k": args.tile_k, + "pid": os.getpid(), + } + exit_code = 1 + try: + configure(args) + run(args, report) + exit_code = 0 + except Exception as error: # noqa: BLE001 - Write failures to the report. + report["status"] = "failed" + report["error"] = f"{type(error).__name__}: {error}" + report["traceback"] = traceback.format_exc() + print(report["error"], file=sys.stderr) + args.output.parent.mkdir(parents=True, exist_ok=True) + args.output.write_text( + json.dumps(report, indent=2, sort_keys=True, allow_nan=False) + "\n", + encoding="utf-8", + ) + print(f"{report['status']}: report written to {args.output}") + return exit_code + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/projects/hipdnn/tools/IngestorGenerator/tools/mine_conv_shapes.py b/projects/hipdnn/tools/IngestorGenerator/tools/mine_conv_shapes.py new file mode 100644 index 000000000000..b57727ca0162 --- /dev/null +++ b/projects/hipdnn/tools/IngestorGenerator/tools/mine_conv_shapes.py @@ -0,0 +1,708 @@ +# Copyright (c) Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +"""Translate recorded convolution workloads into rocKE dispatcher requests. + +Accepts the kernel team's ``bench_cases_conv.json`` and hipDNN frontend graph +JSON, either in a directory or in a dnn-benchmarking workload tarball. Dimensions +and convolution attributes come from the records, never from filenames. + +``--out`` contains deduplicated ConvGroupedRequest mappings for the integration's +2D, channels-last, groups=1, FP16/BF16 forward cross-correlation contract. +``--report`` (default: .report.json) retains EVERY input, its original +attributes, exclusions, and any representable dispatcher request. Exclusions are +integration scope decisions, not claims about the underlying rocKE family. Kernel +support is pending until the actual dispatcher's validity predicate is evaluated. + +Example:: + + python mine_conv_shapes.py --rocke-cases bench_cases_conv.json \\ + --graphs conv.tar.gz --arch gfx950 --out conv_requests.json + +Use ``--source-uri LOCAL_PATH URI`` to record a pinned public repository or DVC +object URI alongside the input's SHA256. No download, compilation or GPU launch +is performed by this tool. +""" + +from __future__ import annotations + +import argparse +import copy +import hashlib +import json +import sys +import tarfile +from collections import Counter +from pathlib import Path + + +class MiningError(ValueError): + """The source cannot be interpreted without guessing its semantics.""" + + +_DTYPES = { + "half": "fp16", + "fp16": "fp16", + "float16": "fp16", + "torch.float16": "fp16", + "bf16": "bf16", + "bfloat16": "bf16", + "torch.bfloat16": "bf16", + "float": "fp32", + "fp32": "fp32", + "float32": "fp32", + "torch.float32": "fp32", + "int8": "int8", + "fp8_e4m3": "fp8_e4m3", + "fp8_e5m2": "fp8_e5m2", +} +_LAYOUTS = {"NHWC", "NCHW", "NDHWC", "NCDHW", "NLC", "NCL"} +_OPS = {"conv1d", "conv2d", "conv3d", "conv2d_transpose", "dcnv3"} +_CONV_MODES = {"CROSS_CORRELATION", "CONVOLUTION"} +_CONV_NODES = { + "ConvolutionFwdAttributes", + "ConvolutionBwdAttributes", + "ConvolutionWrwAttributes", +} +_CASE_FIELDS = { + "N", + "Cin", + "Cout", + "C", + "K", + "D", + "Di", + "H", + "Hi", + "W", + "Wi", + "Kd", + "Z", + "Kh", + "Y", + "Kw", + "X", + "L", + "Kl", + "stride", + "strides", + "pad", + "pads_before", + "pads_after", + "dilation", + "dilations", + "groups", + "dtype", + "layout", + "op", + "conv_mode", + "output_spatial", + "case_id", + "model", + "variant", + "domain", + "owner_story", + "capability", + "used_by", + "note", + "suite", + "purpose", + "priority", + "pre_op", + "causal", + "execution", + "cache_semantics", + "composition_id", + "branch", + "composition_op", + "composition_timing", + "runtime_gate", + "output_padding", + "channels_per_group", + "deform_groups", + "modulation_mask_tensor", + "offset_tensor", + "offset_scale", + "remove_center", +} + + +def _category(value, allowed, label: str, source: str) -> str: + if not isinstance(value, str) or value not in allowed: + raise MiningError(f"{source}: unknown {label} {value!r}") + return value + + +def _dtype(value, source: str) -> str: + if not isinstance(value, str) or value.lower() not in _DTYPES: + raise MiningError(f"{source}: unknown dtype {value!r}") + return _DTYPES[value.lower()] + + +def _int(value, label: str, source: str, minimum: int = 1) -> int: + if type(value) is not int or value < minimum: + raise MiningError( + f"{source}: {label} must be an integer >= {minimum}, got {value!r}" + ) + return value + + +def _vector(value, rank: int, label: str, source: str, minimum: int = 1) -> list[int]: + values = [value] * rank if type(value) is int else value + if not isinstance(values, list) or len(values) != rank: + raise MiningError( + f"{source}: {label} must have {rank} components, got {value!r}" + ) + return [_int(v, label, source, minimum) for v in values] + + +def _alias(raw: dict, *names: str, default=None): + values = [raw[n] for n in names if n in raw] + if values and any(v != values[0] for v in values[1:]): + raise MiningError(f"conflicting aliases {names}: {values}") + return values[0] if values else default + + +def _vector_alias(raw, names, rank, source, *, default, minimum=1): + values = [_vector(raw[n], rank, n, source, minimum) for n in names if n in raw] + if values and any(v != values[0] for v in values[1:]): + raise MiningError(f"{source}: conflicting aliases {names}: {values}") + return values[0] if values else _vector(default, rank, names[0], source, minimum) + + +def _provenance( + source: str, path: str, blob: bytes, uri: str | None, raw: dict, **extra +) -> dict: + return { + "source": source, + "path": path, + "uri": uri or path, + "sha256": hashlib.sha256(blob).hexdigest(), + "case_id": raw.get("case_id"), + "graph": raw.get("name"), + "model": raw.get("model", (raw.get("metadata") or {}).get("model")), + "priority": raw.get("priority"), + "suite": raw.get("suite"), + "attributes": copy.deepcopy(raw), + **extra, + } + + +def _result( + provenance: dict, reasons: list[str], request: dict | None, *, forward=True +) -> dict: + return { + "status": ( + "non_forward" + if not forward + else "outside_contract" if reasons else "request" + ), + "reasons": reasons, + "provenance": provenance, + # This is an exact request for the recorded convolution, including groups + # and depth where representable. It does not assert family support. + "oracle_request": request, + "kernel_support": "pending" if request is not None else "not_representable", + } + + +def _make_request( + *, n, c, k, spatial, kernel, stride, padding, dilation, groups, dtype, layout, arch +): + if len(spatial) not in (2, 3): + return None + # The dispatcher calls its channels-last layout NHWC even when depth is + # supplied. The original NDHWC/NCDHW spelling remains in the provenance. + layout = {"NDHWC": "NHWC", "NCDHW": "NCHW"}.get(layout, layout) + request = { + "N": n, + "C": c, + "K": k, + "Hi": spatial[-2], + "Wi": spatial[-1], + "Y": kernel[-2], + "X": kernel[-1], + "G": groups, + "stride_h": stride[-2], + "stride_w": stride[-1], + "pad_h": padding[-2], + "pad_w": padding[-1], + "dilation_h": dilation[-2], + "dilation_w": dilation[-1], + "dtype": dtype, + "layout": layout, + "direction": "fwd", + "arch": arch, + } + if len(spatial) == 3: + request.update( + Di=spatial[0], + Z=kernel[0], + stride_d=stride[0], + pad_d=padding[0], + dilation_d=dilation[0], + ) + return request + + +def _scope_reasons(rank, groups, dtype, layout, mode, pre, post) -> list[str]: + reasons = [] + if rank != 2: + reasons.append( + f"integration contract covers 2D convolution, recorded spatial rank is {rank}" + ) + if groups != 1: + reasons.append( + f"integration contract covers groups=1, recorded groups={groups}" + ) + if dtype not in ("fp16", "bf16"): + reasons.append(f"integration contract covers fp16/bf16, recorded dtype={dtype}") + if layout not in ("NHWC", "NDHWC", "NLC"): + reasons.append( + f"integration contract requires channels-last storage, recorded layout={layout}" + ) + if mode != "CROSS_CORRELATION": + reasons.append( + f"integration contract requires CROSS_CORRELATION, recorded mode={mode}" + ) + if pre != post: + reasons.append( + "integration contract and dispatcher request require symmetric pre/post padding" + ) + return reasons + + +def _output_spatial(spatial, kernel, stride, pre, post, dilation, source) -> list[int]: + output = [ + (i + p + q - d * (f - 1) - 1) // s + 1 + for i, f, s, p, q, d in zip(spatial, kernel, stride, pre, post, dilation) + ] + if any(v <= 0 for v in output): + raise MiningError( + f"{source}: convolution has nonpositive output dimensions {output}" + ) + return output + + +def mine_case(raw: dict, provenance: dict, arch: str) -> dict: + source = f"{provenance['path']}[{provenance.get('row', '?')}]" + op = _category(raw.get("op"), _OPS, "convolution op", source) + layout = _category(raw.get("layout"), _LAYOUTS, "layout", source) + dtype = _dtype(raw.get("dtype"), source) + mode = _category( + raw.get("conv_mode", "CROSS_CORRELATION"), _CONV_MODES, "conv_mode", source + ) + if op in ("conv2d_transpose", "dcnv3"): + return _result( + provenance, [f"integration contract does not implement {op}"], None + ) + rank = {"conv1d": 1, "conv2d": 2, "conv3d": 3}[op] + layouts = {1: {"NCL", "NLC"}, 2: {"NCHW", "NHWC"}, 3: {"NCDHW", "NDHWC"}} + if layout not in layouts[rank]: + raise MiningError(f"{source}: {layout} is inconsistent with {op}") + n = _int(raw.get("N"), "N", source) + c = _int(_alias(raw, "Cin", "C"), "Cin", source) + k = _int(_alias(raw, "Cout", "K"), "Cout", source) + groups = _int(raw.get("groups", 1), "groups", source) + if c % groups or k % groups: + raise MiningError(f"{source}: groups={groups} must divide Cin={c} and Cout={k}") + if rank == 1: + spatial, kernel = [raw.get("L")], [raw.get("Kl")] + else: + spatial = [_alias(raw, "H", "Hi"), _alias(raw, "W", "Wi")] + kernel = [_alias(raw, "Kh", "Y"), _alias(raw, "Kw", "X")] + if rank == 3: + spatial.insert(0, _alias(raw, "D", "Di")) + kernel.insert(0, _alias(raw, "Kd", "Z")) + spatial = _vector(spatial, rank, "input spatial dimensions", source) + kernel = _vector(kernel, rank, "filter spatial dimensions", source) + stride = _vector_alias(raw, ("strides", "stride"), rank, source, default=1) + pre = _vector_alias(raw, ("pads_before", "pad"), rank, source, default=0, minimum=0) + post = _vector(raw.get("pads_after", pre), rank, "post_padding", source, 0) + dilation = _vector_alias(raw, ("dilations", "dilation"), rank, source, default=1) + output = _output_spatial(spatial, kernel, stride, pre, post, dilation, source) + if ( + "output_spatial" in raw + and _vector(raw["output_spatial"], rank, "output_spatial", source) != output + ): + raise MiningError( + f"{source}: recorded output_spatial disagrees with convolution attributes" + ) + reasons = _scope_reasons(rank, groups, dtype, layout, mode, pre, post) + semantic_reasons = [] + if raw.get("causal"): + semantic_reasons.append( + "causal convolution requires explicit padding/cache semantics" + ) + if raw.get("execution") not in (None, "full_clip") or raw.get("cache_semantics"): + semantic_reasons.append( + "stateful/streaming execution is outside the integration contract" + ) + if raw.get("composition_id") or raw.get("composition_op"): + semantic_reasons.append( + "multi-operation composition is outside the integration contract" + ) + pre_op = raw.get("pre_op") + if pre_op is not None and not ( + isinstance(pre_op, dict) + and pre_op.get("type") == "external_upsample" + and pre_op.get("benchmarked") is False + ): + semantic_reasons.append( + "recorded pre_op is not an explicitly excluded external upsample" + ) + unknown = sorted(raw.keys() - _CASE_FIELDS) + if unknown: + semantic_reasons.append(f"uninterpreted source attributes: {unknown}") + if raw.get("runtime_gate"): + semantic_reasons.append( + "recorded runtime gate is outside the integration contract" + ) + reasons.extend(semantic_reasons) + request = None + if pre == post and mode == "CROSS_CORRELATION" and not semantic_reasons: + request = _make_request( + n=n, + c=c, + k=k, + spatial=spatial, + kernel=kernel, + stride=stride, + padding=pre, + dilation=dilation, + groups=groups, + dtype=dtype, + layout=layout, + arch=arch, + ) + return _result(provenance, reasons, request) + + +def _tensor_layout(dims: list[int], strides: list[int]) -> str: + rank = len(dims) + if rank not in (3, 4, 5): + return "unsupported_rank" + for order, labels in ( + ([0, *range(2, rank), 1], {3: "NLC", 4: "NHWC", 5: "NDHWC"}), + (list(range(rank)), {3: "NCL", 4: "NCHW", 5: "NCDHW"}), + ): + expected = [0] * rank + stride = 1 + for axis in reversed(order): + expected[axis] = stride + stride *= dims[axis] + # A singleton dimension's stride cannot change any accessed address. + if all( + d == 1 or actual == wanted + for d, actual, wanted in zip(dims, strides, expected) + ): + return labels[rank] + return "non_dense" + + +def mine_graph(raw: dict, provenance: dict, arch: str) -> dict: + source = provenance["path"] + override_shapes = raw.get("is_override_shape_enabled", False) + if type(override_shapes) is not bool: + raise MiningError( + f"{source}: is_override_shape_enabled must be a boolean, got {override_shapes!r}" + ) + nodes = raw.get("nodes") + if not isinstance(nodes, list) or any(not isinstance(node, dict) for node in nodes): + raise MiningError(f"{source}: expected graph nodes array") + types = [node.get("type") for node in nodes] + for kind in types: + if ( + isinstance(kind, str) + and kind.startswith("Convolution") + and kind not in _CONV_NODES + ): + raise MiningError(f"{source}: unknown convolution node type {kind!r}") + forwards = [n for n in nodes if n.get("type") == "ConvolutionFwdAttributes"] + if not forwards: + return _result( + provenance, + ["graph contains no forward convolution node"], + None, + forward=False, + ) + if len(nodes) != 1: + return _result( + provenance, + [ + f"integration contract requires a single convolution node, recorded nodes={types}" + ], + None, + ) + node = forwards[0] + attrs = node.get("parameters") + if not isinstance(attrs, dict): + raise MiningError(f"{source}: expected convolution parameters object") + mode = _category(attrs.get("conv_mode"), _CONV_MODES, "conv_mode", source) + tensors = raw.get("tensors") + if not isinstance(tensors, list) or any( + not isinstance(t, dict) or "uid" not in t for t in tensors + ): + raise MiningError(f"{source}: expected tensors with unique uid values") + by_uid = {t["uid"]: t for t in tensors} + if len(by_uid) != len(tensors): + raise MiningError(f"{source}: duplicate tensor uid") + try: + x = by_uid[node["inputs"]["x_tensor_uid"]] + w = by_uid[node["inputs"]["w_tensor_uid"]] + y = by_uid[node["outputs"]["y_tensor_uid"]] + except (KeyError, TypeError) as exc: + raise MiningError( + f"{source}: unresolved convolution tensor binding: {exc}" + ) from exc + resolved = [] + for tensor in (x, w, y): + dims = tensor.get("dims") + if not isinstance(dims, list) or len(dims) < 3: + raise MiningError( + f"{source}: tensor dims must have batch, channel and spatial axes" + ) + dims = _vector(dims, len(dims), "tensor dims", source) + strides = _vector(tensor.get("strides"), len(dims), "tensor strides", source, 0) + dtype = _dtype(tensor.get("data_type", raw.get("io_data_type")), source) + resolved.append((dims, strides, dtype, _tensor_layout(dims, strides))) + xd, _, dtype, layout = resolved[0] + wd, _, wdtype, wlayout = resolved[1] + yd, _, ydtype, ylayout = resolved[2] + rank = len(xd) - 2 + if len(wd) != len(xd) or len(yd) != len(xd): + raise MiningError(f"{source}: input, filter and output ranks disagree") + if xd[1] % wd[1] or wd[0] % (xd[1] // wd[1]): + raise MiningError(f"{source}: invalid grouped convolution channel dimensions") + groups = xd[1] // wd[1] + pre = _vector(attrs.get("pre_padding"), rank, "pre_padding", source, 0) + post = _vector(attrs.get("post_padding"), rank, "post_padding", source, 0) + stride = _vector(attrs.get("stride"), rank, "stride", source) + dilation = _vector(attrs.get("dilation"), rank, "dilation", source) + output = _output_spatial(xd[2:], wd[2:], stride, pre, post, dilation, source) + if yd != [xd[0], wd[0], *output]: + raise MiningError( + f"{source}: output tensor dims disagree with convolution attributes" + ) + reasons = _scope_reasons(rank, groups, dtype, layout, mode, pre, post) + exact = True + if override_shapes: + reasons.append( + "integration contract does not support execution-time shape overrides" + ) + exact = False + if set(node.get("inputs", {})) != {"x_tensor_uid", "w_tensor_uid"} or set( + node.get("outputs", {}) + ) != {"y_tensor_uid"}: + reasons.append("uninterpreted convolution tensor bindings") + exact = False + if len(tensors) != 3 or len({x["uid"], w["uid"], y["uid"]}) != 3: + reasons.append( + "integration contract requires exactly three distinct bound tensors" + ) + exact = False + if dtype != wdtype or dtype != ydtype: + reasons.append( + "integration contract and dispatcher require a uniform input/filter/output dtype" + ) + exact = False + if ( + layout != wlayout + or layout != ylayout + or layout in ("non_dense", "unsupported_rank") + ): + reasons.append( + f"tensor layouts cannot be represented by one dispatcher layout: {layout}/{wlayout}/{ylayout}" + ) + exact = False + compute = _dtype( + node.get("compute_data_type", raw.get("compute_data_type")), source + ) + if compute != "fp32": + reasons.append( + f"integration contract requires fp32 accumulation, recorded compute dtype={compute}" + ) + exact = False + if any(t.get("virtual", False) is not False for t in (x, w, y)): + reasons.append( + "integration contract requires non-virtual input/filter/output tensors" + ) + exact = False + unknown = sorted( + attrs.keys() + - {"conv_mode", "pre_padding", "post_padding", "stride", "dilation"} + ) + if unknown: + reasons.append(f"uninterpreted convolution attributes: {unknown}") + exact = False + for tensor in (x, w, y): + unknown = sorted( + tensor.keys() - {"uid", "name", "dims", "strides", "data_type", "virtual"} + ) + if unknown: + reasons.append( + f"uninterpreted tensor attributes for uid={tensor['uid']}: {unknown}" + ) + exact = False + request = None + if exact and mode == "CROSS_CORRELATION" and pre == post: + request = _make_request( + n=xd[0], + c=xd[1], + k=wd[0], + spatial=xd[2:], + kernel=wd[2:], + stride=stride, + padding=pre, + dilation=dilation, + groups=groups, + dtype=dtype, + layout=layout, + arch=arch, + ) + return _result(provenance, reasons, request) + + +def _json(blob: bytes, source: str): + try: + return json.loads(blob) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise MiningError(f"{source}: invalid JSON: {exc}") from exc + + +def from_rocke_cases(path: Path, arch="gfx950", source_uri=None) -> list[dict]: + blob = path.read_bytes() + raw = _json(blob, str(path)) + if not isinstance(raw, list) or any(not isinstance(r, dict) for r in raw): + raise MiningError(f"{path}: expected an array of convolution case objects") + return [ + mine_case( + row, + _provenance("rocke_bench", str(path), blob, source_uri, row, row=i), + arch, + ) + for i, row in enumerate(raw) + ] + + +def from_graph_corpus(path: Path, arch="gfx950", source_uri=None) -> list[dict]: + records = [] + if path.is_dir(): + blobs = [ + (p.relative_to(path).as_posix(), p.read_bytes()) + for p in sorted(path.rglob("*.json")) + ] + archive_digest = None + elif tarfile.is_tarfile(path): + archive_digest = hashlib.sha256(path.read_bytes()).hexdigest() + with tarfile.open(path, "r:*") as archive: + blobs = [ + (m.name, archive.extractfile(m).read()) + for m in sorted(archive.getmembers(), key=lambda m: m.name) + if m.isfile() and m.name.endswith(".json") + ] + else: + blobs = [(path.name, path.read_bytes())] + archive_digest = None + for name, blob in blobs: + raw = _json(blob, name) + if not isinstance(raw, dict): + raise MiningError(f"{name}: expected a graph object") + uri = ( + f"{source_uri}#{name}" + if source_uri + else str(path / name) if path.is_dir() else f"{path}#{name}" + ) + provenance = _provenance( + "graphs", name, blob, uri, raw, archive_sha256=archive_digest + ) + records.append(mine_graph(raw, provenance, arch)) + return records + + +def build_corpus(records: list[dict]) -> tuple[list[dict], dict]: + requests = {} + for record in records: + if record["status"] != "request": + continue + request = record["oracle_request"] + if request is None: + raise MiningError( + f"{record['provenance']['path']}: contract request is not representable" + ) + key = json.dumps(request, sort_keys=True) + provenance = copy.deepcopy(record["provenance"]) + if key in requests: + requests[key]["_provenance"].setdefault("also", []).append(provenance) + else: + requests[key] = {**request, "_provenance": provenance} + counts = Counter(r["status"] for r in records) + report = { + "schema_version": 1, + "meaning": "Source inventory and integration contract eligibility; kernel validity and runtime dispatch are not evaluated.", + "counts": { + "source_records": len(records), + **dict(counts), + "unique_requests": len(requests), + "merged_request_records": counts["request"] - len(requests), + }, + "by_source": { + source: dict( + Counter( + r["status"] for r in records if r["provenance"]["source"] == source + ) + ) + for source in sorted({r["provenance"]["source"] for r in records}) + }, + "records": records, + } + return list(requests.values()), report + + +def main(argv=None) -> int: + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument("--rocke-cases", type=Path, action="append", default=[]) + parser.add_argument("--graphs", type=Path, action="append", default=[]) + parser.add_argument( + "--source-uri", + nargs=2, + action="append", + default=[], + metavar=("LOCAL_PATH", "URI"), + ) + parser.add_argument("--arch", default="gfx950") + parser.add_argument("--out", type=Path, required=True) + parser.add_argument("--report", type=Path) + args = parser.parse_args(argv) + if not args.rocke_cases and not args.graphs: + parser.error("provide at least one source: --rocke-cases or --graphs") + uris = {str(Path(path).resolve()): uri for path, uri in args.source_uri} + sources = {str(path.resolve()) for path in [*args.rocke_cases, *args.graphs]} + if uris.keys() - sources: + parser.error("--source-uri LOCAL_PATH must name an input source") + try: + records = [] + for paths, reader in ( + (args.rocke_cases, from_rocke_cases), + (args.graphs, from_graph_corpus), + ): + for path in paths: + records.extend(reader(path, args.arch, uris.get(str(path.resolve())))) + requests, report = build_corpus(records) + report_path = args.report or args.out.with_name(args.out.stem + ".report.json") + for path, payload in ((args.out, requests), (report_path, report)): + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(payload, indent=2) + "\n") + print(json.dumps(report["counts"], sort_keys=True)) + print( + f"Kernel support pending actual dispatcher validation; inventory: {report_path}" + ) + except (MiningError, OSError, tarfile.TarError) as exc: + print(f"FAIL: {exc}", file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())