QMCPACK
Mallocator.hpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 // -*- C++ -*-
12 /** @file Mallocator.hpp
13  */
14 #ifndef QMCPLUSPLUS_ALIGNED_ALLOCATOR_H
15 #define QMCPLUSPLUS_ALIGNED_ALLOCATOR_H
16 
17 #include <cstdlib>
18 #include <string>
19 #include <stdexcept>
20 #include <string>
21 
22 namespace qmcplusplus
23 {
24 template<typename T, size_t ALIGN>
25 struct Mallocator
26 {
27  using value_type = T;
28  using size_type = size_t;
29  using pointer = T*;
30  using const_pointer = const T*;
31 
32  static constexpr size_t alignment = ALIGN;
33 
34  Mallocator() = default;
35  template<class U>
37  {}
38 
39  template<class U>
40  struct rebind
41  {
43  };
44 
45  T* allocate(std::size_t n)
46  {
47  if (n == 0)
48  throw std::runtime_error("Mallocator::allocate does not accept size 0 allocations.");
49  void* pt(nullptr);
50  std::size_t asize = n * sizeof(T);
51  std::size_t amod = asize % ALIGN;
52  if (amod != 0)
53  asize += ALIGN - amod;
54 
55 #if __STDC_VERSION__ >= 201112L || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)
56  // as per C11 standard asize must be an integral multiple of ALIGN
57  // or behavior is undefined. Some implementations support all positive
58  // values of asize but the standard has not been amended
59  // This is also not guaranteed threadsafe until it appeared in
60  // the C++17 standard.
61  pt = aligned_alloc(ALIGN, asize);
62 #else
63  // While posix memalign can deal with asize violating the C11 standard
64  // assumptions made later by our simd code namely copyn require allocation
65  // of the entire aligned block to avoid heap buffer read overflows later
66  posix_memalign(&pt, ALIGN, asize);
67 #endif
68  if (pt == nullptr)
69  throw std::runtime_error("Allocation failed in Mallocator, requested size in bytes = " +
70  std::to_string(n * sizeof(T)));
71  return static_cast<T*>(pt);
72  }
73 
74  void deallocate(T* p, std::size_t n)
75  {
76  if (n == 0)
77  throw std::runtime_error("Mallocator::deallocate does not accept size 0 allocations.");
78  free(p);
79  }
80 };
81 
82 template<class T1, size_t ALIGN1, class T2, size_t ALIGN2>
84 {
85  return ALIGN1 == ALIGN2;
86 }
87 template<class T1, size_t ALIGN1, class T2, size_t ALIGN2>
89 {
90  return ALIGN1 != ALIGN2;
91 }
92 } // namespace qmcplusplus
93 
94 #endif
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
static constexpr size_t alignment
Definition: Mallocator.hpp:32
bool operator==(const Matrix< T, Alloc > &lhs, const Matrix< T, Alloc > &rhs)
Definition: OhmmsMatrix.h:388
void deallocate(T *p, std::size_t n)
Definition: Mallocator.hpp:74
T * allocate(std::size_t n)
Definition: Mallocator.hpp:45
bool operator!=(const Matrix< T, Alloc > &lhs, const Matrix< T, Alloc > &rhs)
Definition: OhmmsMatrix.h:403
Mallocator(const Mallocator< U, ALIGN > &)
Definition: Mallocator.hpp:36