Skip to content

Commit 7af7ebb

Browse files
committed
adding a tryGetAllocator
1 parent ac034c7 commit 7af7ebb

4 files changed

Lines changed: 59 additions & 0 deletions

File tree

docs/sphinx/tutorial/resources.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ example:
3535
:end-before: _sphinx_tag_tut_get_allocator_end
3636
:language: C++
3737

38+
If you would prefer to avoid exceptions when an allocator is not available,
39+
you can instead use :func:`umpire::ResourceManager::tryGetAllocator`, which
40+
returns a ``std::optional<umpire::Allocator>`` that is empty when the
41+
requested allocator cannot be found:
42+
43+
.. code-block:: cpp
44+
45+
auto& rm = umpire::ResourceManager::getInstance();
46+
auto maybe_allocator = rm.tryGetAllocator("HOST");
47+
48+
if (maybe_allocator) {
49+
auto allocator = *maybe_allocator;
50+
// use allocator
51+
}
52+
3853
Note that since every allocator supports the same calls, no matter which resource
3954
it is for, this means we can run the same code for all the resources available in
4055
the system.

src/umpire/ResourceManager.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,29 @@ strategy::AllocationStrategy* ResourceManager::getAllocationStrategy(const std::
209209
return m_allocators_by_name[name];
210210
}
211211

212+
std::optional<Allocator> ResourceManager::tryGetAllocator(const std::string& name)
213+
{
214+
UMPIRE_LOG(Debug, "(\"" << name << "\")");
215+
216+
resource::MemoryResourceRegistry& registry{resource::MemoryResourceRegistry::getInstance()};
217+
auto resource_names = registry.getResourceNames();
218+
219+
auto allocator = m_allocators_by_name.find(name);
220+
if (allocator == m_allocators_by_name.end()) {
221+
auto resource_name = std::find(resource_names.begin(), resource_names.end(), name);
222+
if (resource_name != std::end(resource_names)) {
223+
makeResource(name);
224+
allocator = m_allocators_by_name.find(name);
225+
}
226+
}
227+
228+
if (allocator == m_allocators_by_name.end()) {
229+
return std::nullopt;
230+
}
231+
232+
return Allocator{allocator->second};
233+
}
234+
212235
Allocator ResourceManager::getAllocator(const std::string& name)
213236
{
214237
UMPIRE_LOG(Debug, "(\"" << name << "\")");

src/umpire/ResourceManager.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <list>
1111
#include <memory>
1212
#include <mutex>
13+
#include <optional>
1314
#include <string>
1415
#include <unordered_map>
1516
#include <vector>
@@ -67,6 +68,14 @@ class ResourceManager {
6768
*/
6869
Allocator getAllocator(const std::string& name);
6970

71+
/*!
72+
* \brief Try to get the Allocator with the given name.
73+
*
74+
* This function returns an empty optional if the allocator does not exist
75+
* or cannot be created, instead of throwing an exception.
76+
*/
77+
std::optional<Allocator> tryGetAllocator(const std::string& name);
78+
7079
Allocator getAllocator(const char* name);
7180

7281
/*!

tests/integration/allocator_integration_tests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,18 @@ TEST(Allocator, registerAllocator)
230230
ASSERT_FALSE(rm.isAllocator("BANANAS"));
231231
}
232232

233+
TEST(Allocator, TryGetAllocator)
234+
{
235+
auto& rm = umpire::ResourceManager::getInstance();
236+
237+
auto host_allocator = rm.tryGetAllocator("HOST");
238+
ASSERT_TRUE(host_allocator.has_value());
239+
EXPECT_EQ(std::string{"HOST"}, host_allocator->getName());
240+
241+
auto bad_allocator = rm.tryGetAllocator("BANANAS");
242+
EXPECT_FALSE(bad_allocator.has_value());
243+
}
244+
233245
TEST(Allocator, GetSetDefault)
234246
{
235247
auto& rm = umpire::ResourceManager::getInstance();

0 commit comments

Comments
 (0)