1. NPU设备初始化与资源查询
任务目标
编写一个C++程序,完成NPU设备的初始化、基本信息查询(设备名称、内存大小、计算单元数量)以及资源释放,形成最小可复用的设备管理闭环。
环境依赖
- Linux系统(推荐Ubuntu 20.04+)
- NPU驱动已安装,设备节点存在(如
/dev/npu0) - CMake ≥ 3.10,编译器支持C++17
核心实现
// npu_device_info.cpp
#include <cstdint>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
// 模拟NPU设备抽象层(真实场景替换为厂商SDK头文件)
namespace npu {
constexpr int MAX_NAME_LEN = 64;
struct DeviceInfo {
char name[MAX_NAME_LEN];
uint64_t memory_size_bytes;
uint32_t compute_unit_count;
};
// 设备句柄封装
class Device {
public:
Device(uint32_t device_id) : handle_(nullptr), id_(device_id) {
if (initialize(device_id) != 0) {
throw std::runtime_error("NPU初始化失败");
}
}
~Device() {
if (handle_) {
release();
}
}
// 禁止拷贝
Device(const Device&) = delete;
Device& operator=(const Device&) = delete;
// 允许移动
Device(Device&& other) noexcept
: handle_(other.handle_), id_(other.id_) {
other.handle_ = nullptr;
}
DeviceInfo queryInfo() const {
DeviceInfo info{};
if (query_device_info(handle_, &info) != 0) {
throw std::runtime_error("查询设备信息失败");
}
return info;
}
uint32_t id() const { return id_; }
private:
void* handle_;
uint32_t id_;
// ---- 以下为模拟SDK接口,实际使用时替换为厂商API调用 ----
static int initialize(uint32_t dev_id) {
// 模拟:检查设备存在性并打开句柄
if (dev_id > 3) return -1; // 仅支持0-3号设备
// 真实场景: return npu_dev_open(dev_id, &handle);
return 0;
}
static int query_device_info(void* handle, DeviceInfo* info) {
if (!handle || !info) return -1;
// 模拟查询,真实场景: return npu_dev_get_info(handle, info);
std::strncpy(info->name, "NPU-Simulator-X1", MAX_NAME_LEN - 1);
info->memory_size_bytes = 8ULL * 1024 * 1024 * 1024; // 8GB
info->compute_unit_count = 16;
return 0;
}
static void release() {
// 真实场景: npu_dev_close(handle);
}
};
} // namespace npu
int main() {
try {
// 初始化设备0
npu::Device dev(0);
// 查询并打印设备信息
auto info = dev.queryInfo();
std::cout << "设备ID: " << dev.id() << "\n"
<< "设备名称: " << info.name << "\n"
<< "内存大小: " << info.memory_size_bytes / (1024 * 1024)
<< " MB\n"
<< "计算单元数: " << info.compute_unit_count << "\n";
// 析构时自动释放资源
return 0;
} catch (const std::exception& e) {
std::cerr << "错误: " << e.what() << "\n";
return 1;
}
}
编译与运行
# 编译
g++ -std=c++17 -o npu_info npu_device_info.cpp
# 运行
./npu_info
验证方法
- 程序正常退出且返回码为0;
- 输出包含设备名称、内存大小(MB为单位)和计算单元数三行信息;
- 设备ID为0,内存大小为8192 MB,计算单元数为16(与模拟数据一致);
- 程序结束后无资源泄漏(可用
valgrind --leak-check=full ./npu_info确认)。
关键说明
- 代码中
initialize、query_device_info、release为模拟SDK接口,实际使用时替换为对应NPU厂商的API调用即可,接口签名与逻辑保持不变。 - 设备句柄通过RAII管理,析构时自动释放,避免资源泄漏。
- 若初始化失败(如设备ID超出范围),程序抛出异常并返回非零退出码。