Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// REQUIRES: aspect-ext_oneapi_virtual_mem

// This test checks whether data can be correctly written to and read from
// virtual memory.

// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

#include "helpers.hpp"

int main() {
sycl::queue Q;
sycl::context Context = Q.get_context();
sycl::device Device = Q.get_device();
int Failed = 0;
constexpr size_t NumberOfElements = 1000;
size_t BytesRequired = NumberOfElements * sizeof(int);

size_t UsedGranularity = GetLCMGranularity(Device, Context);

size_t AlignedByteSize =
((BytesRequired + UsedGranularity - 1) / UsedGranularity) *
UsedGranularity;

syclext::physical_mem NewPhysicalMem{Device, Context, AlignedByteSize};
uintptr_t VirtualMemoryPtr =
syclext::reserve_virtual_mem(0, AlignedByteSize, Context);

void *MappedPtr =
NewPhysicalMem.map(VirtualMemoryPtr, AlignedByteSize,
syclext::address_access_mode::read_write);

int *DataPtr = reinterpret_cast<int *>(MappedPtr);

std::vector<int> ResultHostData(NumberOfElements);

constexpr int ExpectedValueAfterFill = 1;

Q.fill(DataPtr, ExpectedValueAfterFill, NumberOfElements).wait_and_throw();
{
sycl::buffer<int> CheckBuffer(ResultHostData);
Q.submit([&](sycl::handler &Handle) {
sycl::accessor A(CheckBuffer, Handle, sycl::write_only);
Handle.parallel_for(NumberOfElements,
[=](sycl::id<1> Idx) { A[Idx] = DataPtr[Idx]; });
});
}

for (size_t i = 0; i < ResultHostData.size(); i++) {
if (ResultHostData[i] != ExpectedValueAfterFill) {
std::cout << "Comparison failed after fill operation at index " << i
<< ": " << ResultHostData[i] << " != " << ExpectedValueAfterFill
<< std::endl;
++Failed;
}
}

Q.parallel_for(NumberOfElements, [=](sycl::id<1> Idx) {
DataPtr[Idx] = Idx;
}).wait_and_throw();

syclext::set_access_mode(DataPtr, AlignedByteSize,
syclext::address_access_mode::read, Context);

{
sycl::buffer<int> ResultBuffer(ResultHostData);

Q.submit([&](sycl::handler &Handle) {
sycl::accessor A(ResultBuffer, Handle, sycl::write_only);
Handle.parallel_for(NumberOfElements,
[=](sycl::id<1> Idx) { A[Idx] = DataPtr[Idx]; });
});
}

for (size_t i = 0; i < NumberOfElements; i++) {
const int ExpectedValue = static_cast<int>(i);
if (ResultHostData[i] != ExpectedValue) {
std::cout << "Comparison failed at index " << i << ": "
<< ResultHostData[i] << " != " << ExpectedValue << std::endl;
++Failed;
}
}

syclext::unmap(MappedPtr, AlignedByteSize, Context);
syclext::free_virtual_mem(VirtualMemoryPtr, AlignedByteSize, Context);

return Failed;
}
25 changes: 25 additions & 0 deletions sycl/test-e2e/VirtualMem/helpers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <sycl/detail/core.hpp>
#include <sycl/ext/oneapi/virtual_mem/physical_mem.hpp>
#include <sycl/ext/oneapi/virtual_mem/virtual_mem.hpp>

namespace syclext = sycl::ext::oneapi::experimental;

// Find the least common multiple of the context and device granularities. This
// value can be used for aligning both physical memory allocations and for
// reserving virtual memory ranges.
size_t GetLCMGranularity(
const sycl::device &Dev, const sycl::context &Ctx,
syclext::granularity_mode Gm = syclext::granularity_mode::recommended) {
size_t CtxGranularity = syclext::get_mem_granularity(Ctx, Gm);
size_t DevGranularity = syclext::get_mem_granularity(Dev, Ctx, Gm);

size_t GCD = CtxGranularity;
size_t Rem = DevGranularity % GCD;
while (Rem != 0) {
std::swap(GCD, Rem);
Rem %= GCD;
}
return (DevGranularity / GCD) * CtxGranularity;
}
26 changes: 4 additions & 22 deletions sycl/test-e2e/VirtualMem/vector_with_virtual_mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,12 @@
// RUN: %{build} -o %t.out
// RUN: %{run} %t.out

#include <sycl/detail/core.hpp>
#include <sycl/usm.hpp>

#include <sycl/ext/oneapi/experimental/device_architecture.hpp>
#include <sycl/ext/oneapi/virtual_mem/physical_mem.hpp>
#include <sycl/ext/oneapi/virtual_mem/virtual_mem.hpp>

namespace syclext = sycl::ext::oneapi::experimental;

// Find the least common multiple of the context and device granularities. This
// value can be used for aligning both physical memory allocations and for
// reserving virtual memory ranges.
size_t GetLCMGranularity(const sycl::device &Dev, const sycl::context &Ctx) {
size_t CtxGranularity = syclext::get_mem_granularity(Ctx);
size_t DevGranularity = syclext::get_mem_granularity(Dev, Ctx);

size_t GCD = CtxGranularity;
size_t Rem = DevGranularity % GCD;
while (Rem != 0) {
std::swap(GCD, Rem);
Rem %= GCD;
}
return (DevGranularity / GCD) * CtxGranularity;
}

#include "helpers.hpp"


template <typename T> class VirtualVector {
public:
Expand Down Expand Up @@ -236,4 +218,4 @@ int main() {
}

return 0;
}
}
Loading