runtime/dcmi/ — 超深度逐行分析
三个文件:dcmi.go (360行) + dcmi_api.go (101行) + dcManager.go (294行) = 755行
核心职责:NPU设备管理接口封装,通过CGO调用libdcmi.so
一、模块定位
1.1 业务职责
runtime/dcmi/ 是设备管理抽象层,负责:
1.2 在系统中的位置
#mermaid-svg-MA5V9njIHI1zHJ0f{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MA5V9njIHI1zHJ0f .error-icon{fill:#552222;}#mermaid-svg-MA5V9njIHI1zHJ0f .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MA5V9njIHI1zHJ0f .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MA5V9njIHI1zHJ0f .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MA5V9njIHI1zHJ0f .marker.cross{stroke:#333333;}#mermaid-svg-MA5V9njIHI1zHJ0f svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MA5V9njIHI1zHJ0f p{margin:0;}#mermaid-svg-MA5V9njIHI1zHJ0f .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster-label text{fill:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster-label span{color:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster-label span p{background-color:transparent;}#mermaid-svg-MA5V9njIHI1zHJ0f .label text,#mermaid-svg-MA5V9njIHI1zHJ0f span{fill:#333;color:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f .node rect,#mermaid-svg-MA5V9njIHI1zHJ0f .node circle,#mermaid-svg-MA5V9njIHI1zHJ0f .node ellipse,#mermaid-svg-MA5V9njIHI1zHJ0f .node polygon,#mermaid-svg-MA5V9njIHI1zHJ0f .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MA5V9njIHI1zHJ0f .rough-node .label text,#mermaid-svg-MA5V9njIHI1zHJ0f .node .label text,#mermaid-svg-MA5V9njIHI1zHJ0f .image-shape .label,#mermaid-svg-MA5V9njIHI1zHJ0f .icon-shape .label{text-anchor:middle;}#mermaid-svg-MA5V9njIHI1zHJ0f .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MA5V9njIHI1zHJ0f .rough-node .label,#mermaid-svg-MA5V9njIHI1zHJ0f .node .label,#mermaid-svg-MA5V9njIHI1zHJ0f .image-shape .label,#mermaid-svg-MA5V9njIHI1zHJ0f .icon-shape .label{text-align:center;}#mermaid-svg-MA5V9njIHI1zHJ0f .node.clickable{cursor:pointer;}#mermaid-svg-MA5V9njIHI1zHJ0f .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MA5V9njIHI1zHJ0f .arrowheadPath{fill:#333333;}#mermaid-svg-MA5V9njIHI1zHJ0f .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MA5V9njIHI1zHJ0f .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MA5V9njIHI1zHJ0f .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MA5V9njIHI1zHJ0f .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MA5V9njIHI1zHJ0f .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MA5V9njIHI1zHJ0f .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster text{fill:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f .cluster span{color:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MA5V9njIHI1zHJ0f .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MA5V9njIHI1zHJ0f rect.text{fill:none;stroke-width:0;}#mermaid-svg-MA5V9njIHI1zHJ0f .icon-shape,#mermaid-svg-MA5V9njIHI1zHJ0f .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MA5V9njIHI1zHJ0f .icon-shape p,#mermaid-svg-MA5V9njIHI1zHJ0f .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MA5V9njIHI1zHJ0f .icon-shape .label rect,#mermaid-svg-MA5V9njIHI1zHJ0f .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MA5V9njIHI1zHJ0f .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MA5V9njIHI1zHJ0f .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MA5V9njIHI1zHJ0f :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
外部
dcmi模块
调用方
GetMatchingNpuWorker
CreateVDevice
GetChipName/GetProductType
CGO C.DcmiXXX
runtime/process/process.go
dcmi_api.go顶层APICreateVDevice
dcmi.goWorker接口+V1/V2实现设备查询/虚拟设备
dcManager.goCGO封装直接调用libdcmi.so
libdcmi.soNPU驱动C库
NPU硬件
二、dcmi_api.go 逐行解析(101行)
2.1 数据结构
type VDeviceInfo struct {
CardID int32
DeviceID int32
VdeviceID int32
}
| CardID | NPU卡ID(物理插槽) | 0 |
| DeviceID | 卡内设备ID | 1 |
| VdeviceID | 虚拟设备ID(切分后生成) | 42 |
#mermaid-svg-Cxk2dFq8FtryuRbp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Cxk2dFq8FtryuRbp .error-icon{fill:#552222;}#mermaid-svg-Cxk2dFq8FtryuRbp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Cxk2dFq8FtryuRbp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Cxk2dFq8FtryuRbp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Cxk2dFq8FtryuRbp .marker.cross{stroke:#333333;}#mermaid-svg-Cxk2dFq8FtryuRbp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Cxk2dFq8FtryuRbp p{margin:0;}#mermaid-svg-Cxk2dFq8FtryuRbp g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-Cxk2dFq8FtryuRbp g.classGroup text .title{font-weight:bolder;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster-label text{fill:#333;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster-label span{color:#333;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster-label span p{background-color:transparent;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster text{fill:#333;}#mermaid-svg-Cxk2dFq8FtryuRbp .cluster span{color:#333;}#mermaid-svg-Cxk2dFq8FtryuRbp .nodeLabel,#mermaid-svg-Cxk2dFq8FtryuRbp .edgeLabel{color:#131300;}#mermaid-svg-Cxk2dFq8FtryuRbp .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-Cxk2dFq8FtryuRbp .label text{fill:#131300;}#mermaid-svg-Cxk2dFq8FtryuRbp .labelBkg{background:#ECECFF;}#mermaid-svg-Cxk2dFq8FtryuRbp .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-Cxk2dFq8FtryuRbp .classTitle{font-weight:bolder;}#mermaid-svg-Cxk2dFq8FtryuRbp .node rect,#mermaid-svg-Cxk2dFq8FtryuRbp .node circle,#mermaid-svg-Cxk2dFq8FtryuRbp .node ellipse,#mermaid-svg-Cxk2dFq8FtryuRbp .node polygon,#mermaid-svg-Cxk2dFq8FtryuRbp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Cxk2dFq8FtryuRbp .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp g.clickable{cursor:pointer;}#mermaid-svg-Cxk2dFq8FtryuRbp g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Cxk2dFq8FtryuRbp g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Cxk2dFq8FtryuRbp .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-Cxk2dFq8FtryuRbp .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Cxk2dFq8FtryuRbp .dashed-line{stroke-dasharray:3;}#mermaid-svg-Cxk2dFq8FtryuRbp .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-Cxk2dFq8FtryuRbp #compositionStart,#mermaid-svg-Cxk2dFq8FtryuRbp .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #compositionEnd,#mermaid-svg-Cxk2dFq8FtryuRbp .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #dependencyStart,#mermaid-svg-Cxk2dFq8FtryuRbp .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #dependencyStart,#mermaid-svg-Cxk2dFq8FtryuRbp .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #extensionStart,#mermaid-svg-Cxk2dFq8FtryuRbp .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #extensionEnd,#mermaid-svg-Cxk2dFq8FtryuRbp .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #aggregationStart,#mermaid-svg-Cxk2dFq8FtryuRbp .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #aggregationEnd,#mermaid-svg-Cxk2dFq8FtryuRbp .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #lollipopStart,#mermaid-svg-Cxk2dFq8FtryuRbp .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp #lollipopEnd,#mermaid-svg-Cxk2dFq8FtryuRbp .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Cxk2dFq8FtryuRbp .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-Cxk2dFq8FtryuRbp .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Cxk2dFq8FtryuRbp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Cxk2dFq8FtryuRbp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Cxk2dFq8FtryuRbp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
VDeviceInfo
+int32 CardID
+int32 DeviceID
+int32 VdeviceID
«interface»
WorkerInterface
+Initialize() : error
+ShutDown()
+CreateVDevice(uniqueID, coreNum)(VDeviceInfo, error)
+DestroyVDevice(uniqueID, vDevID) : error
+GetProductType()(string, error)
+GetChipName()(string, error)
2.2 WorkerInterface 接口
type WorkerInterface interface {
Initialize() error
ShutDown()
CreateVDevice(uniqueID int32, coreNum string) (VDeviceInfo, error)
DestroyVDevice(uniqueID int32, vDevID int32) error
GetProductType() (string, error)
GetChipName() (string, error)
}
6个方法的职责:
| Initialize | 无 | error | 初始化dcmi库连接 |
| ShutDown | 无 | 无 | 关闭dcmi库连接 |
| CreateVDevice | uniqueID(物理设备ID), coreNum(切分模板) | VDeviceInfo, error | 创建虚拟NPU |
| DestroyVDevice | uniqueID, vDevID(虚拟设备ID) | error | 销毁虚拟NPU |
| GetProductType | 无 | string, error | 获取产品型号 |
| GetChipName | 无 | string, error | 获取芯片名称 |
设计意图:策略模式接口,V1和V2驱动各自实现此接口,调用方无需关心驱动版本。
2.3 CreateVDevice 顶层API
func CreateVDevice(w WorkerInterface, spec *specs.Spec, devices []int) (VDeviceInfo, error) {
invalidVDevice := VDeviceInfo{CardID: –1, DeviceID: –1, VdeviceID: –1}
if spec == nil {
return invalidVDevice, fmt.Errorf("spec is nil")
}
splitDevice, err := extractVpuParam(spec)
if err != nil {
return invalidVDevice, err
}
if splitDevice == "" {
return invalidVDevice, nil
}
if len(devices) != 1 || devices[0] < 0 || devices[0] >= hiAIMaxCardNum*hiAIMaxDeviceNum {
hwlog.RunLog.Errorf("invalid devices: %v", devices)
return invalidVDevice, fmt.Errorf("invalid devices: %v", devices)
}
if err := w.Initialize(); err != nil {
return invalidVDevice, fmt.Errorf("cannot init dcmi : %v", err)
}
defer w.ShutDown()
vDeviceInfo, err := w.CreateVDevice(int32(devices[0]), splitDevice)
if err != nil || vDeviceInfo.VdeviceID < 0 {
hwlog.RunLog.Errorf("cannot create vd or vdevice is wrong: %v %v", vDeviceInfo.VdeviceID, err)
return invalidVDevice, err
}
return vDeviceInfo, nil
}
逐行解析:
设计意图:此函数是对Worker.CreateVDevice的包装,增加了Spec解析和参数校验。
2.4 extractVpuParam — vNPU切分模板解析
func extractVpuParam(spec *specs.Spec) (string, error) {
allowSplit := map[string]string{
"vir01": "vir01", "vir02": "vir02", "vir04": "vir04", "vir08": "vir08", "vir16": "vir16",
"vir02_1c": "vir02_1c", "vir03_1c_8g": "vir03_1c_8g", "vir04_3c": "vir04_3c",
"vir04_4c_dvpp": "vir04_4c_dvpp", "vir04_3c_ndvpp": "vir04_3c_ndvpp",
"vir05_1c_8g": "vir05_1c_8g", "vir05_1c_16g": "vir05_1c_16g",
"vir06_1c_16g": "vir06_1c_16g", "vir10_3c_16g": "vir10_3c_16g",
"vir10_3c_16g_nm": "vir10_3c_16g_nm", "vir10_3c_32g": "vir10_3c_32g",
"vir10_4c_16g_m": "vir10_4c_16g_m", "vir12_3c_32g": "vir12_3c_32g",
}
for _, line := range spec.Process.Env {
words := strings.Split(line, "=")
const LENGTH int = 2
if len(words) != LENGTH {
continue
}
if strings.TrimSpace(words[0]) == api.AscendVnpuSpescEnv {
if split, ok := allowSplit[words[1]]; ok && split != "" {
return split, nil
}
return "", fmt.Errorf("cannot parse param : %v", words[1])
}
}
return "", nil
}
vNPU切分模板说明:
| vir01 | 1/16切分(最小) |
| vir02 | 1/8切分 |
| vir04 | 1/4切分 |
| vir08 | 1/2切分 |
| vir16 | 不切分(全卡) |
| vir02_1c | 1/8切分+1核 |
| vir04_3c | 1/4切分+3核 |
| vir04_4c_dvpp | 1/4切分+4核+DVPP |
| vir04_3c_ndvpp | 1/4切分+3核+无DVPP |
| vir05_1c_8g | 1/3.2切分+1核+8GB |
| vir10_3c_16g | 1/1.6切分+3核+16GB |
| vir10_4c_16g_m | 1/1.6切分+4核+16GB+内存增强 |
| vir12_3c_32g | 1/1.3切分+3核+32GB |
逐行解析:
设计意图:严格的白名单校验,防止用户传入非法切分参数导致驱动异常。
三、dcmi.go 逐行解析(360行)
3.1 常量定义
const (
retError = –1
hiAIMaxCardNum = 64 // 最大卡数
hiAIMaxCardID = math.MaxInt32 // 卡ID上限
hiAIMaxDeviceID = math.MaxInt32 // 设备ID上限
hiAIMaxDeviceNum = 4 // 每卡最大设备数
maxChipNameLen = 32 // 芯片名最大长度
productTypeLen = 64 // 产品类型最大长度
notSupportCode = –8255 // "不支持"错误码
coreNumLen = 32 // 切分模板名最大长度
vfgID = 4294967295 // 虚拟组ID默认值(0xFFFFFFFF)
notSupportString = "[not support]"
)
| hiAIMaxCardNum | 64 | 系统最多支持64张NPU卡 |
| hiAIMaxDeviceNum | 4 | 每张卡最多4个芯片 |
| maxChipNameLen | 32 | C结构体中芯片名字段长度 |
| vfgID | 0xFFFFFFFF | 虚拟功能组ID,默认自动分配 |
| notSupportCode | -8255 | DCMI库返回的"不支持"错误码 |
3.2 managerList — Worker注册表
var managerList = []WorkerInterface{
&NpuV1Worker{DcMgr: &DcV1Manager{}},
&NpuV2Worker{DcMgr: &DcV2Manager{}},
}
设计意图:全局Worker列表,V1在前V2在后。GetMatchingNpuWorker 按顺序尝试初始化,第一个成功的即为匹配的驱动版本。
3.3 ChipInfo 结构体
type ChipInfo struct {
Type string `json:"chip_type"`
Name string `json:"chip_name"`
Version string `json:"chip_version"`
}
- 从C结构体 DcmiChipInfo 转换而来
- Name 用于判断芯片类型(如"Ascend910A"→Ascend910)
3.4 驱动接口定义
type DcDriverV1Interface interface {
DcInitialize() error
DcShutDown()
DcGetCardList() (int32, []int32, error)
DcGetDeviceNumInCard(cardID int32) (int32, error)
DcGetDeviceLogicID(cardID, deviceID int32) (int32, error)
DcGetProductType(cardID, deviceID int32) (string, error)
DcCreateVDevice(cardID, deviceID int32, coreNum string) (int32, error)
DcDestroyVDevice(cardID, deviceID int32, vDevID int32) error
DcGetChipInfo(cardID, deviceID int32) (*ChipInfo, error)
DcGetDeviceLogicidFromPhyid(phyID int32) (int32, error)
}
type DcDriverV2Interface interface {
DcInitialize() error
DcShutDown()
DcCreateVDevice(deviceID int32, coreNum string) (int32, error)
DcDestroyVDevice(deviceID int32, vDevID int32) error
DcGetChipInfo(deviceID int32) (*ChipInfo, error)
DcGetDeviceList() (int32, []int32, error)
}
V1 vs V2 接口差异:
| 设备寻址 | cardID + deviceID 二级寻址 | deviceID 一级寻址 |
| 卡列表 | DcGetCardList → 每卡DcGetDeviceNumInCard | DcGetDeviceList 直接获取所有设备 |
| 产品类型 | 支持 DcGetProductType | 不支持(返回"[not support]") |
| 物理ID转换 | DcGetDeviceLogicidFromPhyid | 不需要(直接用deviceID) |
| 虚拟设备 | 支持 | 不支持(返回错误) |
3.5 GetMatchingNpuWorker — 工厂函数
func GetMatchingNpuWorker() (WorkerInterface, error) {
for _, manager := range managerList {
err := manager.Initialize()
if err == nil {
manager.ShutDown()
hwlog.RunLog.Infof("worker type: %T", manager)
return manager, nil
}
}
return nil, fmt.Errorf("failed to find a valid manager")
}
逐行解析:
设计意图:V1调用 DcmiInit(),V2调用 DcmiV2Init()。在新版硬件上调用V1初始化会失败,反之亦然。利用这个特性来自动检测驱动版本。
#mermaid-svg-VYcE0T9MJNGyD0Jd{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VYcE0T9MJNGyD0Jd .error-icon{fill:#552222;}#mermaid-svg-VYcE0T9MJNGyD0Jd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VYcE0T9MJNGyD0Jd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .marker.cross{stroke:#333333;}#mermaid-svg-VYcE0T9MJNGyD0Jd svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VYcE0T9MJNGyD0Jd p{margin:0;}#mermaid-svg-VYcE0T9MJNGyD0Jd .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster-label text{fill:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster-label span{color:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster-label span p{background-color:transparent;}#mermaid-svg-VYcE0T9MJNGyD0Jd .label text,#mermaid-svg-VYcE0T9MJNGyD0Jd span{fill:#333;color:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .node rect,#mermaid-svg-VYcE0T9MJNGyD0Jd .node circle,#mermaid-svg-VYcE0T9MJNGyD0Jd .node ellipse,#mermaid-svg-VYcE0T9MJNGyD0Jd .node polygon,#mermaid-svg-VYcE0T9MJNGyD0Jd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .rough-node .label text,#mermaid-svg-VYcE0T9MJNGyD0Jd .node .label text,#mermaid-svg-VYcE0T9MJNGyD0Jd .image-shape .label,#mermaid-svg-VYcE0T9MJNGyD0Jd .icon-shape .label{text-anchor:middle;}#mermaid-svg-VYcE0T9MJNGyD0Jd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .rough-node .label,#mermaid-svg-VYcE0T9MJNGyD0Jd .node .label,#mermaid-svg-VYcE0T9MJNGyD0Jd .image-shape .label,#mermaid-svg-VYcE0T9MJNGyD0Jd .icon-shape .label{text-align:center;}#mermaid-svg-VYcE0T9MJNGyD0Jd .node.clickable{cursor:pointer;}#mermaid-svg-VYcE0T9MJNGyD0Jd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .arrowheadPath{fill:#333333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VYcE0T9MJNGyD0Jd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VYcE0T9MJNGyD0Jd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VYcE0T9MJNGyD0Jd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster text{fill:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd .cluster span{color:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VYcE0T9MJNGyD0Jd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VYcE0T9MJNGyD0Jd rect.text{fill:none;stroke-width:0;}#mermaid-svg-VYcE0T9MJNGyD0Jd .icon-shape,#mermaid-svg-VYcE0T9MJNGyD0Jd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VYcE0T9MJNGyD0Jd .icon-shape p,#mermaid-svg-VYcE0T9MJNGyD0Jd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VYcE0T9MJNGyD0Jd .icon-shape .label rect,#mermaid-svg-VYcE0T9MJNGyD0Jd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VYcE0T9MJNGyD0Jd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VYcE0T9MJNGyD0Jd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VYcE0T9MJNGyD0Jd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
GetMatchingNpuWorker
尝试NpuV1Worker.Initialize
DcmiInit成功?
ShutDown关闭探测连接
返回NpuV1Worker
尝试NpuV2Worker.Initialize
DcmiV2Init成功?
ShutDown
返回NpuV2Worker
返回错误failed to find valid manager
3.6 NpuV1Worker.FindDevice — 物理ID到卡/设备映射
func (w *NpuV1Worker) FindDevice(visibleDevice int32) (int32, int32, error) {
targetLogicID, err := w.DcMgr.DcGetDeviceLogicidFromPhyid(visibleDevice)
if err != nil {
return 0, 0, fmt.Errorf("cannot convert phy id to logic id, err: %v", err)
}
_, cardList, err := w.DcMgr.DcGetCardList()
if err != nil {
return 0, 0, fmt.Errorf("get card list err : %v", err)
}
targetDeviceID, targetCardID := int32(math.MaxInt32), int32(math.MaxInt32)
for _, cardID := range cardList {
deviceCount, err := w.DcMgr.DcGetDeviceNumInCard(cardID)
if err != nil {
return 0, 0, fmt.Errorf("cannot get device num in card : %v", err)
}
for deviceID := int32(0); deviceID < deviceCount; deviceID++ {
logicID, err := w.DcMgr.DcGetDeviceLogicID(cardID, deviceID)
if err != nil {
return 0, 0, fmt.Errorf("cannot get logic id : %v", err)
}
if logicID == targetLogicID {
targetCardID, targetDeviceID = cardID, deviceID
}
}
}
return targetDeviceID, targetCardID, nil
}
逐行解析:
设计意图:V1驱动使用"物理ID"作为用户接口(如ASCEND_VISIBLE_DEVICES=0),但内部操作需要cardID+deviceID二维坐标。此函数完成这个映射。
#mermaid-svg-OFtCmAwrmgWmqUML{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OFtCmAwrmgWmqUML .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OFtCmAwrmgWmqUML .error-icon{fill:#552222;}#mermaid-svg-OFtCmAwrmgWmqUML .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OFtCmAwrmgWmqUML .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OFtCmAwrmgWmqUML .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OFtCmAwrmgWmqUML .marker.cross{stroke:#333333;}#mermaid-svg-OFtCmAwrmgWmqUML svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OFtCmAwrmgWmqUML p{margin:0;}#mermaid-svg-OFtCmAwrmgWmqUML .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-OFtCmAwrmgWmqUML .cluster-label text{fill:#333;}#mermaid-svg-OFtCmAwrmgWmqUML .cluster-label span{color:#333;}#mermaid-svg-OFtCmAwrmgWmqUML .cluster-label span p{background-color:transparent;}#mermaid-svg-OFtCmAwrmgWmqUML .label text,#mermaid-svg-OFtCmAwrmgWmqUML span{fill:#333;color:#333;}#mermaid-svg-OFtCmAwrmgWmqUML .node rect,#mermaid-svg-OFtCmAwrmgWmqUML .node circle,#mermaid-svg-OFtCmAwrmgWmqUML .node ellipse,#mermaid-svg-OFtCmAwrmgWmqUML .node polygon,#mermaid-svg-OFtCmAwrmgWmqUML .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OFtCmAwrmgWmqUML .rough-node .label text,#mermaid-svg-OFtCmAwrmgWmqUML .node .label text,#mermaid-svg-OFtCmAwrmgWmqUML .image-shape .label,#mermaid-svg-OFtCmAwrmgWmqUML .icon-shape .label{text-anchor:middle;}#mermaid-svg-OFtCmAwrmgWmqUML .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OFtCmAwrmgWmqUML .rough-node .label,#mermaid-svg-OFtCmAwrmgWmqUML .node .label,#mermaid-svg-OFtCmAwrmgWmqUML .image-shape .label,#mermaid-svg-OFtCmAwrmgWmqUML .icon-shape .label{text-align:center;}#mermaid-svg-OFtCmAwrmgWmqUML .node.clickable{cursor:pointer;}#mermaid-svg-OFtCmAwrmgWmqUML .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OFtCmAwrmgWmqUML .arrowheadPath{fill:#333333;}#mermaid-svg-OFtCmAwrmgWmqUML .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OFtCmAwrmgWmqUML .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OFtCmAwrmgWmqUML .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OFtCmAwrmgWmqUML .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OFtCmAwrmgWmqUML .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OFtCmAwrmgWmqUML .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OFtCmAwrmgWmqUML .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OFtCmAwrmgWmqUML .cluster text{fill:#333;}#mermaid-svg-OFtCmAwrmgWmqUML .cluster span{color:#333;}#mermaid-svg-OFtCmAwrmgWmqUML div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OFtCmAwrmgWmqUML .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OFtCmAwrmgWmqUML rect.text{fill:none;stroke-width:0;}#mermaid-svg-OFtCmAwrmgWmqUML .icon-shape,#mermaid-svg-OFtCmAwrmgWmqUML .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OFtCmAwrmgWmqUML .icon-shape p,#mermaid-svg-OFtCmAwrmgWmqUML .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OFtCmAwrmgWmqUML .icon-shape .label rect,#mermaid-svg-OFtCmAwrmgWmqUML .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OFtCmAwrmgWmqUML .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OFtCmAwrmgWmqUML .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OFtCmAwrmgWmqUML :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
是
否
FindDevicevisibleDevice=0
DcGetDeviceLogicidFromPhyid物理ID→逻辑ID
DcGetCardList获取所有卡ID
遍历每张卡
DcGetDeviceNumInCard获取卡内设备数
遍历卡内每个设备
DcGetDeviceLogicID获取设备的逻辑ID
逻辑ID == 目标?
记录cardID和deviceID
还有更多设备?
还有更多卡?
返回deviceID, cardID
3.7 NpuV1Worker.GetChipName
func (w *NpuV1Worker) GetChipName() (string, error) {
invalidName := ""
if err := w.Initialize(); err != nil {
return invalidName, fmt.Errorf("cannot init dcmi : %v", err)
}
defer w.ShutDown()
cardNum, cardList, err := w.DcMgr.DcGetCardList()
if err != nil {
return invalidName, err
}
if cardNum == 0 {
return invalidName, fmt.Errorf("get chip info failed, no card found")
}
for _, cardID := range cardList {
devNum, err := w.DcMgr.DcGetDeviceNumInCard(cardID)
if err != nil || devNum == 0 {
continue
}
for devID := int32(0); devID < devNum; devID++ {
chipInfo, err := w.DcMgr.DcGetChipInfo(cardID, devID)
if err != nil {
continue
}
if !isValidChipInfo(chipInfo) {
continue
}
return (*chipInfo).Name, nil
}
}
return invalidName, fmt.Errorf("cannot get valid chip info")
}
执行流程:
设计意图:只需要获取任意一个有效芯片的名称即可确定整个系统的芯片类型(假设同一机器上芯片类型一致)。
3.8 NpuV2Worker.GetChipName
func (a *NpuV2Worker) GetChipName() (string, error) {
invalidName := ""
if err := a.Initialize(); err != nil {
return invalidName, fmt.Errorf("cannot init dcmi : %v", err)
}
defer a.ShutDown()
deviceNum, deviceList, err := a.DcMgr.DcGetDeviceList()
// …
for _, devID := range deviceList {
chipInfo, err := a.DcMgr.DcGetChipInfo(devID)
// …
return (*chipInfo).Name, nil
}
return invalidName, fmt.Errorf("cannot get valid chip info")
}
与V1的区别:
- V1:卡列表→每卡设备数→遍历cardID+deviceID
- V2:直接获取设备列表→遍历deviceID
3.9 NpuV1Worker.CreateVDevice
func (w *NpuV1Worker) CreateVDevice(uniqueID int32, coreNum string) (VDeviceInfo, error) {
deviceID, cardID, err := w.FindDevice(uniqueID)
if err != nil {
return VDeviceInfo{CardID: –1, DeviceID: –1, VdeviceID: –1}, err
}
vdevId, err := w.DcMgr.DcCreateVDevice(cardID, deviceID, coreNum)
if err != nil {
return VDeviceInfo{CardID: –1, DeviceID: –1, VdeviceID: math.MaxInt32}, err
}
if vdevId > math.MaxInt32 {
return VDeviceInfo{CardID: cardID, DeviceID: deviceID, VdeviceID: math.MaxInt32},
fmt.Errorf("create virtual device failed, vdeviceId too large")
}
return VDeviceInfo{CardID: cardID, DeviceID: deviceID, VdeviceID: int32(vdevId)}, nil
}
逐行解析:
3.10 NpuV2Worker.CreateVDevice
func (a *NpuV2Worker) CreateVDevice(uniqueID int32, coreNum string) (VDeviceInfo, error) {
vdevId, err := a.DcMgr.DcCreateVDevice(uniqueID, coreNum)
if err != nil {
return VDeviceInfo{
CardID: –1,
DeviceID: –1,
VdeviceID: –1,
}, err
}
return VDeviceInfo{VdeviceID: vdevId}, nil
}
注意:V2的 DcCreateVDevice 实际返回错误(“ascend 950 not support virtual device”),所以这段代码在当前版本实际上不会成功执行。
四、dcManager.go 逐行解析(294行)
4.1 CGO导入
// #cgo LDFLAGS: -ldl
// #include "dcmi_interface_api.h"
import "C"
- LDFLAGS: -ldl — 链接动态加载库(dlopen)
- #include "dcmi_interface_api.h" — DCMI C接口头文件
- import "C" — Go的CGO机制,允许调用C函数
4.2 DcV1Manager.DcInitialize
func (d *DcV1Manager) DcInitialize() error {
cDlPath := C.CString(string(make([]byte, int32(C.PATH_MAX))))
defer C.free(unsafe.Pointer(cDlPath))
if err := C.DcmiInitDl(cDlPath); err != C.SUCCESS {
errInfo := fmt.Errorf("dcmi lib load failed, error code: %d", int32(err))
return errInfo
}
dlPath := C.GoString(cDlPath)
if _, err := mindxcheckutils.RealFileChecker(dlPath, true, false, mindxcheckutils.DefaultSize); err != nil {
return err
}
if err := C.DcmiInit(); err != C.SUCCESS {
errInfo := fmt.Errorf("dcmi init failed, error code: %d", int32(err))
return errInfo
}
return nil
}
逐行解析:
设计意图:两步初始化——先加载动态库(dlopen),再初始化设备连接。安全校验确保加载的是合法dcmi库。
#mermaid-svg-tu8zhbbKHxJoZJTO{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tu8zhbbKHxJoZJTO .error-icon{fill:#552222;}#mermaid-svg-tu8zhbbKHxJoZJTO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tu8zhbbKHxJoZJTO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tu8zhbbKHxJoZJTO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tu8zhbbKHxJoZJTO .marker.cross{stroke:#333333;}#mermaid-svg-tu8zhbbKHxJoZJTO svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tu8zhbbKHxJoZJTO p{margin:0;}#mermaid-svg-tu8zhbbKHxJoZJTO .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster-label text{fill:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster-label span{color:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster-label span p{background-color:transparent;}#mermaid-svg-tu8zhbbKHxJoZJTO .label text,#mermaid-svg-tu8zhbbKHxJoZJTO span{fill:#333;color:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO .node rect,#mermaid-svg-tu8zhbbKHxJoZJTO .node circle,#mermaid-svg-tu8zhbbKHxJoZJTO .node ellipse,#mermaid-svg-tu8zhbbKHxJoZJTO .node polygon,#mermaid-svg-tu8zhbbKHxJoZJTO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tu8zhbbKHxJoZJTO .rough-node .label text,#mermaid-svg-tu8zhbbKHxJoZJTO .node .label text,#mermaid-svg-tu8zhbbKHxJoZJTO .image-shape .label,#mermaid-svg-tu8zhbbKHxJoZJTO .icon-shape .label{text-anchor:middle;}#mermaid-svg-tu8zhbbKHxJoZJTO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tu8zhbbKHxJoZJTO .rough-node .label,#mermaid-svg-tu8zhbbKHxJoZJTO .node .label,#mermaid-svg-tu8zhbbKHxJoZJTO .image-shape .label,#mermaid-svg-tu8zhbbKHxJoZJTO .icon-shape .label{text-align:center;}#mermaid-svg-tu8zhbbKHxJoZJTO .node.clickable{cursor:pointer;}#mermaid-svg-tu8zhbbKHxJoZJTO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tu8zhbbKHxJoZJTO .arrowheadPath{fill:#333333;}#mermaid-svg-tu8zhbbKHxJoZJTO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tu8zhbbKHxJoZJTO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tu8zhbbKHxJoZJTO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tu8zhbbKHxJoZJTO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tu8zhbbKHxJoZJTO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tu8zhbbKHxJoZJTO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster text{fill:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO .cluster span{color:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tu8zhbbKHxJoZJTO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tu8zhbbKHxJoZJTO rect.text{fill:none;stroke-width:0;}#mermaid-svg-tu8zhbbKHxJoZJTO .icon-shape,#mermaid-svg-tu8zhbbKHxJoZJTO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tu8zhbbKHxJoZJTO .icon-shape p,#mermaid-svg-tu8zhbbKHxJoZJTO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tu8zhbbKHxJoZJTO .icon-shape .label rect,#mermaid-svg-tu8zhbbKHxJoZJTO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tu8zhbbKHxJoZJTO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tu8zhbbKHxJoZJTO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tu8zhbbKHxJoZJTO :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
失败
成功
不通过
通过
失败
成功
DcInitialize
分配C字符串bufferPATH_MAX长度
DcmiInitDldlopen加载libdcmi.so
返回错误dcmi lib load failed
获取库路径C.GoString
RealFileChecker安全校验库文件
返回错误
DcmiInit初始化设备连接
返回错误dcmi init failed
返回nil
4.3 DcV1Manager.DcGetCardList
func (d *DcV1Manager) DcGetCardList() (int32, []int32, error) {
var ids [hiAIMaxCardNum]C.int
var cNum C.int
if err := C.DcmiGetCardNumList(&cNum, &ids[0], hiAIMaxCardNum); err != 0 {
return retError, nil, fmt.Errorf("get card list failed, error code: %d", int32(err))
}
if cNum <= 0 || cNum > hiAIMaxCardNum {
return retError, nil, fmt.Errorf("get error card quantity: %d", int32(cNum))
}
var cardNum = int32(cNum)
var cardIDList []int32
for i := int32(0); i < cardNum; i++ {
cardID := int32(ids[i])
if cardID < 0 {
continue
}
cardIDList = append(cardIDList, cardID)
}
return cardNum, cardIDList, nil
}
逐行解析:
4.4 DcV1Manager.DcCreateVDevice
func (d *DcV1Manager) DcCreateVDevice(cardID, deviceID int32, coreNum string) (int32, error) {
var createInfo C.struct_DcmiCreateVdevOut
createInfo.vdevId = C.uint(math.MaxUint32)
var deviceCreateStr C.struct_DcmiCreateVdevResStru
deviceCreateStr = C.struct_DcmiCreateVdevResStru{
vdevId: C.uint(vfgID),
vfgId: C.uint(vfgID),
}
deviceCreateStrArr := [coreNumLen]C.char{0}
for i := 0; i < len(coreNum); i++ {
if i >= coreNumLen {
return math.MaxInt32, fmt.Errorf("wrong template")
}
deviceCreateStrArr[i] = C.char(coreNum[i])
}
deviceCreateStr.templateName = deviceCreateStrArr
ret := C.DcmiCreateVdevice(C.int(cardID), C.int(deviceID), &deviceCreateStr, &createInfo)
if ret != 0 {
return math.MaxInt32, fmt.Errorf("create virtual device failed, error code: %d", int32(ret))
}
return int32(createInfo.vdevId), nil
}
逐行解析:
关键数据结构:
#mermaid-svg-Ls9qSzt4Ej6fTd78{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .error-icon{fill:#552222;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .marker.cross{stroke:#333333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 p{margin:0;}#mermaid-svg-Ls9qSzt4Ej6fTd78 g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 g.classGroup text .title{font-weight:bolder;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster-label text{fill:#333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster-label span{color:#333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster-label span p{background-color:transparent;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster text{fill:#333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .cluster span{color:#333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .nodeLabel,#mermaid-svg-Ls9qSzt4Ej6fTd78 .edgeLabel{color:#131300;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .label text{fill:#131300;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .labelBkg{background:#ECECFF;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .classTitle{font-weight:bolder;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .node rect,#mermaid-svg-Ls9qSzt4Ej6fTd78 .node circle,#mermaid-svg-Ls9qSzt4Ej6fTd78 .node ellipse,#mermaid-svg-Ls9qSzt4Ej6fTd78 .node polygon,#mermaid-svg-Ls9qSzt4Ej6fTd78 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 g.clickable{cursor:pointer;}#mermaid-svg-Ls9qSzt4Ej6fTd78 g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Ls9qSzt4Ej6fTd78 g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .dashed-line{stroke-dasharray:3;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #compositionStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #compositionEnd,#mermaid-svg-Ls9qSzt4Ej6fTd78 .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #dependencyStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #dependencyStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #extensionStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #extensionEnd,#mermaid-svg-Ls9qSzt4Ej6fTd78 .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #aggregationStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #aggregationEnd,#mermaid-svg-Ls9qSzt4Ej6fTd78 .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #lollipopStart,#mermaid-svg-Ls9qSzt4Ej6fTd78 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 #lollipopEnd,#mermaid-svg-Ls9qSzt4Ej6fTd78 .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ls9qSzt4Ej6fTd78 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ls9qSzt4Ej6fTd78 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
输入→输出
DcmiCreateVdevResStru
+uint vdevId
+uint vfgId
+char[32] templateName "切分模板名如vir04"
DcmiCreateVdevOut
+uint vdevId "创建后的虚拟设备ID"
4.5 DcV1Manager.DcGetChipInfo
func (d *DcV1Manager) DcGetChipInfo(cardID, deviceID int32) (*ChipInfo, error) {
if !isValidCardIDAndDeviceID(cardID, deviceID) {
return nil, fmt.Errorf("cardID(%d) or deviceID(%d) is invalid", cardID, deviceID)
}
var chipInfo C.struct_DcmiChipInfo
if rCode := C.DcmiGetDeviceChipInfo(C.int(cardID), C.int(deviceID), &chipInfo); int32(rCode) != 0 {
return nil, fmt.Errorf("get device ChipInfo information failed, …")
}
name := convertUCharToCharArr(chipInfo.chipName)
cType := convertUCharToCharArr(chipInfo.chipType)
ver := convertUCharToCharArr(chipInfo.chipVer)
chip := &ChipInfo{
Name: string(name),
Type: string(cType),
Version: string(ver),
}
if !isValidChipInfo(chip) {
return nil, fmt.Errorf("get device ChipInfo information failed, chip info is empty, …")
}
return chip, nil
}
逐行解析:
4.6 convertUCharToCharArr — C数组转Go
func convertUCharToCharArr(cgoArr [maxChipNameLen]C.uchar) []byte {
var charArr []byte
for _, v := range cgoArr {
if v == 0 {
break
}
charArr = append(charArr, byte(v))
}
return charArr
}
- C字符串以null(0)结尾,遍历到0即停止
- 将C的[32]uchar转为Go的[]byte,再转为string
4.7 DcV2Manager — V2 CGO实现
func (d *DcV2Manager) DcInitialize() error {
// …同V1的DcmiInitDl…
if err := C.DcmiV2Init(); err != C.SUCCESS {
return fmt.Errorf("dcmi init failed, error code: %d", int32(err))
}
return nil
}
关键差异:V2调用 C.DcmiV2Init() 而非 C.DcmiInit()。
func (d *DcV2Manager) DcCreateVDevice(deviceID int32, coreNum string) (int32, error) {
return –1, fmt.Errorf("create error, ascend 950 not support virtual device")
}
func (d *DcV2Manager) DcDestroyVDevice(deviceID int32, vDevID int32) error {
return fmt.Errorf("destroy error, ascend 950 not support virtual device")
}
V2不支持虚拟设备:Ascend 950(910A5)不支持vNPU切分,直接返回错误。
func (d *DcV2Manager) DcGetDeviceList() (int32, []int32, error) {
var ids [hiAIMaxCardNum]C.int
var cNum C.int
if err := C.DcmiV2GetDeviceList(&ids[0], &cNum, hiAIMaxCardNum); err != 0 {
return retError, nil, fmt.Errorf("get device list failed, error code: %d", int32(err))
}
// …校验+转换…
return deviceNum, deviceIDList, nil
}
V2直接获取设备列表,无需先获取卡列表再遍历卡内设备。
五、V1 vs V2 完整对比
#mermaid-svg-7FJDdB1jd6Ui6Vgt{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .error-icon{fill:#552222;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .marker.cross{stroke:#333333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt p{margin:0;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster-label text{fill:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster-label span{color:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster-label span p{background-color:transparent;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .label text,#mermaid-svg-7FJDdB1jd6Ui6Vgt span{fill:#333;color:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .node rect,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node circle,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node ellipse,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node polygon,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .rough-node .label text,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node .label text,#mermaid-svg-7FJDdB1jd6Ui6Vgt .image-shape .label,#mermaid-svg-7FJDdB1jd6Ui6Vgt .icon-shape .label{text-anchor:middle;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .rough-node .label,#mermaid-svg-7FJDdB1jd6Ui6Vgt .node .label,#mermaid-svg-7FJDdB1jd6Ui6Vgt .image-shape .label,#mermaid-svg-7FJDdB1jd6Ui6Vgt .icon-shape .label{text-align:center;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .node.clickable{cursor:pointer;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .arrowheadPath{fill:#333333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7FJDdB1jd6Ui6Vgt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7FJDdB1jd6Ui6Vgt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster text{fill:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .cluster span{color:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7FJDdB1jd6Ui6Vgt rect.text{fill:none;stroke-width:0;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .icon-shape,#mermaid-svg-7FJDdB1jd6Ui6Vgt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .icon-shape p,#mermaid-svg-7FJDdB1jd6Ui6Vgt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .icon-shape .label rect,#mermaid-svg-7FJDdB1jd6Ui6Vgt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7FJDdB1jd6Ui6Vgt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7FJDdB1jd6Ui6Vgt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7FJDdB1jd6Ui6Vgt :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
V2 新版驱动 Ascend 910B/A5
DcmiV2Init
DcmiV2GetDeviceList直接获取设备列表
DcmiV2GetDeviceChipInfo仅deviceID
不支持vNPU返回错误
V1 旧版驱动 Ascend 910/310
DcmiInit
DcmiGetCardNumList获取卡列表
DcmiGetDeviceNumInCard每卡设备数
DcmiGetDeviceChipInfocardID+deviceID
DcmiCreateVdevice支持vNPU切分
DcmiSetDestroyVdevice销毁vNPU
DcmiGetDeviceLogicidFromPhyid物理ID→逻辑ID
| 初始化 | DcmiInitDl + DcmiInit | DcmiInitDl + DcmiV2Init |
| 设备寻址 | cardID + deviceID 二级 | deviceID 一级 |
| 获取设备列表 | DcmiGetCardNumList → 遍历卡 → DcmiGetDeviceNumInCard | DcmiV2GetDeviceList 一步到位 |
| 芯片信息 | DcmiGetDeviceChipInfo(cardID, deviceID) | DcmiV2GetDeviceChipInfo(deviceID) |
| 产品类型 | 支持 DcmiGetProductType | 不支持(返回"[not support]") |
| vNPU切分 | 支持 DcmiCreateVdevice | 不支持(返回错误) |
| 物理ID转换 | 需要 DcmiGetDeviceLogicidFromPhyid | 不需要 |
| 适用芯片 | Ascend 910, 310, 310P, 310B | Ascend 910B, A5 (950) |
网硕互联帮助中心


评论前必须登录!
注册