alloc.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "platform.h"
  5. #include <vector>
  6. #include <set>
  7. namespace embree
  8. {
  9. #if defined(EMBREE_SYCL_SUPPORT)
  10. /* enables SYCL USM allocation */
  11. void enableUSMAllocEmbree(sycl::context* context, sycl::device* device);
  12. void enableUSMAllocTutorial(sycl::context* context, sycl::device* device);
  13. /* disables SYCL USM allocation */
  14. void disableUSMAllocEmbree();
  15. void disableUSMAllocTutorial();
  16. #endif
  17. #define ALIGNED_STRUCT_(align) \
  18. void* operator new(size_t size) { return alignedMalloc(size,align); } \
  19. void operator delete(void* ptr) { alignedFree(ptr); } \
  20. void* operator new[](size_t size) { return alignedMalloc(size,align); } \
  21. void operator delete[](void* ptr) { alignedFree(ptr); }
  22. #define ALIGNED_STRUCT_USM_(align) \
  23. void* operator new(size_t size) { return alignedUSMMalloc(size,align); } \
  24. void operator delete(void* ptr) { alignedUSMFree(ptr); } \
  25. void* operator new[](size_t size) { return alignedUSMMalloc(size,align); } \
  26. void operator delete[](void* ptr) { alignedUSMFree(ptr); }
  27. #define ALIGNED_CLASS_(align) \
  28. public: \
  29. ALIGNED_STRUCT_(align) \
  30. private:
  31. #define ALIGNED_CLASS_USM_(align) \
  32. public: \
  33. ALIGNED_STRUCT_USM_(align) \
  34. private:
  35. enum EmbreeUSMMode {
  36. EMBREE_USM_SHARED = 0,
  37. EMBREE_USM_SHARED_DEVICE_READ_WRITE = 0,
  38. EMBREE_USM_SHARED_DEVICE_READ_ONLY = 1
  39. };
  40. /*! aligned allocation */
  41. void* alignedMalloc(size_t size, size_t align);
  42. void alignedFree(void* ptr);
  43. /*! aligned allocation using SYCL USM */
  44. void* alignedUSMMalloc(size_t size, size_t align = 16, EmbreeUSMMode mode = EMBREE_USM_SHARED_DEVICE_READ_ONLY);
  45. void alignedUSMFree(void* ptr);
  46. #if defined(EMBREE_SYCL_SUPPORT)
  47. /*! aligned allocation using SYCL USM */
  48. void* alignedSYCLMalloc(sycl::context* context, sycl::device* device, size_t size, size_t align, EmbreeUSMMode mode);
  49. void alignedSYCLFree(sycl::context* context, void* ptr);
  50. // deleter functor to use as deleter in std unique or shared pointers that
  51. // capture raw pointers created by sycl::malloc and it's variants
  52. template<typename T>
  53. struct sycl_deleter
  54. {
  55. void operator()(T const* ptr)
  56. {
  57. alignedUSMFree((void*)ptr);
  58. }
  59. };
  60. #endif
  61. /*! allocator that performs aligned allocations */
  62. template<typename T, size_t alignment>
  63. struct aligned_allocator
  64. {
  65. typedef T value_type;
  66. typedef T* pointer;
  67. typedef const T* const_pointer;
  68. typedef T& reference;
  69. typedef const T& const_reference;
  70. typedef std::size_t size_type;
  71. typedef std::ptrdiff_t difference_type;
  72. __forceinline pointer allocate( size_type n ) {
  73. return (pointer) alignedMalloc(n*sizeof(value_type),alignment);
  74. }
  75. __forceinline void deallocate( pointer p, size_type n ) {
  76. return alignedFree(p);
  77. }
  78. __forceinline void construct( pointer p, const_reference val ) {
  79. new (p) T(val);
  80. }
  81. __forceinline void destroy( pointer p ) {
  82. p->~T();
  83. }
  84. };
  85. /*! allocates pages directly from OS */
  86. bool win_enable_selockmemoryprivilege(bool verbose);
  87. bool os_init(bool hugepages, bool verbose);
  88. void* os_malloc (size_t bytes, bool& hugepages);
  89. size_t os_shrink (void* ptr, size_t bytesNew, size_t bytesOld, bool hugepages);
  90. void os_free (void* ptr, size_t bytes, bool hugepages);
  91. void os_advise (void* ptr, size_t bytes);
  92. /*! allocator that performs OS allocations */
  93. template<typename T>
  94. struct os_allocator
  95. {
  96. typedef T value_type;
  97. typedef T* pointer;
  98. typedef const T* const_pointer;
  99. typedef T& reference;
  100. typedef const T& const_reference;
  101. typedef std::size_t size_type;
  102. typedef std::ptrdiff_t difference_type;
  103. __forceinline os_allocator ()
  104. : hugepages(false) {}
  105. __forceinline pointer allocate( size_type n ) {
  106. return (pointer) os_malloc(n*sizeof(value_type),hugepages);
  107. }
  108. __forceinline void deallocate( pointer p, size_type n ) {
  109. return os_free(p,n*sizeof(value_type),hugepages);
  110. }
  111. __forceinline void construct( pointer p, const_reference val ) {
  112. new (p) T(val);
  113. }
  114. __forceinline void destroy( pointer p ) {
  115. p->~T();
  116. }
  117. bool hugepages;
  118. };
  119. /*! allocator that newer performs allocations */
  120. template<typename T>
  121. struct no_allocator
  122. {
  123. typedef T value_type;
  124. typedef T* pointer;
  125. typedef const T* const_pointer;
  126. typedef T& reference;
  127. typedef const T& const_reference;
  128. typedef std::size_t size_type;
  129. typedef std::ptrdiff_t difference_type;
  130. __forceinline pointer allocate( size_type n ) {
  131. //throw std::runtime_error("no allocation supported");
  132. abort();
  133. }
  134. __forceinline void deallocate( pointer p, size_type n ) {
  135. }
  136. __forceinline void construct( pointer p, const_reference val ) {
  137. new (p) T(val);
  138. }
  139. __forceinline void destroy( pointer p ) {
  140. p->~T();
  141. }
  142. };
  143. /*! allocator for IDs */
  144. template<typename T, size_t max_id>
  145. struct IDPool
  146. {
  147. typedef T value_type;
  148. IDPool ()
  149. : nextID(0) {}
  150. T allocate()
  151. {
  152. /* return ID from list */
  153. if (!IDs.empty())
  154. {
  155. T id = *IDs.begin();
  156. IDs.erase(IDs.begin());
  157. return id;
  158. }
  159. /* allocate new ID */
  160. else
  161. {
  162. if (size_t(nextID)+1 > max_id)
  163. return -1;
  164. return nextID++;
  165. }
  166. }
  167. /* adds an ID provided by the user */
  168. bool add(T id)
  169. {
  170. if (id > max_id)
  171. return false;
  172. /* check if ID should be in IDs set */
  173. if (id < nextID) {
  174. auto p = IDs.find(id);
  175. if (p == IDs.end()) return false;
  176. IDs.erase(p);
  177. return true;
  178. }
  179. /* otherwise increase ID set */
  180. else
  181. {
  182. for (T i=nextID; i<id; i++) {
  183. IDs.insert(i);
  184. }
  185. nextID = id+1;
  186. return true;
  187. }
  188. }
  189. void deallocate( T id )
  190. {
  191. assert(id < nextID);
  192. MAYBE_UNUSED auto done = IDs.insert(id).second;
  193. assert(done);
  194. }
  195. private:
  196. std::set<T> IDs; //!< stores deallocated IDs to be reused
  197. T nextID; //!< next ID to use when IDs vector is empty
  198. };
  199. }