dae54f2144be7f2adf9867a1bcafcc722661acf9
[alexxy/gromacs.git] / src / gromacs / gpu_utils / hostallocator.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2017, 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 /*! \libinternal \file
36  * \brief Declares gmx::HostAllocationPolicy and gmx::HostAllocator,
37  * which are used to make standard library containers that can
38  * allocate memory suitable for GPU transfers.
39  *
40  * \author Mark Abraham <mark.j.abraham@gmail.com>
41  * \inlibraryapi
42  */
43 #ifndef GMX_GPU_UTILS_HOSTALLOCATOR_H
44 #define GMX_GPU_UTILS_HOSTALLOCATOR_H
45
46 #include <cstddef>
47
48 #include "gromacs/utility/allocator.h"
49
50 namespace gmx
51 {
52
53 /*! \libinternal
54  * \brief Policy class for configuring gmx::Allocator, to manage
55  * allocations of memory that is suitable for GPU transfers.
56  *
57  * This allocator has state, so is most useful in cases where it is
58  * not known at compile time whether the allocated memory will be
59  * transferred to a GPU. It will increase the size of containers that
60  * use it. Memory allocated will always be aligned by the GPU
61  * framework, or by AlignedAllocationPolicy.
62  *
63  * \todo Consider also having a stateless version of this policy,
64  * which might be slightly faster or more convenient to use in the
65  * cases where it is known at compile time that the allocation will be
66  * used to transfer to a GPU.
67  */
68 class HostAllocationPolicy
69 {
70     public:
71         //! Helper construction enum
72         enum class Impl : int
73         {
74             AllocateAligned  = 0,
75             AllocateForGpu   = 1
76         };
77         //! Constructor.
78         explicit HostAllocationPolicy(Impl s = Impl::AllocateAligned);
79         /*! \brief Allocate GPU memory
80          *
81          *  \param bytes Amount of memory (bytes) to allocate. It is
82          *               valid to ask for 0 bytes, which will return a
83          *               non-null pointer that is properly aligned in
84          *               page-locked memory (but that you should not
85          *               use). TODO check this.
86          *
87          * \return Valid pointer if the allocation worked, otherwise nullptr.
88          *
89          * The memory will always be allocated according to the requirements
90          * of the acceleration platform in use (e.g. CUDA).
91          *
92          *  \note Memory allocated with this routine must be released
93          *        with gmx::HostAllocationPolicy::free(), and
94          *        absolutely not the system free().
95          */
96         void *
97         malloc(std::size_t bytes) const;
98         /*! \brief Free GPU memory
99          *
100          *  \param buffer  Memory pointer previously returned from gmx::HostAllocationPolicy::malloc()
101          *
102          *  \note This routine should only be called with pointers
103          *        obtained from gmx:HostAllocationPolicy::malloc(),
104          *        and absolutely not any pointers obtained the system
105          *        malloc().
106          */
107         void
108         free(void *buffer) const;
109     private:
110         /*! \brief State of the allocator.
111          *
112          * This could change through assignment of one policy to
113          * another, so isn't const. */
114         Impl allocateForGpu_;
115 };
116
117 /*! \brief Convenience function
118  *
119  * The default construction is for non-GPU allocation, and this
120  * function makes it less verbose to get allocation intended for use
121  * with a GPU. */
122 HostAllocationPolicy makeHostAllocationPolicyForGpu();
123
124 /*! \brief Memory allocator for host-side memory for GPU transfers.
125  *
126  *  \tparam T          Type of objects to allocate
127  *
128  * This convenience partial specialization can be used for the
129  * optional allocator template parameter in standard library
130  * containers whose memory will be used for GPU transfers. The memory
131  * will always be allocated according to the behavior of
132  * HostAllocationPolicy.
133  */
134 template <class T>
135 using HostAllocator = Allocator<T, HostAllocationPolicy>;
136
137 }      // namespace gmx
138
139 #endif