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

HiCR: /home/runner/work/HiCR/HiCR/include/hicr/backends/ascend/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
17/*
18 * Copyright Huawei Technologies Switzerland AG
19 * All rights reserved.
20 */
21
29#pragma once
30
31#include <acl/acl.h>
37
38namespace HiCR::backend::ascend
39{
40
49{
50 public:
51
56 : HiCR::MemoryManager()
57 {}
58 ~MemoryManager() = default;
59
60 private:
61
62 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> allocateLocalMemorySlotImpl(std::shared_ptr<HiCR::MemorySpace> memorySpace, const size_t size) override
63 {
64 // Getting up-casted pointer for the ascend instance, first try with the device memory space
65 auto ascendMemSpace = dynamic_pointer_cast<const ascend::MemorySpace>(memorySpace);
66
67 // Checking whether the memory space passed belongs to the device
68 if (ascendMemSpace != NULL) return allocateLocalDeviceMemorySlot(memorySpace, size);
69
70 // Retry with the host memory space
71 auto hostMemSpace = dynamic_pointer_cast<hwloc::MemorySpace>(memorySpace);
72
73 // Checking whether the memory space passed belongs to the host
74 if (hostMemSpace != NULL) return allocateLocalHostMemorySlot(memorySpace, size);
75
76 HICR_THROW_LOGIC("The passed memory space is not supported by this memory manager. Supported ascend and hwloc\n");
77 }
78
79 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> allocateLocalDeviceMemorySlot(const std::shared_ptr<HiCR::MemorySpace> memorySpace, const size_t size)
80 {
81 void *ptr = NULL;
82 aclDataBuffer *dataBuffer;
83
84 // do a malloc on the ascend and create the databuffer
85 auto ascendMemSpace = dynamic_pointer_cast<ascend::MemorySpace>(memorySpace);
86 ptr = deviceAlloc(ascendMemSpace, size);
87 dataBuffer = aclCreateDataBuffer(ptr, size);
88 if (dataBuffer == NULL) HICR_THROW_RUNTIME("Can not create data buffer in device");
89
90 // create the new memory slot
91 return std::make_shared<LocalMemorySlot>(ptr, size, dataBuffer, memorySpace);
92 }
93
94 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> allocateLocalHostMemorySlot(const std::shared_ptr<HiCR::MemorySpace> memorySpace, const size_t size)
95 {
96 void *ptr = NULL;
97
98 // do a malloc on the ascend and create the databuffer
99 ptr = hostAlloc(memorySpace, size);
100
101 // create the new memory slot
102 return std::make_shared<HiCR::LocalMemorySlot>(ptr, size, memorySpace);
103 }
104
111 __INLINE__ void *deviceAlloc(std::shared_ptr<ascend::MemorySpace> memorySpace, const size_t size)
112 {
113 // Getting device associated with this memory space
114 auto device = memorySpace->getDevice().lock();
115
116 // select the device context on which we should allocate the memory
117 device->select();
118
119 // Storage for the allocation pointer
120 void *ptr = nullptr;
121
122 // Do the allocation on device memory
123 aclError err = aclrtMalloc(&ptr, size, ACL_MEM_MALLOC_HUGE_FIRST);
124 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Can not allocate memory on Ascend device %d. Error %d", device->getId(), err);
125
126 // Returning allocated pointer
127 return ptr;
128 }
129
136 __INLINE__ void *hostAlloc(std::shared_ptr<HiCR::MemorySpace> memorySpace, const size_t size)
137 {
138 // Storage for the allocation pointer
139 void *ptr = nullptr;
140
141 // Do the allocation on device memory
142 aclError err = aclrtMallocHost(&ptr, size);
143 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Can not allocate memory on host through ascend-dedicated function. Error %d", err);
144
145 // Returning allocated pointer
146 return ptr;
147 }
148
149 __INLINE__ std::shared_ptr<HiCR::LocalMemorySlot> registerLocalMemorySlotImpl(std::shared_ptr<HiCR::MemorySpace> memorySpace, void *const ptr, const size_t size) override
150 {
151 return std::make_shared<HiCR::LocalMemorySlot>(ptr, size, memorySpace);
152 }
153
154 __INLINE__ void memsetImpl(const std::shared_ptr<HiCR::LocalMemorySlot> memorySlot, int value, size_t size) override
155 {
156 // Filling the memory slot with the provided value
157 // Ascend aclrtMemset() automatically understands if the memory resides on the device or the host, so we can use it directly
158 aclError err = aclrtMemset(memorySlot->getPointer(), memorySlot->getSize(), value, size);
159 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Error while performing memset. Error %d", err);
160 }
161
162 __INLINE__ void freeLocalMemorySlotImpl(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot) override
163 {
164 // Getting up-casted pointer for the memory slot
165 auto m = dynamic_pointer_cast<ascend::LocalMemorySlot>(memorySlot);
166
167 // Checking whether the memory slot passed is compatible with this backend
168 if (m == NULL) freeLocalHostMemorySlot(memorySlot);
169 if (m != NULL) freeLocalDeviceMemorySlot(m);
170 }
171
172 __INLINE__ void freeLocalDeviceMemorySlot(std::shared_ptr<LocalMemorySlot> memorySlot)
173 {
174 // Getting memory slot info
175 const auto memorySlotPointer = memorySlot->getPointer();
176 const auto memorySlotMemorySpace = dynamic_pointer_cast<HiCR::backend::ascend::MemorySpace>(memorySlot->getMemorySpace());
177 const auto memorySlotDevice = memorySlotMemorySpace->getDevice().lock();
178 const auto memorySlotDeviceId = memorySlotDevice->getId();
179
180 aclError err = aclrtFree(memorySlotPointer);
181 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Error while freeing device %d memory. Error %d", memorySlotDeviceId, err);
182
183 err = aclDestroyDataBuffer(memorySlot->getDataBuffer());
184 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Can not destroy data buffer. Error %d", err);
185 }
186
187 __INLINE__ void freeLocalHostMemorySlot(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot)
188 {
189 aclError err = aclrtFreeHost(memorySlot->getPointer());
190 if (err != ACL_SUCCESS) HICR_THROW_RUNTIME("Error while freeing host memory. Error %d", err);
191 }
192
198 __INLINE__ void deregisterLocalMemorySlotImpl(std::shared_ptr<HiCR::LocalMemorySlot> memorySlot) override {}
199};
200
201} // namespace HiCR::backend::ascend
This file implements the Device class for the Ascend backend.
Provides a definition for the local memory slot class for the Ascend backend.
This file implements the memory space class for the Ascend backend.
This file implements the memory space class for the HWLoc-based backend.
Definition memoryManager.hpp:51
Definition memoryManager.hpp:49
MemoryManager()
Definition memoryManager.hpp:55
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