32 #ifndef VSMC_UTILITY_ALIGNED_MEMORY
33 #define VSMC_UTILITY_ALIGNED_MEMORY
39 #elif defined(VSMC_MSVC)
43 #if VSMC_HAS_TBB_MALLOC
44 #include <tbb/scalable_allocator.h>
48 #include <mkl_service.h>
53 #ifndef VSMC_ALIGNED_MEMORY_TYPE
54 #if VSMC_HAS_POSIX || defined(VSMC_MSVC)
55 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySYS
56 #elif VSMC_HAS_TBB_MALLOC
57 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemoryTBB
59 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemoryMKL
61 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySTD
65 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(Alignment) \
66 VSMC_STATIC_ASSERT((Alignment != 0 && (Alignment & (Alignment - 1)) == 0),\
67 USE_AlignedAllocator_WITH_ALIGNEMNT_NOT_A_POWER_OF_TWO)
69 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(Alignemnt) \
70 VSMC_STATIC_ASSERT((Alignment >= sizeof(void *)), \
71 USE_AlignedAllocator_WITH_ALIGNMENT_LESS_THAN_SIZEOF_VOID_POINTER)
73 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY \
74 VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(Alignment); \
75 VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(Alignment);
77 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(alignment) \
78 VSMC_RUNTIME_ASSERT((alignment != 0 && (alignment & (alignment - 1)) == 0),\
79 "**aligned_malloc** USED WITH ALIGNMENT NOT A POWER OF TWO")
81 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(alignemnt) \
82 VSMC_RUNTIME_ASSERT((alignment >= sizeof(void *)), \
83 "**aligned_malloc** USED WITH ALIGNMENT LESS THAN sizeof(void *)")
85 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY \
86 VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(alignment); \
87 VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(alignment);
108 void *orig_ptr = std::malloc(n + alignment +
sizeof(
void *));
110 throw std::bad_alloc();
112 uintptr_t address =
reinterpret_cast<uintptr_t
>(orig_ptr);
113 uintptr_t offset = alignment - (address +
sizeof(
void *)) % alignment;
114 void *ptr =
reinterpret_cast<void *
>(address + offset +
sizeof(
void *));
115 void **orig =
reinterpret_cast<void **
>(address + offset);
123 std::free(*reinterpret_cast<void **>(
124 reinterpret_cast<uintptr_t>(ptr) -
sizeof(
void *)));
148 if (posix_memalign(&ptr, alignment, n) != 0)
149 throw std::bad_alloc();
157 #elif defined(VSMC_MSVC)
159 class AlignedMemorySYS
163 static void *
aligned_malloc (std::size_t n, std::size_t alignment)
170 void *ptr = _aligned_malloc(n, alignment);
172 throw std::bad_alloc();
177 static void aligned_free (
void *ptr) {_aligned_free(ptr);}
180 #endif // VSMC_HAS_POSIX
182 #if VSMC_HAS_TBB_MALLOC
198 void *ptr = scalable_aligned_malloc(n, alignment);
200 throw std::bad_alloc();
208 #endif // VSMC_HAS_TBB_MALLOC
225 void *ptr = mkl_malloc(n, static_cast<int>(alignment));
227 throw std::bad_alloc();
235 #endif // VSMC_HAS_MKL
252 template <
typename T, std::size_t Alignment = 32,
253 typename Memory = AlignedMemory>
258 typedef typename std::allocator<T>::size_type
size_type;
259 typedef typename std::allocator<T>::pointer
pointer;
267 std::allocator<T>(other)
270 template <
typename U>
272 std::allocator<T>(static_cast<
std::allocator<U> >(other))
279 return static_cast<pointer
>(
280 memory_.aligned_malloc(
sizeof(T) * n, Alignment));
286 memory_.aligned_free(ptr);
296 #endif // VSMC_UTILITY_ALIGNED_MEMORY
AlignedAllocator(const AlignedAllocator< T, Alignment > &other)
static void * aligned_malloc(std::size_t n, std::size_t alignment)
AlignedAllocator< U, Alignment > other
Aligned memory using std::malloc and std::free
Aligned memory using Intel TBB scalable_aligned_malloc and scalable_aligned_free. ...
static void aligned_free(void *ptr)
#define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY
Aligned memory using Intel MKL mkl_malloc and mkl_free
#define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY
AlignedAllocator(const AlignedAllocator< U, Alignment > &other)
static void * aligned_malloc(std::size_t n, std::size_t alignment)
static void aligned_free(void *ptr)
static void * aligned_malloc(std::size_t n, std::size_t alignment)
::vsmc::AlignedMemorySYS AlignedMemory
Default AlignedMemory type.
static void aligned_free(void *ptr)
Aligned memory using native system aligned memory allocation.
std::allocator< T >::pointer pointer
#define VSMC_NULLPTR
nullptr
static void * aligned_malloc(std::size_t n, std::size_t alignment)
pointer allocate(size_type n, const void *=nullptr)
static void aligned_free(void *ptr)
void deallocate(pointer ptr, size_type)
#define VSMC_ALIGNED_MEMORY_TYPE
Default AlignedMemory type.
std::allocator< T >::size_type size_type