Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

326 lines
11 KiB
Python

# Copyright (c) Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
"""
Tests for OpenMP integration with rocprofiler-systems.
"""
from __future__ import annotations
import pytest
from pathlib import Path
from conftest import RocprofsysTest
pytestmark = [
pytest.mark.openmp,
pytest.mark.rocm_min_version(
"6.4"
), # Requires SDK version >= 600, 6.3 ships with 500
]
# ============================================================================
# OpenMP Fixtures
# ============================================================================
@pytest.fixture
def ompt_base_env() -> dict[str, str]:
"""Environment variables for OMPT tests."""
return {
"ROCPROFSYS_TRACE": "ON",
"ROCPROFSYS_PROFILE": "ON",
"ROCPROFSYS_TIME_OUTPUT": "OFF",
"ROCPROFSYS_USE_OMPT": "ON",
"ROCPROFSYS_TIMEMORY_COMPONENTS": "wall_clock,trip_count,peak_rss",
"OMP_PROC_BIND": "spread",
"OMP_PLACES": "threads",
"OMP_NUM_THREADS": "2",
}
@pytest.fixture
def ompt_sampling_env(ompt_base_env: dict[str, str]) -> dict[str, str]:
"""Environment variables for sampling duration tests."""
env = ompt_base_env.copy()
env.update(
{
"ROCPROFSYS_USE_OMPT": "OFF",
"ROCPROFSYS_USE_SAMPLING": "ON",
"ROCPROFSYS_USE_PROCESS_SAMPLING": "OFF",
"ROCPROFSYS_SAMPLING_FREQ": "100",
"ROCPROFSYS_SAMPLING_DELAY": "0.1",
"ROCPROFSYS_SAMPLING_DURATION": "0.25",
"ROCPROFSYS_SAMPLING_CPUTIME": "ON",
"ROCPROFSYS_SAMPLING_REALTIME": "ON",
"ROCPROFSYS_SAMPLING_CPUTIME_FREQ": "1000",
"ROCPROFSYS_SAMPLING_REALTIME_FREQ": "500",
"ROCPROFSYS_MONOCHROME": "ON",
}
)
return env
@pytest.fixture
def ompt_target_env(ompt_base_env: dict[str, str]) -> dict[str, str]:
"""Environment variables for OpenMP target (GPU) tests."""
env = ompt_base_env.copy()
env["ROCPROFSYS_ROCM_DOMAINS"] = "hip_api,hsa_api,kernel_dispatch"
return env
@pytest.fixture
def ompt_no_tmp_env(ompt_base_env: dict[str, str]) -> dict[str, str]:
"""Environment variables for no-tmp-files tests."""
env = ompt_base_env.copy()
env.update(
{
"ROCPROFSYS_USE_OMPT": "OFF",
"ROCPROFSYS_USE_SAMPLING": "ON",
"ROCPROFSYS_USE_PROCESS_SAMPLING": "OFF",
"ROCPROFSYS_SAMPLING_CPUTIME": "ON",
"ROCPROFSYS_SAMPLING_REALTIME": "OFF",
"ROCPROFSYS_SAMPLING_CPUTIME_FREQ": "700",
"ROCPROFSYS_USE_TEMPORARY_FILES": "OFF",
"ROCPROFSYS_MONOCHROME": "ON",
}
)
return env
@pytest.fixture
def openmp_target_rules(validation_rules_dir: Path) -> list[Path]:
"""Get validation rules for OpenMP target tests."""
rules_dir = validation_rules_dir / "openmp-target"
return [
rules_dir / "kernel-rules.json",
rules_dir / "sdk-metrics-rules.json",
]
# ============================================================================
# Test Class: OpenMP CG Tests
# ============================================================================
class TestOpenMPCG(RocprofsysTest):
BINARY_REWRITE_ARGS = ["-e", "-v", "2", "--instrument-loops"]
DURATION_SAMPLING_PASS_REGEX = [
r"Sampler for thread 0 will be triggered 1000\.0x per second of CPU-time",
r"Sampler for thread 0 will be triggered 500\.0x per second of wall-time",
r"Sampling will be disabled after 0\.250000 seconds",
r"Sampling duration of 0\.250000 seconds (has elapsed|was interrupted by finalization)\. Shutting down sampling",
r"sampling_percent\.(json|txt)",
r"sampling_cpu_clock\.(json|txt)",
r"sampling_wall_clock\.(json|txt)",
]
NOTMP_SAMPLING_FILE_REGEX = [
r"sampling_percent\.(json|txt)",
r"sampling_cpu_clock\.(json|txt)",
r"sampling_wall_clock\.(json|txt)",
]
@pytest.mark.timeout(180)
@pytest.mark.parametrize("mode", ["sampling", "binary_rewrite"])
def test(self, mode, ompt_base_env):
env = ompt_base_env.copy()
env["ROCPROFSYS_USE_SAMPLING"] = "OFF"
env["ROCPROFSYS_COUT_OUTPUT"] = "ON"
result = self.run_test(
mode,
"openmp-cg",
env=env,
binary_rewrite_args=self.BINARY_REWRITE_ARGS,
)
self.assert_regex(result)
@pytest.mark.sampling_duration
def test_sampling_duration(self, ompt_sampling_env):
result = self.run_test(
"sampling",
target="openmp-cg",
env=ompt_sampling_env,
)
self.assert_regex(result, pass_regex=self.DURATION_SAMPLING_PASS_REGEX)
@pytest.mark.no_tmp_files
def test_no_tmp_files(self, ompt_no_tmp_env):
result = self.run_test(
"sampling",
target="openmp-cg",
env=ompt_no_tmp_env,
)
self.assert_regex(result, pass_regex=self.NOTMP_SAMPLING_FILE_REGEX)
self.assert_perfetto(result)
# ============================================================================
# Test Class: OpenMP LU Tests
# ============================================================================
class TestOpenMPLU(RocprofsysTest):
BINARY_REWRITE_ARGS = ["-e", "-v", "2", "--instrument-loops"]
BINARY_REWRITE_PASS_REGEX = ["\\|_omp_"]
BINARY_REWRITE_FAIL_REGEX = ["0 instrumented loops in procedure"]
DURATION_SAMPLING_PASS_REGEX = [
r"Sampler for thread 0 will be triggered 1000\.0x per second of CPU-time",
r"Sampler for thread 0 will be triggered 500\.0x per second of wall-time",
r"Sampling will be disabled after 0\.250000 seconds",
r"Sampling duration of 0\.250000 seconds (has elapsed|was interrupted by finalization)\. Shutting down sampling",
r"sampling_percent\.(json|txt)",
r"sampling_cpu_clock\.(json|txt)",
r"sampling_wall_clock\.(json|txt)",
]
NOTMP_SAMPLING_FILE_REGEX = [
r"sampling_percent\.(json|txt)",
r"sampling_cpu_clock\.(json|txt)",
r"sampling_wall_clock\.(json|txt)",
]
@pytest.mark.timeout(180)
@pytest.mark.parametrize("mode", ["baseline", "sampling", "binary_rewrite"])
def test(self, mode, ompt_base_env):
env = ompt_base_env.copy()
env["ROCPROFSYS_USE_SAMPLING"] = "ON"
env["ROCPROFSYS_SAMPLING_FREQ"] = "50"
env["ROCPROFSYS_COUT_OUTPUT"] = "ON"
result = self.run_test(
mode,
"openmp-lu",
env=env,
binary_rewrite_args=self.BINARY_REWRITE_ARGS,
)
self.assert_regex(
result,
mode,
binary_rewrite_pass_regex=self.BINARY_REWRITE_PASS_REGEX,
binary_rewrite_fail_regex=self.BINARY_REWRITE_FAIL_REGEX,
)
@pytest.mark.sampling_duration
def test_sampling_duration(self, ompt_sampling_env):
result = self.run_test(
"sampling",
target="openmp-lu",
env=ompt_sampling_env,
)
self.assert_regex(result, pass_regex=self.DURATION_SAMPLING_PASS_REGEX)
# ============================================================================
# Test Class: OpenMP Target (GPU) Tests
# ============================================================================
@pytest.mark.build_only
@pytest.mark.rocm
@pytest.mark.gpu
@pytest.mark.class_name("openmp-target")
class TestOpenMPTarget(RocprofsysTest):
@pytest.mark.parametrize(
"mode",
[
"baseline",
pytest.param("sampling", marks=pytest.mark.rocpd("ompt_target_env")),
"sys_run",
],
)
def test(self, mode, ompt_target_env, openmp_target_rules):
result = self.run_test(mode, "openmp-target", env=ompt_target_env)
self.assert_regex(result)
if mode == "sampling":
self.assert_rocpd(result, rules_files=openmp_target_rules)
self.assert_perfetto(
result,
subtest_name="Perfetto Kernel Dispatch Validation",
categories=["rocm_kernel_dispatch"],
label_substrings=[
"Z4vmulIiEvPT_S1_S1_i_l51.kd",
"Z4vmulIfEvPT_S1_S1_i_l51.kd",
"Z4vmulIdEvPT_S1_S1_i_l51.kd",
],
counts=[4, 4, 4],
)
# ============================================================================
# Test Class: OpenMP Fortran Tests
# ============================================================================
@pytest.mark.fortran
@pytest.mark.class_name("openmp-fortran")
class TestOpenMPFortran(RocprofsysTest):
BINARY_REWRITE_ARGS = ["-e", "-v", "2", "--instrument-loops"]
RUNTIME_INSTRUMENT_ARGS = ["-e", "-v", "2", "--label", "return", "args"]
@pytest.mark.parametrize(
"mode",
["baseline", "sampling", "binary_rewrite", "runtime_instrument", "sys_run"],
)
def test_host(self, mode, ompt_base_env):
env = ompt_base_env.copy()
env["ROCPROFSYS_COUT_OUTPUT"] = "ON"
result = self.run_test(
mode,
"openmp-fortran-host",
env=env,
binary_rewrite_args=self.BINARY_REWRITE_ARGS,
runtime_instrument_args=self.RUNTIME_INSTRUMENT_ARGS,
)
self.assert_regex(
result,
mode,
binary_rewrite_pass_regex=["omp_parallel"],
runtime_instrument_pass_regex=["omp_parallel"],
sys_run_pass_regex=["omp_parallel"],
)
@pytest.mark.parametrize(
"mode",
[
"baseline",
"sampling",
"binary_rewrite",
"sys_run",
pytest.param(
"runtime_instrument",
marks=[
pytest.mark.slow,
pytest.mark.serialize,
],
),
],
)
@pytest.mark.gpu
def test_offload(self, mode, ompt_target_env):
env = ompt_target_env.copy()
env["ROCPROFSYS_COUT_OUTPUT"] = "ON"
# libomptarget exceeds the default --max-library-functions threshold and
# would normally be skipped. Force it to be kept via module-include
runtime_instrument_args = self.RUNTIME_INSTRUMENT_ARGS + [
"-MI",
"libomptarget",
]
result = self.run_test(
mode,
"openmp-fortran-offload",
env=env,
binary_rewrite_args=self.BINARY_REWRITE_ARGS,
runtime_instrument_args=runtime_instrument_args,
check_target_arch=True,
)
self.assert_regex(
result,
mode,
binary_rewrite_pass_regex=["omp_offloading"],
runtime_instrument_pass_regex=["omp_offloading"],
sys_run_pass_regex=["omp_offloading"],
)