SYCL: Avoid using no_init read accessor in rocFFT
[alexxy/gromacs.git] / src / gromacs / utility / alignedallocator.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2017,2019,2021, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief Declares allocation policy classes and allocators that are
37  * used to make library containers compatible with alignment
38  * requirements of particular hardware, e.g. memory operations for
39  * SIMD or accelerators.
40  *
41  * \author Erik Lindahl <erik.lindahl@gmail.com>
42  * \author Mark Abraham <mark.j.abraham@gmail.com>
43  * \inpublicapi
44  * \ingroup module_utility
45  */
46 #ifndef GMX_UTILITY_ALIGNEDALLOCATOR_H
47 #define GMX_UTILITY_ALIGNEDALLOCATOR_H
48
49 #include <cstddef>
50
51 #include "gromacs/utility/allocator.h"
52
53 namespace gmx
54 {
55
56 /*! \libinternal \brief Policy class for configuring gmx::Allocator, to manage
57  * allocations of aligned memory for SIMD code.
58  */
59 class AlignedAllocationPolicy
60 {
61 public:
62     /*! \brief Return the alignment size. */
63     static std::size_t alignment();
64     /*! \brief Allocate memory aligned to alignment() bytes.
65      *
66      *  \param bytes Amount of memory (bytes) to allocate. It is valid to ask for
67      *               0 bytes, which will return a non-null pointer that is properly
68      *               aligned and padded (but that you should not use).
69      *
70      * \return Valid pointer if the allocation worked, otherwise nullptr.
71      *
72      * The memory will always be aligned to 128 bytes, which is our
73      * estimate of the longest cache lines on architectures currently in use.
74      * It will also be padded by the same amount at the end of the
75      * area, to help avoid false cache sharing.
76      *
77      *  \note Memory allocated with this routine must be released with
78      *        gmx::AlignedAllocationPolicy::free(), and absolutely not the system free().
79      */
80     static void* malloc(std::size_t bytes);
81     /*! \brief Free aligned memory
82      *
83      *  \param p  Memory pointer previously returned from malloc()
84      *
85      *  \note This routine should only be called with pointers obtained from
86      *        gmx::AlignedAllocationPolicy::malloc(), and absolutely not any
87      *        pointers obtained the system malloc().
88      */
89     static void free(void* p);
90 };
91
92 /*! \brief Aligned memory allocator.
93  *
94  *  \tparam T          Type of objects to allocate
95  *
96  * This convenience partial specialization can be used for the
97  * optional allocator template parameter in standard library
98  * containers, which is necessary e.g. to use SIMD aligned load and
99  * store operations on data in those containers. The memory will
100  * always be aligned according to the behavior of
101  * AlignedAllocationPolicy.
102  */
103 template<class T>
104 using AlignedAllocator = Allocator<T, AlignedAllocationPolicy>;
105
106
107 /*! \brief Return the memory page size on this system
108  *
109  * Implements the "construct on first use" idiom to avoid the static
110  * initialization order fiasco where a possible static page-aligned
111  * container would be initialized before the alignment variable was.
112  *
113  * Note that thread-safety is guaranteed by the C++11 language
114  * standard. */
115 std::size_t pageSize();
116
117 /*! \libinternal \brief Policy class for configuring gmx::Allocator,
118  * to manage allocations of page-aligned memory that can be locked for
119  * asynchronous transfer to GPU devices.
120  */
121 class PageAlignedAllocationPolicy
122 {
123 public:
124     /*! \brief Return the alignment size of memory pages on this system.
125      *
126      * Queries sysconf/WinAPI, otherwise guesses 4096. */
127     static std::size_t alignment();
128     /*! \brief Allocate memory aligned to alignment() bytes.
129      *
130      *  \param bytes Amount of memory (bytes) to allocate. It is valid to ask for
131      *               0 bytes, which will return a non-null pointer that is properly
132      *               aligned and padded (but that you should not use).
133      *
134      * \return Valid pointer if the allocation worked, otherwise nullptr.
135      *
136      *  \note Memory allocated with this routine must be released with
137      *        gmx::PageAlignedAllocationPolicy::free(), and absolutely not the system free().
138      */
139     static void* malloc(std::size_t bytes);
140     /*! \brief Free aligned memory
141      *
142      *  \param p  Memory pointer previously returned from malloc()
143      *
144      *  \note This routine should only be called with pointers obtained from
145      *        gmx::PageAlignedAllocationPolicy::malloc(), and absolutely not any
146      *        pointers obtained the system malloc().
147      */
148     static void free(void* p);
149 };
150
151 /*! \brief PageAligned memory allocator.
152  *
153  *  \tparam T          Type of objects to allocate
154  *
155  * This convenience partial specialization can be used for the
156  * optional allocator template parameter in standard library
157  * containers, which is necessary for locking memory pages for
158  * asynchronous transfer between a GPU device and the host.  The
159  * memory will always be aligned according to the behavior of
160  * PageAlignedAllocationPolicy.
161  */
162 template<class T>
163 using PageAlignedAllocator = Allocator<T, PageAlignedAllocationPolicy>;
164
165 } // namespace gmx
166
167 #endif // GMX_UTILITY_ALIGNEDALLOCATOR_H