Skip to content

Commit

Permalink
[CUDA] Return error on silently failing urEventGetInfo queries for in…
Browse files Browse the repository at this point in the history
…terop created events
  • Loading branch information
GeorgeWeb committed Feb 29, 2024
1 parent e0393a4 commit ed85be9
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 17 deletions.
31 changes: 28 additions & 3 deletions source/adapters/cuda/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <cassert>
#include <cuda.h>
#include <memory>

ur_event_handle_t_::ur_event_handle_t_(ur_command_t Type,
ur_context_handle_t Context,
Expand Down Expand Up @@ -162,11 +163,26 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventGetInfo(ur_event_handle_t hEvent,
size_t propValueSize,
void *pPropValue,
size_t *pPropValueSizeRet) {
#ifndef NDEBUG
UR_ASSERT(hEvent, UR_RESULT_ERROR_INVALID_NULL_HANDLE);
#endif

UrReturnHelper ReturnValue(propValueSize, pPropValue, pPropValueSizeRet);

switch (propName) {
case UR_EVENT_INFO_COMMAND_QUEUE:
case UR_EVENT_INFO_COMMAND_QUEUE: {
// If the runtime owns the native handle, we have reference to the queue.
// Otherwise, the event handle comes from an interop API with no RT refs.
if (!hEvent->backendHasOwnership()) {
setErrorMessage("Command queue info cannot be queried for the event. The "
"event object was created from a native event and has no "
"valid reference to a command queue.",
UR_RESULT_ERROR_INVALID_VALUE);
return UR_RESULT_ERROR_ADAPTER_SPECIFIC;
}
assert(hEvent->getQueue());
return ReturnValue(hEvent->getQueue());
}
case UR_EVENT_INFO_COMMAND_TYPE:
return ReturnValue(hEvent->getCommandType());
case UR_EVENT_INFO_REFERENCE_COUNT:
Expand Down Expand Up @@ -283,8 +299,17 @@ UR_APIEXPORT ur_result_t UR_APICALL urEventCreateWithNativeHandle(

std::unique_ptr<ur_event_handle_t_> EventPtr{nullptr};

*phEvent = ur_event_handle_t_::makeWithNative(
hContext, reinterpret_cast<CUevent>(hNativeEvent));
try {
EventPtr =
std::unique_ptr<ur_event_handle_t_>(ur_event_handle_t_::makeWithNative(
hContext, reinterpret_cast<CUevent>(hNativeEvent)));
} catch (const std::bad_alloc &) {
return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY;
} catch (...) {
return UR_RESULT_ERROR_UNKNOWN;
}

*phEvent = EventPtr.release();

return UR_RESULT_SUCCESS;
}
1 change: 1 addition & 0 deletions test/adapters/cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_adapter_test(cuda
urEventCreateWithNativeHandle.cpp
kernel_tests.cpp
memory_tests.cpp
event_tests.cpp
ENVIRONMENT
"UR_ADAPTERS_FORCE_LOAD=\"$<TARGET_FILE:ur_adapter_cuda>\""
)
Expand Down
59 changes: 59 additions & 0 deletions test/adapters/cuda/event_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (C) 2022-2024 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

#include "event.hpp"
#include "fixtures.h"
#include "raii.h"

using cudaEventTest = uur::urContextTest;
UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(cudaEventTest);

// Testing the urEventGetInfo behaviour for natively constructed (Cuda) events.
// Backend interop APIs can lead to creating event objects that are not fully
// initialized. In the Cuda adapter, an event can have nullptr command queue
// because the interop API does not associate a UR-owned queue with the event.
TEST_P(cudaEventTest, GetQueueFromEventCreatedWithNativeHandle) {
RAIICUevent cuda_event;
ASSERT_SUCCESS_CUDA(cuEventCreate(cuda_event.ptr(), CU_EVENT_DEFAULT));

auto native_event = reinterpret_cast<ur_native_handle_t>(cuda_event.get());
uur::raii::Event event{nullptr};
ASSERT_SUCCESS(urEventCreateWithNativeHandle(native_event, context, nullptr,
event.ptr()));
EXPECT_NE(event, nullptr);

size_t ret_size{};
ur_queue_handle_t q{};
ASSERT_EQ_RESULT(urEventGetInfo(event, UR_EVENT_INFO_COMMAND_QUEUE,
sizeof(ur_queue_handle_t), &q, &ret_size),
UR_RESULT_ERROR_ADAPTER_SPECIFIC);
}

TEST_P(cudaEventTest, GetQueueFromNativeEvent) {
// Create a Cuda event object
CUevent cuda_event{nullptr};
ASSERT_SUCCESS_CUDA(cuEventCreate(&cuda_event, CU_EVENT_DEFAULT));

auto native_event = reinterpret_cast<ur_native_handle_t>(cuda_event);

{
uur::raii::Event event{nullptr};
ASSERT_SUCCESS(urEventCreateWithNativeHandle(native_event, context,
nullptr, event.ptr()));
EXPECT_NE(event, nullptr);

size_t ret_size{};
ur_queue_handle_t q{};
ASSERT_EQ_RESULT(urEventGetInfo(event, UR_EVENT_INFO_COMMAND_QUEUE,
sizeof(ur_queue_handle_t), &q,
&ret_size),
UR_RESULT_ERROR_ADAPTER_SPECIFIC);
}

// Release the Cuda event object
if (cuda_event) {
ASSERT_SUCCESS_CUDA(cuEventDestroy(cuda_event));
}
}
25 changes: 25 additions & 0 deletions test/adapters/cuda/raii.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2022-2024 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

#ifndef UR_TEST_CONFORMANCE_ADAPTERS_CUDA_RAII_H_INCLUDED
#define UR_TEST_CONFORMANCE_ADAPTERS_CUDA_RAII_H_INCLUDED

#include "uur/raii.h"
#include <cuda.h>

struct RAIICUevent {
CUevent handle = nullptr;

~RAIICUevent() {
if (handle) {
cuEventDestroy(handle);
}
}

CUevent *ptr() { return &handle; }
CUevent get() { return handle; }
};

#endif // UR_TEST_CONFORMANCE_ADAPTERS_CUDA_RAII_H_INCLUDED
15 changes: 1 addition & 14 deletions test/adapters/cuda/urEventCreateWithNativeHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,11 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "fixtures.h"
#include "uur/raii.h"
#include "raii.h"

using urCudaEventCreateWithNativeHandleTest = uur::urQueueTest;
UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urCudaEventCreateWithNativeHandleTest);

struct RAIICUevent {
CUevent handle = nullptr;

~RAIICUevent() {
if (handle) {
cuEventDestroy(handle);
}
}

CUevent *ptr() { return &handle; }
CUevent get() { return handle; }
};

TEST_P(urCudaEventCreateWithNativeHandleTest, Success) {
RAIICUevent cuda_event;
ASSERT_SUCCESS_CUDA(cuEventCreate(cuda_event.ptr(), CU_EVENT_DEFAULT));
Expand Down

0 comments on commit ed85be9

Please sign in to comment.