Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions unified-runtime/test/conformance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ add_subdirectory(queue)
add_subdirectory(sampler)
add_subdirectory(virtual_memory)
add_subdirectory(exp_usm_context_memcpy)
add_subdirectory(exp_graph)

set(TEST_SUBDIRECTORIES_DPCXX
"device_code"
Expand Down
15 changes: 15 additions & 0 deletions unified-runtime/test/conformance/exp_graph/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright (C) 2025 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

add_conformance_devices_test(exp_graph
urEnqueueGraphExp.cpp
urGraphCreateExp.cpp
urGraphDestroy.cpp
urGraphInstantiateGraphExp.cpp
urGraphIsEmptyExp.cpp
urQueueBeginCaptureIntoGraphExp.cpp
urQueueBeginGraphCaptureExp.cpp
urQueueEndGraphCaptureExp.cpp
urQueueIsGraphCaptureEnabledExp.cpp)
130 changes: 130 additions & 0 deletions unified-runtime/test/conformance/exp_graph/fixtures.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (C) 2025 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_CONFORMANCE_GRAPH_FIXTURES_H
#define UR_CONFORMANCE_GRAPH_FIXTURES_H

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

namespace uur {

struct urGraphSupportedExpTest : uur::urQueueTest {
void SetUp() override {
UUR_RETURN_ON_FATAL_FAILURE(urQueueTest::SetUp());

UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}, uur::NativeCPU{},
uur::OpenCL{}, uur::LevelZero{}, uur::LevelZeroV2{});
}
};

struct urGraphExpTest : urGraphSupportedExpTest {
void SetUp() override {
UUR_RETURN_ON_FATAL_FAILURE(urGraphSupportedExpTest::SetUp());

ASSERT_SUCCESS(urGraphCreateExp(context, &graph));
}

void TearDown() override {
if (graph) {
ASSERT_SUCCESS(urGraphDestroyExp(graph));
}

UUR_RETURN_ON_FATAL_FAILURE(urGraphSupportedExpTest::TearDown());
}

ur_exp_graph_handle_t graph = nullptr;
};

struct urGraphPopulatedExpTest : urGraphExpTest {
void SetUp() override {
UUR_RETURN_ON_FATAL_FAILURE(urGraphExpTest::SetUp());

ur_device_usm_access_capability_flags_t deviceUSMSupport = 0;
ASSERT_SUCCESS(uur::GetDeviceUSMDeviceSupport(device, deviceUSMSupport));
if (!deviceUSMSupport) {
GTEST_SKIP() << "Device USM is not supported";
}
uur::generateMemFillPattern(pattern);

ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr,
allocationSize, &deviceMem));

ASSERT_SUCCESS(urQueueBeginCaptureIntoGraphExp(queue, graph));

ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, patternSize,
pattern.data(), allocationSize, 0, nullptr,
fillEvent.ptr()));
ASSERT_SUCCESS(urQueueFinish(queue));

ur_exp_graph_handle_t sameGraph = nullptr;
ASSERT_SUCCESS(urQueueEndGraphCaptureExp(queue, &sameGraph));
ASSERT_EQ(graph, sameGraph);

ASSERT_NO_FATAL_FAILURE(verifyData(false));
}

void TearDown() override {
if (deviceMem) {
ASSERT_SUCCESS(urUSMFree(context, deviceMem));
}

UUR_RETURN_ON_FATAL_FAILURE(urGraphExpTest::TearDown());
}

void verifyData(const bool shouldMatch) {
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, true, hostMem.data(), deviceMem,
allocationSize, 0, nullptr, nullptr));

size_t patternIdx = 0;
for (size_t i = 0; i < allocationSize; ++i) {
uint8_t *hostPtr = hostMem.data();
ASSERT_EQ((*(hostPtr + i) == pattern[patternIdx]), shouldMatch);

++patternIdx;
if (patternIdx % pattern.size() == 0) {
patternIdx = 0;
}
}
}

void resetData() {
const uint8_t zero = 0;
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
allocationSize, 0, nullptr, nullptr));
ASSERT_SUCCESS(urQueueFinish(queue));
}

const size_t allocationSize = 256;
void *deviceMem{nullptr};
std::vector<uint8_t> hostMem = std::vector<uint8_t>(allocationSize);
const size_t patternSize = 64;
std::vector<uint8_t> pattern = std::vector<uint8_t>(patternSize);
uur::raii::Event fillEvent = nullptr;
};

struct urGraphExecutableExpTest : urGraphPopulatedExpTest {
void SetUp() override {
UUR_RETURN_ON_FATAL_FAILURE(urGraphPopulatedExpTest::SetUp());

ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraph));
}

void TearDown() override {
if (exGraph) {
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraph));
}

UUR_RETURN_ON_FATAL_FAILURE(urGraphPopulatedExpTest::TearDown());
}

ur_exp_executable_graph_handle_t exGraph = nullptr;
};

} // namespace uur

#endif // UR_CONFORMANCE_GRAPH_FIXTURES_H
111 changes: 111 additions & 0 deletions unified-runtime/test/conformance/exp_graph/urEnqueueGraphExp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright (C) 2025 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 "fixtures.h"
#include "uur/raii.h"

#include <vector>

using urEnqueueGraphExpTest = uur::urGraphExecutableExpTest;

UUR_INSTANTIATE_DEVICE_TEST_SUITE(urEnqueueGraphExpTest);

TEST_P(urEnqueueGraphExpTest, Success) {
verifyData(false);
ASSERT_SUCCESS(urEnqueueGraphExp(queue, exGraph, 0, nullptr, nullptr));
ASSERT_SUCCESS(urQueueFinish(queue));

ASSERT_NO_FATAL_FAILURE(verifyData(true));
}

TEST_P(urEnqueueGraphExpTest, SuccessWithEvent) {
uur::raii::Event graphEvent = nullptr;
ASSERT_SUCCESS(
urEnqueueGraphExp(queue, exGraph, 0, nullptr, graphEvent.ptr()));
ASSERT_SUCCESS(urQueueFlush(queue));
ASSERT_SUCCESS(urEventWait(1, graphEvent.ptr()));
}

TEST_P(urEnqueueGraphExpTest, InvalidNullHandleQueue) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urEnqueueGraphExp(nullptr, exGraph, 0, nullptr, nullptr));
}

TEST_P(urEnqueueGraphExpTest, InvalidNullHandleExGraph) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urEnqueueGraphExp(queue, nullptr, 0, nullptr, nullptr));
}

TEST_P(urEnqueueGraphExpTest, InvalidEventWaitListArray) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST,
urEnqueueGraphExp(queue, nullptr, 1, nullptr, nullptr));
}

TEST_P(urEnqueueGraphExpTest, InvalidEventWaitListSize) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST,
urEnqueueGraphExp(queue, nullptr, 0,
(ur_event_handle_t *)0xC0FFEE, nullptr));
}

TEST_P(urEnqueueGraphExpTest, SuccessMultipleExecutions) {
const size_t numExecutions = 5;

for (size_t i = 0; i < numExecutions; ++i) {
ASSERT_NO_FATAL_FAILURE(verifyData(false));

ASSERT_SUCCESS(urEnqueueGraphExp(queue, exGraph, 0, nullptr, nullptr));
ASSERT_SUCCESS(urQueueFinish(queue));

ASSERT_NO_FATAL_FAILURE(verifyData(true));
ASSERT_NO_FATAL_FAILURE(resetData());
}
}

TEST_P(urEnqueueGraphExpTest, SuccessEventDependant) {
uur::raii::Event fillEvent1 = nullptr;
uur::raii::Event fillEvent2 = nullptr;
uur::raii::Event graphEvent = nullptr;

std::vector<uint8_t> pattern2 = std::vector<uint8_t>(patternSize);
uur::generateMemFillPattern(pattern2);
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, patternSize,
pattern2.data(), allocationSize / 2, 0,
nullptr, fillEvent1.ptr()));
ASSERT_SUCCESS(urEnqueueUSMFill(
queue, static_cast<uint8_t *>(deviceMem) + allocationSize / 2,
patternSize, pattern2.data(), allocationSize / 2, 0, nullptr,
fillEvent2.ptr()));

ur_event_handle_t waitEvents[] = {fillEvent1.get(), fillEvent2.get()};
ASSERT_SUCCESS(
urEnqueueGraphExp(queue, exGraph, 2, waitEvents, graphEvent.ptr()));

ASSERT_SUCCESS(urEventWait(1, graphEvent.ptr()));

ASSERT_NO_FATAL_FAILURE(verifyData(true));
}

TEST_P(urEnqueueGraphExpTest, SuccessEventOrdering) {
uur::raii::Event clearEvent = nullptr;
uur::raii::Event graphEvent = nullptr;
uur::raii::Event verifyEvent = nullptr;

const uint8_t zero = 0;
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
allocationSize, 0, nullptr,
clearEvent.ptr()));

ASSERT_SUCCESS(
urEnqueueGraphExp(queue, exGraph, 1, clearEvent.ptr(), graphEvent.ptr()));

ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
allocationSize, 1, graphEvent.ptr(),
verifyEvent.ptr()));

ASSERT_SUCCESS(urEventWait(1, verifyEvent.ptr()));

ASSERT_NO_FATAL_FAILURE(verifyData(false));
}
28 changes: 28 additions & 0 deletions unified-runtime/test/conformance/exp_graph/urGraphCreateExp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2025 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 "fixtures.h"

using urGraphDestroyExpTest = uur::urGraphSupportedExpTest;

UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphDestroyExpTest);

TEST_P(urGraphDestroyExpTest, Success) {
ur_exp_graph_handle_t graph = nullptr;
ASSERT_SUCCESS(urGraphCreateExp(context, &graph));
ASSERT_SUCCESS(urGraphDestroyExp(graph));
}

TEST_P(urGraphDestroyExpTest, InvalidNullHandleContext) {
ur_exp_graph_handle_t graph = nullptr;
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urGraphCreateExp(nullptr, &graph));
}

TEST_P(urGraphDestroyExpTest, InvalidNullPtrGraph) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER,
urGraphCreateExp(context, nullptr));
}
18 changes: 18 additions & 0 deletions unified-runtime/test/conformance/exp_graph/urGraphDestroy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) 2025 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 "fixtures.h"

using urGraphDestroyExpTest = uur::urGraphSupportedExpTest;

UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphDestroyExpTest);

/* TODO: Test destroying graph with active executable graph instances. */

TEST_P(urGraphDestroyExpTest, InvalidNullHandle) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urGraphDestroyExp(nullptr));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (C) 2025 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 "fixtures.h"

using urGraphInstantiateGraphExpTest = uur::urGraphExpTest;

UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphInstantiateGraphExpTest);

TEST_P(urGraphInstantiateGraphExpTest, InvalidEmptyGraph) {
ur_exp_executable_graph_handle_t exGraph = nullptr;
ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraph));
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraph));
}

TEST_P(urGraphInstantiateGraphExpTest, InvalidNullHandleGraph) {
ur_exp_executable_graph_handle_t exGraph = nullptr;
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
urGraphInstantiateGraphExp(nullptr, &exGraph));
}

TEST_P(urGraphInstantiateGraphExpTest, InvalidNullPtrExGraph) {
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER,
urGraphInstantiateGraphExp(graph, nullptr));
}

using urGraphInstantiatePopulatedGraphExpTest = uur::urGraphPopulatedExpTest;

UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphInstantiatePopulatedGraphExpTest);

TEST_P(urGraphInstantiatePopulatedGraphExpTest, SuccessMultipleInstantiations) {
const size_t numInstances = 5;
std::vector<ur_exp_executable_graph_handle_t> exGraphs(numInstances, nullptr);

for (size_t i = 0; i < numInstances; ++i) {
ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraphs[i]));
ASSERT_NE(exGraphs[i], nullptr);
}

for (size_t i = 0; i < numInstances; ++i) {
for (size_t j = i + 1; j < numInstances; ++j) {
ASSERT_NE(exGraphs[i], exGraphs[j]);
}
}

for (size_t i = 0; i < numInstances; ++i) {
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraphs[i]));
}
}
Loading