Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions dnn-providers/integration-tests/docs/adding-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -649,5 +649,4 @@ the harness (`hipdnn_integration_tests_unit_tests`).
- [ ] `python dnn-providers/integration-tests/scripts/verify_support_claims.py`
passes when you run it by hand.
- [ ] If you regenerated or renamed sweep cases, no sidecar names a case that no
longer exists. The `ffm-quick` ids of miopen-provider still exist
(`ctest --test-dir build/dnn-providers/miopen-provider -L ffm-quick -N`).
longer exists.
5 changes: 1 addition & 4 deletions dnn-providers/integration-tests/docs/file-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ suffix only when the readable part is not already unique.
**Do not write cases by hand.** Generate them with `import_graph.py` (see
[Adding Tests](adding-tests.md#add-a-bundle)). You can edit a field of an existing
case, for example to add its `golden` pointer. Do not rename ids without a
reason, because support-claim sidecars and the `ffm-quick` tier of
miopen-provider name cases by id.
reason, because support-claim sidecars name cases by id.

#### `tensor_patches`

Expand Down Expand Up @@ -545,8 +544,6 @@ execution_settings:
`DISABLED` and is never launched. Variants are generated for each `ex_gpu_*`
label declared in the file, not for the arch that you build. To select one, use
`ctest -L ex_gpu_<arch>`.
- miopen-provider's `ffm-quick` lists exact test names (sweep case ids).
Regenerating a sweep can rename those ids and silently shrink that tier.

## Where each format is enforced

Expand Down
2 changes: 1 addition & 1 deletion dnn-providers/integration-tests/docs/running-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ Each lane YAML also defines an `ffm-quick` category (labels `ffm-quick`,
`ffm-full`). This is the fast-feedback tier. It is not a superset of `quick`.
It differs for each lane:

- miopen lists one sweep case per op by exact name.
- miopen selects `quick_*`, `Smoke/*` and `Quick/*`, the same as its quick tier.
- HIP_MLOPS selects `quick_*`, `Smoke/*` and `Quick/*`.
- ASM_SDPA selects the `*Sdpa*` subset of those.
- hipBLASLt selects only `Smoke/*`, `Quick/*` and `TestCpu*GoldenReference*`,
Expand Down
11 changes: 10 additions & 1 deletion dnn-providers/integration-tests/test_categories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ test_categories:
- "slow"

ffm-quick:
description: "Fast-feedback mechanism (FFM) quick tier - currently mirrors the quick tier"
description: "Fast-feedback mechanism (FFM) quick tier - mirrors the quick tier minus the quick-tier SDPA golden-data GPU-reference cases"
test_patterns:
- "*"
exclude:
Expand All @@ -97,6 +97,15 @@ test_categories:
- "comprehensive_*"
- "Full*"
- "full_*"
# The GPU SDPA reference recomputes QK^T per output element, so cost tracks
# B*H*Sq*Skv*D. On the FFM simulator even the smallest quick-tier bundle
# (1x8x256x128, 36 ms on MI300X) took 329 s, hd192 took 484 s, and the
# 2x32x2048x128 bundle had not finished after 40 minutes.
# referenceShapeIsAffordable() gates only the CPU reference, on the
# assumption that the GPU reference runs these shapes in milliseconds;
# that holds on hardware, not on FFM. Real-GPU lanes still run these
# cases and the CpuRef lane still validates the same bundles on the host.
- "quick_SdpaFwd_*_GpuRef.*"
labels:
- "ffm-quick"
- "ffm-full"
Expand Down
25 changes: 10 additions & 15 deletions dnn-providers/miopen-provider/test_categories_integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,17 @@ test_categories:
- "all"

ffm-quick:
description: "Fast-feedback mechanism (FFM) quick tier: one bundle case per operation for rapid signal"
description: "Fast-feedback mechanism (FFM) quick tier: same coverage as the quick tier (quick-tier bundle sweeps plus always-built C++ tests), with a 2 hour ctest timeout"
test_patterns:
# One case per op, named exactly. These are sweep-case ids taken from
# integration-test-bundles/quick/<Op>/Default/sweep.json (and the SDPA
# single-graph bundle path); regenerating a sweep can rename them, in
# which case this tier silently shrinks. Verify with:
# ctest -L ffm-quick -N
- "quick_ConvolutionFwd_Default.1_16_16_16_bfp16_nchw_dil1x1_postpad0x0_prepad0x0"
- "quick_BatchnormInference_Default.1_3_224_fp32_ncl"
- "quick_Pointwise_Default.2_4_8_8_fp16_nchw"
- "quick_Reduction_Default.1_16_8_8_bfp16_nchw_modeadd"
- "quick_RMSNorm_Default.2_3_4_4_bfp16_nchw_bcd247"
# Layernorm had no entry here at all, so the op had no fast-feedback
# signal; this is the smallest quick-tier layernorm bundle case.
- "quick_Layernorm_Default.2_2_3_2_bfp16_nhwc_normalized_dim_count1_6d6330"
- "quick_SdpaFwd_bhsd_bf16_hd128_nomask_batch_Small.Small"
# Deliberately identical to the quick tier above. This tier used to name
# six sweep-case ids explicitly (one per op); those ids are silently
# renamed whenever a sweep is regenerated, and the FFM run only ever
# exercised three of them (the other three skipped). Mirroring quick
# removes that maintenance trap and gives FFM the same bundle coverage
# every other tier gets.
- "quick_*"
- "Smoke/*"
- "Quick/*"
exclude: *common_excludes
labels:
- "ffm-quick"
Expand Down
2 changes: 1 addition & 1 deletion projects/hipdnn/backend/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,4 @@ add_dependencies(hipdnn_backend_tests
${HIPDNN_TEST_MALFORMED_VERSION_PLUGIN_TARGET}
)

add_hipdnn_test(hipdnn_backend_tests ${CMAKE_CURRENT_BINARY_DIR})
add_hipdnn_test(hipdnn_backend_tests ${CMAKE_CURRENT_BINARY_DIR} GTEST_CATEGORIES)
81 changes: 77 additions & 4 deletions projects/hipdnn/cmake/Tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ findandcheckllvmsymbolizer()

# YAML-driven CTest categorisation. Build-tree tests get labels as they are
# registered; install_hipdnn_ctest_files() bakes the same labels into the
# installed CTestTestfile.cmake.
# installed CTestTestfile.cmake. test_categories.yaml labels whole CTest entries by
# name. A target that must run a gtest-filtered subset (add_hipdnn_test(...
# GTEST_CATEGORIES)) also gets suites generated from test_categories_gtest.yaml.
set(_HIPDNN_TEST_CATEGORIES_YAML "${PROJECT_SOURCE_DIR}/test_categories.yaml")
set(_HIPDNN_GTEST_CATEGORIES_YAML "${PROJECT_SOURCE_DIR}/test_categories_gtest.yaml")
set(_HIPDNN_SHARED_CTEST "${ROCM_LIBRARIES_ROOT}/shared/ctest/TestCategories.cmake")
if(EXISTS "${_HIPDNN_SHARED_CTEST}" AND EXISTS "${_HIPDNN_TEST_CATEGORIES_YAML}")
include("${_HIPDNN_SHARED_CTEST}")
Expand Down Expand Up @@ -176,9 +179,10 @@ function(_add_check_target_internal PREFIX_NAME TARGET_NAME LABEL VERBOSE COMMEN
# Build the ctest command
set(CTEST_CMD ${CMAKE_COMMAND} -E env ${CTEST_ENV} ${CMAKE_CTEST_COMMAND})

# Add label filter if specified
# Add label filter if specified. Anchored: -L is a regex search, so a bare `quick` would
# also select every test labelled `ffm-quick`.
if(NOT "${LABEL}" STREQUAL "")
list(APPEND CTEST_CMD -L "${LABEL}")
list(APPEND CTEST_CMD -L "^${LABEL}$")
endif()

# Always add --output-on-failure
Expand All @@ -194,7 +198,10 @@ function(_add_check_target_internal PREFIX_NAME TARGET_NAME LABEL VERBOSE COMMEN

# Create the target with prefix
set(FULL_TARGET_NAME "${PREFIX_NAME}-${TARGET_NAME}")
add_custom_target(${FULL_TARGET_NAME} COMMAND ${CTEST_CMD} COMMENT "${COMMENT}" USES_TERMINAL)
# VERBATIM: the anchors in -L "^label$" are shell-special (cmd.exe treats ^ as its escape
# character), so the arguments must be quoted for the host shell.
add_custom_target(${FULL_TARGET_NAME} COMMAND ${CTEST_CMD} COMMENT "${COMMENT}" USES_TERMINAL
VERBATIM)
add_dependencies(${FULL_TARGET_NAME} ${PREFIX_NAME}-validate_test_names)
message(VERBOSE "Created ${FULL_TARGET_NAME} target")
endfunction() # _add_check_target_internal
Expand Down Expand Up @@ -292,6 +299,53 @@ function(finalize_test_targets prefix_name)
# cmake-format: on
endfunction() # finalize_test_targets

# Generates the <TARGET>_<category>_suite entries of a GTEST_CATEGORIES target from
# test_categories_gtest.yaml (see add_hipdnn_test).
#
# Without shared/ctest (a sparse or standalone checkout of projects/hipdnn) no test gets category
# labels at all, so there is nothing to pair these suites with: skip them, as the label pass above
# skips. A missing yaml next to a present shared/ctest would instead drop the target out of every
# category the yaml defines, so that case is a warning.
function(_hipdnn_add_gtest_category_suites TARGET WORKING_DIR)
Comment thread
adickin-amd marked this conversation as resolved.
Resolved
if(NOT COMMAND apply_test_category_labels)
message(STATUS "hipDNN: shared/ctest not available; skipping the gtest-filter suites of ${TARGET}")
return()
endif()
if(NOT EXISTS "${_HIPDNN_GTEST_CATEGORIES_YAML}")
message(WARNING
"hipDNN: ${_HIPDNN_GTEST_CATEGORIES_YAML} not found; ${TARGET} gets no gtest-filter "
"suites and is not selected by the categories that file defines"
)
return()
endif()

# Same environment and fixtures as the plain entry. The installed-tree lines that the parser
# writes into the fragment carry the same ENVIRONMENT, which only differs from the plain
# installed entry in sanitizer builds.
set(_category_args "")
if(DEFINED TEST_ENVIRONMENT)
list(APPEND _category_args ENVIRONMENT ${TEST_ENVIRONMENT})
endif()
if(DEFINED TEST_ENVIRONMENT_MODIFICATION)
list(APPEND _category_args ENVIRONMENT_MODIFICATION ${TEST_ENVIRONMENT_MODIFICATION})
endif()
if(DEFINED HIPDNN_TEST_MIOPEN_CACHE_DIR)
list(APPEND _category_args FIXTURES_REQUIRED hipdnn_clear_miopen_test_cache)
endif()

# The parser appends the installed-tree add_test() lines to this fragment;
# install_hipdnn_ctest_files() copies it into the installed CTestTestfile.cmake.
set(_fragment "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_gtest_categories.ctest")
file(WRITE "${_fragment}" "")
set_property(GLOBAL APPEND PROPERTY HIPDNN_GTEST_CATEGORY_FRAGMENTS "${_fragment}")

apply_test_category_labels(
${TARGET} "${_HIPDNN_GTEST_CATEGORIES_YAML}" "${WORKING_DIR}"
INSTALL_TEST_FILE "${_fragment}"
${_category_args}
)
endfunction() # _hipdnn_add_gtest_category_suites

# ~~~
# Records, configures, and registers a hipDNN gtest-based CTest test target. Assumes that the
# test target is a gtest executable, setting up:
Expand All @@ -304,8 +358,14 @@ endfunction() # finalize_test_targets
# Parameters:
# TARGET - Name of the test executable target (must already exist)
# WORKING_DIR - Working directory for test execution
# GTEST_CATEGORIES - Optional flag. Also generate <TARGET>_<category>_suite entries, each running
# the binary with the --gtest_filter that test_categories_gtest.yaml defines for that
# category, labelled as that file says. The target must then be listed under
# `exclude_tests` for the same categories in test_categories.yaml, or its plain entry would
# carry those labels too and run the tests the filter excludes.
# ~~~
function(add_hipdnn_test TARGET WORKING_DIR)
cmake_parse_arguments(ARG "GTEST_CATEGORIES" "" "" ${ARGN})
# ROCm ships its own googletest, which hip::host puts on the include path. Ahead of the
# fetched googletest it compiles against ROCm's headers but links the fetched archive.
# Pinned per target, for both gtest and gmock, so library sources never see googletest.
Expand Down Expand Up @@ -381,6 +441,10 @@ function(add_hipdnn_test TARGET WORKING_DIR)
if(DEFINED HIPDNN_TEST_MIOPEN_CACHE_DIR)
set_tests_properties(${TARGET} PROPERTIES FIXTURES_REQUIRED hipdnn_clear_miopen_test_cache)
endif()

if(ARG_GTEST_CATEGORIES)
_hipdnn_add_gtest_category_suites(${TARGET} "${WORKING_DIR}")
endif()
endfunction() # add_hipdnn_test

# Install CTest configuration files for direct test execution This should be called once at the end
Expand Down Expand Up @@ -431,6 +495,15 @@ function(install_hipdnn_ctest_files)
)
endif()

# Suites generated from test_categories_gtest.yaml. Appended after the label pass on
# purpose: that pass would label them through test_categories.yaml's `.*` patterns
# (quick, standard, ...), and their only labels are the ones the gtest yaml gives them.
get_property(gtest_category_fragments GLOBAL PROPERTY HIPDNN_GTEST_CATEGORY_FRAGMENTS)
foreach(_fragment IN LISTS gtest_category_fragments)
file(READ "${_fragment}" _fragment_contents)
file(APPEND "${INSTALLED_CTEST_FILE}" "\n${_fragment_contents}")
endforeach()

# Install the generated CTestTestfile.cmake to HIPDNN_CTEST_FILE_INSTALL_PATH
install(FILES "${INSTALLED_CTEST_FILE}" DESTINATION ${HIPDNN_CTEST_FILE_INSTALL_PATH}
RENAME CTestTestfile.cmake
Expand Down
2 changes: 2 additions & 0 deletions projects/hipdnn/docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ cmake --build build --target hipdnn-standard-check

`hipdnn-<category>-check` and `hipdnn-<category>-check-verbose` exist for each category in [`test_categories.yaml`](../test_categories.yaml): the tiers `quick`, `standard`, `comprehensive` and `full`, plus `ffm-quick`, `unit` and `integration`. They build and run the hipDNN core tests only; `hipdnn-check` runs all core tests. Provider and integration-tests targets are listed in [Building hipDNN: Superbuild Targets](./Building.md#superbuild-targets).

`test_categories.yaml` labels whole CTest entries by name, so it cannot leave one gtest out of a binary. A target registered with `add_hipdnn_test(<target> <dir> GTEST_CATEGORIES)` also gets `<target>_<category>_suite` entries generated from [`test_categories_gtest.yaml`](../test_categories_gtest.yaml). Each runs the binary with that category's `--gtest_filter` and carries exactly the labels the file lists. Today only `hipdnn_backend_tests` opts in, and only for `ffm-quick`, where the file excludes tests the FFM simulator cannot pass. List such a target under `exclude_tests` for the same category in `test_categories.yaml`, so the plain entry does not carry the label and run the excluded tests. The `hipdnn-<category>-check` targets match their label exactly (`ctest -L '^<category>$'`), so `hipdnn-quick-check` does not also run the `ffm-quick` suite.

**One provider.** Build the provider's preset (for example `miopen-provider`), then run the shared integration suite against it:

```bash
Expand Down
7 changes: 6 additions & 1 deletion projects/hipdnn/test_categories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ test_categories:
test_patterns:

ffm-quick:
description: "Fast-feedback mechanism (FFM) quick tier; currently mirrors the quick tier"
description: "Fast-feedback mechanism (FFM) quick tier; mirrors the quick tier"
test_patterns:
- ".*"
# Targets whose ffm-quick suite is generated from test_categories_gtest.yaml (so
# it can exclude individual gtests) carry the ffm labels on that suite only.
# Labelling the plain entry too would run the excluded tests under -L ffm-quick.
exclude_tests:
- "hipdnn_backend_tests"
labels:
- "ffm-full"

Expand Down
38 changes: 38 additions & 0 deletions projects/hipdnn/test_categories_gtest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# hipDNN gtest-filter test categories.
#
# test_categories.yaml labels whole CTest entries by name; it cannot drop a single
# gtest from a binary. This file is the gtest-schema counterpart (shared/ctest/
# parse_test_categories.py): each category becomes a CTest suite named
# <target>_<category>_suite that runs the binary with a --gtest_filter built from
# test_patterns/exclude. Labels are exactly the ones listed here; tiers do not
# cascade.
#
# It applies to every gtest target that opts in with
# add_hipdnn_test(... GTEST_CATEGORIES) (cmake/Tests.cmake), so one exclude list
# serves all of them. A pattern that matches no test in a binary is harmless, but
# qualify excludes as Suite.Test so they cannot match anything unintended.
#
# A target that opts in carries the labels of the categories below on these suites
# only, so test_categories.yaml must list it under `exclude_tests` for the same
# categories. Today that is ffm-quick.

test_categories:
ffm-quick:
description: "Fast-feedback mechanism (FFM) quick tier - mirrors the quick tier minus tests that cannot pass on the simulator"
test_patterns:
- "*"
exclude:
- "*DISABLED*"
# Asserts that a stalled start event excludes a 20 ms host delay from the
# measured span. FFM does not honour the stall gate: stalled timing reported
# 100-112 ms against an expected < 5 ms.
- "TestGpuProfilingControlDescriptor.StallGateExcludesHostSubmissionDelay"
labels:
- "ffm-quick"
- "ffm-full"

execution_settings:
default_timeout: 600
timeout_multiplier: 1
category_timeouts:
ffm-quick: 7200 # 2 hours; matches the integration-tests ffm-quick tier
Loading
Loading