Files
vikingowl a0a947094d feat: add multi-GPU support and operational modes
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>
2025-12-28 07:21:50 +01:00

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,
}
}