egpu: show progress

This commit is contained in:
royjr
2026-08-23 20:15:54 -04:00
parent 718db8c62e
commit f0a402d420
6 changed files with 74 additions and 3 deletions
+1
View File
@@ -132,6 +132,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"UptimeOnroad", {PERSISTENT, FLOAT, "0.0"}},
{"UsbGpuActive", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, BOOL}},
{"UsbGpuLoading", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, BOOL}},
{"UsbGpuLoadProgress", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, INT, "0"}},
{"Version", {PERSISTENT, STRING}},
// --- sunnypilot params --- //
@@ -0,0 +1,45 @@
import os
from openpilot.common.file_chunker import open_file_chunked, get_existing_chunks
from openpilot.common.params import Params
PARAM = "UsbGpuLoadProgress"
class ProgressReader:
def __init__(self, inner, total):
self._inner = inner
self._total = total
self._params = Params()
self._read = 0
self._pct = -1
self._step = max(64 * 1024, total // 100)
def _bump(self, n):
self._read += n
if self._total:
pct = min(100, self._read * 100 // self._total)
if pct != self._pct:
self._pct = pct
self._params.put(PARAM, pct)
def read(self, size=-1):
data = self._inner.read(size)
self._bump(len(data))
return data
def readinto(self, b):
view = memoryview(b)
done = 0
while done < len(view):
n = self._inner.readinto(view[done:done + self._step])
if not n:
break
done += n
self._bump(n)
return done
def open_with_progress(pkl_path):
chunks = [p for p in get_existing_chunks(pkl_path) if not p.endswith(".chunkmanifest")]
total = sum(os.path.getsize(p) for p in chunks)
return ProgressReader(open_file_chunked(pkl_path), total)
+3 -1
View File
@@ -29,6 +29,7 @@ from openpilot.selfdrive.modeld.parse_model_outputs import Parser
from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS
from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState
from openpilot.common.file_chunker import open_file_chunked
from openpilot.selfdrive.modeld.load_progress import open_with_progress
from openpilot.selfdrive.modeld.constants import ModelConstants, Plan
from openpilot.selfdrive.modeld.helpers import usbgpu_present, usbgpu_compiled, modeld_pkl_path, get_tg_input_devices, load_oob
@@ -145,7 +146,7 @@ class ModelState(ModelStateBase):
ModelStateBase.__init__(self)
input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu)
self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV']
jits = load_oob(open_file_chunked(modeld_pkl_path(usbgpu)))
jits = load_oob(open_with_progress(modeld_pkl_path(usbgpu)) if usbgpu else open_file_chunked(modeld_pkl_path(usbgpu)))
metadata = jits['metadata']
self.input_shapes = metadata['input_shapes']
self.vision_input_names = [k for k in self.input_shapes if 'img' in k]
@@ -223,6 +224,7 @@ def main(demo=False):
os.environ['HCQDEV_WAIT_TIMEOUT_MS'] = '3000'
params = Params()
params.put_bool("UsbGpuLoading", USBGPU)
params.put("UsbGpuLoadProgress", 0)
params.remove("UsbGpuActive")
config_realtime_process(7, 54)
@@ -223,7 +223,7 @@ class HudRenderer(Widget):
if icon is not self._egpu_icon:
self._egpu_fade_time = rl.get_time()
self._egpu_icon = icon
alpha = self._egpu_alpha_filter.update(loading or 0 < rl.get_time() - self._egpu_fade_time < SET_SPEED_PERSISTENCE)
alpha = self._egpu_alpha_filter.update(True)
if alpha < 1e-2:
return
@@ -231,6 +231,23 @@ class HudRenderer(Widget):
rect.y + rect.height - 14 - (self._txt_wheel.height + icon.height) / 2)
rl.draw_texture_ex(icon, pos, 0.0, 1.0, rl.Color(255, 255, 255, int(255 * opacity * alpha)))
if loading and ui_state.usbgpu_load_progress < 100:
pct_text = f"{ui_state.usbgpu_load_progress}%"
size = FONT_SIZES.max_speed
cell = measure_text_cached(self._font_bold, "0", size)
widths = [cell.x if c.isdigit() else measure_text_cached(self._font_bold, c, size).x for c in pct_text]
x = pos.x - 8 - sum(widths)
y = pos.y + (icon.height - cell.y) / 2
for c, w in zip(pct_text, widths):
glyph = measure_text_cached(self._font_bold, c, size).x
rl.draw_text_ex(self._font_bold, c, rl.Vector2(x + (w - glyph) / 2, y), size, 0, rl.WHITE)
x += w
elif loading:
r = 14.0
center = rl.Vector2(pos.x - 8 - r, pos.y + icon.height / 2)
start = (rl.get_time() * 360) % 360
rl.draw_ring(center, r - 4, r, start, start + 270, 32, rl.WHITE)
def _draw_steering_wheel(self, rect: rl.Rectangle) -> None:
wheel_txt = self._txt_wheel_critical if self._show_wheel_critical else self._txt_wheel
+4
View File
@@ -86,6 +86,7 @@ class UIState(UIStateSP):
self.usbgpu_compiled: bool = usbgpu_compiled()
self.usbgpu_active: bool | None = self.params.get("UsbGpuActive")
self.usbgpu_loading: bool = self.params.get_bool("UsbGpuLoading")
self.usbgpu_load_progress: int = self.params.get("UsbGpuLoadProgress", return_default=True)
self.started: bool = False
self.ignition: bool = False
self.recording_audio: bool = False
@@ -164,6 +165,9 @@ class UIState(UIStateSP):
# Update started state
self.started = self.sm["deviceState"].started and self.ignition
if self.usbgpu_loading:
self.usbgpu_load_progress = self.params.get("UsbGpuLoadProgress", return_default=True)
# Update body state
if self.CP is not None and self.is_body != self.CP.notCar:
self.is_body = self.CP.notCar
+3 -1
View File
@@ -25,6 +25,7 @@ from opendbc.car.car_helpers import get_demo_car_params
from tinygrad.tensor import Tensor
from openpilot.common.file_chunker import open_file_chunked
from openpilot.selfdrive.modeld.load_progress import open_with_progress
from openpilot.common.swaglog import cloudlog
from openpilot.common.params import Params
from openpilot.common.filter_simple import FirstOrderFilter
@@ -107,7 +108,7 @@ class ModelState(ModelStateBase):
def _init_combined(self, pkl_path, cam_w, cam_h, bundle):
cloudlog.warning(f"loading combined pkl: {pkl_path}")
jits = load_oob(open_file_chunked(pkl_path))
jits = load_oob(open_with_progress(pkl_path) if self.usbgpu else open_file_chunked(pkl_path))
self.WARP_DEV = 'QCOM' if COMMA_HARDWARE else 'CPU'
self.DEV = 'AMD' if self.usbgpu else self.WARP_DEV
@@ -333,6 +334,7 @@ def main(demo=False):
params = Params()
params.put_bool("UsbGpuLoading", USBGPU)
params.put("UsbGpuLoadProgress", 0)
params.remove("UsbGpuActive")
# visionipc clients