Copyright (c) 2025-2025 Huawei Technologies Co., Ltd.
sysHAX-adapter is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
PURPOSE.
See the Mulan PSL v2 for more details.
Created: 2026-1-31
Desc: CPU inference memory manager
*/
#include "memory_manager.h"
namespace cpu_inference {
MemoryManager::MemoryManager() {
if (numa_available() == -1) {
std::cerr << "[MemoryManager] NUMA not available, assuming 1 node.\n";
tot_numa_cnt = 1;
} else {
numa_set_strict(1);
tot_numa_cnt = numa_max_node() + 1;
}
}
MemoryManager::~MemoryManager() {}
MemoryManager& MemoryManager::get() {
static MemoryManager instance;
return instance;
}
void MemoryManager::clear_all(){
alloc_memory.clear();
}
Tensor& MemoryManager::alloc_single_numa(const std::string& name,
const std::vector<int>& shape,
int numa_node,
const std::string& dtype,
const std::string& quant_type
) {
if (numa_node < 0 || numa_node >= tot_numa_cnt) {
throw std::out_of_range("Invalid NUMA node: " + std::to_string(numa_node));
}
auto res = alloc_memory.emplace(
name,
Tensor(name, {numa_node}, shape, dtype, quant_type)
);
if (!res.second) {
throw std::runtime_error("Tensor name already exists: " + name);
}
return res.first->second;
}
Tensor& MemoryManager::alloc_multi_numa(const std::string& name,
const std::vector<int>& shape,
const std::vector<int>& numas,
const std::string& dtype,
const std::string& quant_type
) {
if (numas.empty()) {
throw std::invalid_argument("numas list is empty");
}
std::vector<int> unique_numas(numas.begin(), numas.end());
std::sort(unique_numas.begin(), unique_numas.end());
unique_numas.erase(std::unique(unique_numas.begin(), unique_numas.end()), unique_numas.end());
for (int node : unique_numas) {
if (node < 0 || node >= tot_numa_cnt) {
throw std::out_of_range("Invalid NUMA node: " + std::to_string(node));
}
}
auto res = alloc_memory.emplace(
name,
Tensor(name, numas, shape, dtype, quant_type)
);
return res.first->second;
}
Tensor& MemoryManager::alloc_all_numa(const std::string& name,
const std::vector<int>& shape,
const std::string& dtype,
const std::string& quant_type) {
std::vector<int> all_numas(tot_numa_cnt);
std::iota(all_numas.begin(), all_numas.end(), 0);
return alloc_multi_numa(name, shape, all_numas, dtype, quant_type);
}
Tensor& MemoryManager::get_memory(const std::string& name) {
auto it = alloc_memory.find(name);
if (it == alloc_memory.end()) {
throw std::out_of_range("Tensor not found: " + name);
}
return it->second;
}
int MemoryManager::get_tot_numa_cnt() const {
return tot_numa_cnt;
}
}