1 | /** |
2 | * Copyright (c) Glow Contributors. See CONTRIBUTORS file. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #ifndef GLOW_SUPPORT_MEMORY_H |
17 | #define GLOW_SUPPORT_MEMORY_H |
18 | |
19 | #include "glow/Support/Compiler.h" |
20 | |
21 | #include <glog/logging.h> |
22 | |
23 | #include <cstdlib> |
24 | #include <memory> |
25 | |
26 | namespace glow { |
27 | |
28 | /// The tensor payload is allocated to be aligned to this value. |
29 | constexpr unsigned TensorAlignment = 64; |
30 | |
31 | /// Allocate \p size bytes of memory aligned to \p align bytes. |
32 | inline void *alignedAlloc(size_t size, size_t align) { |
33 | DCHECK_GE(align, sizeof(void *)) << "Alignment too small." ; |
34 | DCHECK_EQ(align % sizeof(void *), 0) |
35 | << "Alignment is not a multiple of the machine word size." ; |
36 | void *ptr; |
37 | int res = glow_aligned_malloc(&ptr, align, size); |
38 | CHECK_EQ(res, 0) << "Memory allocation: posix_memalign failed with code " |
39 | << res << "! Possibly out of heap memory!" ; |
40 | CHECK_EQ((size_t)ptr % align, 0) << "Memory allocation: Alignment failed!" ; |
41 | return ptr; |
42 | } |
43 | |
44 | /// Free aligned memory. |
45 | inline void alignedFree(void *p) { glow_aligned_free(p); } |
46 | |
47 | /// Rounds up \p size to the nearest \p alignment. |
48 | inline size_t alignedSize(size_t size, size_t alignment) { |
49 | size_t mod = size % alignment; |
50 | return mod ? size + alignment - mod : size; |
51 | } |
52 | |
53 | // Implement make_unique according to N3656. |
54 | |
55 | /// \brief Constructs a `new T()` with the given args and returns a |
56 | /// `unique_ptr<T>` which owns the object. |
57 | /// |
58 | /// Example: |
59 | /// |
60 | /// auto p = make_unique<int>(); |
61 | /// auto p = make_unique<std::tuple<int, int>>(0, 1); |
62 | template <class T, class... Args> |
63 | typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type |
64 | make_unique(Args &&...args) { |
65 | return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); |
66 | } |
67 | |
68 | /// \brief Constructs a `new T[n]` with the given args and returns a |
69 | /// `unique_ptr<T[]>` which owns the object. |
70 | /// |
71 | /// \param n size of the new array. |
72 | /// |
73 | /// Example: |
74 | /// |
75 | /// auto p = make_unique<int[]>(2); // value-initializes the array with 0's. |
76 | template <class T> |
77 | typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, |
78 | std::unique_ptr<T>>::type |
79 | make_unique(size_t n) { |
80 | return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]()); |
81 | } |
82 | |
83 | /// This function isn't used and is only here to provide better compile errors. |
84 | template <class T, class... Args> |
85 | typename std::enable_if<std::extent<T>::value != 0>::type |
86 | make_unique(Args &&...) = delete; |
87 | |
88 | } // end namespace glow |
89 | |
90 | #endif // GLOW_SUPPORT_MEMORY_H |
91 | |