Documentation 6b54b78464
Loading...
Searching...
No Matches
allocation_toolbox.hpp
Go to the documentation of this file.
1/*!
2 * \file allocation_toolbox.hpp
3 * \brief Helper function and classes for memory allocation.
4 * Focus on portability across platforms.
5 * \note These are "kernel" functions, only to be used with good reason,
6 * always try to use higher level container classes.
7 * \author P. Gomes, D. Kavolis
8 * \version 8.5.0 "Harrier"
9 *
10 * SU2 Project Website: https://su2code.github.io
11 *
12 * The SU2 Project is maintained by the SU2 Foundation
13 * (http://su2foundation.org)
14 *
15 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
16 *
17 * SU2 is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
21 *
22 * SU2 is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
29 */
30
31#pragma once
32
33#if defined(_WIN32)
34#include <malloc.h>
35#else
36#include <stdlib.h>
37#endif
38
39#ifdef HAVE_CUDA
40#include "../linear_algebra/GPUComms.cuh"
41#endif
42
43#include <cstring>
44
45#include <cassert>
46
48
49inline constexpr bool is_power_of_two(size_t x) { return x && !(x & (x - 1)); }
50
51inline constexpr size_t round_up(size_t multiple, size_t x) { return ((x + multiple - 1) / multiple) * multiple; }
52
53/*!
54 * \brief Aligned memory allocation compatible across platforms.
55 * \param[in] alignment, in bytes, of the memory being allocated.
56 * \param[in] size, also in bytes.
57 * \tparam ZeroInit, initialize memory to 0.
58 * \return Pointer to memory, always use su2::aligned_free to deallocate.
59 */
60template <class T, bool ZeroInit = false>
61inline T* aligned_alloc(size_t alignment, size_t size) noexcept {
62 assert(is_power_of_two(alignment));
63
64 if (alignment < alignof(void*)) alignment = alignof(void*);
65
66 size = round_up(alignment, size);
67
68 void* ptr = nullptr;
69
70 if (size > 0) {
71#if defined(__APPLE__)
72 if (::posix_memalign(&ptr, alignment, size) != 0) {
73 ptr = nullptr;
74 }
75#elif defined(_WIN32)
76 ptr = _aligned_malloc(size, alignment);
77#else
78 ptr = ::aligned_alloc(alignment, size);
79#endif
80 if (ZeroInit) memset(ptr, 0, size);
81 }
82 return static_cast<T*>(ptr);
83}
84
85/*!
86 * \brief Free memory allocated with su2::aligned_alloc.
87 * \param[in] ptr, pointer to memory we want to release.
88 */
89template <class T>
90inline void aligned_free(T* ptr) noexcept {
91#if defined(_WIN32)
92 _aligned_free(ptr);
93#else
94 free(ptr);
95#endif
96}
97
98} // namespace MemoryAllocation
99
101/*!
102 * \brief Memory allocation for variables on the GPU.
103 * \param[in] size in bytes.
104 * \tparam ZeroInit, initialize memory to 0.
105 * \return Pointer to memory, always use gpu_free to deallocate.
106 */
107template <class T, bool ZeroInit = false>
108inline T* gpu_alloc(size_t size) noexcept {
109 void* ptr = nullptr;
110
111#if defined(HAVE_CUDA)
112 gpuErrChk(cudaMalloc((void**)(&ptr), size));
113 if (ZeroInit) gpuErrChk(cudaMemset((void*)(ptr), 0.0, size));
114#else
115 return 0;
116#endif
117
118 return static_cast<T*>(ptr);
119}
120
121/*!
122 * \brief Free memory allocated on the GPU with gpu_alloc.
123 * \param[in] ptr, pointer to memory we want to release.
124 */
125template <class T>
126inline void gpu_free(T* ptr) noexcept {
127#ifdef HAVE_CUDA
128 gpuErrChk(cudaFree((void*)ptr));
129#endif
130}
131/*!
132 * \brief Memory allocation for variables on the GPU along with initialization from a source host array.
133 * \param[in] size in bytes.
134 * \return Pointer to memory, always use gpu_free to deallocate.
135 */
136template <class T>
137inline T* gpu_alloc_cpy(const T* src_ptr, size_t size) noexcept {
138 void* ptr = nullptr;
139
140#ifdef HAVE_CUDA
141 gpuErrChk(cudaMalloc((void**)(&ptr), size));
142 gpuErrChk(cudaMemcpy((void*)(ptr), (void*)src_ptr, size, cudaMemcpyHostToDevice));
143#endif
144
145 return static_cast<T*>(ptr);
146}
147
148/*!
149 * \brief Page-locked ("pinned") host memory allocation.
150 * \note Unlike regular (pageable) host memory, cudaMemcpyAsync from/to a pinned buffer is
151 * actually asynchronous with respect to the host thread; from pageable memory the driver
152 * silently falls back to a synchronous staged copy. Only worth it for host buffers that
153 * are the source/destination of an async transfer meant to overlap with other host work.
154 * \param[in] size in bytes.
155 * \tparam ZeroInit, initialize memory to 0.
156 * \return Pointer to memory, always use pinned_free to deallocate.
157 */
158template <class T, bool ZeroInit = false>
159inline T* pinned_alloc(size_t size) noexcept {
160 void* ptr = nullptr;
161
162#if defined(HAVE_CUDA)
163 gpuErrChk(cudaMallocHost((void**)(&ptr), size));
164 if (ZeroInit) memset(ptr, 0, size);
165#else
166 return 0;
167#endif
168
169 return static_cast<T*>(ptr);
170}
171
172/*!
173 * \brief Free memory allocated with pinned_alloc.
174 * \param[in] ptr, pointer to memory we want to release.
175 */
176template <class T>
177inline void pinned_free(T* ptr) noexcept {
178#ifdef HAVE_CUDA
179 gpuErrChk(cudaFreeHost((void*)ptr));
180#endif
181}
182} // namespace GPUMemoryAllocation
#define gpuErrChk(ans)
Definition GPUComms.cuh:58
Definition allocation_toolbox.hpp:100
T * gpu_alloc(size_t size) noexcept
Memory allocation for variables on the GPU.
Definition allocation_toolbox.hpp:108
void pinned_free(T *ptr) noexcept
Free memory allocated with pinned_alloc.
Definition allocation_toolbox.hpp:177
T * pinned_alloc(size_t size) noexcept
Page-locked ("pinned") host memory allocation.
Definition allocation_toolbox.hpp:159
void gpu_free(T *ptr) noexcept
Free memory allocated on the GPU with gpu_alloc.
Definition allocation_toolbox.hpp:126
T * gpu_alloc_cpy(const T *src_ptr, size_t size) noexcept
Memory allocation for variables on the GPU along with initialization from a source host array.
Definition allocation_toolbox.hpp:137
Definition allocation_toolbox.hpp:47
void aligned_free(T *ptr) noexcept
Free memory allocated with su2::aligned_alloc.
Definition allocation_toolbox.hpp:90
constexpr bool is_power_of_two(size_t x)
Definition allocation_toolbox.hpp:49
constexpr size_t round_up(size_t multiple, size_t x)
Definition allocation_toolbox.hpp:51
T * aligned_alloc(size_t alignment, size_t size) noexcept
Aligned memory allocation compatible across platforms.
Definition allocation_toolbox.hpp:61