Skip to content

Commit 7116e9d

Browse files
authored
[SYCL][E2E] Add re-mapping virtual memory range test for sycl_ext_oneapi_virtual_mem extension (#15887)
Based on the test plan #15509, this PR adds an e2e test checking whether virtual memory range can correctly be accessed even if it was re-mapped to a different physical range.
1 parent 5d5a570 commit 7116e9d

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

sycl/test-e2e/VirtualMem/helpers.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include <sycl/detail/core.hpp>
4+
#include <sycl/ext/oneapi/virtual_mem/physical_mem.hpp>
5+
#include <sycl/ext/oneapi/virtual_mem/virtual_mem.hpp>
6+
7+
namespace syclext = sycl::ext::oneapi::experimental;
8+
9+
// Find the least common multiple of the context and device granularities. This
10+
// value can be used for aligning both physical memory allocations and for
11+
// reserving virtual memory ranges.
12+
size_t GetLCMGranularity(
13+
const sycl::device &Dev, const sycl::context &Ctx,
14+
syclext::granularity_mode Gm = syclext::granularity_mode::recommended) {
15+
size_t CtxGranularity = syclext::get_mem_granularity(Ctx, Gm);
16+
size_t DevGranularity = syclext::get_mem_granularity(Dev, Ctx, Gm);
17+
18+
size_t GCD = CtxGranularity;
19+
size_t Rem = DevGranularity % GCD;
20+
while (Rem != 0) {
21+
std::swap(GCD, Rem);
22+
Rem %= GCD;
23+
}
24+
return (DevGranularity / GCD) * CtxGranularity;
25+
}
26+
27+
size_t GetAlignedByteSize(const size_t UnalignedBytes,
28+
const size_t AligmentGranularity) {
29+
return ((UnalignedBytes + AligmentGranularity - 1) / AligmentGranularity) *
30+
AligmentGranularity;
31+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// This test checks whether virtual memory range can correctly be accessed
2+
// even if it was re-mapped to a different physical range.
3+
4+
// RUN: %{build} -o %t.out
5+
// RUN: %{run} %t.out
6+
7+
#include <sycl/detail/core.hpp>
8+
9+
#include <cassert>
10+
11+
#include "helpers.hpp"
12+
13+
namespace syclext = sycl::ext::oneapi::experimental;
14+
15+
int main() {
16+
17+
sycl::queue Q;
18+
sycl::context Context = Q.get_context();
19+
sycl::device Device = Q.get_device();
20+
21+
int Failed = 0;
22+
23+
constexpr size_t NumberOfElements = 1000;
24+
constexpr int ValueSetInFirstKernel = 555;
25+
constexpr int ValueSetInSecondKernel = 999;
26+
27+
size_t BytesRequired = NumberOfElements * sizeof(int);
28+
29+
size_t UsedGranularity = GetLCMGranularity(Device, Context);
30+
size_t AlignedByteSize = GetAlignedByteSize(BytesRequired, UsedGranularity);
31+
32+
syclext::physical_mem FirstPhysicalMemory{Device, Context, AlignedByteSize};
33+
uintptr_t VirtualMemoryPtr =
34+
syclext::reserve_virtual_mem(0, AlignedByteSize, Context);
35+
36+
void *MappedPtr =
37+
FirstPhysicalMemory.map(VirtualMemoryPtr, AlignedByteSize,
38+
syclext::address_access_mode::read_write);
39+
40+
int *DataPtr = reinterpret_cast<int *>(MappedPtr);
41+
42+
std::vector<int> ResultHostData(NumberOfElements);
43+
44+
Q.parallel_for(NumberOfElements, [=](sycl::id<1> Idx) {
45+
DataPtr[Idx] = ValueSetInFirstKernel;
46+
}).wait_and_throw();
47+
48+
syclext::unmap(MappedPtr, AlignedByteSize, Context);
49+
50+
syclext::physical_mem SecondPhysicalMemory{Device, Context, AlignedByteSize};
51+
MappedPtr =
52+
SecondPhysicalMemory.map(VirtualMemoryPtr, AlignedByteSize,
53+
syclext::address_access_mode::read_write);
54+
55+
Q.parallel_for(NumberOfElements, [=](sycl::id<1> Idx) {
56+
DataPtr[Idx] = ValueSetInSecondKernel;
57+
}).wait_and_throw();
58+
59+
{
60+
sycl::buffer<int> ResultBuffer(ResultHostData);
61+
62+
Q.submit([&](sycl::handler &Handle) {
63+
sycl::accessor A(ResultBuffer, Handle, sycl::write_only);
64+
Handle.parallel_for(NumberOfElements,
65+
[=](sycl::id<1> Idx) { A[Idx] = DataPtr[Idx]; });
66+
});
67+
}
68+
69+
for (size_t i = 0; i < NumberOfElements; i++) {
70+
if (ResultHostData[i] != ValueSetInSecondKernel) {
71+
std::cout << "Comparison failed at index " << i << ": "
72+
<< ResultHostData[i] << " != " << ValueSetInSecondKernel
73+
<< std::endl;
74+
++Failed;
75+
}
76+
}
77+
78+
syclext::unmap(MappedPtr, AlignedByteSize, Context);
79+
syclext::free_virtual_mem(VirtualMemoryPtr, AlignedByteSize, Context);
80+
81+
return Failed;
82+
}

0 commit comments

Comments
 (0)