From d8090be19db949cd8858cf0b9fc04f95e3db3c05 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Thu, 20 Aug 2026 15:31:44 -0500 Subject: [PATCH] fotos glo glo --- .../opendbc/car/subaru/carcontroller.py | 151 ++++++++++-------- opendbc_repo/opendbc/car/subaru/interface.py | 2 + .../opendbc/car/subaru/tests/test_subaru.py | 6 +- selfdrive/controls/controlsd.py | 6 +- selfdrive/controls/tests/test_turn_lead.py | 9 ++ selfdrive/modeld/modeld.py | 12 +- .../modeld/tests/test_lateral_smoothing.py | 11 ++ selfdrive/modeld/tests/test_model_fallback.py | 17 +- selfdrive/modeld/tests/test_usbgpu_helpers.py | 30 ++++ starpilot/car/ford/lateral.py | 5 +- starpilot/car/ford/tests/test_lateral.py | 10 +- tinygrad_repo/tinygrad/runtime/ops_amd.py | 7 +- 12 files changed, 173 insertions(+), 93 deletions(-) diff --git a/opendbc_repo/opendbc/car/subaru/carcontroller.py b/opendbc_repo/opendbc/car/subaru/carcontroller.py index 0a5ee1b30..027de5cce 100644 --- a/opendbc_repo/opendbc/car/subaru/carcontroller.py +++ b/opendbc_repo/opendbc/car/subaru/carcontroller.py @@ -22,14 +22,14 @@ _LEGACY_2025_REENGAGE_MAX_STEER_RATE = 2.0 _LEGACY_2025_REENGAGE_MAX_ANGLE_DELTA = 1.0 _LEGACY_2025_RECLAIM_FRAMES = 36 _LEGACY_2025_RECLAIM_EXPONENT = 2.5 -_ASCENT_OVERRIDE_HOLD_FRAMES = 10 -_ASCENT_REENGAGE_SETTLE_FRAMES = 8 -_ASCENT_REENGAGE_MAX_STEER_RATE = 2.0 -_ASCENT_REENGAGE_MAX_ANGLE_DELTA = 1.0 -_ASCENT_RECLAIM_FRAMES = 36 -_ASCENT_RECLAIM_EXPONENT = 2.5 -_ASCENT_MADS_MIN_SPEED = 0.44704 -_ASCENT_MADS_MAX_STEER_ANGLE = 120.0 +_ANGLE_OVERRIDE_HOLD_FRAMES = 10 +_ANGLE_REENGAGE_SETTLE_FRAMES = 8 +_ANGLE_REENGAGE_MAX_STEER_RATE = 2.0 +_ANGLE_REENGAGE_MAX_ANGLE_DELTA = 1.0 +_ANGLE_RECLAIM_FRAMES = 36 +_ANGLE_RECLAIM_EXPONENT = 2.5 +_ANGLE_MADS_MIN_SPEED = 0.44704 +_ANGLE_MADS_MAX_STEER_ANGLE = 120.0 def get_safety_CP(): @@ -50,13 +50,13 @@ class CarController(CarControllerBase): self.legacy_2025_reengage_reference_angle = 0.0 self.legacy_2025_reclaim_frames = 0 self.legacy_2025_reclaim_start_angle = 0.0 - self.ascent_lkas_active = False - self.ascent_handoff_active = False - self.ascent_override_hold_frames = 0 - self.ascent_reengage_settle_frames = 0 - self.ascent_reengage_reference_angle = 0.0 - self.ascent_reclaim_frames = 0 - self.ascent_reclaim_start_angle = 0.0 + self.angle_lkas_active = False + self.angle_handoff_active = False + self.angle_override_hold_frames = 0 + self.angle_reengage_settle_frames = 0 + self.angle_reengage_reference_angle = 0.0 + self.angle_reclaim_frames = 0 + self.angle_reclaim_start_angle = 0.0 self.cruise_button_prev = 0 self.steer_rate_counter = 0 @@ -137,67 +137,67 @@ class CarController(CarControllerBase): self.legacy_2025_reclaim_frames -= 1 return target_angle - def _reset_ascent_handoff(self): - self.ascent_handoff_active = False - self.ascent_override_hold_frames = 0 - self.ascent_reengage_settle_frames = 0 - self.ascent_reengage_reference_angle = 0.0 - self.ascent_reclaim_frames = 0 - self.ascent_reclaim_start_angle = 0.0 + def _reset_angle_handoff(self): + self.angle_handoff_active = False + self.angle_override_hold_frames = 0 + self.angle_reengage_settle_frames = 0 + self.angle_reengage_reference_angle = 0.0 + self.angle_reclaim_frames = 0 + self.angle_reclaim_start_angle = 0.0 - def _ascent_manual_handoff(self, CS, lat_active): + def _angle_manual_handoff(self, CS, lat_active): if not lat_active: - self._reset_ascent_handoff() + self._reset_angle_handoff() return False if CS.out.steeringPressed: - self.ascent_handoff_active = True - self.ascent_override_hold_frames = _ASCENT_OVERRIDE_HOLD_FRAMES - self.ascent_reengage_settle_frames = 0 - self.ascent_reengage_reference_angle = CS.out.steeringAngleDeg - self.ascent_reclaim_frames = 0 + self.angle_handoff_active = True + self.angle_override_hold_frames = _ANGLE_OVERRIDE_HOLD_FRAMES + self.angle_reengage_settle_frames = 0 + self.angle_reengage_reference_angle = CS.out.steeringAngleDeg + self.angle_reclaim_frames = 0 return True - if not self.ascent_handoff_active and not self.ascent_lkas_active and \ - abs(CS.out.steeringRateDeg) > _ASCENT_REENGAGE_MAX_STEER_RATE: - self.ascent_handoff_active = True - self.ascent_reengage_reference_angle = CS.out.steeringAngleDeg + if not self.angle_handoff_active and not self.angle_lkas_active and \ + abs(CS.out.steeringRateDeg) > _ANGLE_REENGAGE_MAX_STEER_RATE: + self.angle_handoff_active = True + self.angle_reengage_reference_angle = CS.out.steeringAngleDeg - if not self.ascent_handoff_active: + if not self.angle_handoff_active: return False - if self.ascent_override_hold_frames > 0: - self.ascent_override_hold_frames -= 1 - if self.ascent_override_hold_frames == 0: - self.ascent_reengage_reference_angle = CS.out.steeringAngleDeg + if self.angle_override_hold_frames > 0: + self.angle_override_hold_frames -= 1 + if self.angle_override_hold_frames == 0: + self.angle_reengage_reference_angle = CS.out.steeringAngleDeg return True - wheel_stable = abs(CS.out.steeringRateDeg) <= _ASCENT_REENGAGE_MAX_STEER_RATE and \ - abs(CS.out.steeringAngleDeg - self.ascent_reengage_reference_angle) <= _ASCENT_REENGAGE_MAX_ANGLE_DELTA + wheel_stable = abs(CS.out.steeringRateDeg) <= _ANGLE_REENGAGE_MAX_STEER_RATE and \ + abs(CS.out.steeringAngleDeg - self.angle_reengage_reference_angle) <= _ANGLE_REENGAGE_MAX_ANGLE_DELTA if wheel_stable: - self.ascent_reengage_settle_frames += 1 + self.angle_reengage_settle_frames += 1 else: - self.ascent_reengage_settle_frames = 0 - self.ascent_reengage_reference_angle = CS.out.steeringAngleDeg + self.angle_reengage_settle_frames = 0 + self.angle_reengage_reference_angle = CS.out.steeringAngleDeg - if self.ascent_reengage_settle_frames < _ASCENT_REENGAGE_SETTLE_FRAMES: + if self.angle_reengage_settle_frames < _ANGLE_REENGAGE_SETTLE_FRAMES: return True - self.ascent_handoff_active = False - self.ascent_reengage_settle_frames = 0 - self.ascent_reclaim_frames = _ASCENT_RECLAIM_FRAMES - self.ascent_reclaim_start_angle = CS.out.steeringAngleDeg + self.angle_handoff_active = False + self.angle_reengage_settle_frames = 0 + self.angle_reclaim_frames = _ANGLE_RECLAIM_FRAMES + self.angle_reclaim_start_angle = CS.out.steeringAngleDeg return True - def _ascent_reclaim_target(self, target_angle): - if self.ascent_reclaim_frames <= 0: + def _angle_reclaim_target(self, target_angle): + if self.angle_reclaim_frames <= 0: return target_angle - progress = (_ASCENT_RECLAIM_FRAMES - self.ascent_reclaim_frames + 1) / _ASCENT_RECLAIM_FRAMES - eased_progress = progress ** _ASCENT_RECLAIM_EXPONENT - target_angle = self.ascent_reclaim_start_angle + eased_progress * \ - (target_angle - self.ascent_reclaim_start_angle) - self.ascent_reclaim_frames -= 1 + progress = (_ANGLE_RECLAIM_FRAMES - self.angle_reclaim_frames + 1) / _ANGLE_RECLAIM_FRAMES + eased_progress = progress ** _ANGLE_RECLAIM_EXPONENT + target_angle = self.angle_reclaim_start_angle + eased_progress * \ + (target_angle - self.angle_reclaim_start_angle) + self.angle_reclaim_frames -= 1 return target_angle def lateral_angle(self, CC, CS): @@ -224,30 +224,41 @@ class CarController(CarControllerBase): self.legacy_2025_lkas_active = lkas_active return subarucan.create_steering_control_angle(self.packer, apply_steer, lkas_active, self.angle_bus) - if self.CP.carFingerprint == CAR.SUBARU_ASCENT_2023: + if self.CP.carFingerprint in (CAR.SUBARU_ASCENT_2023, CAR.SUBARU_OUTBACK_2023): mads_only = CC.latActive and not CC.enabled - mads_only_ok = CS.out.vEgoRaw > _ASCENT_MADS_MIN_SPEED and \ - abs(CS.out.steeringAngleDeg) < _ASCENT_MADS_MAX_STEER_ANGLE + mads_only_ok = CS.out.vEgoRaw > _ANGLE_MADS_MIN_SPEED and \ + abs(CS.out.steeringAngleDeg) < _ANGLE_MADS_MAX_STEER_ANGLE lkas_available = CC.latActive and (not mads_only or mads_only_ok) and \ CS.out.gearShifter == structs.CarState.GearShifter.drive and not CS.out.standstill - manual_handoff = self._ascent_manual_handoff(CS, lkas_available) + manual_handoff = self._angle_manual_handoff(CS, lkas_available) lkas_active = lkas_available and not manual_handoff - if lkas_active and not self.ascent_lkas_active: + if lkas_active and not self.angle_lkas_active: self.apply_steer_last = CS.out.steeringAngleDeg - steer_target = self._ascent_reclaim_target(CC.actuators.steeringAngleDeg) if lkas_active else CC.actuators.steeringAngleDeg - apply_steer = apply_std_steer_angle_limits( - steer_target, - self.apply_steer_last, - CS.out.vEgoRaw, - CS.out.steeringAngleDeg, - lkas_active, - self.p.FIXED_ANGLE_LIMITS, - ) + steer_target = self._angle_reclaim_target(CC.actuators.steeringAngleDeg) if lkas_active else CC.actuators.steeringAngleDeg + if self.CP.carFingerprint == CAR.SUBARU_ASCENT_2023: + apply_steer = apply_std_steer_angle_limits( + steer_target, + self.apply_steer_last, + CS.out.vEgoRaw, + CS.out.steeringAngleDeg, + lkas_active, + self.p.FIXED_ANGLE_LIMITS, + ) + else: + apply_steer = apply_steer_angle_limits_vm( + steer_target, + self.apply_steer_last, + CS.out.vEgoRaw, + CS.out.steeringAngleDeg, + lkas_active, + self.p, + self.VM, + ) self.apply_steer_last = apply_steer - self.ascent_lkas_active = lkas_active + self.angle_lkas_active = lkas_active return subarucan.create_steering_control_angle(self.packer, apply_steer, lkas_active, self.angle_bus) abs_torque = abs(CS.out.steeringTorque) diff --git a/opendbc_repo/opendbc/car/subaru/interface.py b/opendbc_repo/opendbc/car/subaru/interface.py index 59dd14422..b3548cc3d 100644 --- a/opendbc_repo/opendbc/car/subaru/interface.py +++ b/opendbc_repo/opendbc/car/subaru/interface.py @@ -51,6 +51,8 @@ class CarInterface(CarInterfaceBase): if ret.flags & SubaruFlags.LKAS_ANGLE: ret.steerControlType = structs.CarParams.SteerControlType.angle + if candidate == CAR.SUBARU_OUTBACK_2023: + ret.lateralSmoothSeconds = 0.4 elif candidate in (CAR.SUBARU_ASCENT, CAR.SUBARU_ASCENT_2023): ret.steerActuatorDelay = 0.3 # end-to-end angle controller diff --git a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py index 74e3ac684..0c2535ef1 100644 --- a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py +++ b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py @@ -202,6 +202,7 @@ def test_outback_2023_uses_d_platform_bus_layout(): assert parsers[Bus.main].bus == CanBus.main assert controller.angle_bus == CanBus.main assert controller.status_bus == CanBus.main + assert CP.lateralSmoothSeconds == pytest.approx(0.4) def test_legacy_2025_uses_gen2_angle_bus_layout(): @@ -458,8 +459,9 @@ def test_ascent_angle_controller_uses_fixed_angle_rate_limits(): assert CS.out.steeringAngleDeg < parser.vl["ES_LKAS_ANGLE"]["LKAS_Output"] < -25.0 -def test_ascent_angle_controller_yields_until_manual_steering_settles(): - CP = CarInterface.get_non_essential_params(CAR.SUBARU_ASCENT_2023) +@pytest.mark.parametrize("platform", (CAR.SUBARU_ASCENT_2023, CAR.SUBARU_OUTBACK_2023)) +def test_angle_controller_yields_until_manual_steering_settles(platform): + CP = CarInterface.get_non_essential_params(platform) controller = CarController({}, CP) CC = SimpleNamespace(enabled=True, latActive=True, actuators=SimpleNamespace(steeringAngleDeg=-10.0)) CS = SimpleNamespace(out=SimpleNamespace( diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index b5dc4e673..3bef259f8 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -221,9 +221,9 @@ def get_plan_reach(model_v2) -> float: def get_control_lateral_smooth_seconds(brand: str, v_ego: float, vehicle_smooth_seconds: float) -> float: - if brand != "rivian": - return LAT_SMOOTH_SECONDS - return get_car_lateral_smooth_seconds(brand, v_ego, vehicle_smooth_seconds) + if brand == "rivian" or (brand == "subaru" and vehicle_smooth_seconds > 0.0): + return get_car_lateral_smooth_seconds(brand, v_ego, vehicle_smooth_seconds) + return LAT_SMOOTH_SECONDS def turn_lead_allowed(brand: str, lateral_control_mode: car.CarControl.Actuators.LateralControlMode) -> bool: diff --git a/selfdrive/controls/tests/test_turn_lead.py b/selfdrive/controls/tests/test_turn_lead.py index 7f3d975fd..765e3507e 100644 --- a/selfdrive/controls/tests/test_turn_lead.py +++ b/selfdrive/controls/tests/test_turn_lead.py @@ -21,6 +21,15 @@ def test_non_rivian_control_smoothing_matches_starpilot(v_ego): assert get_control_lateral_smooth_seconds("toyota", v_ego, 0.0) == 0.1 +@pytest.mark.parametrize(("v_ego", "expected"), [ + (0.0, 0.4), + (5.0, 0.2), + (30.0, 0.0), +]) +def test_subaru_control_smoothing_uses_vehicle_schedule(v_ego, expected): + assert get_control_lateral_smooth_seconds("subaru", v_ego, 0.4) == pytest.approx(expected) + + @pytest.mark.parametrize(("v_ego", "expected"), [ (0.0, 0.4), (5.0, 0.2), diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 9f3daa508..29989956c 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -68,8 +68,8 @@ def _model_smooth_seconds(params, key, default): return round(min(max(value, SMOOTH_SECONDS_STEP), 2.0) / SMOOTH_SECONDS_STEP) * SMOOTH_SECONDS_STEP -def _should_publish_model_output(model_output, vipc_dropped_frames: int) -> bool: - return model_output is not None and vipc_dropped_frames == 0 +def _should_publish_model_output(model_output, vipc_dropped_frames: int, external_gpu_active: bool = False) -> bool: + return model_output is not None and (external_gpu_active or vipc_dropped_frames == 0) MIN_LAT_CONTROL_SPEED = 0.3 @@ -129,7 +129,7 @@ def get_lateral_smooth_seconds(v_ego: float, maximum: float = 0.0) -> float: def get_car_lateral_smooth_seconds(brand: str, v_ego: float, maximum: float) -> float: - if brand == "rivian": + if brand in ("rivian", "subaru"): return get_lateral_smooth_seconds(v_ego, maximum) return maximum @@ -844,7 +844,7 @@ def main(demo=False): is_rhd = sm["driverMonitoringState"].isRHD frame_id = sm["roadCameraState"].frameId v_ego = max(sm["carState"].vEgo, 0.) - lat_smooth_default = CP.lateralSmoothSeconds if CP.brand == "rivian" else LAT_SMOOTH_SECONDS + lat_smooth_default = CP.lateralSmoothSeconds if (CP.brand == "rivian" or CP.lateralSmoothSeconds > 0.0) else LAT_SMOOTH_SECONDS lat_smooth_maximum = _model_smooth_seconds(params, "LatSmoothSeconds", lat_smooth_default) lat_smooth_seconds = get_car_lateral_smooth_seconds(CP.brand, v_ego, lat_smooth_maximum) lat_delay = sm["liveDelay"].lateralDelay + lat_smooth_seconds @@ -939,10 +939,10 @@ def main(demo=False): mt2 = time.perf_counter() model_execution_time = mt2 - mt1 - if model_output is not None and vipc_dropped_frames > 0: + if model_output is not None and vipc_dropped_frames > 0 and not external_gpu_active: cloudlog.error(f"suppressing model output after dropping {vipc_dropped_frames} frames") - if _should_publish_model_output(model_output, vipc_dropped_frames): + if _should_publish_model_output(model_output, vipc_dropped_frames, external_gpu_active): modelv2_send = messaging.new_message('modelV2') starpilot_modelv2_send = messaging.new_message('starpilotModelV2') drivingdata_send = messaging.new_message('drivingModelData') diff --git a/selfdrive/modeld/tests/test_lateral_smoothing.py b/selfdrive/modeld/tests/test_lateral_smoothing.py index c70c069f9..843959e17 100644 --- a/selfdrive/modeld/tests/test_lateral_smoothing.py +++ b/selfdrive/modeld/tests/test_lateral_smoothing.py @@ -24,6 +24,17 @@ def test_non_rivian_cars_keep_configured_starpilot_smoothing(v_ego): assert get_car_lateral_smooth_seconds("toyota", v_ego, 0.4) == 0.4 +@pytest.mark.parametrize(("v_ego", "expected"), [ + (0.0, 0.4), + (2.0, 0.4), + (5.0, 0.2), + (8.0, 0.0), + (30.0, 0.0), +]) +def test_subaru_uses_low_speed_configured_smoothing(v_ego, expected): + assert get_car_lateral_smooth_seconds("subaru", v_ego, 0.4) == pytest.approx(expected) + + @pytest.mark.parametrize(("v_ego", "maximum", "expected"), [ (0.0, 0.4, 0.4), (5.0, 0.4, 0.2), diff --git a/selfdrive/modeld/tests/test_model_fallback.py b/selfdrive/modeld/tests/test_model_fallback.py index 5ad51cfbe..a1b2e8280 100644 --- a/selfdrive/modeld/tests/test_model_fallback.py +++ b/selfdrive/modeld/tests/test_model_fallback.py @@ -11,14 +11,17 @@ class FakeParams: self.values[key] = value -@pytest.mark.parametrize(("model_output", "dropped_frames", "expected"), [ - (object(), 0, True), - (object(), 1, False), - (object(), 2, False), - (None, 0, False), +@pytest.mark.parametrize(("model_output", "dropped_frames", "external_gpu_active", "expected"), [ + (object(), 0, False, True), + (object(), 1, False, False), + (object(), 2, False, False), + (object(), 1, True, True), + (object(), 2, True, True), + (None, 0, False, False), + (None, 1, True, False), ]) -def test_model_output_is_suppressed_after_vipc_drop(model_output, dropped_frames, expected): - assert modeld._should_publish_model_output(model_output, dropped_frames) is expected +def test_model_output_is_suppressed_after_vipc_drop(model_output, dropped_frames, external_gpu_active, expected): + assert modeld._should_publish_model_output(model_output, dropped_frames, external_gpu_active) is expected def test_incompatible_downloaded_model_falls_back_to_builtin(monkeypatch): diff --git a/selfdrive/modeld/tests/test_usbgpu_helpers.py b/selfdrive/modeld/tests/test_usbgpu_helpers.py index 5d74a8a87..aff76bf88 100644 --- a/selfdrive/modeld/tests/test_usbgpu_helpers.py +++ b/selfdrive/modeld/tests/test_usbgpu_helpers.py @@ -37,6 +37,36 @@ def test_external_gpu_uses_a_longer_load_watchdog(): assert modeld.BIG_MODEL_RUN_WAIT_TIMEOUT_MS == 3000 +def test_external_gpu_signal_wait_yields_cpu(): + from tinygrad.runtime import ops_amd + + sleeps = [] + signal = ops_amd.AMDSignal.__new__(ops_amd.AMDSignal) + signal.should_return = False + signal.owner = SimpleNamespace(is_usb=lambda: True, iface=SimpleNamespace(sleep=sleeps.append)) + + signal._sleep(0) + + assert sleeps == [1] + + +def test_native_amd_signal_keeps_existing_short_wait_behavior(): + from tinygrad.runtime import ops_amd + + sleeps = [] + signal = ops_amd.AMDSignal.__new__(ops_amd.AMDSignal) + signal.should_return = False + signal.owner = SimpleNamespace(is_usb=lambda: False, iface=SimpleNamespace(sleep=sleeps.append)) + + signal._sleep(199) + + assert sleeps == [] + + signal._sleep(201) + + assert sleeps == [200] + + def test_external_gpu_power_must_be_stable_after_vehicle_start(): panda_type = modeld.log.PandaState.PandaType.tres diff --git a/starpilot/car/ford/lateral.py b/starpilot/car/ford/lateral.py index 711cf1b10..ae25655f9 100644 --- a/starpilot/car/ford/lateral.py +++ b/starpilot/car/ford/lateral.py @@ -155,8 +155,9 @@ class FordLateralController: def _lane_change(self) -> tuple[bool, int]: if self.model is None: return False, 0 - state = int(self.model.meta.laneChangeState) - return state in (1, 2, 3), int(self.model.meta.laneChangeDirection) + state = int(getattr(self.model.meta.laneChangeState, "raw", self.model.meta.laneChangeState)) + direction = int(getattr(self.model.meta.laneChangeDirection, "raw", self.model.meta.laneChangeDirection)) + return state in (1, 2, 3), direction @staticmethod def _current_curvature(CS) -> float: diff --git a/starpilot/car/ford/tests/test_lateral.py b/starpilot/car/ford/tests/test_lateral.py index 88b83a376..5fe96e7b3 100644 --- a/starpilot/car/ford/tests/test_lateral.py +++ b/starpilot/car/ford/tests/test_lateral.py @@ -49,13 +49,21 @@ def test_curvature_strategy_uses_polynomial_signals(controller): assert result.ramp_type == 2 +def test_lane_change_accepts_capnp_enum_wrappers(controller): + controller.model = SimpleNamespace(meta=SimpleNamespace( + laneChangeState=SimpleNamespace(raw=2), + laneChangeDirection=SimpleNamespace(raw=1), + )) + assert controller._lane_change() == (True, 1) + + def test_angle_strategy_uses_path_angle_and_shadow(controller): result = controller.update_angle( SimpleNamespace(latActive=True), car_state(curvature=0.001), SimpleNamespace(curvature=0.001)) assert result.active assert result.curvature == 0.0 assert result.path_angle > 0.0 - assert result.shadow_curvature == pytest.approx(0.001) + assert result.shadow_curvature == pytest.approx(0.0005) def test_manual_turn_releases_lateral(controller): diff --git a/tinygrad_repo/tinygrad/runtime/ops_amd.py b/tinygrad_repo/tinygrad/runtime/ops_amd.py index 7404a1fca..e46798ff8 100644 --- a/tinygrad_repo/tinygrad/runtime/ops_amd.py +++ b/tinygrad_repo/tinygrad/runtime/ops_amd.py @@ -1,6 +1,6 @@ from __future__ import annotations from typing import cast -import os, ctypes, struct, hashlib, functools, importlib, mmap, errno, array, contextlib, sys, weakref, itertools, collections, atexit +import os, ctypes, struct, hashlib, functools, importlib, mmap, errno, array, contextlib, sys, weakref, itertools, collections, atexit, time assert sys.platform != 'win32' from dataclasses import dataclass from tinygrad.runtime.support.hcq import HCQCompiled, HCQAllocator, HCQBuffer, HWQueue, CLikeArgsState, HCQSignal, HCQProgram, FileIOInterface @@ -45,6 +45,9 @@ class AMDSignal(HCQSignal): def __init__(self, *args, **kwargs): super().__init__(*args, **{**kwargs, 'timestamp_divider': 100}) def _sleep(self, time_spent_since_last_sleep_ms:int): + if self.owner is not None and self.owner.is_usb(): + self.owner.iface.sleep(1) + return # Reasonable to sleep for long workloads (which take more than 200ms) and only timeline signals. if time_spent_since_last_sleep_ms > 200 and self.owner is not None: self.owner.iface.sleep(200) @@ -933,7 +936,7 @@ class USBIface(PCIIface): # force devmem return super().alloc(size, host=False, uncached=uncached, cpu_access=cpu_access, contiguous=contiguous, force_devmem=True, **kwargs) - def sleep(self, timeout): pass + def sleep(self, timeout): time.sleep(timeout / 1000) def _mock(iface, name=None): return type(name or f"MOCK{iface.__name__}", (iface,), {})