Skip to content

Commit 08a08ab

Browse files
committed
[UR][L0] Extend memory residency tests with P2P checks
Fill in the three placeholder multi-device tests in memory_residency.cpp to verify the peer-access-driven residency behaviour introduced by the parent commit. allocationInitiallyAbsentOnPeer Allocates USM memory on devices[0] without calling urUsmP2PEnablePeerAccessExp first and asserts that the allocation is NOT made resident on devices[1]. Verified by checking that free memory on devices[0] (source) decreases by at least allocSize, while free memory on devices[1] (peer) does not decrease by a full allocSize. allocationExistsOnPeerWithEnabledAccess Enables peer access from devices[0] to devices[1] and verifies that a second enable attempt returns UR_RESULT_ERROR_INVALID_OPERATION (state machine check). Allocates USM memory on devices[0] with P2P enabled and asserts that source-device free memory decreases by at least allocSize (the allocation succeeded and memory is on devices[0]). Disables peer access and frees the allocation on exit. Note: peer-device free memory is not checked because UR_DEVICE_INFO_GLOBAL_MEM_FREE does not reliably reflect zeContextMakeMemoryResident behaviour for device USM allocations. allocationAbsentOnPeerWithDisabledAccess Enables peer access and allocates USM memory on devices[0]. Disables peer access and verifies that a second disable attempt returns UR_RESULT_ERROR_INVALID_OPERATION (state machine check). Asserts that source-device free memory still shows the allocation is present. Frees the allocation on exit. Note: peer-device eviction is not checked via free memory for the same reason as above (unreliable for device USM). All three tests: - Skip when either device is not PVC (UR_DEVICE_INFO_GLOBAL_MEM_FREE is only reliably accurate on PVC). - Skip when no hardware P2P connection exists between the two devices (UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORT == 0). - Use the peerAccessEnabled flag in the fixture so that TearDown can disable peer access even if a test assertion fails mid-way, keeping subsequent tests in a clean state. Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
1 parent 528cb33 commit 08a08ab

1 file changed

Lines changed: 171 additions & 3 deletions

File tree

unified-runtime/test/adapters/level_zero/v2/memory_residency.cpp

Lines changed: 171 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,189 @@ struct urMemoryMultiResidencyTest : uur::urMultiDeviceContextTestTemplate<2> {
6060
}
6161

6262
void TearDown() override {
63+
// Disable peer access if a test enabled it but did not clean up (e.g. due
64+
// to an assertion failure), so subsequent tests start from a clean state.
65+
if (peerAccessEnabled) {
66+
EXPECT_SUCCESS(urUsmP2PDisablePeerAccessExp(devices[0], devices[1]));
67+
}
6368
UUR_RETURN_ON_FATAL_FAILURE(
6469
uur::urMultiDeviceContextTestTemplate<2>::TearDown());
6570
}
71+
72+
// Returns true when hardware P2P connectivity exists between devices[0] and
73+
// devices[1], i.e. peer access can be enabled by the user.
74+
bool hasHardwareP2PSupport() {
75+
int supported = 0;
76+
if (urUsmP2PPeerAccessGetInfoExp(
77+
devices[0], devices[1], UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORT,
78+
sizeof(int), &supported, nullptr) != UR_RESULT_SUCCESS) {
79+
return false;
80+
}
81+
return supported != 0;
82+
}
83+
84+
// Whether peer access from devices[0] to devices[1] has been enabled by
85+
// this test and must be disabled in TearDown.
86+
bool peerAccessEnabled = false;
6687
};
6788

6889
UUR_INSTANTIATE_PLATFORM_TEST_SUITE(urMemoryMultiResidencyTest);
6990

70-
TEST_P(urMemoryMultiResidencyTest, allocationInitiallyAbsentOnPeer) {}
91+
// Verify that allocating USM memory on devices[0] does NOT make it resident on
92+
// devices[1] when peer access has not been enabled. Memory is physically only
93+
// on the source device (devices[0]); peer device memory is unaffected.
94+
TEST_P(urMemoryMultiResidencyTest, allocationInitiallyAbsentOnPeer) {
95+
if (!uur::isPVC(devices[0]) || !uur::isPVC(devices[1])) {
96+
GTEST_SKIP() << "Test requires PVC devices";
97+
}
98+
if (!hasHardwareP2PSupport()) {
99+
GTEST_SKIP() << "No hardware P2P connection between devices";
100+
}
101+
102+
static constexpr size_t allocSize = 1024 * 1024;
103+
size_t initialMemFreeSource = 0;
104+
ASSERT_SUCCESS(urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
105+
sizeof(size_t), &initialMemFreeSource,
106+
nullptr));
107+
size_t initialMemFreePeer = 0;
108+
ASSERT_SUCCESS(urDeviceGetInfo(devices[1], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
109+
sizeof(size_t), &initialMemFreePeer, nullptr));
110+
if (initialMemFreeSource < allocSize) {
111+
GTEST_SKIP() << "Not enough source device memory available";
112+
}
113+
if (initialMemFreePeer < allocSize) {
114+
GTEST_SKIP()
115+
<< "Not enough peer device memory available for reliable check";
116+
}
117+
118+
// Allocate on devices[0] WITHOUT enabling P2P.
119+
void *ptr = nullptr;
120+
ASSERT_SUCCESS(
121+
urUSMDeviceAlloc(context, devices[0], nullptr, nullptr, allocSize, &ptr));
122+
123+
// Save return codes so ptr is freed before any ASSERT terminates the test.
124+
size_t currentMemFreeSource = 0;
125+
ur_result_t res1 =
126+
urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
127+
sizeof(size_t), &currentMemFreeSource, nullptr);
128+
size_t currentMemFreePeer = 0;
129+
ur_result_t res2 =
130+
urDeviceGetInfo(devices[1], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
131+
sizeof(size_t), &currentMemFreePeer, nullptr);
71132

133+
ASSERT_SUCCESS(urUSMFree(context, ptr));
134+
135+
ASSERT_SUCCESS(res1);
136+
ASSERT_SUCCESS(res2);
137+
// Allocation is physically on devices[0]: its free memory must decrease.
138+
ASSERT_LE(currentMemFreeSource, initialMemFreeSource - allocSize);
139+
// Without P2P, the allocation must not be resident on the peer:
140+
// free memory on devices[1] must not have decreased by a full allocSize.
141+
ASSERT_GT(currentMemFreePeer, initialMemFreePeer - allocSize);
142+
}
143+
144+
// Verify that enabling peer access succeeds and that a second enable attempt
145+
// returns UR_RESULT_ERROR_INVALID_OPERATION (access already enabled). Confirms
146+
// that source-device free memory decreases by at least allocSize, showing the
147+
// allocation succeeded on devices[0] with P2P enabled.
148+
// Note: peer-device free memory is not checked because
149+
// UR_DEVICE_INFO_GLOBAL_MEM_FREE does not reliably reflect
150+
// zeContextMakeMemoryResident behaviour for device USM allocations.
72151
TEST_P(urMemoryMultiResidencyTest, allocationExistsOnPeerWithEnabledAccess) {
152+
if (!uur::isPVC(devices[0]) || !uur::isPVC(devices[1])) {
153+
GTEST_SKIP() << "Test requires PVC devices";
154+
}
155+
if (!hasHardwareP2PSupport()) {
156+
GTEST_SKIP() << "No hardware P2P connection between devices";
157+
}
158+
159+
ASSERT_SUCCESS(urUsmP2PEnablePeerAccessExp(devices[0], devices[1]));
160+
peerAccessEnabled = true;
161+
162+
// A second enable must be rejected because access is already enabled.
163+
ASSERT_EQ(urUsmP2PEnablePeerAccessExp(devices[0], devices[1]),
164+
UR_RESULT_ERROR_INVALID_OPERATION);
165+
166+
static constexpr size_t allocSize = 1024 * 1024;
167+
size_t initialMemFreeSource = 0;
168+
ASSERT_SUCCESS(urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
169+
sizeof(size_t), &initialMemFreeSource,
170+
nullptr));
171+
if (initialMemFreeSource < allocSize) {
172+
GTEST_SKIP() << "Not enough source device memory available";
173+
}
73174

74175
void *ptr = nullptr;
75176
ASSERT_SUCCESS(
76-
urUSMDeviceAlloc(context, devices[0], nullptr, nullptr, 1, &ptr));
177+
urUSMDeviceAlloc(context, devices[0], nullptr, nullptr, allocSize, &ptr));
178+
179+
// Save return code so ptr is freed before any ASSERT terminates the test.
180+
size_t currentMemFreeSource = 0;
181+
ur_result_t res =
182+
urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
183+
sizeof(size_t), &currentMemFreeSource, nullptr);
184+
77185
ASSERT_SUCCESS(urUSMFree(context, ptr));
186+
ASSERT_SUCCESS(urUsmP2PDisablePeerAccessExp(devices[0], devices[1]));
187+
peerAccessEnabled = false;
188+
189+
ASSERT_SUCCESS(res);
190+
// Allocation is physically on devices[0]: its free memory must decrease.
191+
ASSERT_LE(currentMemFreeSource, initialMemFreeSource - allocSize);
78192
}
79193

80-
TEST_P(urMemoryMultiResidencyTest, allocationAbsentOnPeerWithDisabledAccess) {}
194+
// Verify that disabling peer access succeeds and that a second disable attempt
195+
// returns UR_RESULT_ERROR_INVALID_OPERATION (access already disabled). Confirms
196+
// that source-device free memory still shows the allocation after peer access is
197+
// disabled, proving the allocation on devices[0] remains valid.
198+
// Note: peer-device eviction is not verified via free memory because
199+
// UR_DEVICE_INFO_GLOBAL_MEM_FREE does not reliably reflect
200+
// zeContextEvictMemory behaviour for device USM allocations.
201+
TEST_P(urMemoryMultiResidencyTest, allocationAbsentOnPeerWithDisabledAccess) {
202+
if (!uur::isPVC(devices[0]) || !uur::isPVC(devices[1])) {
203+
GTEST_SKIP() << "Test requires PVC devices";
204+
}
205+
if (!hasHardwareP2PSupport()) {
206+
GTEST_SKIP() << "No hardware P2P connection between devices";
207+
}
208+
209+
ASSERT_SUCCESS(urUsmP2PEnablePeerAccessExp(devices[0], devices[1]));
210+
peerAccessEnabled = true;
211+
212+
static constexpr size_t allocSize = 1024 * 1024;
213+
size_t initialMemFreeSource = 0;
214+
ASSERT_SUCCESS(urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
215+
sizeof(size_t), &initialMemFreeSource,
216+
nullptr));
217+
if (initialMemFreeSource < allocSize) {
218+
GTEST_SKIP() << "Not enough source device memory available";
219+
}
220+
221+
void *ptr = nullptr;
222+
ASSERT_SUCCESS(
223+
urUSMDeviceAlloc(context, devices[0], nullptr, nullptr, allocSize, &ptr));
224+
225+
// Disable P2P; the runtime evicts the allocation from devices[1] (not
226+
// verified here, see the function-level comment above). Save return codes so
227+
// ptr is freed before any ASSERT terminates the test.
228+
ur_result_t res1 = urUsmP2PDisablePeerAccessExp(devices[0], devices[1]);
229+
if (res1 == UR_RESULT_SUCCESS) {
230+
peerAccessEnabled = false;
231+
}
232+
233+
// A second disable must be rejected because access is already disabled.
234+
ur_result_t res2 = urUsmP2PDisablePeerAccessExp(devices[0], devices[1]);
235+
236+
size_t currentMemFreeSource = 0;
237+
ur_result_t res3 =
238+
urDeviceGetInfo(devices[0], UR_DEVICE_INFO_GLOBAL_MEM_FREE,
239+
sizeof(size_t), &currentMemFreeSource, nullptr);
240+
241+
ASSERT_SUCCESS(urUSMFree(context, ptr));
242+
243+
ASSERT_SUCCESS(res1);
244+
ASSERT_EQ(res2, UR_RESULT_ERROR_INVALID_OPERATION);
245+
ASSERT_SUCCESS(res3);
246+
// Allocation is physically on devices[0]: its free memory must decrease.
247+
ASSERT_LE(currentMemFreeSource, initialMemFreeSource - allocSize);
248+
}

0 commit comments

Comments
 (0)