diff --git a/source/adapters/hip/CMakeLists.txt b/source/adapters/hip/CMakeLists.txt index 2f205d84e6..3be96278e1 100644 --- a/source/adapters/hip/CMakeLists.txt +++ b/source/adapters/hip/CMakeLists.txt @@ -3,7 +3,7 @@ # See LICENSE.TXT # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(HIP_DIR "${SYCL_ADAPTER_DIR}/sycl/plugins/unified_runtime/ur/adapters/hip") +set(HIP_DIR "${SYCL_ADAPTER_DIR}/sycl/plugins/unified_runtime/ur/adapters/hip" CACHE PATH "HIP adapter directory") set(TARGET_NAME ur_adapter_hip) diff --git a/test/conformance/adapters/hip/CMakeLists.txt b/test/conformance/adapters/hip/CMakeLists.txt index 8cbd4c19ac..c834361dc2 100644 --- a/test/conformance/adapters/hip/CMakeLists.txt +++ b/test/conformance/adapters/hip/CMakeLists.txt @@ -8,8 +8,12 @@ add_conformance_test_with_devices_environment(adapter-hip hip_urContextGetNativeHandle.cpp hip_urDeviceGetNativeHandle.cpp hip_urEventGetNativeHandle.cpp + test_context.cpp ) target_link_libraries(test-adapter-hip PRIVATE rocmdrv) +target_include_directories(test-adapter-hip PRIVATE ${HIP_DIR} "${HIP_DIR}/../../..") +# TODO - remove as part of #789 +target_compile_definitions(test-adapter-hip PRIVATE UR_INCLUDE_HANDLE_IMPLEMENTATION_OVERLOADS) if(UR_HIP_PLATFORM STREQUAL "AMD") target_compile_definitions(test-adapter-hip PRIVATE __HIP_PLATFORM_AMD__) diff --git a/test/conformance/adapters/hip/hip_fixtures.h b/test/conformance/adapters/hip/hip_fixtures.h index 077ab28b71..f982cc0490 100644 --- a/test/conformance/adapters/hip/hip_fixtures.h +++ b/test/conformance/adapters/hip/hip_fixtures.h @@ -37,8 +37,7 @@ struct ResultHip { #endif // EXPECT_EQ_RESULT_HIP #ifndef EXPECT_SUCCESS_HIP -#define EXPECT_SUCCESS_HIP(ACTUAL) \ - EXPECT_EQ_RESULT_HIP(UR_RESULT_SUCCESS, ACTUAL) +#define EXPECT_SUCCESS_HIP(ACTUAL) EXPECT_EQ_RESULT_HIP(hipSuccess, ACTUAL) #endif // EXPECT_EQ_RESULT_HIP #endif // UR_TEST_CONFORMANCE_ADAPTERS_HIP_FIXTURES_H_INCLUDED diff --git a/test/conformance/adapters/hip/test_context.cpp b/test/conformance/adapters/hip/test_context.cpp new file mode 100644 index 0000000000..1d538a738b --- /dev/null +++ b/test/conformance/adapters/hip/test_context.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2022-2023 Intel Corporation +// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions. +// See LICENSE.TXT +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#include "context.hpp" +#include "hip_fixtures.h" +#include "queue.hpp" + +using urHipContextTest = uur::urDeviceTest; +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urHipContextTest); + +TEST_P(urHipContextTest, ActiveContexts) { + ur_context_handle_t context = nullptr; + ASSERT_SUCCESS(urContextCreate(1, &device, nullptr, &context)); + ASSERT_NE(context, nullptr); + + ur_queue_handle_t queue = nullptr; + ASSERT_SUCCESS(urQueueCreate(context, device, nullptr, &queue)); + ASSERT_NE(queue, nullptr); + + // ensure that the queue has the correct context + ASSERT_EQ(context, queue->getContext()); + + // check that the current context is the active HIP context + hipCtx_t hipContext = nullptr; + ASSERT_SUCCESS_HIP(hipCtxGetCurrent(&hipContext)); + ASSERT_NE(hipContext, nullptr); + ASSERT_EQ(hipContext, context->getDevice()->getNativeContext()); + + ASSERT_SUCCESS(urQueueRelease(queue)); + ASSERT_SUCCESS(urContextRelease(context)); +} + +TEST_P(urHipContextTest, ActiveContextsThreads) { + ur_context_handle_t context1 = nullptr; + ASSERT_SUCCESS(urContextCreate(1, &device, nullptr, &context1)); + ASSERT_NE(context1, nullptr); + + ur_context_handle_t context2 = nullptr; + ASSERT_SUCCESS(urContextCreate(1, &device, nullptr, &context2)); + ASSERT_NE(context2, nullptr); + + // setup synchronization + std::mutex mtx; + std::condition_variable cv; + bool released = false; + bool thread_done = false; + + auto test_thread = std::thread([&] { + hipCtx_t current = nullptr; + ur_queue_handle_t queue = nullptr; + ASSERT_SUCCESS(urQueueCreate(context1, device, nullptr, &queue)); + ASSERT_NE(queue, nullptr); + + // ensure queue has the correct context + ASSERT_EQ(queue->getContext(), context1); + + // check that the first context is now the active HIP context + ASSERT_SUCCESS_HIP(hipCtxGetCurrent(¤t)); + ASSERT_EQ(current, context1->getDevice()->getNativeContext()); + + ASSERT_SUCCESS(urQueueRelease(queue)); + + // mark the first set of processing as done and notify the main thread + { + std::unique_lock lock(mtx); + thread_done = true; + } + cv.notify_one(); + + // wait for main thread to release the first context + { + std::unique_lock lock(mtx); + cv.wait(lock, [&] { return released; }); + } + + // create a queue with the 2nd context + queue = nullptr; + ASSERT_SUCCESS(urQueueCreate(context2, device, nullptr, &queue)); + ASSERT_NE(queue, nullptr); + + // ensure the queue has the correct context + ASSERT_EQ(queue->getContext(), context2); + + // check that the second context is now the active HIP context + ASSERT_SUCCESS_HIP(hipCtxGetCurrent(¤t)); + ASSERT_EQ(current, context2->getDevice()->getNativeContext()); + + ASSERT_SUCCESS(urQueueRelease(queue)); + }); + + // wait for the thread to be done with the first queue + std::unique_lock lock(mtx); + cv.wait(lock, [&] { return thread_done; }); + ASSERT_SUCCESS(urContextRelease(context1)); + + released = true; + lock.unlock(); + cv.notify_one(); + + // wait for thread to finish + test_thread.join(); + + ASSERT_SUCCESS(urContextRelease(context2)); +} +#pragma GCC diagnostic pop