From 6d856ddf53f09ba4c3c6376fbd2d2c904606b3c6 Mon Sep 17 00:00:00 2001 From: Laurent Morichetti Date: Thu, 28 Jul 2022 23:58:09 -0700 Subject: [PATCH] Add a HIP domain callback stress test This test verifies that callback argument matches the callback function as a race condition while setting and reading the pair could result in mismatched arguments. Change-Id: I2fe49d98d19bb780b6956ea6718762cfa0de93f8 [ROCm/roctracer commit: 602c67ee0028c3fd30996f64c3c1a842f09c4cfc] --- .../test/stress/set_hip_api_callback.cpp | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 projects/roctracer/test/stress/set_hip_api_callback.cpp diff --git a/projects/roctracer/test/stress/set_hip_api_callback.cpp b/projects/roctracer/test/stress/set_hip_api_callback.cpp new file mode 100644 index 0000000000..46be856551 --- /dev/null +++ b/projects/roctracer/test/stress/set_hip_api_callback.cpp @@ -0,0 +1,81 @@ +/* Copyright (c) 2022 Advanced Micro Devices, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include +#include + +// Create as many threads as there are cores, half changing the hipSetDevice roctracer API callback +// and argument, and the other half calling hipSetDevice, all running concurrently. If there is a +// race when setting the API callback and argument, the test aborts. + +constexpr int N_ITER = 1000000; + +namespace { + +std::ifstream cpuinfo("/proc/cpuinfo"); +const int num_cpu_cores = + std::count(std::istream_iterator(cpuinfo), std::istream_iterator(), + std::string("processor")); + +template void callback(uint32_t, uint32_t, const void*, void* arg) { + // The callback argument must match the callback function. + if (arg != callback) abort(); +} + +template constexpr auto create_callbacks(std::index_sequence) { + return std::array{&callback...}; +} + +template constexpr auto create_callbacks() { + return create_callbacks(std::make_index_sequence{}); +} + +constexpr auto callbacks = create_callbacks<128>(); + +} // namespace + +int main() { + if (hipSetDevice(0) != hipSuccess) abort(); + + std::vector threads; + for (int i = 0; i < std::max(2, num_cpu_cores / 2); ++i) { + threads.emplace_back( + [](auto callback) { + for (int n = 0; n < N_ITER; ++n) + roctracer_enable_op_callback(ACTIVITY_DOMAIN_HIP_API, HIP_API_ID_hipSetDevice, callback, + reinterpret_cast(callback)); + }, + callbacks[i % callbacks.size()]); + threads.emplace_back([]() { + for (int n = 0; n < N_ITER; ++n) + if (hipSetDevice(0) != hipSuccess) abort(); + }); + } + for (auto&& thread : threads) thread.join(); + + roctracer_disable_domain_callback(ACTIVITY_DOMAIN_HIP_API); + return 0; +} \ No newline at end of file