mem_utils.txx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * \file mat_utils.txx
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 11-5-2013
  5. * \brief This file contains implementation of mem_utils.hpp.
  6. */
  7. #include <cassert>
  8. #include <cstring>
  9. #include <cstdlib>
  10. #include <stdint.h>
  11. #include <mem_mgr.hpp>
  12. #ifdef __INTEL_OFFLOAD
  13. #pragma offload_attribute(push,target(mic))
  14. #endif
  15. namespace pvfmm{
  16. namespace mem{
  17. template <class T>
  18. class TypeId{
  19. public:
  20. static uintptr_t value(){
  21. return (uintptr_t)&value;
  22. }
  23. };
  24. struct PtrData{
  25. size_t n_elem;
  26. size_t type_id;
  27. size_t base_size;
  28. uintptr_t base;
  29. };
  30. // For fundamental data types.
  31. template <class T>
  32. T* aligned_malloc_f(size_t n_elem, size_t alignment){
  33. if(!n_elem) return NULL;
  34. size_t base_size=n_elem*sizeof(T) + --alignment+sizeof(PtrData);
  35. uintptr_t base_ptr = (uintptr_t)glbMemMgr.malloc(base_size);
  36. { // Debugging
  37. #ifndef NDEBUG
  38. for(size_t i=0;i<base_size;i++){
  39. ((char*)base_ptr)[i]=MemoryManager::init_mem_val;
  40. }
  41. #endif
  42. }
  43. ASSERT_WITH_MSG(base_ptr!=0, "malloc failed.");
  44. uintptr_t A = (uintptr_t)(base_ptr + alignment+sizeof(PtrData)) & ~(uintptr_t)alignment;
  45. PtrData& p_data=((PtrData*)A)[-1];
  46. p_data.n_elem=n_elem;
  47. p_data.type_id=TypeId<T>::value();
  48. p_data.base_size=base_size;
  49. p_data.base=base_ptr;
  50. return (T*)A;
  51. }
  52. template <class T>
  53. void aligned_free_f(T* A){
  54. void* p=(void*)A;
  55. if (!p) return;
  56. PtrData& p_data=((PtrData*)p)[-1];
  57. { // Debugging
  58. #ifndef NDEBUG
  59. for(char* ptr=(char*)p_data.base;ptr<((char*)A)-sizeof(PtrData);ptr++){
  60. assert(*ptr==MemoryManager::init_mem_val);
  61. }
  62. for(char* ptr=(char*)(A+p_data.n_elem);ptr<((char*)p_data.base)+p_data.base_size;ptr++){
  63. assert(*ptr==MemoryManager::init_mem_val);
  64. }
  65. #endif
  66. }
  67. glbMemMgr.free((char*)p_data.base);
  68. }
  69. template <class T>
  70. T* aligned_malloc(size_t n_elem, size_t alignment){
  71. if(!n_elem) return NULL;
  72. #ifdef NDEBUG
  73. T* A=new T[n_elem];
  74. assert(A!=NULL);
  75. #else
  76. T* A=aligned_malloc_f<T>(n_elem,alignment);
  77. PtrData& p_data=((PtrData*)A)[-1];
  78. assert(p_data.n_elem==n_elem);
  79. assert(p_data.type_id==TypeId<T>::value());
  80. for(size_t i=0;i<n_elem;i++){
  81. T* Ai=new(A+i) T();
  82. assert(Ai==(A+i));
  83. }
  84. #endif
  85. return A;
  86. }
  87. template <>
  88. inline double* aligned_malloc<double>(size_t n_elem, size_t alignment){
  89. return aligned_malloc_f<double>(n_elem,alignment);
  90. }
  91. template <>
  92. inline float* aligned_malloc<float>(size_t n_elem, size_t alignment){
  93. return aligned_malloc_f<float>(n_elem,alignment);
  94. }
  95. template <>
  96. inline char* aligned_malloc<char>(size_t n_elem, size_t alignment){
  97. return aligned_malloc_f<char>(n_elem,alignment);
  98. }
  99. template <class T>
  100. void aligned_free(T* A){
  101. #ifdef NDEBUG
  102. delete[] A;
  103. #else
  104. void* p=(void*)A;
  105. if (!p) return;
  106. PtrData& p_data=((PtrData*)p)[-1];
  107. assert(p_data.type_id==TypeId<T>::value());
  108. size_t n_elem=p_data.n_elem;
  109. for(size_t i=0;i<n_elem;i++){
  110. (A+i)->~T();
  111. }
  112. aligned_free_f<T>(A);
  113. #endif
  114. }
  115. template <>
  116. inline void aligned_free<double>(double* p_){
  117. aligned_free_f<double>(p_);
  118. }
  119. template <>
  120. inline void aligned_free<float>(float* p_){
  121. aligned_free_f<float>(p_);
  122. }
  123. template <>
  124. inline void aligned_free<char>(char* p_){
  125. aligned_free_f<char>(p_);
  126. }
  127. inline void * memcopy ( void * destination, const void * source, size_t num ){
  128. if(destination==source || num==0) return destination;
  129. return memcpy ( destination, source, num );
  130. }
  131. }//end namespace
  132. }//end namespace
  133. #ifdef __INTEL_OFFLOAD
  134. #pragma offload_attribute(pop)
  135. #endif