/home/runner/work/HiCR/HiCR/include/hicr/backends/hwloc/memoryManager.hpp Source File

HiCR: /home/runner/work/HiCR/HiCR/include/hicr/backends/hwloc/memoryManager.hpp Source File
HiCR
memoryManager.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2025 Huawei Technologies Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
24#pragma once
25
26#include "hwloc.h"
27#include "pthread.h"
31
32namespace HiCR::backend::hwloc
33{
34
39{
40 public:
41
47 MemoryManager(const hwloc_topology_t *topology)
48 : HiCR::MemoryManager(),
49 _topology{topology}
50 {}
51 ~MemoryManager() override = default;
52
58 void setRequestedBindingType(const LocalMemorySlot::binding_type type) { _hwlocBindingRequested = type; }
59
65 [[nodiscard]] LocalMemorySlot::binding_type getRequestedBindingType() const { return _hwlocBindingRequested; }
66
72 __INLINE__ static std::unique_ptr<HiCR::MemoryManager> createDefault()
73 {
74 // Creating HWloc topology object
75 auto topology = new hwloc_topology_t;
76
77 // Reserving memory for hwloc
78 hwloc_topology_init(topology);
79
80 // Initializing HWLoc-based host (CPU) topology manager
81 return std::make_unique<HiCR::backend::hwloc::MemoryManager>(topology);
82 }
83
84 private:
85
91
95 const hwloc_topology_t *const _topology;
96
97 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> allocateLocalMemorySlotImpl(std::shared_ptr<HiCR::MemorySpace> memorySpace, const size_t size) override
98 {
99 // Getting up-casted pointer for the MPI instance
100 auto m = dynamic_pointer_cast<MemorySpace>(memorySpace);
101
102 // Checking whether the memory space passed is compatible with this backend
103 if (m == nullptr) HICR_THROW_LOGIC("The passed memory space is not supported by this memory manager\n");
104
105 // Getting binding type supported by the memory space
106 const auto supportedBindingType = m->getSupportedBindingType();
107
108 // Determining binding type to use
110
111 // Checking whether the operation requested is supported by the HWLoc on this memory space
113 if (_hwlocBindingRequested == LocalMemorySlot::binding_type::relaxed_binding && supportedBindingType == LocalMemorySlot::binding_type::strict_binding)
115 if (_hwlocBindingRequested == LocalMemorySlot::binding_type::relaxed_binding && supportedBindingType == LocalMemorySlot::binding_type::strict_non_binding)
118
119 // Check for failure to provide strict binding
120 if (_hwlocBindingRequested > supportedBindingType)
122 "Requesting an allocation binding support level (%u) not supported by the operating system (HWLoc max support: %u)", _hwlocBindingRequested, supportedBindingType);
123
124 // Getting memory space's HWLoc object to perform the operation with
125 const auto hwlocObj = m->getHWLocObject();
126
127 // Allocating memory in the reqested memory space
128 void *ptr = nullptr;
129 if (bindingTypeToUse == LocalMemorySlot::binding_type::strict_binding)
130 ptr = hwloc_alloc_membind(*_topology, size, hwlocObj->nodeset, HWLOC_MEMBIND_DEFAULT, HWLOC_MEMBIND_BYNODESET | HWLOC_MEMBIND_STRICT);
131 if (bindingTypeToUse == LocalMemorySlot::binding_type::strict_non_binding) ptr = malloc(size);
132
133 // Error checking
134 if (ptr == nullptr) HICR_THROW_RUNTIME("Could not allocate memory (size %lu) in the requested memory space", size);
135
136 // Creating new memory slot object
137 auto memorySlot = std::make_shared<LocalMemorySlot>(supportedBindingType, ptr, size, memorySpace);
138
139 // Assinging new entry in the memory slot map
140 return memorySlot;
141 }
142
143 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> registerLocalMemorySlotImpl(std::shared_ptr<HiCR::MemorySpace> memorySpace, void *const ptr, const size_t size) override
144 {
145 // Creating new memory slot object
146 auto memorySlot = std::make_shared<LocalMemorySlot>(LocalMemorySlot::binding_type::strict_non_binding, ptr, size, memorySpace);
147
148 // Returning new memory slot pointer
149 return memorySlot;
150 }
151
152 __INLINE__ void deregisterLocalMemorySlotImpl(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot) override
153 {
154 // Nothing to do here
155 }
156
157 __INLINE__ void freeLocalMemorySlotImpl(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot) override
158 {
159 // Getting up-casted pointer for the memory slot
160 auto m = dynamic_pointer_cast<LocalMemorySlot>(memorySlot);
161
162 // Checking whether the memory slot passed is compatible with this backend
163 if (m == nullptr) HICR_THROW_LOGIC("The passed memory slot is not supported by this backend\n");
164
165 // Getting memory slot info
166 const auto memorySlotBindingType = m->getBindingType();
167 const auto memorySlotPointer = m->getPointer();
168 const auto memorySlotSize = m->getSize();
169
170 // If using strict binding, use hwloc_free to properly unmap the memory binding
171 if (memorySlotBindingType == LocalMemorySlot::binding_type::strict_binding)
172 {
173 // Freeing memory slot
174 auto status = hwloc_free(*_topology, memorySlotPointer, memorySlotSize);
175
176 // Error checking
177 if (status != 0) HICR_THROW_RUNTIME("Could not free bound memory slot.");
178 }
179
180 // If using strict non binding, use system's free
181 if (memorySlotBindingType == LocalMemorySlot::binding_type::strict_non_binding) { free(memorySlotPointer); }
182 }
183};
184
185} // namespace HiCR::backend::hwloc
Provides a definition for the local memory slot class for the HWLoc-based backend.
This file implements the memory space class for the HWLoc-based backend.
Definition memoryManager.hpp:51
binding_type
Definition localMemorySlot.hpp:44
@ strict_binding
Definition localMemorySlot.hpp:48
@ relaxed_binding
Definition localMemorySlot.hpp:58
@ strict_non_binding
Definition localMemorySlot.hpp:53
Definition memoryManager.hpp:39
LocalMemorySlot::binding_type getRequestedBindingType() const
Definition memoryManager.hpp:65
MemoryManager(const hwloc_topology_t *topology)
Definition memoryManager.hpp:47
void setRequestedBindingType(const LocalMemorySlot::binding_type type)
Definition memoryManager.hpp:58
static __INLINE__ std::unique_ptr< HiCR::MemoryManager > createDefault()
Definition memoryManager.hpp:72
Provides a definition for the base backend's memory manager class.
#define HICR_THROW_RUNTIME(...)
Definition exceptions.hpp:74
#define HICR_THROW_LOGIC(...)
Definition exceptions.hpp:67