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
26namespace glow {
27
28/// The tensor payload is allocated to be aligned to this value.
29constexpr unsigned TensorAlignment = 64;
30
31/// Allocate \p size bytes of memory aligned to \p align bytes.
32inline 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.
45inline void alignedFree(void *p) { glow_aligned_free(p); }
46
47/// Rounds up \p size to the nearest \p alignment.
48inline 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);
62template <class T, class... Args>
63typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
64make_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.
76template <class T>
77typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
78 std::unique_ptr<T>>::type
79make_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.
84template <class T, class... Args>
85typename std::enable_if<std::extent<T>::value != 0>::type
86make_unique(Args &&...) = delete;
87
88} // end namespace glow
89
90#endif // GLOW_SUPPORT_MEMORY_H
91