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 ...@@ -2,10 +2,10 @@ package tui
import ( import (
"fmt" "fmt"
"get-container/gpu" "time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"time"
) )
type ModelHeader struct { type ModelHeader struct {
...@@ -16,28 +16,24 @@ type ModelHeader struct { ...@@ -16,28 +16,24 @@ type ModelHeader struct {
} }
func (mh *ModelHeader) Init() tea.Cmd { 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() mh.t = time.Now()
return func() tea.Msg { return nil
return TickMsg(time.Now())
}
} }
func (mh *ModelHeader) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) { func (mh *ModelHeader) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := inputMsg.(type) { switch msg := inputMsg.(type) {
case TickMsg: case ModelMsg:
mh.t = time.Time(msg) mh.t = msg.t
return mh, tea.Every(time.Second, func(t time.Time) tea.Msg { mh.DCUTopVersion = msg.MyVersion
return TickMsg(t) 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 return mh, nil
} }
......
...@@ -2,30 +2,42 @@ package tui ...@@ -2,30 +2,42 @@ package tui
import ( import (
"get-container/gpu" "get-container/gpu"
"time"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"time" )
const (
DCUTopVersion = "1.0.0"
) )
// ModelMsg 模型信息,在父组件和各个子组件间共享信息 // ModelMsg 模型信息,在父组件和各个子组件间共享信息
type ModelMsg struct { type ModelMsg struct {
t time.Time // 当前时间 t time.Time // 当前时间
index uint64 // update次数 index uint64 // update次数
Version *gpu.HYVersionInfo // gpu版本相关信息 Version *gpu.HYVersionInfo // gpu版本相关信息
DCUInfo []gpu.DCUInfo // DCU全量信息 MyVersion string
DCUPidInfo []gpu.DCUPidInfo // 使用dcu的进程信息 // DCUInfo []gpu.DCUInfo // DCU全量信息
// DCUPidInfo []gpu.DCUPidInfo // 使用dcu的进程信息
} }
type TickMsg time.Time type TickMsg time.Time
// ModelMain tui主模型类 // ModelMain tui主模型类
type ModelMain struct { type ModelMain struct {
Header *ModelHeader Header *ModelHeader
GPUInfo *ModelDCUInfo // GPUInfo *ModelDCUInfo
SysLoad *ModelSysLoad // SysLoad *ModelSysLoad
ProcessInfo *ModelProcess // ProcessInfo *ModelProcess
index uint64 // 记录update次数的值 index uint64 // 记录update次数的值
modelMsg *ModelMsg // 记录模型信息 modelMsg *ModelMsg // 记录模型信息
}
func NewModelMain() ModelMain {
result := ModelMain{}
result.Header = &ModelHeader{}
return result
} }
func tickCmd() tea.Cmd { func tickCmd() tea.Cmd {
...@@ -42,8 +54,10 @@ func sendMsgCmd(modelMsg *ModelMsg) tea.Cmd { ...@@ -42,8 +54,10 @@ func sendMsgCmd(modelMsg *ModelMsg) tea.Cmd {
// Init 初始化信息 // Init 初始化信息
func (m *ModelMain) Init() tea.Cmd { func (m *ModelMain) Init() tea.Cmd {
// todo 初始化一个ModelMsg实例
modelMsg := &ModelMsg{} modelMsg := &ModelMsg{}
if err := initModelInfo(modelMsg); err != nil {
return tea.Quit
}
cmds := make([]tea.Cmd, 0) cmds := make([]tea.Cmd, 0)
if c := m.Header.Init(); c != nil { if c := m.Header.Init(); c != nil {
cmds = append(cmds, c) cmds = append(cmds, c)
...@@ -77,9 +91,9 @@ func (m *ModelMain) View() string { ...@@ -77,9 +91,9 @@ func (m *ModelMain) View() string {
return m.Header.View() return m.Header.View()
} }
type ModelDCUInfo struct{} // type ModelDCUInfo struct{}
type ModelSysLoad struct{} // type ModelSysLoad struct{}
type ModelProcess struct{} // type ModelProcess struct{}
var myBorder = lipgloss.Border{ var myBorder = lipgloss.Border{
Top: "═", Top: "═",
...@@ -97,6 +111,18 @@ var myBorder = lipgloss.Border{ ...@@ -97,6 +111,18 @@ var myBorder = lipgloss.Border{
MiddleBottom: "┴", 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 更新模型信息 // updateModelInfo 更新模型信息
func updateModelInfo(modelMsg *ModelMsg, index uint64, t time.Time) { func updateModelInfo(modelMsg *ModelMsg, index uint64, t time.Time) {
modelMsg.index = index modelMsg.index = index
......
...@@ -3,7 +3,6 @@ module get-container ...@@ -3,7 +3,6 @@ module get-container
go 1.24.2 go 1.24.2
require ( require (
github.com/NimbleMarkets/ntcharts v0.3.1
github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/lipgloss v1.1.0
github.com/moby/moby/api v1.52.0-beta.2 github.com/moby/moby/api v1.52.0-beta.2
...@@ -15,7 +14,6 @@ require ( ...@@ -15,7 +14,6 @@ require (
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // 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/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect github.com/charmbracelet/x/ansi v0.10.1 // indirect
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
...@@ -31,7 +29,6 @@ require ( ...@@ -31,7 +29,6 @@ require (
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // 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/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
......
...@@ -432,6 +432,7 @@ type DCUPidInfo struct { ...@@ -432,6 +432,7 @@ type DCUPidInfo struct {
} }
// GetDCUPidInfo 获取Pid相关信息 // GetDCUPidInfo 获取Pid相关信息
// 需要剔除PCIBus为空的项
func GetDCUPidInfo() ([]DCUPidInfo, error) { func GetDCUPidInfo() ([]DCUPidInfo, error) {
output, err := exec.Command(DCUBinaryFile, "--showpids").Output() output, err := exec.Command(DCUBinaryFile, "--showpids").Output()
if err != nil { if err != nil {
...@@ -461,33 +462,22 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) { ...@@ -461,33 +462,22 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
index += 1 index += 1
infosArray = append(infosArray, make(map[string]string)) infosArray = append(infosArray, make(map[string]string))
infosArray[index][PIDHeader] = line[1] infosArray[index][PIDHeader] = line[1]
break
case PASIDHeader: case PASIDHeader:
infosArray[index][PASIDHeader] = line[1] infosArray[index][PASIDHeader] = line[1]
break
case HCUNodeHeader: case HCUNodeHeader:
infosArray[index][HCUNodeHeader] = line[1] infosArray[index][HCUNodeHeader] = line[1]
break
case HCUIndexHeader: case HCUIndexHeader:
infosArray[index][HCUIndexHeader] = line[1] infosArray[index][HCUIndexHeader] = line[1]
break
case GPUIDHeader: case GPUIDHeader:
infosArray[index][GPUIDHeader] = line[1] infosArray[index][GPUIDHeader] = line[1]
break
case PCIBusHeader: case PCIBusHeader:
infosArray[index][PCIBusHeader] = line[1] infosArray[index][PCIBusHeader] = line[1]
break
case VRamUsedHeader: case VRamUsedHeader:
infosArray[index][VRamUsedHeader] = line[1] infosArray[index][VRamUsedHeader] = line[1]
break
case VRamUsedPercentHeader: case VRamUsedPercentHeader:
infosArray[index][VRamUsedPercentHeader] = line[1] infosArray[index][VRamUsedPercentHeader] = line[1]
break
case SDMAUsedHeader: case SDMAUsedHeader:
infosArray[index][SDMAUsedHeader] = line[1] infosArray[index][SDMAUsedHeader] = line[1]
break
default:
break
} }
} }
result := make([]DCUPidInfo, 0) result := make([]DCUPidInfo, 0)
...@@ -496,6 +486,13 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) { ...@@ -496,6 +486,13 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
} }
for _, info := range infosArray { for _, info := range infosArray {
i := DCUPidInfo{} 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) pid, innerErr := strconv.ParseUint(info[PIDHeader], 10, 64)
if innerErr != nil { if innerErr != nil {
return nil, innerErr return nil, innerErr
...@@ -505,10 +502,6 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) { ...@@ -505,10 +502,6 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
if innerErr != nil { if innerErr != nil {
return nil, innerErr 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) s, innerErr := strconv.ParseUint(info[VRamUsedHeader], 10, 64)
if innerErr != nil { if innerErr != nil {
return nil, innerErr return nil, innerErr
...@@ -528,6 +521,18 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) { ...@@ -528,6 +521,18 @@ func parseDCUPidInfo(s string) ([]DCUPidInfo, error) {
} }
result = append(result, i) 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 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) { ...@@ -109,16 +109,12 @@ func GetVersionInfo() (*NVVersionInfo, error) {
switch strings.ToLower(strings.TrimSpace(field[0])) { switch strings.ToLower(strings.TrimSpace(field[0])) {
case strings.ToLower(SmiVersionHeader): case strings.ToLower(SmiVersionHeader):
result.SMIVersion = strings.TrimSpace(field[1]) result.SMIVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(NvmlVersionHeader): case strings.ToLower(NvmlVersionHeader):
result.NVMLVersion = strings.TrimSpace(field[1]) result.NVMLVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(DriverVersionHeader): case strings.ToLower(DriverVersionHeader):
result.DriverVersion = strings.TrimSpace(field[1]) result.DriverVersion = strings.TrimSpace(field[1])
break
case strings.ToLower(CudaVersionHeader): case strings.ToLower(CudaVersionHeader):
result.CUDAVersion = strings.TrimSpace(field[1]) result.CUDAVersion = strings.TrimSpace(field[1])
break
} }
} }
return result, err return result, err
......
...@@ -253,7 +253,7 @@ func TestParseSMIAllOutput(t *testing.T) { ...@@ -253,7 +253,7 @@ func TestParseSMIAllOutput(t *testing.T) {
} }
if ReInfoHeader.MatchString(line) { if ReInfoHeader.MatchString(line) {
fields := ReInfoHeader.FindStringSubmatch(strings.TrimSpace(strings.ReplaceAll(line, "\t", " "))) fields := ReInfoHeader.FindStringSubmatch(strings.TrimSpace(strings.ReplaceAll(line, "\t", " ")))
if fields == nil || len(fields) <= 2 { if len(fields) <= 2 {
continue continue
} }
id, innerErr := strconv.Atoi(fields[1]) 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