工具简介

EFSMI (Enflame System Management Interface)是用于管理 Enflame GCU 设备的Linux命令行工具。 可以实时查询各种 GCU 设备信息:包含温度、功耗、时钟频率等。 有关EFSMI命令的详细用法,请参考 EFSMI 命令。 EFSMI是基于 EFML (Enflame Management Library)开发的,EFML是提供给用户的一套访问底层GCU硬件的代码库。 请参阅章节 EFML - Enflame 管理库

如果需要任何支持,请联系 Enflame Technology

参考文献

词汇表

表 1 词汇表

名称

说明

EFSMI

EnFlame System Management Interface Tool which is based on EFML library for monitoring GCU device in system

EFML

EnFlame System Management Library, a C/C++/Script library providing system management APIs

GCU

General Compute Unit, refer to PCIe based computing Devices delivered by Enflame

UUID

Universally Unique Identifier

DPM

Dynamic Power Managerment

TDP

Thermal Design Power

分发包

支持的OS类型

EFSMI仅支持 Linux 操作系统。所测试的系统如下所示。

表 2 支持操作系统类型

系统

内核

架构

Ubuntu 18.04.4 Server LTS

4.15.0

x86_64/amd64

Ubuntu 16.04.6 Desktop LTS

4.15.0

x86_64/amd64

Ubuntu 20.04.2 Desktop LTS

5.15.0

x86_64/amd64

TLinux

4.14.105

x86_64/amd64

kylinos

4.19.90

x86_64/amd64

kylinos

4.19.90

aarch64

安装包内容

安装包以压缩包的形式提供,比如‘ efsmi-{version_number}.tar.gz’,下面是解压后安装包的清单。其中包含 efsmi RPM/DEB包和用户手册, 具体内容如下表所示:

表 3 zip 包包含的文件列表

内容

说明

efsmi-x.x.x-x86_64-linux-rel.rpm

RPM 软件包

efsmi-x.x.x-aarch64-linux-rel.rpm

ARM 软件包

efsmi-x.x.x-x86_64-linux-rel.deb

Debian 软件包

efsmi_用户手册.pdf

用户手册

Attention

请联系客户支持工程师获取发布软件包。

安装步骤

目前提供两种形式的安装包,debrpmdeb 包是针对Debian(Ubuntu, Mint)衍生的linux发行版的。 rpm 包是针对Redhat(CentOS, Fedora, RHEL)衍生的linux发行版的。 在安装EFSMI时,EFSMI/EFML同时会被安装,还包括EFML的python语言支持库。

RPM

RPM 软件包的名字类似于 efsmi-x.x.x-x86_64-linux-rel.rpm , ‘x.x.x’ 遵循 ‘大版本.小版本.补丁’ 的格式。

以 ‘1.0.0’为例, 执行如下命令安装:

$ rpm -ivh efsmi-1.0.0-x86_64-linux-rel.rpm

Preparing...                       ################################# [100%]
Updating / installing...
1:efsmi-1.0.0-1                    ################################# [100%]
running install
running build
running build_py
creating build
creating build/lib
copying pyefml.py -> build/lib
running install_lib
copying build/lib/pyefml.py -> /usr/lib/python2.7/site-packages
byte-compiling /usr/lib/python2.7/site-packages/pyefml.py to pyefml.pyc
running install_egg_info
Writing /usr/lib/python2.7/site-packages/efmlpy-1.0.0-py2.7.egg-info

执行如下命令卸载efsmi, 卸载过程会删除已安装的文件。

$ rpm -e efsmi

DEB

Debian 软件包的名字类似于 efsmi-x.x.x-x86_64-linux-rel.deb。 执行如下命令安装:

$ dpkg -i efsmi-x.x.x-x86_64-linux-rel.deb

安装完成后, 可以通过 dpkg -L efsmi 命令去检查安装了哪些文件:

$ dpkg -L efsmi
/usr
/usr/local
/usr/local/efsmi
/usr/local/efsmi/efsmi-1.0.0
/usr/local/efsmi/efsmi-1.0.0/doc
/usr/local/efsmi/efsmi-1.0.0/doc/efsmi.1
/usr/local/efsmi/efsmi-1.0.0/doc/efsmi.pdf
/usr/local/efsmi/efsmi-1.0.0/efsmi
/usr/local/efsmi/efsmi-1.0.0/lib
/usr/local/efsmi/efsmi-1.0.0/lib/bindings
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/__init__.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example/dev_info.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example/dev_list.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example/driver_ver.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example/esl_info.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/example/pcie_info.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/pyefml.py
/usr/local/efsmi/efsmi-1.0.0/lib/bindings/python/setup.py
/usr/local/efsmi/efsmi-1.0.0/lib/efml.h
/usr/local/efsmi/efsmi-1.0.0/lib/libefml.a
/usr/local/efsmi/efsmi-1.0.0/lib/libefml.so.1.0.0
/usr/local/efsmi/efsmi-1.0.0/lib/libefml.so

卸载的deb 包的命令如下:

$ dpkg -r efsmi

驱动

efsmi 的部分功能依赖于 enflame 提供的 linux 版设备驱动程序, 详细信息请参考 EFSMI 命令 的命令介绍。

驱动安装方法请参考 enflame 提供的软件安装手册。

使用须知

在宿主机中运行

Attention

  1. efsmi 的部分功能仅支持特权模式下执行

  2. efsmi 在非特权模式下运行,需要依赖 enflame 提供的设备驱动程序

在容器中运行

efsmi 支持在容器中运行, 可以通过以下方式:

赋予容器特权模式

Attention

  1. 在宿主机上以特权用户身份启动容器

  2. 启动容器时, 使能 –privileged=true 参数以赋予容器内用户特权

不赋予特权模式

Attention

  1. 宿主机需要加载 enflame 提供的内核模块设备驱动程序

  2. 启动容器时, 使能 –device 选项映射 enflame 设备到容器内

在虚拟机中运行

Attention

  1. efsmi 不支持在使用mdev虚拟设备的虚拟机中运行

EFSMI 命令

EFSMI是用于监控 GCU 状态的可执行程序,它基于 EFML 库。 EFSMI当前支持的命令如下表所示。

Attention

EFSMI 不支持在宿主机和docker 里面同时运行。

当前支持的命令列表:

表 4 命令列表

参数

说明

-h, –help

显示此帮助说明

“”

不带参数执行 ‘sudo efsmi’ , efsmi 将显示包含 版本号/驱动/功耗/频率/温度
支持的子命令:

a. -i X

选择指定的 GCU 卡

e.g. 'sudo efsmi -i 0'
显示 GCU 卡 0 的信息

-L

显示所有支持的 GCUs

–version

显示 efsmi 版本号

-dmon

监控 GCU 设备的各种数据,刷新率为 1s。
Ctrl + C 退出监控。
子命令:
a. -i X

选择指定的 GCU

b. -s XXX

选择显示部分数据,XXX 可以是 “p”, “g”, “c”, “m”, “t” 及其组合, “all” 为所有信息。

p: 显示功耗/温度/使用率的监控信息

g: 显示物理组的监控信息

c: 显示频率的监控信息

m: 显示内存信息, 此功能依赖 enflame 提供的设备驱动程序, 在缺少驱动程序时, 内存信息为 0

t: 显示 PCIe/GCU-LARE 吞吐量的监控信息, GCU-LARE 在 i10 上不支持

all: 在同一行显示所有信息

e.g. 'sudo efsmi -dmon -s c -i 0'
显示 GCU0 的频率信息

-dmon

c. -c X

设置循环次数

e.g. 'sudo efsmi -dmon -c 10'
打印10次设备监控信息

d. -o

显示时间戳信息

e. -w X

以秒为单位设置刷新时间间隔

-pmon

监控使用 GCU 设备的进程的各种数据,刷新率为 1s。
Ctrl + C 退出监控。
子命令:
a. -i X

选择指定的 GCU

b. -c X

设置循环次数

e.g. 'sudo efsmi -pmon -c 10'
打印10次设备监控信息

c. -o

显示时间戳信息

d. -w X

以秒为单位设置刷新时间间隔

-q

获取 GCU 状态信息
列出 GCUs 状态的详细信息,以 TAB 对齐


支持的子命令:

a. –i X

指定的 GCU

b. –l X

指定loops的次数

c. -d XXX

选择要显示的内容
XXX 可以设定为以下之一:
“POWER”, “GCU-LARE”, “CLOCK”, “DRIVER”, “DEVICE”, “PCIE” “MEMORY” “TEMP” “VOLT”
“USAGE”, “ECC”, “RETIRED”
e.g. 'sudo efsmi -q -d CLOCK -i 0'


选择显示GCU0 的频率信息

注意:
内存信息依赖 enflame 提供的设备驱动程序

-f xxx

将log 信息输出到 file xxx
e.g. 'sudo efsmi -q -f log.txt'

重定向 console 输出到 log.txt

-topo

显示 GCU 卡间的GCU-LARE互联拓扑

-ptopo

显示 设备的PCIE 拓扑信息

-r

该指令会复位 GCU 设备, 此命令需要依赖 enflame 提供的设备驱动程序

支持的子命令:

a. –i X

选择指定的 GCU

-ecc

设置设备的Ecc 状态
ecc 状态变更后需重启机器方可生效

支持的子命令:
a. -i X
选择指定的 GCU
b. -m 0|1
设置 ecc 状态, 0 为 关闭, 1 为打开

-env

显示系统环境的详细信息

支持的子命令:
a. -i X
选择指定的 GCU

-eid

收集KMD eid(错误id)信息
用法:
-eid start|stop # 开始/停止收集错误id信息
e.g. “sudo efsmi -eid start
开始收集错误信息

-dic

搜集系统环境详细信息及日志

包含如下信息:
EFSMI 版本信息
GCU 状态信息
系统状态信息
处理器信息
BIOS 信息
操作系统信息
PCIe 拓扑信息
GCU-LARE 拓扑信息
GCU 防火墙状态信息
NUMA节点中的宿主机CPU列表
宿主机 GRUB 设置
宿主机硬盘信息
GCC 版本信息
宿主机内存信息
宿主机 SMBIOS 信息
Enflame 驱动版本
Enflame 驱动模块参数
Enflame 设备列表
Enflame 设备 NUMA 节点
Enflame 设备固件版本
Enflame 设备互联状态
Enflame 设备 MaxPayload 信息
Enflame 设备 BAR 信息
宿主机进程
宿主机dmesg错误日志
宿主机demsg日志

-vdtu

查询 vGCU 状态信息

支持的子命令:

a. –i X
指定的 GCU

Attention

GCU-LARE 1 在部分产品上不支持。

信息概览

不带参数执行 'sudo efsmi', 将显示如下的看板信息:

TBA

图 1 efsmi 看板信息的输出

表 5 看板信息详细说明

字段

字段内容

EFSMI Ver:

EFSMI 版本号

Driver Ver:

Driver 版本号

DEV:

GCU 设备的ID号

NAME:

GCU 设备型号

FW Ver:

固件版本

Bus-ID:

PCIe 设备 Domain/Bus/Device/Function ID

ECC:

Memory ECC 开/关 状态

TEMP:

GCU 设备当前温度

DPM:

动态功耗管理,对应于GCU频率等级

Pwr (Usage/Cap):

当前功耗/额定功耗

DEV-Util:

设备使用率

UUID:

设备识别码

vGCU:

vGCU 状态

Attention

默认条件下将展示所有设备的信息。 参数 “-i X” 可以用来获取指定的设备信息。

设备利用率:在 1 个采样周期内, GCU 上有 1 个或多于 1 个的 SIP 处于工作状态的时间占比, 采样周期为 1 秒。

信息查询

下图显示了执行命令 'sudo efsmi -q' 时得到的查询信息。 部分内容定义与EFSMI 看板中定义的相同。另有更多信息展示: 例如PCIe Tx/Rx 实时带宽信息、GCU-LARE端口连接情况和实时带宽信息和GCU/Mem信息。 默认情况下, “-q” 命令将查询并显示所有检测到的 GCU 设备, 参数 “-i X” 可用于选择特定的 GCU 。 支持的子命令请参见本章 EFSMI 命令

TBA

图 2 ` sudo efsmi -q ` 命令的输出

设备监控

下面的图片显示了执行 'sudo efsmi -dmon' 时得到的设备监视器信息,它将显示功耗,GCU/Mem温度,频率等的实时抓取的板卡信息 详细的子命令请参见本章中的表格 EFSMI 命令

收集的数据将显示在一行,每秒刷新一次。循环数和刷新周期可以通过子命令 “-c X” 和 “-w X” 调整。 ` Ctrl + C ` 可退出显示 。

TBA

图 3 ` sudo efsmi -dmon ` 命令的输出

表 6 监控功能数据详细介绍

字段

字段内容

Dev Idx:

GCU卡序号

Logic Id:

GCU卡逻辑序号

Pwr:

板卡功耗(瓦)

DTemp:

板卡温度

Dpm:

DPM 等级

M1Temp/M2Temp:

芯片中内存的温度

Mem:

GCU 内存的大小

Ecc:

ECC 状态,部分产品不支持

Dclk MHz:

GCU 频率

Mclk MHz:

内存频率

TxPci/RxPci:

PCIe Tx/Rx 带宽

TxE/RxE:

GCU-LARE Tx/Rx 带宽,部分产品不支持

Attention

通常情况下, 设备ID与逻辑ID是相同的;在某些平台上, 可能存在设备ID与逻辑ID不同的情况, 请留意这一点。

GCU 卡序号:按PCI 总线上Enflame GCU 设备bdf信息排列。

GCU 卡逻辑序号:按Enflame KerneL Module Driver 枚举 GCU 设备的先后次序排列。

GCU-LARE 拓扑

每个 GCU 设备都支持通过GCU-LARE和其他 GCU 设备互联, i10 不支持这种互联方式。 命令 'sudo efsmi -topo' 可以显示详细的连接信息。 下面图中为 4个GCUs 之间的互联拓扑 。

TBA

图 4 4个GCUs 之间的互联拓扑的输出

表 7 GCU-LARE 拓扑信息

字段

字段内容

Card ID:

GCU卡的ID

UUID:

GCU卡的设备识别码

VID/DID:

Vendor和设备的ID

Domain/B/D/F:

Domain/Bus/Device/Function ID

Port ID:

远程连接端口信息

PCIE 拓扑

在PCIe的树形结构里, 每个GCU设备都是一个EP、endpoint,它会跟PCIe Switch 的下游端口相连。 PCIe Switch的上游端口会继续跟别的Switch或者CPU的RC(Root Complex)/Host Bridge的下游端口相连。 这样构建出一个树形的topo结构。

‘sudo efsmi -ptopo’ 命令可以展示这种结构的详细信息

TBA

图 5 系统中GCU设备的PCIe路由拓扑信息的输出

ECC 状态

各个 GCU 的ECC状态可能不同,以’-q’ 命令获取当前模式, 可以通过 'sudo efsmi -ecc -i 0 -m [0|1]' 设置设备0的ecc状态,’-m 0’是禁用,’-m 1’是启用; 设置后需重启设备方可生效 。

Attention

S6/S60/S90 产品不支持此特性

EFML - Enflame 管理库

EFML是一套基于C/C++语言开发的程序库,使用这套程序库,应用软件可以很方便的实现对Enflame 硬件设备的访问。 EFML公开提供的API可以被C/C++/Python/Go… 等语言开发的程序使用。

EFSMI 就是利用 EFML 实现硬件监控和管理的应用之一 。 EFML 是与 EFSMI 包一起发布的,包括它的头文件、库文件、脚本,还有一些示例代码 。

EFML包含的文件

下表是 EFML 库包含的文件列表

表 8 EFML 包包含的文件列表

名称:

说明

efml.h

提供API 支持的C头文件

libefml.a

静态链接库

libefml.so

动态链接库

setup.py

python APIS 安装脚本

example

python 示例

pyefml.py

python binding APIs

C/C++ 示例

下面的例子展示了如何使用EFML库开发C/C++程序获取系统中GCU设备个数。

#include <iostream>
#include <string>
#include <string.h>
#include <stdint.h>
#include "efml.h"

int main(void)
{
   int ret = 0;

   // init library
   ret += static_cast<int>EfmlInit();

   // device info structure
   efmlDeviceInfo_t dev_info;

   // call 'EfmlGetDevCount' to get total device counts in system
   uint32_t dev_cnt = 0;
   ret += static_cast<int>EfmlGetDevCount(&dev_cnt);
   std::cout << "device count = " << dev_cnt << std::endl;

   // loop through each device get and print device VID/DID and Bus/Dev/Func info
   for (uint32_t i = 0; i < dev_cnt; i++)
   {
      memset(&dev_info, 0, sizeof(efmlDeviceInfo_t));
      ret += static_cast<int>EfmlGetDevInfo(i, &dev_info);
      std::cout << "dev id = " << i << std::endl;
      std::cout << "name = " << dev_info.name << std::endl;
      std::cout << "vendor id = " << std::hex << dev_info.vendor_id << std::endl;
      std::cout << "device id = " << std::hex << dev_info.vendor_id << std::endl;
      std::cout << "domain = " << std::hex << dev_info.domain_id << std::endl;
      std::cout << "bus = " << std::hex << dev_info.bus_id << std::endl;
      std::cout << "dev = " << std::hex << dev_info.dev_id << std::endl;
      std::cout << "func = " << std::hex << dev_info.func_id << std::endl;
   }

   // check if error returned in above steps
   if (ret != static_cast<int>(EFML_SUCCESS))
      std::cout <<  `execute failed! check log ` << std::endl;

   // shutdown library
   EfmlShutdown();

   return ret;
}

上述代码是C++ 代码, 编译上述代码, 请注意以下事项:

Attention

a.包含头文件efml .h b.首先调用API ‘EfmlInit()’来初始化库 c.在所有进程结束时,调用API ‘EfmlShutdown()’来释放库使用的资源 d.编译时使用’-L DIR_TO_EFML_LIB’来指定库文件存在的目录 e.编译时使用’-lefml’链接库文件 当使用静态链接库进行链接时,需要使用’-lpthread’

Script Bindings

Python

在人工智能行业中,Python 是开发应用程序的主要语言之一 。 EFML 还提供了python语言开发库。

Attention

如果我们安装了一个新版本的python,比如python3 。想在这个python环境中使用pyefml, 我们需去efsmi安装目录/usr/local/efsmi/efsmi-xx.xx.xx/lib/bindings/python/ 并执行 ‘python3 .X setup.py install’,请确保’distutils’包存在于当前python使用环境。

安装完成后,pyefml.py已经作为python模块安装到系统操作系统中,您可以导入该模块。

如果您想快速体验python中的pyefml,请尝试以下命令。

python
>>> import pyefml
>>> pyefml.efmlInit()
0
>>> pyefml.efmlGetDevCount()
1L
>>> pyefml.efmlShutdown()

第一条返回值 ‘0’ 表示 EFML 初始化正常。

第二条返回值 ‘1L’ 表示系统中检测到一张 GCU 卡。

下面的例子展示如何使用EFML python库的example.py脚本获取设备信息。 安装完成后命令行执行 ‘python ./example.py’即可。

# -*- coding: utf-8 -*-
import sys
from ctypes import *
import pyefml

# init and enumerate device
pyefml.efmlInit()

# get device counts
dev_cnt = pyefml.efmlGetDevCount()
print('total device count = {}'.format(dev_cnt))

for idx in range(dev_cnt):
   dev_info = pyefml.efmlGetDevInfo(idx)
   print('device idx: {}'.format(idx))
   print('name = {}'.format(dev_info.name))
   print('vendor_id = {:04x}'.format(dev_info.vendor_id))
   print('device_id = {:04x}'.format(dev_info.device_id))
   print('domain_id = {:04x}'.format(dev_info.domain_id))
   print('bus_id = {:02x}'.format(dev_info.bus_id))
   print('dev_id = {:x}'.format(dev_info.dev_id))
   print("func_id = {:x}".format(dev_info.func_id))

# shutdown
pyefml.efmlShutdown()

与 C++ 的示例一样,pyefml.efmlInit()/pyefml.efmlShutdown() 需在初始化/退出的时候加载。 示例中的代码会打印出系统中所有 GCU 设备的 厂商识别码/设备识别码 Bus/Dev/Func 信息。

Go

Go 是一款开源编程软件,它使得代码实现更加简单,可靠和高效,也因此越来越受欢迎。 我们也提供了支持Go语言的efml 库。

Attention

请参阅 Golang 的官方文档去搭建 Go 开发环境。 简而言之,你需要安装Golang并设置Go 开发环境,包含设置 “$GOPATH” and “$GOROOT”。

下面有一个简单的示例 “main.go” ,示例可以打印出基本的设备信息。

package main

import (
      "efml"
      "fmt"
)

func main() {
      efml.Init()
      cnt, _ := efml.GetDevCount()
      for dev_idx := uint32(0); dev_idx < cnt; dev_idx++ {
               devInfo, _ := efml.GetDevInfo(dev_idx)

               fmt.Println("device idx:", dev_idx)
               fmt.Println("name = ", devInfo.Name)
               fmt.Printf("vendor_id = %4x\n", devInfo.Vendor_id)
               fmt.Printf("device_id = %4x\n", devInfo.Device_id)
               fmt.Printf("domain_id = %4x\n", devInfo.Domain_id)
               fmt.Printf("bus_id    = %2x\n", devInfo.Bus_id)
               fmt.Printf("dev_id    = %2x\n", devInfo.Dev_id)
               fmt.Printf("func_id   = %2x\n", devInfo.Func_id)
      }

      efml.Shutdown()
}

编译上述代码,你需要正确的生成和放置库文件的源代码。 Golang 的源代码放置于名为“src”的文件夹, efml 库文件放在下面的子目录。 在 efml 目录,你可以找到如下文件:

表 9 Go 绑定文件

名称:

说明

efml.h

提供API 支持的C头文件

libefml.so

动态链接库

efml_dl.go

go binding 库文件

efml_bindings.go

go binding 文件

源文件的代码结构应类似于:

dev_info
|—src
|– efml
|– libefml.go
|– efml.h
|– efml_dl.go
|– efml_bindings.go
|– main.go

重定向 “$GOPATH” to “dev_info” 链接, 你可以执行如下命令:

'export GOPATH="/PATH/TO/dev_info'

另,需设置环境变量 “LD_LIBRARY_PATH” 以便于查找 “libefml.so”:

'export LD_LIBRARY_PATH=/PATH/TO/dev_info/src/efml:$LD_LIBRARY_PATH' 'ldconfig'

返回到 “dev_info” 目录,执行 “go build”, 代码将被编译成 “dev_info” 可执行文件。

在目标机器执行生成的 “dev_info” 程序,将会输出目标设备的基本信息。

其他脚本支持

Enflame 正致力于支持当前流行的脚本实现,如有特殊需求,请联系 Enflame 寻求帮助。

1

GCU-LARE TM 是为支持加速卡之间互联的燧原智能互联技术。