hip-tests: Improve rtc compiler option test#3944
hip-tests: Improve rtc compiler option test#3944manocharahul wants to merge 10 commits intodevelopfrom
Conversation
143df2e to
0ba363d
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates the HIPRTC compiler-option test suite in hip-tests to be faster and more reliable by reducing redundant work (config reads / kernel launches), tightening specific compiler-option validations (e.g., SLP vectorize disable), and reducing resource/memory leaks via std::vector and additional cleanup calls.
Changes:
- Cache
RtcConfig.jsonparsing to avoid repeated file reads and remove a flaky denormals input case. - Refactor multiple tests to replace dynamic allocations with
std::vectorand add missinghiprtcDestroyProgramcalls on some failure paths. - Adjust SLP vectorize IR-dump based checks and build logic to make runtime assets (headers/config) available from the build tree.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
projects/hip-tests/catch/unit/rtc/RtcUtility.cpp |
Switches config/header path derivation and caches JSON parsing for speed. |
projects/hip-tests/catch/unit/rtc/RtcFunctions.cpp |
Refactors many compiler-option checks to reduce leaks and remove unnecessary kernel launches; updates SLP vectorize IR matching. |
projects/hip-tests/catch/unit/rtc/RtcConfig.json |
Tweaks denormals test inputs to remove a flaky case. |
projects/hip-tests/catch/unit/rtc/CMakeLists.txt |
Adds build-time copying/install wiring for RTC test assets (headers/config). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -1257,6 +1208,7 @@ bool check_undef_macro(const char** Combination_CO, int Combination_CO_size, int | |||
| std::string log(logSize, '\0'); | |||
| HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); | |||
| if (log.find("undeclared identifier")) { | |||
There was a problem hiding this comment.
In the Combination_CO path, if (log.find("undeclared identifier")) is incorrect: std::string::find returns 0 when the substring is at the start (evaluates false) and npos when not found (evaluates true). This can cause the test to pass when the expected error is missing, and fail when it is present at position 0. Compare the result against std::string::npos (as done in the non-combination branch).
| if (log.find("undeclared identifier")) { | |
| if (log.find("undeclared identifier") != std::string::npos) { |
| } | ||
| HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
hiprtcDestroyProgram(&prog) was added on compile failure paths, but on the success path this function returns without destroying prog. This leaks HIPRTC program resources across test cases; please ensure hiprtcDestroyProgram is called on all paths (e.g., before the final return 1, or via an RAII/scope-guard).
| HIPRTC_CHECK(hiprtcGetProgramLog(prog, &log[0])); | ||
| WARN(log); | ||
| } | ||
| HIPRTC_CHECK(hiprtcDestroyProgram(&prog)); | ||
| return 0; |
There was a problem hiding this comment.
hiprtcDestroyProgram(&prog) is only called on compile failure paths here; on the successful path, prog is never destroyed before returning. Please destroy prog (and ideally use RAII) on all exit paths to avoid leaking HIPRTC program state during the test run.
| const std::string search_string = "contract half"; | ||
| size_t start = 0; | ||
| while ((start = data.find(search_string, start)) != std::string::npos) { | ||
| ++times; | ||
| ++start; |
There was a problem hiding this comment.
The disabled-SLP check searches for the very broad substring "contract half" but the test expectation is about the specific vector-contract pattern (previous warnings also referenced fadd contract <2 x half>). This broad match can over-count unrelated instructions and make the test flaky. Prefer searching for the exact IR pattern you intend to validate (and keep the diagnostic messages consistent with the searched string/expectation).
| std::string config_path = wor_dir + "/RtcConfig.json"; | ||
| std::ifstream json_file(config_path.c_str()); | ||
| if (!json_file.is_open()) { | ||
| FAIL("Error loading config.json"); | ||
| } |
There was a problem hiding this comment.
This path construction depends on finding the literal substring "build" in the current working directory and then concatenates a relative path without a path separator. If "build" is not present (or is named differently), config_path becomes invalid and the test will fail. Use std::filesystem::path joins and resolve the JSON path deterministically (e.g., relative to CMAKE_CURRENT_BINARY_DIR/a copied file, or by searching known candidate locations).
| std::string retrived_CO = get_string_parameters("compiler_option", "header_dir"); | ||
| std::string str = "pwd"; | ||
| const char* cmd = str.c_str(); | ||
| CaptureStream capture(stdout); | ||
| capture.Begin(); | ||
| system(cmd); | ||
| capture.End(); | ||
| std::string wor_dir = capture.getData(); | ||
| std::string break_dir = wor_dir.substr(0, wor_dir.find("build")); | ||
| std::string append_str = "catch/unit/rtc/headers"; | ||
| std::string CO = retrived_CO + " " + break_dir + append_str; | ||
| std::string wor_dir = std::filesystem::current_path().string(); | ||
| std::string append_str = "/headers"; | ||
| std::string CO = retrived_CO + " " + wor_dir + append_str; | ||
| hold_CO[i] = CO; | ||
| } else if (combi_vec_list[i] == "architecture") { |
There was a problem hiding this comment.
Similar to the JSON path logic, deriving the headers path by truncating current_path() at the first "build" occurrence is brittle and can break depending on the build directory name/layout. Consider resolving the headers directory via std::filesystem::path relative to a known location (e.g., current binary dir after copy) instead of string searching.
| static picojson::array cached_blocks; | ||
| static bool initialized = false; | ||
| if (!initialized) { | ||
| std::string wor_dir = std::filesystem::current_path().string(); |
There was a problem hiding this comment.
getblock_fromconfig() uses static bool initialized as a manual guard. If the test runner executes test cases concurrently in-process, this introduces a data race (two threads can observe initialized == false and both initialize). Prefer std::once_flag/std::call_once or a single static const initialized via a lambda to get thread-safe one-time initialization.
Motivation
Technical Details
JIRA ID
https://amd-hub.atlassian.net/browse/ROCM-466
Test Plan
Test Result
Submission Checklist