Multi-GPU Collection System: - Add modular GPU collector architecture in collectors/gpu/ - Support AMD (amdgpu), NVIDIA (nvidia-smi), and Intel (i915/xe) GPUs - GPU Manager auto-detects and aggregates all vendor collectors - Backward-compatible JSON output for existing frontend Operational Modes: - Standalone mode (default): single-host monitoring, no database - Server mode: multi-device with database, auth, agents (WIP) - Agent mode: lightweight reporter to central server (WIP) - Mode selection via TYTO_MODE env var or config.yaml Configuration Updates: - Add server config (gRPC port, mTLS settings, registration) - Add agent config (ID, server URL, TLS certificates) - Add database config (SQLite/PostgreSQL support) - Support TYTO_* prefixed environment variables 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
package models
|
|
|
|
// GPUVendor identifies the GPU manufacturer.
|
|
type GPUVendor string
|
|
|
|
const (
|
|
GPUVendorAMD GPUVendor = "amd"
|
|
GPUVendorNVIDIA GPUVendor = "nvidia"
|
|
GPUVendorIntel GPUVendor = "intel"
|
|
)
|
|
|
|
// GPUInfo contains metrics for a single GPU.
|
|
type GPUInfo struct {
|
|
Index int `json:"index"`
|
|
Name string `json:"name"`
|
|
Vendor GPUVendor `json:"vendor"`
|
|
Driver string `json:"driver,omitempty"`
|
|
Utilization int `json:"utilization"`
|
|
MemoryUsed uint64 `json:"memoryUsed"`
|
|
MemoryTotal uint64 `json:"memoryTotal"`
|
|
Temperature float64 `json:"temperature"`
|
|
FanRPM int `json:"fanRpm,omitempty"`
|
|
PowerWatts float64 `json:"powerWatts,omitempty"`
|
|
ClockCore int `json:"clockCore,omitempty"`
|
|
ClockMemory int `json:"clockMemory,omitempty"`
|
|
}
|
|
|
|
// GPUStats contains aggregate GPU information for all detected GPUs.
|
|
type GPUStats struct {
|
|
Available bool `json:"available"`
|
|
GPUs []GPUInfo `json:"gpus"`
|
|
}
|
|
|
|
// AMDGPUStats is kept for backward compatibility with existing API consumers.
|
|
// Deprecated: Use GPUStats instead.
|
|
type AMDGPUStats struct {
|
|
Available bool `json:"available"`
|
|
Name string `json:"name,omitempty"`
|
|
Utilization int `json:"utilization"`
|
|
VRAMUsed uint64 `json:"vramUsed"`
|
|
VRAMTotal uint64 `json:"vramTotal"`
|
|
Temperature float64 `json:"temperature"`
|
|
FanRPM int `json:"fanRpm"`
|
|
PowerWatts float64 `json:"powerWatts"`
|
|
ClockGPU int `json:"clockGpu"`
|
|
ClockMemory int `json:"clockMemory"`
|
|
}
|
|
|
|
// ToGPUStats converts the legacy AMD stats to the new multi-GPU format.
|
|
func (a *AMDGPUStats) ToGPUStats() GPUStats {
|
|
if !a.Available {
|
|
return GPUStats{Available: false}
|
|
}
|
|
|
|
return GPUStats{
|
|
Available: true,
|
|
GPUs: []GPUInfo{
|
|
{
|
|
Index: 0,
|
|
Name: a.Name,
|
|
Vendor: GPUVendorAMD,
|
|
Driver: "amdgpu",
|
|
Utilization: a.Utilization,
|
|
MemoryUsed: a.VRAMUsed,
|
|
MemoryTotal: a.VRAMTotal,
|
|
Temperature: a.Temperature,
|
|
FanRPM: a.FanRPM,
|
|
PowerWatts: a.PowerWatts,
|
|
ClockCore: a.ClockGPU,
|
|
ClockMemory: a.ClockMemory,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// FromGPUInfo converts the new GPU info to legacy AMD format (for first AMD GPU).
|
|
func AMDGPUStatsFromGPUInfo(stats GPUStats) AMDGPUStats {
|
|
if !stats.Available || len(stats.GPUs) == 0 {
|
|
return AMDGPUStats{Available: false}
|
|
}
|
|
|
|
// Find first AMD GPU or use first GPU
|
|
var gpu *GPUInfo
|
|
for i := range stats.GPUs {
|
|
if stats.GPUs[i].Vendor == GPUVendorAMD {
|
|
gpu = &stats.GPUs[i]
|
|
break
|
|
}
|
|
}
|
|
if gpu == nil {
|
|
gpu = &stats.GPUs[0]
|
|
}
|
|
|
|
return AMDGPUStats{
|
|
Available: true,
|
|
Name: gpu.Name,
|
|
Utilization: gpu.Utilization,
|
|
VRAMUsed: gpu.MemoryUsed,
|
|
VRAMTotal: gpu.MemoryTotal,
|
|
Temperature: gpu.Temperature,
|
|
FanRPM: gpu.FanRPM,
|
|
PowerWatts: gpu.PowerWatts,
|
|
ClockGPU: gpu.ClockCore,
|
|
ClockMemory: gpu.ClockMemory,
|
|
}
|
|
}
|