AlignOf.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
  2. //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===//
  3. //
  4. // The LLVM Compiler Infrastructure
  5. //
  6. // This file is distributed under the University of Illinois Open Source
  7. // License. See LICENSE.TXT for details.
  8. //
  9. //===----------------------------------------------------------------------===//
  10. //
  11. // This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. // ATen: modified from llvm::AlignOf
  15. // replaced LLVM_ALIGNAS with alignas
  16. #pragma once
  17. #include <cstddef>
  18. namespace c10 {
  19. /// \struct AlignedCharArray
  20. /// \brief Helper for building an aligned character array type.
  21. ///
  22. /// This template is used to explicitly build up a collection of aligned
  23. /// character array types. We have to build these up using a macro and explicit
  24. /// specialization to cope with MSVC (at least till 2015) where only an
  25. /// integer literal can be used to specify an alignment constraint. Once built
  26. /// up here, we can then begin to indirect between these using normal C++
  27. /// template parameters.
  28. // MSVC requires special handling here.
  29. #ifndef _MSC_VER
  30. template <size_t Alignment, size_t Size>
  31. struct AlignedCharArray {
  32. // NOLINTNEXTLINE(*c-arrays)
  33. alignas(Alignment) char buffer[Size];
  34. };
  35. #else // _MSC_VER
  36. /// \brief Create a type with an aligned char buffer.
  37. template <size_t Alignment, size_t Size>
  38. struct AlignedCharArray;
  39. // We provide special variations of this template for the most common
  40. // alignments because __declspec(align(...)) doesn't actually work when it is
  41. // a member of a by-value function argument in MSVC, even if the alignment
  42. // request is something reasonably like 8-byte or 16-byte. Note that we can't
  43. // even include the declspec with the union that forces the alignment because
  44. // MSVC warns on the existence of the declspec despite the union member forcing
  45. // proper alignment.
  46. template <size_t Size>
  47. struct AlignedCharArray<1, Size> {
  48. union {
  49. char aligned;
  50. char buffer[Size];
  51. };
  52. };
  53. template <size_t Size>
  54. struct AlignedCharArray<2, Size> {
  55. union {
  56. short aligned;
  57. char buffer[Size];
  58. };
  59. };
  60. template <size_t Size>
  61. struct AlignedCharArray<4, Size> {
  62. union {
  63. int aligned;
  64. char buffer[Size];
  65. };
  66. };
  67. template <size_t Size>
  68. struct AlignedCharArray<8, Size> {
  69. union {
  70. double aligned;
  71. char buffer[Size];
  72. };
  73. };
  74. // The rest of these are provided with a __declspec(align(...)) and we simply
  75. // can't pass them by-value as function arguments on MSVC.
  76. #define AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
  77. template <size_t Size> \
  78. struct AlignedCharArray<x, Size> { \
  79. __declspec(align(x)) char buffer[Size]; \
  80. };
  81. AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
  82. AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
  83. AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
  84. AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
  85. #undef AT_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
  86. #endif // _MSC_VER
  87. namespace detail {
  88. template <
  89. typename T1,
  90. typename T2 = char,
  91. typename T3 = char,
  92. typename T4 = char,
  93. typename T5 = char,
  94. typename T6 = char,
  95. typename T7 = char,
  96. typename T8 = char,
  97. typename T9 = char,
  98. typename T10 = char>
  99. class AlignerImpl {
  100. T1 t1;
  101. T2 t2;
  102. T3 t3;
  103. T4 t4;
  104. T5 t5;
  105. T6 t6;
  106. T7 t7;
  107. T8 t8;
  108. T9 t9;
  109. T10 t10;
  110. public:
  111. AlignerImpl() = delete;
  112. };
  113. template <
  114. typename T1,
  115. typename T2 = char,
  116. typename T3 = char,
  117. typename T4 = char,
  118. typename T5 = char,
  119. typename T6 = char,
  120. typename T7 = char,
  121. typename T8 = char,
  122. typename T9 = char,
  123. typename T10 = char>
  124. union SizerImpl {
  125. // NOLINTNEXTLINE(*c-arrays)
  126. char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
  127. arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
  128. arr9[sizeof(T9)], arr10[sizeof(T10)];
  129. };
  130. } // end namespace detail
  131. /// \brief This union template exposes a suitably aligned and sized character
  132. /// array member which can hold elements of any of up to ten types.
  133. ///
  134. /// These types may be arrays, structs, or any other types. The goal is to
  135. /// expose a char array buffer member which can be used as suitable storage for
  136. /// a placement new of any of these types. Support for more than ten types can
  137. /// be added at the cost of more boilerplate.
  138. template <
  139. typename T1,
  140. typename T2 = char,
  141. typename T3 = char,
  142. typename T4 = char,
  143. typename T5 = char,
  144. typename T6 = char,
  145. typename T7 = char,
  146. typename T8 = char,
  147. typename T9 = char,
  148. typename T10 = char>
  149. struct AlignedCharArrayUnion
  150. : AlignedCharArray<
  151. alignof(detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>),
  152. sizeof(::c10::detail::
  153. SizerImpl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>)> {};
  154. } // end namespace c10
  155. #else
  156. #error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
  157. #endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)