Gromacs  2018.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
List of all members | Classes | Public Types | Public Member Functions | Friends
gmx::HostAllocationPolicy Class Reference

#include <gromacs/gpu_utils/hostallocator.h>

Description

Policy class for configuring gmx::Allocator, to manage allocations of memory that may be needed for e.g. GPU transfers.

This allocator has state, so is most useful in cases where it is not known at compile time whether the allocated memory will be transferred to some device. It will increase the size of containers that use it. If the GROMACS build is configured with CUDA support, then memory will be allocated with PageAlignedAllocator, and that page pinned to physical memory if the pinning mode has been activated. If pinning mode is deactivated, or the GROMACS build does not support CUDA, then the memory will be allocated with AlignedAllocator. The pin() and unpin() methods work with the CUDA build, and silently do nothing otherwise. In future, we may modify or generalize this to work differently in other cases.

The intended use is to configure gmx::Allocator with this class as its policy class, and then to use e.g. std::vector::get_allocator().getPolicy() to control whether the allocation policy should activate its pinning mode. The policy object can also be used to explicitly pin() and unpin() the buffer when it is using PinningPolicy::CanBePinned. The policy object is returned by value (as required by the C++ standard for get_allocator(), which copies a std::shared_ptr, so the policy object should be retrieved sparingly, e.g. only upon resize of the allocation. (Normal operation of the vector, e.g. during resize, incurs only the cost of the pointer indirection needed to consult the current state of the allocation policy.)

Todo:
As a minor optimization, consider also having a stateless version of this policy, which might be slightly faster or more convenient to use in the cases where it is known at compile time that the allocation will be used to transfer to a GPU.

Classes

class  Impl
 Private implementation class. More...
 

Public Types

using propagate_on_container_copy_assignment = std::true_type
 Specify an allocator trait so that the stateful allocator should propagate.
 
using propagate_on_container_move_assignment = std::true_type
 Specify an allocator trait so that the stateful allocator should propagate.
 
using propagate_on_container_swap = std::true_type
 Specify an allocator trait so that the stateful allocator should propagate.
 

Public Member Functions

 HostAllocationPolicy ()
 Default constructor.
 
std::size_t alignment ()
 Return the alignment size currently used by the active pinning policy.
 
void * malloc (std::size_t bytes) const noexcept
 Allocate and perhaps pin page-aligned memory suitable for e.g. GPU transfers. More...
 
void free (void *buffer) const noexcept
 Free the memory, after unpinning (if appropriate). More...
 
void pin () const noexcept
 Pin the allocation to physical memory, if appropriate. More...
 
void unpin () const noexcept
 Unpin the allocation, if appropriate. More...
 
PinningPolicy pinningPolicy () const
 Return the current pinning policy (which is semi-independent of whether the buffer is actually pinned). More...
 

Friends

template<class T >
void changePinningPolicy (HostVector< T > *v, PinningPolicy pinningPolicy)
 Declare as a friend function the only supported way to change the pinning policy. More...
 

Member Function Documentation

void gmx::HostAllocationPolicy::free ( void *  buffer) const
noexcept

Free the memory, after unpinning (if appropriate).

Parameters
bufferMemory pointer previously returned from gmx::HostAllocationPolicy::malloc()
Note
This routine should only be called with pointers obtained from gmx:HostAllocationPolicy::malloc(), and absolutely not any pointers obtained the system malloc().

Does not throw.

void * gmx::HostAllocationPolicy::malloc ( std::size_t  bytes) const
noexcept

Allocate and perhaps pin page-aligned memory suitable for e.g. GPU transfers.

Before attempting to allocate, unpin() is called. After a successful allocation, pin() is called. (Whether these do things depends on the PinningPolicy that is in effect.)

Parameters
bytesAmount of memory (bytes) to allocate. It is valid to ask for 0 bytes, which will return a non-null pointer that is properly aligned and padded (but that you should not use).
Returns
Valid pointer if the allocation+optional pinning worked, otherwise nullptr.
Note
Memory allocated with this routine must be released with gmx::HostAllocationPolicy::free(), and absolutely not the system free().

Does not throw.

void gmx::HostAllocationPolicy::pin ( ) const
noexcept

Pin the allocation to physical memory, if appropriate.

If the allocation policy is not in pinning mode, or the allocation is empty, ot the allocation is already pinned, then do nothing.

Does not throw.

PinningPolicy gmx::HostAllocationPolicy::pinningPolicy ( ) const

Return the current pinning policy (which is semi-independent of whether the buffer is actually pinned).

Does not throw.

void gmx::HostAllocationPolicy::unpin ( ) const
noexcept

Unpin the allocation, if appropriate.

Regardless of the allocation policy, unpin the memory if previously pinned, otherwise do nothing.

Does not throw.

Friends And Related Function Documentation

template<class T >
void changePinningPolicy ( HostVector< T > *  v,
PinningPolicy  pinningPolicy 
)
friend

Declare as a friend function the only supported way to change the pinning policy.

When the pinning policy changes, we want the state of the allocation to match the new policy. However, that requires a copy and swap of the buffers, which can only take place at the level of the container. So we wrap the required operations in a helper friend function.

Of course, if there is no allocation because the vector is empty, then nothing will change.

If the vector has contents, then a full reallocation and buffer copy are needed if the policy change requires tighter restrictions, and desirable even if the policy change requires looser restrictions. That cost is OK, because GROMACS will do this operation very rarely (e.g. when auto-tuning and deciding to switch whether a task will run on a GPU, or not).


The documentation for this class was generated from the following files: