Depends on https://github.com/llvm/llvm-project/pull/184110 This is part of the SYCL support upstreaming effort. The relevant RFCs can be found here: https://discourse.llvm.org/t/rfc-add-full-support-for-the-sycl-programming-model/74080 https://discourse.llvm.org/t/rfc-sycl-runtime-upstreaming/74479 --------- Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
125 lines
4.0 KiB
C++
125 lines
4.0 KiB
C++
// REQUIRES: any-device
|
|
// RUN: %clangxx %sycl_options %s -o %t.out
|
|
// RUN: %t.out
|
|
|
|
#include <sycl/sycl.hpp>
|
|
|
|
#include <cstddef>
|
|
#include <iostream>
|
|
#include <tuple>
|
|
|
|
using namespace sycl;
|
|
|
|
constexpr size_t Align = 256;
|
|
|
|
struct alignas(Align) Aligned {
|
|
int x;
|
|
};
|
|
|
|
int main() {
|
|
queue q;
|
|
context ctx = q.get_context();
|
|
device d = q.get_device();
|
|
|
|
auto check = [&q](size_t Alignment, auto AllocFn, int Line = __builtin_LINE(),
|
|
int Case = 0) {
|
|
// First allocation might naturally be over-aligned. Do several of them to
|
|
// do the verification;
|
|
decltype(AllocFn()) Arr[10];
|
|
for (auto *&Elem : Arr)
|
|
Elem = AllocFn();
|
|
for (auto *Ptr : Arr) {
|
|
auto v = reinterpret_cast<uintptr_t>(Ptr);
|
|
if ((v & (Alignment - 1)) != 0) {
|
|
std::cout << "Failed at line " << Line << ", case " << Case
|
|
<< std::endl;
|
|
assert(false && "Not properly aligned!");
|
|
break; // To be used with commented out assert above.
|
|
}
|
|
}
|
|
for (auto *Ptr : Arr)
|
|
free(Ptr, q);
|
|
};
|
|
|
|
// The strictest (largest) fundamental alignment of any type is the alignment
|
|
// of max_align_t. This is, however, smaller than the minimal alignment
|
|
// returned by the underlying runtime as of now.
|
|
constexpr size_t FAlign = alignof(std::max_align_t);
|
|
|
|
auto CheckAll = [&](size_t Expected, auto Funcs,
|
|
int Line = __builtin_LINE()) {
|
|
std::apply(
|
|
[&](auto... Fs) {
|
|
int Case = 0;
|
|
(void)std::initializer_list<int>{
|
|
(check(Expected, Fs, Line, Case++), 0)...};
|
|
},
|
|
Funcs);
|
|
};
|
|
|
|
auto MDevice = [&](auto... args) {
|
|
return malloc_device(sizeof(std::max_align_t), args...);
|
|
};
|
|
CheckAll(FAlign,
|
|
std::tuple{[&]() { return MDevice(q); },
|
|
[&]() { return MDevice(d, ctx); },
|
|
[&]() { return MDevice(q, property_list{}); },
|
|
[&]() { return MDevice(d, ctx, property_list{}); }});
|
|
|
|
auto MHost = [&](auto... args) {
|
|
return malloc_host(sizeof(std::max_align_t), args...);
|
|
};
|
|
CheckAll(FAlign,
|
|
std::tuple{[&]() { return MHost(q); }, [&]() { return MHost(ctx); },
|
|
[&]() { return MHost(q, property_list{}); },
|
|
[&]() { return MHost(ctx, property_list{}); }});
|
|
|
|
if (d.has(aspect::usm_shared_allocations)) {
|
|
auto MShared = [&](auto... args) {
|
|
return malloc_shared(sizeof(std::max_align_t), args...);
|
|
};
|
|
|
|
CheckAll(FAlign,
|
|
std::tuple{[&]() { return MShared(q); },
|
|
[&]() { return MShared(d, ctx); },
|
|
[&]() { return MShared(q, property_list{}); },
|
|
[&]() { return MShared(d, ctx, property_list{}); }});
|
|
}
|
|
|
|
auto TDevice = [&](auto... args) {
|
|
return malloc_device<Aligned>(1, args...);
|
|
};
|
|
CheckAll(Align, std::tuple{[&]() { return TDevice(q); },
|
|
[&]() { return TDevice(d, ctx); }});
|
|
|
|
auto THost = [&](auto... args) { return malloc_host<Aligned>(1, args...); };
|
|
CheckAll(Align, std::tuple{[&]() { return THost(q); },
|
|
[&]() { return THost(ctx); }});
|
|
|
|
if (d.has(aspect::usm_shared_allocations)) {
|
|
auto TShared = [&](auto... args) {
|
|
return malloc_shared<Aligned>(1, args...);
|
|
};
|
|
CheckAll(Align, std::tuple{[&]() { return TShared(q); },
|
|
[&]() { return TShared(d, ctx); }});
|
|
}
|
|
|
|
auto Malloc = [&](auto... args) {
|
|
return malloc(sizeof(std::max_align_t), args...);
|
|
};
|
|
CheckAll(
|
|
FAlign,
|
|
std::tuple{
|
|
[&]() { return Malloc(q, usm::alloc::host); },
|
|
[&]() { return Malloc(d, ctx, usm::alloc::host); },
|
|
[&]() { return Malloc(q, usm::alloc::host, property_list{}); },
|
|
[&]() { return Malloc(d, ctx, usm::alloc::host, property_list{}); }});
|
|
|
|
auto TMalloc = [&](auto... args) { return malloc<Aligned>(1, args...); };
|
|
CheckAll(Align,
|
|
std::tuple{[&]() { return TMalloc(q, usm::alloc::host); },
|
|
[&]() { return TMalloc(d, ctx, usm::alloc::host); }});
|
|
|
|
return 0;
|
|
}
|