1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include <sycl/sycl.hpp>
template <typename T, sycl::usm::alloc AllocKind, size_t Alignment = 0>
class usm_allocator {
public:
using value_type = T;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
public:
template <typename U> struct rebind {
typedef usm_allocator<U, AllocKind, Alignment> other;
};
usm_allocator() = delete;
usm_allocator(const sycl::context& context, const sycl::device& device, const sycl::property_list& PropList = {})
: context(context), device(device), props(PropList) {}
usm_allocator(const usm_allocator& ) = default;
usm_allocator(usm_allocator&& ) noexcept = default;
usm_allocator& operator=(const usm_allocator& other) {
context = other.context;
device = other.device;
props = other.props;
return *this;
}
usm_allocator& operator=(usm_allocator&& other) {
context = std::move(other.context);
device = std::move(other.device);
props = std::move(other.props);
return *this;
}
template <class U>
usm_allocator(const usm_allocator<U, AllocKind, Alignment>& other) noexcept
: context(other.context), device(other.device), props(other.props) {}
T* allocate(size_t n)
{
if (n == 0)
return nullptr;
auto ptr = reinterpret_cast<T*>(aligned_alloc(getAlignment(), n*sizeof(value_type), device, context, AllocKind, props));
if (!ptr)
throw std::runtime_error("USM allocation failed");
return ptr;
}
void deallocate(T* ptr, size_t) {
if (ptr) sycl::free(ptr, context);
}
template <class U, sycl::usm::alloc AllocKindU, size_t AlignmentU> friend bool operator==(const usm_allocator<T, AllocKind, Alignment>& first,
const usm_allocator<U, AllocKindU, AlignmentU>& second)
{
return ((AllocKind == AllocKindU) && (first.context == second.context) && (first.device == second.device));
}
template <class U, sycl::usm::alloc AllocKindU, size_t AlignmentU>
friend bool operator!=(const usm_allocator<T, AllocKind, Alignment>& first, const usm_allocator<U, AllocKindU, AlignmentU>& second) {
return !(first == second);
}
private:
constexpr size_t getAlignment() const { return std::max(alignof(T), Alignment); }
sycl::context context;
sycl::device device;
sycl::property_list props;
};
|