diff --git a/dnn-providers/integration-tests/cmake/HipdnnIntegrationTestHelpers.cmake b/dnn-providers/integration-tests/cmake/HipdnnIntegrationTestHelpers.cmake index 9b6564aaacbc..40581e22f892 100644 --- a/dnn-providers/integration-tests/cmake/HipdnnIntegrationTestHelpers.cmake +++ b/dnn-providers/integration-tests/cmake/HipdnnIntegrationTestHelpers.cmake @@ -130,7 +130,9 @@ function(add_external_integration_test_target) file(RELATIVE_PATH _install_bin "${_install_cwd_abs}" "${_bin_abs}") file(RELATIVE_PATH _install_plugin "${_install_cwd_abs}" "${_plugin_abs}") - set(_install_cmd "add_test([=[${ARG_TARGET_NAME}]=] \"${_install_bin}\" \"--test-article\" \"${_install_plugin}\" \"--test-engine\" \"${ARG_ENGINE_NAME}\"") + # Double-quote the name (not [=[ ]=]); the category parser only scans + # bare/quoted add_test() names, so this keeps it discoverable. + set(_install_cmd "add_test(\"${ARG_TARGET_NAME}\" \"${_install_bin}\" \"--test-article\" \"${_install_plugin}\" \"--test-engine\" \"${ARG_ENGINE_NAME}\"") if(ARG_TEST_CONFIG) string(APPEND _install_cmd " \"--test-config\" \"${_install_config}\"") endif() @@ -139,7 +141,7 @@ function(add_external_integration_test_target) endif() string(APPEND _install_cmd ")\n") string(APPEND _install_cmd - "set_tests_properties([=[${ARG_TARGET_NAME}]=] PROPERTIES LABELS \"${_LABELS}\")\n" + "set_tests_properties(\"${ARG_TARGET_NAME}\" PROPERTIES LABELS \"${_LABELS}\")\n" ) set_property(GLOBAL APPEND_STRING diff --git a/dnn-providers/miopen-provider/CMakeLists.txt b/dnn-providers/miopen-provider/CMakeLists.txt index 55d25ce652e6..9138baee43bc 100644 --- a/dnn-providers/miopen-provider/CMakeLists.txt +++ b/dnn-providers/miopen-provider/CMakeLists.txt @@ -19,6 +19,13 @@ dnn_provider_setup_version(miopen_provider ${CMAKE_CURRENT_LIST_DIR}) # Set project with version project(miopen-provider VERSION ${MIOPEN_PROVIDER_VERSION} LANGUAGES CXX) +# Root of the rocm-libraries monorepo (for shared infrastructure like CTest categories). +# Used by the YAML-based test categorization wiring further down. Guarded with an EXISTS +# check at the point of use so standalone / sparse checkouts that lack shared/ctest still build. +if(NOT DEFINED ROCM_LIBRARIES_ROOT) + set(ROCM_LIBRARIES_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..") +endif() + include(CMakePackageConfigHelpers) include(${CMAKE_CURRENT_LIST_DIR}/cmake/CheckPreCommit.cmake) @@ -271,6 +278,47 @@ if(NOT MIOPENPROVIDER_SKIP_TESTS) finalize_test_targets("${PROJECT_NAME}") endif() + # Optional: YAML-driven CTest test categorization for TheRock CI's test_runner.py. + # Skipped when shared/ctest is not present (e.g. standalone miopen-provider or sparse + # checkout that doesn't include rocm-libraries/shared/), in which case we fall back to + # the project's own install_provider_ctest_files() below. + set(MIOPENPROVIDER_CTEST_INSTALL_FILE "") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test_categories.yaml" + AND EXISTS "${ROCM_LIBRARIES_ROOT}/shared/ctest/TestCategories.cmake") + include("${ROCM_LIBRARIES_ROOT}/shared/ctest/TestCategories.cmake") + enable_testing() + message(STATUS "miopen-provider: YAML-based test categorization") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/staging") + # Install-time CTestTestfile uses relative paths so `ctest` can run from the + # installed location (bin/miopen_plugin/) and reach ../miopen_plugin_tests etc. + set(MIOPENPROVIDER_CTEST_INSTALL_FILE "${CMAKE_CURRENT_BINARY_DIR}/install_CTestTestfile.cmake") + file(WRITE "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" +[=[ +# This is a test file generated by miopen-provider for install time. +# Tests are defined with relative paths to work in the installed location. +]=] + ) + # The YAML applies to both test binaries; each call appends its category suites + # (e.g. miopen_plugin_tests_quick_suite, miopen_plugin_integration_tests_quick_suite) + # to the same install-time CTestTestfile.cmake. + apply_test_category_labels( + miopen_plugin_tests + "${CMAKE_CURRENT_SOURCE_DIR}/test_categories.yaml" + "${PROJECT_BINARY_DIR}/staging" + "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" + ) + apply_test_category_labels( + miopen_plugin_integration_tests + "${CMAKE_CURRENT_SOURCE_DIR}/test_categories.yaml" + "${PROJECT_BINARY_DIR}/staging" + "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" + ) + else() + message(STATUS "miopen-provider: shared/ctest or test_categories.yaml not found, skipping YAML-based CTest categories") + endif() + + # Must run before the CTestTestfile install below so the staged snippet + # can be folded into the labeled file and labeled there. if(NOT TARGET hipdnn_integration_tests) find_package(hipdnn_integration_tests CONFIG QUIET) endif() @@ -284,15 +332,50 @@ if(NOT MIOPENPROVIDER_SKIP_TESTS) TEST_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/config/MIOPEN_ENGINE.toml ) message(STATUS "Created ${PROJECT_NAME}-external-integration-check target") + + # This is a pre-registered CTest test (not a GTest binary), so it is + # labeled via apply_ctest_category_labels()/test_categories_external.yaml. + if(MIOPENPROVIDER_CTEST_INSTALL_FILE) + # Fold the staged add_test() into the labeled file before labeling; + # apply_ctest_category_labels() scans the file's add_test() names. + get_property(_external_staging GLOBAL + PROPERTY "EXTERNAL_TEST_INSTALL_STAGING_miopen_plugin" + ) + if(_external_staging) + file(APPEND "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" + "\n# External integration test (cross-provider suite)\n${_external_staging}" + ) + endif() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test_categories_external.yaml") + # Install tree. + apply_ctest_category_labels( + "${CMAKE_CURRENT_SOURCE_DIR}/test_categories_external.yaml" + "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" + ) + # Build tree (so a local `ctest -L ` selects it too). + apply_ctest_category_labels( + "${CMAKE_CURRENT_SOURCE_DIR}/test_categories_external.yaml" + ) + endif() + endif() else() message(STATUS "hipdnn_integration_tests not found - skipping external-integration-check") endif() - # For standalone builds we need to install the ctest files. Must run - # AFTER add_external_integration_test_target so the staged install-tree - # snippet for the cross-provider test is included. + # For standalone builds we need to install the ctest files. + # When YAML-based categorization is active, install the generated install_CTestTestfile.cmake + # to bin/miopen_plugin/ so TheRock CI's test_runner.py can drive `ctest -L quick` + # (etc.) from the artifact's install tree. Otherwise, fall back to the project's + # own install_provider_ctest_files() which emits an unlabeled CTestTestfile.cmake. if(NOT ROCM_LIBS_SUPERBUILD) - install_provider_ctest_files("miopen_plugin") + if(MIOPENPROVIDER_CTEST_INSTALL_FILE) + install(FILES "${MIOPENPROVIDER_CTEST_INSTALL_FILE}" + DESTINATION "${CMAKE_INSTALL_BINDIR}/miopen_plugin" + RENAME "CTestTestfile.cmake" + ) + else() + install_provider_ctest_files("miopen_plugin") + endif() endif() endif() diff --git a/dnn-providers/miopen-provider/test_categories.yaml b/dnn-providers/miopen-provider/test_categories.yaml new file mode 100644 index 000000000000..5875fd5e91ae --- /dev/null +++ b/dnn-providers/miopen-provider/test_categories.yaml @@ -0,0 +1,111 @@ +# Copyright © Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +# +# miopen-provider Test Categories Configuration +# Aligned with Test Filter Standardization (RFC0010). +# +# miopen-provider has two GTest binaries (miopen_plugin_tests and +# miopen_plugin_integration_tests) that share this YAML. Tier behaviour +# mirrors the legacy test_miopenprovider.py runner: +# - quick: GTEST_FILTER="-Full*" (skip the Full/* INSTANTIATE_TEST_SUITE_P +# parameterised expansions used by integration tests; unit tests have no +# Full* prefix so they all run) +# - comprehensive/full: run everything (including Full*) +# +# Unit tests in tests/ use INSTANTIATE_TEST_SUITE_P prefixes "AllCases" and +# bare TEST/TEST_F; integration tests in integration_tests/ use "Smoke" and +# "Full" prefixes. There are no Standard*/Comprehensive* prefixes, so the +# standard tier is the same shape as quick (matches pre-checkin scope). + +# YAML anchor for the shared exclusion list. Mirrors the legacy filter in +# TheRock build_tools/github_actions/test_executable_scripts/test_miopenprovider.py +# (which only used GTEST_FILTER="-Full*" for quick, and *DISABLED* is the +# standard GTest convention for skipped tests). +_common_excludes: &common_excludes + - "*DISABLED*" + +test_categories: + quick: + description: "Fast sanity checks (target: < 5 min) - excludes Full* parameterised expansions" + test_patterns: + - "*" + exclude: + - "*DISABLED*" + - "Full*" + labels: + - "quick" + - "pre-commit" + - "smoke" + + standard: + description: "Pre-checkin validation (target: < 45 min) - same shape as quick (no Standard* tier exists)" + test_patterns: + - "*" + exclude: + - "*DISABLED*" + - "Full*" + labels: + - "standard" + - "pr" + - "precheckin" + + comprehensive: + description: "Nightly comprehensive tests (target: < 7 hours) - includes Full* tier" + test_patterns: + - "*" + exclude: *common_excludes + labels: + - "comprehensive" + - "nightly" + - "extended" + + full: + description: "Complete test suite - all tests including Full*" + test_patterns: + - "*" + exclude: *common_excludes + labels: + - "full" + - "all" + +# GPU-arch-specific exclusions. Mirrors the TEST_TO_IGNORE map in the legacy +# TheRock/build_tools/github_actions/test_executable_scripts/test_miopenprovider.py: +# +# TEST_TO_IGNORE = { +# # TODO(#3709): Re-enable gfx110X tests once issues are resolved +# "gfx110X-all": { +# "windows": ["miopen_plugin_integration_tests"], +# }, +# } +# +# The legacy carve-out is OS-scoped (Windows only). The shared parser accepts +# an optional `_windows` / `_linux` suffix on the key and skips the entire +# block when configuring on the wrong OS, so this entry never reaches the +# Linux install file. The runtime label is still `ex_gpu_gfx110X` (no OS +# suffix) so test_runner.py's GPU-arch matching needs no changes. +# +# `*Integration*` is the gtest filter that scopes the exclusion to the +# integration binary only: all TEST_P classes in integration_tests/ are named +# IntegrationGpu*, and no TEST_P class in tests/ contains "Integration". So +# the filter is a no-op on miopen_plugin_tests (unit tests still run) and a +# full exclusion on miopen_plugin_integration_tests, matching the legacy +# script's ctest --exclude-regex "miopen_plugin_integration_tests" exactly. +exclude_gpu: + exclude_gpu_gfx110X_windows: + test_patterns: + - "*Integration*" + labels: + - "quick" + - "standard" + - "comprehensive" + - "full" + - "ex_gpu_gfx110X" + +execution_settings: + default_timeout: 300 + timeout_multiplier: 1 + category_timeouts: + quick: 300 # 5 minutes + standard: 2700 # 45 minutes + comprehensive: 25200 # 7 hours + full: 28800 # 8 hours diff --git a/dnn-providers/miopen-provider/test_categories_external.yaml b/dnn-providers/miopen-provider/test_categories_external.yaml new file mode 100644 index 000000000000..d33d1b6097a5 --- /dev/null +++ b/dnn-providers/miopen-provider/test_categories_external.yaml @@ -0,0 +1,32 @@ +# Copyright © Advanced Micro Devices, Inc., or its affiliates. +# SPDX-License-Identifier: MIT +# +# miopen-provider External Integration Test Categories (RFC0010). +# +# Separate from test_categories.yaml: this drives apply_ctest_category_labels() +# over the pre-registered CTest test `miopen-provider-external-integration-check` +# (patterns match CTest test NAMES), whereas test_categories.yaml drives +# apply_test_category_labels() over GTest binaries (patterns are GTest globs). +# +# Placed in the quick tier so it runs in every category (quick -> standard -> +# comprehensive -> full), matching the legacy test_miopenprovider.py which ran +# ctest with no label filter (the test executed in all TEST_TYPEs). +# +# `labels:` must carry the COMPLETE set (tier labels + descriptive/engine +# labels) because apply_ctest_category_labels() emits one replacing +# set_tests_properties(); anything omitted is lost in the install tree. + +test_categories: + quick: + description: "Cross-provider integration suite against the miopen plugin (slow)" + test_patterns: + - "miopen-provider-external-integration-check" + labels: + - "quick" + - "standard" + - "comprehensive" + - "full" + - "integration_test" + - "slow" + - "external_integration_test" + - "MIOPEN_ENGINE"