Skip to content

Commit bc09b7b

Browse files
committed
[UR] Add initial graph record & replay tests
1 parent 041422f commit bc09b7b

12 files changed

+528
-0
lines changed

unified-runtime/test/conformance/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ add_subdirectory(queue)
7070
add_subdirectory(sampler)
7171
add_subdirectory(virtual_memory)
7272
add_subdirectory(exp_usm_context_memcpy)
73+
add_subdirectory(exp_graph)
7374

7475
set(TEST_SUBDIRECTORIES_DPCXX
7576
"device_code"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (C) 2025 Intel Corporation
2+
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
# See LICENSE.TXT
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
add_conformance_devices_test(exp_graph
7+
urEnqueueGraphExp.cpp
8+
urGraphCreateExp.cpp
9+
urGraphDestroy.cpp
10+
urGraphInstantiateGraphExp.cpp
11+
urGraphIsEmptyExp.cpp
12+
urQueueBeginCaptureIntoGraphExp.cpp
13+
urQueueBeginGraphCaptureExp.cpp
14+
urQueueEndGraphCaptureExp.cpp
15+
urQueueIsGraphCaptureEnabledExp.cpp)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
//
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
7+
#ifndef UR_CONFORMANCE_GRAPH_FIXTURES_H
8+
#define UR_CONFORMANCE_GRAPH_FIXTURES_H
9+
10+
#include "uur/fixtures.h"
11+
#include "uur/known_failure.h"
12+
#include "uur/raii.h"
13+
14+
namespace uur {
15+
16+
struct urGraphSupportedExpTest : uur::urQueueTest {
17+
void SetUp() override {
18+
UUR_RETURN_ON_FATAL_FAILURE(urQueueTest::SetUp());
19+
20+
UUR_KNOWN_FAILURE_ON(uur::CUDA{}, uur::HIP{}, uur::NativeCPU{},
21+
uur::OpenCL{}, uur::LevelZero{}, uur::LevelZeroV2{});
22+
}
23+
};
24+
25+
struct urGraphExpTest : urGraphSupportedExpTest {
26+
void SetUp() override {
27+
UUR_RETURN_ON_FATAL_FAILURE(urGraphSupportedExpTest::SetUp());
28+
29+
ASSERT_SUCCESS(urGraphCreateExp(context, &graph));
30+
}
31+
32+
void TearDown() override {
33+
if (graph) {
34+
ASSERT_SUCCESS(urGraphDestroyExp(graph));
35+
}
36+
37+
UUR_RETURN_ON_FATAL_FAILURE(urGraphSupportedExpTest::TearDown());
38+
}
39+
40+
ur_exp_graph_handle_t graph = nullptr;
41+
};
42+
43+
struct urGraphPopulatedExpTest : urGraphExpTest {
44+
void SetUp() override {
45+
UUR_RETURN_ON_FATAL_FAILURE(urGraphExpTest::SetUp());
46+
47+
ur_device_usm_access_capability_flags_t deviceUSMSupport = 0;
48+
ASSERT_SUCCESS(uur::GetDeviceUSMDeviceSupport(device, deviceUSMSupport));
49+
if (!deviceUSMSupport) {
50+
GTEST_SKIP() << "Device USM is not supported";
51+
}
52+
uur::generateMemFillPattern(pattern);
53+
54+
ASSERT_SUCCESS(urUSMDeviceAlloc(context, device, nullptr, nullptr,
55+
allocationSize, &deviceMem));
56+
57+
ASSERT_SUCCESS(urQueueBeginCaptureIntoGraphExp(queue, graph));
58+
59+
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, patternSize,
60+
pattern.data(), allocationSize, 0, nullptr,
61+
fillEvent.ptr()));
62+
ASSERT_SUCCESS(urQueueFinish(queue));
63+
64+
ur_exp_graph_handle_t sameGraph = nullptr;
65+
ASSERT_SUCCESS(urQueueEndGraphCaptureExp(queue, &sameGraph));
66+
ASSERT_EQ(graph, sameGraph);
67+
68+
ASSERT_NO_FATAL_FAILURE(verifyData(false));
69+
}
70+
71+
void TearDown() override {
72+
if (deviceMem) {
73+
ASSERT_SUCCESS(urUSMFree(context, deviceMem));
74+
}
75+
76+
UUR_RETURN_ON_FATAL_FAILURE(urGraphExpTest::TearDown());
77+
}
78+
79+
void verifyData(const bool shouldMatch) {
80+
ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, true, hostMem.data(), deviceMem,
81+
allocationSize, 0, nullptr, nullptr));
82+
83+
size_t patternIdx = 0;
84+
for (size_t i = 0; i < allocationSize; ++i) {
85+
uint8_t *hostPtr = hostMem.data();
86+
ASSERT_EQ((*(hostPtr + i) == pattern[patternIdx]), shouldMatch);
87+
88+
++patternIdx;
89+
if (patternIdx % pattern.size() == 0) {
90+
patternIdx = 0;
91+
}
92+
}
93+
}
94+
95+
void resetData() {
96+
const uint8_t zero = 0;
97+
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
98+
allocationSize, 0, nullptr, nullptr));
99+
ASSERT_SUCCESS(urQueueFinish(queue));
100+
}
101+
102+
const size_t allocationSize = 256;
103+
void *deviceMem{nullptr};
104+
std::vector<uint8_t> hostMem = std::vector<uint8_t>(allocationSize);
105+
const size_t patternSize = 64;
106+
std::vector<uint8_t> pattern = std::vector<uint8_t>(patternSize);
107+
uur::raii::Event fillEvent = nullptr;
108+
};
109+
110+
struct urGraphExecutableExpTest : urGraphPopulatedExpTest {
111+
void SetUp() override {
112+
UUR_RETURN_ON_FATAL_FAILURE(urGraphPopulatedExpTest::SetUp());
113+
114+
ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraph));
115+
}
116+
117+
void TearDown() override {
118+
if (exGraph) {
119+
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraph));
120+
}
121+
122+
UUR_RETURN_ON_FATAL_FAILURE(urGraphPopulatedExpTest::TearDown());
123+
}
124+
125+
ur_exp_executable_graph_handle_t exGraph = nullptr;
126+
};
127+
128+
} // namespace uur
129+
130+
#endif // UR_CONFORMANCE_GRAPH_FIXTURES_H
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
//
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
7+
#include "fixtures.h"
8+
#include "uur/raii.h"
9+
10+
#include <vector>
11+
12+
using urEnqueueGraphExpTest = uur::urGraphExecutableExpTest;
13+
14+
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urEnqueueGraphExpTest);
15+
16+
TEST_P(urEnqueueGraphExpTest, Success) {
17+
verifyData(false);
18+
ASSERT_SUCCESS(urEnqueueGraphExp(queue, exGraph, 0, nullptr, nullptr));
19+
ASSERT_SUCCESS(urQueueFinish(queue));
20+
21+
ASSERT_NO_FATAL_FAILURE(verifyData(true));
22+
}
23+
24+
TEST_P(urEnqueueGraphExpTest, SuccessWithEvent) {
25+
uur::raii::Event graphEvent = nullptr;
26+
ASSERT_SUCCESS(
27+
urEnqueueGraphExp(queue, exGraph, 0, nullptr, graphEvent.ptr()));
28+
ASSERT_SUCCESS(urQueueFlush(queue));
29+
ASSERT_SUCCESS(urEventWait(1, graphEvent.ptr()));
30+
}
31+
32+
TEST_P(urEnqueueGraphExpTest, InvalidNullHandleQueue) {
33+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
34+
urEnqueueGraphExp(nullptr, exGraph, 0, nullptr, nullptr));
35+
}
36+
37+
TEST_P(urEnqueueGraphExpTest, InvalidNullHandleExGraph) {
38+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
39+
urEnqueueGraphExp(queue, nullptr, 0, nullptr, nullptr));
40+
}
41+
42+
TEST_P(urEnqueueGraphExpTest, InvalidEventWaitListArray) {
43+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST,
44+
urEnqueueGraphExp(queue, nullptr, 1, nullptr, nullptr));
45+
}
46+
47+
TEST_P(urEnqueueGraphExpTest, InvalidEventWaitListSize) {
48+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST,
49+
urEnqueueGraphExp(queue, nullptr, 0,
50+
(ur_event_handle_t *)0xC0FFEE, nullptr));
51+
}
52+
53+
TEST_P(urEnqueueGraphExpTest, SuccessMultipleExecutions) {
54+
const size_t numExecutions = 5;
55+
56+
for (size_t i = 0; i < numExecutions; ++i) {
57+
ASSERT_NO_FATAL_FAILURE(verifyData(false));
58+
59+
ASSERT_SUCCESS(urEnqueueGraphExp(queue, exGraph, 0, nullptr, nullptr));
60+
ASSERT_SUCCESS(urQueueFinish(queue));
61+
62+
ASSERT_NO_FATAL_FAILURE(verifyData(true));
63+
ASSERT_NO_FATAL_FAILURE(resetData());
64+
}
65+
}
66+
67+
TEST_P(urEnqueueGraphExpTest, SuccessEventDependant) {
68+
uur::raii::Event fillEvent1 = nullptr;
69+
uur::raii::Event fillEvent2 = nullptr;
70+
uur::raii::Event graphEvent = nullptr;
71+
72+
std::vector<uint8_t> pattern2 = std::vector<uint8_t>(patternSize);
73+
uur::generateMemFillPattern(pattern2);
74+
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, patternSize,
75+
pattern2.data(), allocationSize / 2, 0,
76+
nullptr, fillEvent1.ptr()));
77+
ASSERT_SUCCESS(urEnqueueUSMFill(
78+
queue, static_cast<uint8_t *>(deviceMem) + allocationSize / 2,
79+
patternSize, pattern2.data(), allocationSize / 2, 0, nullptr,
80+
fillEvent2.ptr()));
81+
82+
ur_event_handle_t waitEvents[] = {fillEvent1.get(), fillEvent2.get()};
83+
ASSERT_SUCCESS(
84+
urEnqueueGraphExp(queue, exGraph, 2, waitEvents, graphEvent.ptr()));
85+
86+
ASSERT_SUCCESS(urEventWait(1, graphEvent.ptr()));
87+
88+
ASSERT_NO_FATAL_FAILURE(verifyData(true));
89+
}
90+
91+
TEST_P(urEnqueueGraphExpTest, SuccessEventOrdering) {
92+
uur::raii::Event clearEvent = nullptr;
93+
uur::raii::Event graphEvent = nullptr;
94+
uur::raii::Event verifyEvent = nullptr;
95+
96+
const uint8_t zero = 0;
97+
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
98+
allocationSize, 0, nullptr,
99+
clearEvent.ptr()));
100+
101+
ASSERT_SUCCESS(
102+
urEnqueueGraphExp(queue, exGraph, 1, clearEvent.ptr(), graphEvent.ptr()));
103+
104+
ASSERT_SUCCESS(urEnqueueUSMFill(queue, deviceMem, sizeof(zero), &zero,
105+
allocationSize, 1, graphEvent.ptr(),
106+
verifyEvent.ptr()));
107+
108+
ASSERT_SUCCESS(urEventWait(1, verifyEvent.ptr()));
109+
110+
ASSERT_NO_FATAL_FAILURE(verifyData(false));
111+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
//
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
7+
#include "fixtures.h"
8+
9+
using urGraphDestroyExpTest = uur::urGraphSupportedExpTest;
10+
11+
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphDestroyExpTest);
12+
13+
TEST_P(urGraphDestroyExpTest, Success) {
14+
ur_exp_graph_handle_t graph = nullptr;
15+
ASSERT_SUCCESS(urGraphCreateExp(context, &graph));
16+
ASSERT_SUCCESS(urGraphDestroyExp(graph));
17+
}
18+
19+
TEST_P(urGraphDestroyExpTest, InvalidNullHandleContext) {
20+
ur_exp_graph_handle_t graph = nullptr;
21+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
22+
urGraphCreateExp(nullptr, &graph));
23+
}
24+
25+
TEST_P(urGraphDestroyExpTest, InvalidNullPtrGraph) {
26+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER,
27+
urGraphCreateExp(context, nullptr));
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
//
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
7+
#include "fixtures.h"
8+
9+
using urGraphDestroyExpTest = uur::urGraphSupportedExpTest;
10+
11+
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphDestroyExpTest);
12+
13+
/* TODO: Test destroying graph with active executable graph instances. */
14+
15+
TEST_P(urGraphDestroyExpTest, InvalidNullHandle) {
16+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
17+
urGraphDestroyExp(nullptr));
18+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (C) 2025 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
//
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
7+
#include "fixtures.h"
8+
9+
using urGraphInstantiateGraphExpTest = uur::urGraphExpTest;
10+
11+
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphInstantiateGraphExpTest);
12+
13+
TEST_P(urGraphInstantiateGraphExpTest, InvalidEmptyGraph) {
14+
ur_exp_executable_graph_handle_t exGraph = nullptr;
15+
ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraph));
16+
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraph));
17+
}
18+
19+
TEST_P(urGraphInstantiateGraphExpTest, InvalidNullHandleGraph) {
20+
ur_exp_executable_graph_handle_t exGraph = nullptr;
21+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
22+
urGraphInstantiateGraphExp(nullptr, &exGraph));
23+
}
24+
25+
TEST_P(urGraphInstantiateGraphExpTest, InvalidNullPtrExGraph) {
26+
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER,
27+
urGraphInstantiateGraphExp(graph, nullptr));
28+
}
29+
30+
using urGraphInstantiatePopulatedGraphExpTest = uur::urGraphPopulatedExpTest;
31+
32+
UUR_INSTANTIATE_DEVICE_TEST_SUITE(urGraphInstantiatePopulatedGraphExpTest);
33+
34+
TEST_P(urGraphInstantiatePopulatedGraphExpTest, SuccessMultipleInstantiations) {
35+
const size_t numInstances = 5;
36+
std::vector<ur_exp_executable_graph_handle_t> exGraphs(numInstances, nullptr);
37+
38+
for (size_t i = 0; i < numInstances; ++i) {
39+
ASSERT_SUCCESS(urGraphInstantiateGraphExp(graph, &exGraphs[i]));
40+
ASSERT_NE(exGraphs[i], nullptr);
41+
}
42+
43+
for (size_t i = 0; i < numInstances; ++i) {
44+
for (size_t j = i + 1; j < numInstances; ++j) {
45+
ASSERT_NE(exGraphs[i], exGraphs[j]);
46+
}
47+
}
48+
49+
for (size_t i = 0; i < numInstances; ++i) {
50+
ASSERT_SUCCESS(urGraphExecutableGraphDestroyExp(exGraphs[i]));
51+
}
52+
}

0 commit comments

Comments
 (0)