File: usm_allocator.h

package info (click to toggle)
level-zero-gpu-raytracing 1.2.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,560 kB
  • sloc: cpp: 43,788; ansic: 1,342; makefile: 21; sh: 14
file content (80 lines) | stat: -rw-r--r-- 2,572 bytes parent folder | download
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;
};