Allocators

The fundamental concept for accessing memory through Umpire is the umpire::Allocator. An umpire::Allocator is a C++ object that can be used to allocate and deallocate memory, as well as query a pointer to get some extra information about it.

All umpire::Allocator s are created and managed by Umpire’s umpire::ResourceManager. To get an Allocator, you need to ask for one:

  umpire::Allocator allocator = rm.getAllocator("HOST");

You can also use an existing allocator to build an additional allocator off of it:

  auto addon_allocator = rm.getAllocator(allocator.getName());

This “add-on” allocator will also be built with the same memory resource. More information on memory resources is provided in the next section. Additionally, once you have an umpire::Allocator you can use it to allocate and deallocate memory:

  double* data =
      static_cast<double*>(allocator.allocate(SIZE * sizeof(double)));
  allocator.deallocate(data);

In the next section, we will see how to allocate memory using different resources.

//////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-20, Lawrence Livermore National Security, LLC and Umpire
// project contributors. See the COPYRIGHT file for details.
//
// SPDX-License-Identifier: (MIT)
//////////////////////////////////////////////////////////////////////////////
#include "umpire/Allocator.hpp"
#include "umpire/ResourceManager.hpp"

int main(int, char**)
{
  auto& rm = umpire::ResourceManager::getInstance();

  // _sphinx_tag_tut_get_allocator_start
  umpire::Allocator allocator = rm.getAllocator("HOST");
  // _sphinx_tag_tut_get_allocator_end

  constexpr std::size_t SIZE = 1024;

  // _sphinx_tag_tut_allocate_start
  double* data =
      static_cast<double*>(allocator.allocate(SIZE * sizeof(double)));
  // _sphinx_tag_tut_allocate_end

  std::cout << "Allocated " << (SIZE * sizeof(double)) << " bytes using the "
            << allocator.getName() << " allocator." << std::endl;

  //_sphinx_tag_tut_getAllocator_start
  auto addon_allocator = rm.getAllocator(allocator.getName());
  //_sphinx_tag_tut_getAllocator_end
  
  std::cout << "Created an add-on allocator of size " << addon_allocator.getCurrentSize()
            << " using the " << allocator.getName() << " allocator." << std::endl;

  // _sphinx_tag_tut_deallocate_start
  allocator.deallocate(data);
  // _sphinx_tag_tut_deallocate_end

  std::cout << "...Memory deallocated." << std::endl;

  return 0;
}