Commit 93262722 authored by liming6's avatar liming6
Browse files

fix 修正获取dcu信息的方法

parent 771221d9
package main
import (
"get-container/cmd/dcutop/tui"
"log"
"os"
tea "github.com/charmbracelet/bubbletea"
)
func main() {
model := tui.NewModelMain()
if _, err := tea.NewProgram(&model).Run(); err != nil {
log.Fatalf("error create program; %v", err)
}
os.Exit(0)
}
......@@ -2,10 +2,10 @@ package tui
import (
"fmt"
"get-container/gpu"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"time"
)
type ModelHeader struct {
......@@ -16,28 +16,24 @@ type ModelHeader struct {
}
func (mh *ModelHeader) Init() tea.Cmd {
v, err := gpu.GetHYVersionInfo()
if err != nil || v == nil {
return tea.Quit
}
mh.DCUTopVersion = "1.0.0"
//mh.SMIVersion = v.SMIVersion // 1.14.0
//mh.DriverVersion = v.DriverVersion // 6.3.6-V1.9.0
mh.SMIVersion = "1.14.0"
mh.DriverVersion = "6.3.6-V1.9.0"
mh.t = time.Now()
return func() tea.Msg {
return TickMsg(time.Now())
}
return nil
}
func (mh *ModelHeader) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := inputMsg.(type) {
case TickMsg:
mh.t = time.Time(msg)
return mh, tea.Every(time.Second, func(t time.Time) tea.Msg {
return TickMsg(t)
})
case ModelMsg:
mh.t = msg.t
mh.DCUTopVersion = msg.MyVersion
mh.DriverVersion = msg.Version.DriverVersion
mh.SMIVersion = msg.Version.SMIVersion
return mh, nil
case *ModelMsg:
mh.t = msg.t
mh.DCUTopVersion = msg.MyVersion
mh.DriverVersion = msg.Version.DriverVersion
mh.SMIVersion = msg.Version.SMIVersion
return mh, nil
}
return mh, nil
}
......
......@@ -2,30 +2,42 @@ package tui
import (
"get-container/gpu"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"time"
)
const (
DCUTopVersion = "1.0.0"
)
// ModelMsg 模型信息,在父组件和各个子组件间共享信息
type ModelMsg struct {
t time.Time // 当前时间
index uint64 // update次数
Version *gpu.HYVersionInfo // gpu版本相关信息
DCUInfo []gpu.DCUInfo // DCU全量信息
DCUPidInfo []gpu.DCUPidInfo // 使用dcu的进程信息
t time.Time // 当前时间
index uint64 // update次数
Version *gpu.HYVersionInfo // gpu版本相关信息
MyVersion string
// DCUInfo []gpu.DCUInfo // DCU全量信息
// DCUPidInfo []gpu.DCUPidInfo // 使用dcu的进程信息
}
type TickMsg time.Time
// ModelMain tui主模型类
type ModelMain struct {
Header *ModelHeader
GPUInfo *ModelDCUInfo
SysLoad *ModelSysLoad
ProcessInfo *ModelProcess
index uint64 // 记录update次数的值
modelMsg *ModelMsg // 记录模型信息
Header *ModelHeader
// GPUInfo *ModelDCUInfo
// SysLoad *ModelSysLoad
// ProcessInfo *ModelProcess
index uint64 // 记录update次数的值
modelMsg *ModelMsg // 记录模型信息
}
func NewModelMain() ModelMain {
result := ModelMain{}
result.Header = &ModelHeader{}
return result
}
func tickCmd() tea.Cmd {
......@@ -42,8 +54,10 @@ func sendMsgCmd(modelMsg *ModelMsg) tea.Cmd {
// Init 初始化信息
func (m *ModelMain) Init() tea.Cmd {
// todo 初始化一个ModelMsg实例
modelMsg := &ModelMsg{}
if err := initModelInfo(modelMsg); err != nil {
return tea.Quit
}
cmds := make([]tea.Cmd, 0)
if c := m.Header.Init(); c != nil {
cmds = append(cmds, c)
......@@ -77,9 +91,9 @@ func (m *ModelMain) View() string {
return m.Header.View()
}
type ModelDCUInfo struct{}
type ModelSysLoad struct{}
type ModelProcess struct{}
// type ModelDCUInfo struct{}
// type ModelSysLoad struct{}
// type ModelProcess struct{}
var myBorder = lipgloss.Border{
Top: "═",
......@@ -97,6 +111,18 @@ var myBorder = lipgloss.Border{
MiddleBottom: "┴",
}
func initModelInfo(model *ModelMsg) error {
model.MyVersion = DCUTopVersion
model.index = 0
model.t = time.Now()
ver, err := gpu.GetHYVersionInfo()
if err != nil {
return err
}
model.Version = ver
return nil
}
// updateModelInfo 更新模型信息
func updateModelInfo(modelMsg *ModelMsg, index uint64, t time.Time) {
modelMsg.index = index
......
......@@ -3,7 +3,6 @@ module get-container
go 1.24.2
require (
github.com/NimbleMarkets/ntcharts v0.3.1
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0
github.com/moby/moby/api v1.52.0-beta.2
......@@ -15,7 +14,6 @@ require (
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/bubbles v0.20.0 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
......@@ -31,7 +29,6 @@ require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/lrstanley/bubblezone v0.0.0-20240914071701-b48c55a5e78e // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
......
......@@ -432,6 +432,7 @@ type DCUPidInfo struct {
}
// GetDCUPidInfo 获取Pid相关信息
// 需要剔除PCIBus为空的项
func GetDCUPidInfo() ([]DCUPidInfo, error) {
output, err := exec.Command(DCUBinaryFile, "--showpids").Output()
if err != nil {
......@@ -461,33 +462,22 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
index += 1
infosArray = append(infosArray, make(map[string]string))
infosArray[index][PIDHeader] = line[1]
break
case PASIDHeader:
infosArray[index][PASIDHeader] = line[1]
break
case HCUNodeHeader:
infosArray[index][HCUNodeHeader] = line[1]
break
case HCUIndexHeader:
infosArray[index][HCUIndexHeader] = line[1]
break
case GPUIDHeader:
infosArray[index][GPUIDHeader] = line[1]
break
case PCIBusHeader:
infosArray[index][PCIBusHeader] = line[1]
break
case VRamUsedHeader:
infosArray[index][VRamUsedHeader] = line[1]
break
case VRamUsedPercentHeader:
infosArray[index][VRamUsedPercentHeader] = line[1]
break
case SDMAUsedHeader:
infosArray[index][SDMAUsedHeader] = line[1]
break
default:
break
}
}
result := make([]DCUPidInfo, 0)
......@@ -496,6 +486,13 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
}
for _, info := range infosArray {
i := DCUPidInfo{}
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[HCUNodeHeader], "'", `"`)), &i.HCUNode)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[HCUIndexHeader], "'", `"`)), &i.HCUIndex)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[GPUIDHeader], "'", `"`)), &i.GPUID)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[PCIBusHeader], "'", `"`)), &i.PCIBus)
if len(i.PCIBus) == 0 {
continue
}
pid, innerErr := strconv.ParseUint(info[PIDHeader], 10, 64)
if innerErr != nil {
return nil, innerErr
......@@ -505,10 +502,6 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
if innerErr != nil {
return nil, innerErr
}
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[HCUNodeHeader], "'", `"`)), &i.HCUNode)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[HCUIndexHeader], "'", `"`)), &i.HCUIndex)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[GPUIDHeader], "'", `"`)), &i.GPUID)
_ = json.Unmarshal([]byte(strings.ReplaceAll(info[PCIBusHeader], "'", `"`)), &i.PCIBus)
s, innerErr := strconv.ParseUint(info[VRamUsedHeader], 10, 64)
if innerErr != nil {
return nil, innerErr
......@@ -528,6 +521,18 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
}
result = append(result, i)
}
// 按照DCU index排序
sort.Slice(result, func(i, j int) bool {
ii, err := strconv.Atoi(result[i].HCUIndex[0])
if err != nil {
return false
}
jj, err := strconv.Atoi(result[j].HCUIndex[0])
if err != nil {
return false
}
return ii < jj
})
return result, nil
}
......
package gpu
import (
"encoding/json"
"strings"
"testing"
)
func TestGetHYVersionInfo(t *testing.T) {
ver, err := GetHYVersionInfo()
if err != nil {
t.Errorf("error get hygon dcu version info: %v", err)
}
t.Logf("version: %+v", ver)
}
func TestGetSMIAllOutput(t *testing.T) {
info, err := GetSMIAllOutput()
if err != nil {
t.Errorf("error get hygon dcu device info: %v", err)
}
for _, i := range info {
t.Logf("%+v", i)
}
}
func TestGetRunningInfo(t *testing.T) {
info, err := GetRunningInfo()
if err != nil {
t.Errorf("error get hygon dcu running info: %v", err)
}
for _, i := range info {
t.Logf("%+v", i)
}
}
func TestGetDCUPidInfo(t *testing.T) {
info, err := GetDCUPidInfo()
if err != nil {
t.Errorf("error get hygon dcu process: %v", err)
}
for _, i := range info {
t.Logf("%+v", i)
}
}
func TestJson(t *testing.T) {
str := "['0','2']"
s := make([]string, 0)
err := json.Unmarshal([]byte(strings.ReplaceAll(str, "'", `"`)), &s)
if err != nil {
t.Errorf("error unmarshal: %v", err)
}
t.Logf("%+v", s)
}
......@@ -109,16 +109,12 @@ func GetVersionInfo() (*NVVersionInfo, error) {
switch strings.ToLower(strings.TrimSpace(field[0])) {
case strings.ToLower(SmiVersionHeader):
result.SMIVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(NvmlVersionHeader):
result.NVMLVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(DriverVersionHeader):
result.DriverVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(CudaVersionHeader):
result.CUDAVersion = strings.TrimSpace(field[1])
break
}
}
return result, err
......
......@@ -253,7 +253,7 @@ func TestParseSMIAllOutput(t *testing.T) {
}
if ReInfoHeader.MatchString(line) {
fields := ReInfoHeader.FindStringSubmatch(strings.TrimSpace(strings.ReplaceAll(line, "\t", " ")))
if fields == nil || len(fields) <= 2 {
if len(fields) <= 2 {
continue
}
id, innerErr := strconv.Atoi(fields[1])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment