1a69fcfd04
- Updated the installation script to clarify that production wrappers do not include fixed test secrets, improving user guidance for local testing. - Modified the jiggablend-manager and jiggablend-runner scripts to remove fixed test configurations, emphasizing the use of local test credentials via `make init-test`. - Enhanced error handling in the runner script to ensure that an API key is provided, improving security and user feedback. - Added new flags and options for the runner, including sandboxing capabilities and GPU ray tracing control, enhancing flexibility for users. - Improved README documentation to reflect changes in usage and configuration, ensuring users have clear instructions for setup and execution.
132 lines
3.1 KiB
Go
132 lines
3.1 KiB
Go
// Package blender: host GPU backend detection for AMD/NVIDIA/Intel.
|
|
package blender
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// DetectGPUBackends detects whether AMD, NVIDIA, and/or Intel GPUs are available
|
|
// using host-level hardware probing only.
|
|
func DetectGPUBackends() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
return detectGPUBackendsFromHost()
|
|
}
|
|
|
|
func detectGPUBackendsFromHost() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
if amd, nvidia, intel, found := detectGPUBackendsFromDRM(); found {
|
|
return amd, nvidia, intel, true
|
|
}
|
|
if amd, nvidia, intel, found := detectGPUBackendsFromLSPCI(); found {
|
|
return amd, nvidia, intel, true
|
|
}
|
|
return false, false, false, false
|
|
}
|
|
|
|
func detectGPUBackendsFromDRM() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
entries, err := os.ReadDir("/sys/class/drm")
|
|
if err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
name := entry.Name()
|
|
if !isDRMCardNode(name) {
|
|
continue
|
|
}
|
|
|
|
vendorPath := filepath.Join("/sys/class/drm", name, "device", "vendor")
|
|
vendorRaw, err := os.ReadFile(vendorPath)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
vendor := strings.TrimSpace(strings.ToLower(string(vendorRaw)))
|
|
switch vendor {
|
|
case "0x1002":
|
|
hasAMD = true
|
|
ok = true
|
|
case "0x10de":
|
|
hasNVIDIA = true
|
|
ok = true
|
|
case "0x8086":
|
|
hasIntel = true
|
|
ok = true
|
|
}
|
|
}
|
|
|
|
return hasAMD, hasNVIDIA, hasIntel, ok
|
|
}
|
|
|
|
func isDRMCardNode(name string) bool {
|
|
if !strings.HasPrefix(name, "card") {
|
|
return false
|
|
}
|
|
if strings.Contains(name, "-") {
|
|
// Connector entries like card0-DP-1 are not GPU device nodes.
|
|
return false
|
|
}
|
|
if len(name) <= len("card") {
|
|
return false
|
|
}
|
|
_, err := strconv.Atoi(strings.TrimPrefix(name, "card"))
|
|
return err == nil
|
|
}
|
|
|
|
func detectGPUBackendsFromLSPCI() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
if _, err := exec.LookPath("lspci"); err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
out, err := exec.Command("lspci").CombinedOutput()
|
|
if err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
scanner := bufio.NewScanner(strings.NewReader(string(out)))
|
|
for scanner.Scan() {
|
|
line := strings.ToLower(strings.TrimSpace(scanner.Text()))
|
|
if !isGPUControllerLine(line) {
|
|
continue
|
|
}
|
|
|
|
if strings.Contains(line, "nvidia") {
|
|
hasNVIDIA = true
|
|
ok = true
|
|
}
|
|
if strings.Contains(line, "amd") || strings.Contains(line, "ati") || strings.Contains(line, "radeon") {
|
|
hasAMD = true
|
|
ok = true
|
|
}
|
|
if strings.Contains(line, "intel") {
|
|
hasIntel = true
|
|
ok = true
|
|
}
|
|
}
|
|
|
|
return hasAMD, hasNVIDIA, hasIntel, ok
|
|
}
|
|
|
|
func isGPUControllerLine(line string) bool {
|
|
return strings.Contains(line, "vga compatible controller") ||
|
|
strings.Contains(line, "3d controller") ||
|
|
strings.Contains(line, "display controller")
|
|
}
|
|
|
|
func parseRocmAgentArch(output string) (arch string, ok bool) {
|
|
scanner := bufio.NewScanner(strings.NewReader(output))
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if !strings.HasPrefix(line, "Name:") {
|
|
continue
|
|
}
|
|
name := strings.TrimSpace(strings.TrimPrefix(line, "Name:"))
|
|
if strings.HasPrefix(name, "gfx") {
|
|
return name, true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|