32 #ifndef VSMC_UTILITY_ALIGNED_MEMORY 33 #define VSMC_UTILITY_ALIGNED_MEMORY 42 #include <type_traits> 47 #elif defined(VSMC_MSVC) 51 #if VSMC_HAS_TBB_MALLOC 52 #include <tbb/scalable_allocator.h> 56 #include <mkl_service.h> 61 #ifndef VSMC_ALIGNED_MEMORY_TYPE 62 #if VSMC_HAS_TBB_MALLOC 63 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemoryTBB 65 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemoryMKL 66 #elif VSMC_HAS_POSIX || defined(VSMC_MSVC) 67 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySYS 69 #define VSMC_ALIGNED_MEMORY_TYPE ::vsmc::AlignedMemorySTD 75 #ifndef VSMC_ALIGNMENT 76 #define VSMC_ALIGNMENT 32 79 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(Alignment) \ 81 (Alignment != 0 && (Alignment & (Alignment - 1)) == 0), \ 82 "**AlignedAllocator** USED WITH Alignment NOT A POWER OF TWO") 84 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(Alignemnt) \ 85 VSMC_STATIC_ASSERT((Alignment >= sizeof(void *)), \ 86 "**AlginedAllocator** USED WITH Alignment LESS THAN sizeof(void *)") 88 #define VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY \ 89 VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(Alignment); \ 90 VSMC_STATIC_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(Alignment); 92 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(alignment) \ 93 VSMC_RUNTIME_ASSERT( \ 94 (alignment != 0 && (alignment & (alignment - 1)) == 0), \ 95 "**aligned_malloc** USED WITH ALIGNMENT NOT A POWER OF TWO") 97 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(alignemnt) \ 98 VSMC_RUNTIME_ASSERT((alignment >= sizeof(void *)), \ 99 "**aligned_malloc** USED WITH ALIGNMENT LESS THAN sizeof(void *)") 101 #define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY \ 102 VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_POWER_OF_TWO(alignment); \ 103 VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY_SIZEOF_VOID(alignment); 124 void *orig_ptr = std::malloc(n + alignment +
sizeof(
void *));
125 if (orig_ptr ==
nullptr)
126 throw std::bad_alloc();
128 uintptr_t address =
reinterpret_cast<uintptr_t
>(orig_ptr);
129 uintptr_t offset = alignment - (address +
sizeof(
void *)) % alignment;
131 reinterpret_cast<void *
>(address + offset +
sizeof(
void *));
132 void **orig =
reinterpret_cast<void **
>(address + offset);
140 std::free(*reinterpret_cast<void **>(
141 reinterpret_cast<uintptr_t>(ptr) -
sizeof(
void *)));
164 if (posix_memalign(&ptr, alignment, n) != 0)
165 throw std::bad_alloc();
173 #elif defined(VSMC_MSVC) 185 void *ptr = _aligned_malloc(n, alignment);
187 throw std::bad_alloc();
192 static void aligned_free(
void *ptr) { _aligned_free(ptr); }
195 #endif // VSMC_HAS_POSIX 197 #if VSMC_HAS_TBB_MALLOC 212 void *ptr = scalable_aligned_malloc(n, alignment);
214 throw std::bad_alloc();
222 #endif // VSMC_HAS_TBB_MALLOC 238 void *ptr = mkl_malloc(n, static_cast<int>(alignment));
240 throw std::bad_alloc();
248 #endif // VSMC_HAS_MKL 270 using size_type =
typename std::allocator<T>::size_type;
271 using pointer =
typename std::allocator<T>::pointer;
273 template <
typename U>
283 :
std::allocator<T>(other)
288 template <
typename U>
290 :
std::allocator<T>(static_cast<
std::allocator<U>>(other))
299 :
std::allocator<T>(
std::move(other))
304 template <
typename U>
306 :
std::allocator<T>(static_cast<
std::allocator<U>>(
std::move(other)))
322 memory_.aligned_malloc(
sizeof(T) * n, Alignment));
328 memory_.aligned_free(ptr);
337 template <
typename T>
338 using Allocator =
typename std::conditional<std::is_scalar<T>::value,
343 template <
typename T>
348 template <
typename T>
349 using Vector =
typename std::conditional<std::is_scalar<T>::value,
350 std::vector<T, AlignedAllocator<T>>, std::vector<T>>::type;
354 #endif // VSMC_UTILITY_ALIGNED_MEMORY AlignedAllocator(AlignedAllocator< T, Alignment, Memory > &&other)
static void * aligned_malloc(std::size_t n, std::size_t alignment)
AlignedAllocator(AlignedAllocator< U, Alignment, Memory > &&other)
std::vector< T, AlignedAllocator< T >> AlignedVector
Vector type using AlignedAllocator.
Aligned memory using std::malloc and std::free
Aligned memory using Intel TBB scalable_aligned_malloc and scalable_aligned_free. ...
typename std::allocator< T >::size_type size_type
typename std::conditional< std::is_scalar< T >::value, std::vector< T, AlignedAllocator< T >>, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
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_ALIGNMENT
Defualt alignment.
#define VSMC_RUNTIME_ASSERT_UTILITY_ALIGNED_MEMORY
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)
AlignedAllocator(const AlignedAllocator< T, Alignment, Memory > &other)
static void aligned_free(void *ptr)
Aligned memory using native system aligned memory allocation.
typename std::allocator< T >::pointer pointer
AlignedAllocator(const AlignedAllocator< U, Alignment, Memory > &other)
typename std::conditional< std::is_scalar< T >::value, AlignedAllocator< T >, std::allocator< T >>::type Allocator
AlignedAllocator for scalar type and std::allocator for others.
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.