model replay: framereader cache (#35576)

* Simpler cache version

* cachetools

* different LRU

* lint

* smaller

* just write LRU

* mypy

* same length
pull/35581/head
Harald Schäfer 3 months ago committed by GitHub
parent 5f559cfcc7
commit 5f3d876aaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      pyproject.toml
  2. 33
      selfdrive/test/process_replay/model_replay.py
  3. 23
      tools/lib/framereader.py
  4. 4391
      uv.lock

@ -106,7 +106,6 @@ dev = [
"azure-storage-blob", "azure-storage-blob",
"dbus-next", "dbus-next",
"dictdiffer", "dictdiffer",
"lru-dict",
"matplotlib", "matplotlib",
"parameterized >=0.8, <0.9", "parameterized >=0.8, <0.9",
"pyautogui", "pyautogui",

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import pickle
import sys import sys
from collections import defaultdict from collections import defaultdict
from typing import Any from typing import Any
@ -194,17 +195,39 @@ def model_replay(lr, frs):
return msgs return msgs
def get_frames():
regen_cache = "--regen-cache" in sys.argv
frames_cache = '/tmp/model_replay_cache' if PC else '/data/model_replay_cache'
os.makedirs(frames_cache, exist_ok=True)
cache_name = f'{frames_cache}/{TEST_ROUTE}_{SEGMENT}_{START_FRAME}_{END_FRAME}.pkl'
if os.path.isfile(cache_name) and not regen_cache:
try:
print(f"Loading frames from cache {cache_name}")
return pickle.load(open(cache_name, "rb"))
except Exception as e:
print(f"Failed to load frames from cache {cache_name}: {e}")
frs = {
'roadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "fcamera.hevc"), pix_fmt='nv12', cache_size=END_FRAME - START_FRAME),
'driverCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "dcamera.hevc"), pix_fmt='nv12', cache_size=END_FRAME - START_FRAME),
'wideRoadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "ecamera.hevc"), pix_fmt='nv12', cache_size=END_FRAME - START_FRAME),
}
for fr in frs.values():
for fidx in range(START_FRAME, END_FRAME):
fr.get(fidx)
fr.it = None
print(f"Dumping frame cache {cache_name}")
pickle.dump(frs, open(cache_name, "wb"))
return frs
if __name__ == "__main__": if __name__ == "__main__":
update = "--update" in sys.argv or (os.getenv("GIT_BRANCH", "") == 'master') update = "--update" in sys.argv or (os.getenv("GIT_BRANCH", "") == 'master')
replay_dir = os.path.dirname(os.path.abspath(__file__)) replay_dir = os.path.dirname(os.path.abspath(__file__))
# load logs # load logs
lr = list(LogReader(get_url(TEST_ROUTE, SEGMENT, "rlog.zst"))) lr = list(LogReader(get_url(TEST_ROUTE, SEGMENT, "rlog.zst")))
frs = { frs = get_frames()
'roadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "fcamera.hevc"), pix_fmt='nv12'),
'driverCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "dcamera.hevc"), pix_fmt='nv12'),
'wideRoadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, "ecamera.hevc"), pix_fmt='nv12')
}
log_msgs = [] log_msgs = []
# run replays # run replays

@ -2,10 +2,9 @@ import os
import subprocess import subprocess
import json import json
from collections.abc import Iterator from collections.abc import Iterator
from collections import OrderedDict
import numpy as np import numpy as np
from lru import LRU
from openpilot.tools.lib.filereader import FileReader, resolve_name from openpilot.tools.lib.filereader import FileReader, resolve_name
from openpilot.tools.lib.exceptions import DataUnreadableError from openpilot.tools.lib.exceptions import DataUnreadableError
from openpilot.tools.lib.vidindex import hevc_index from openpilot.tools.lib.vidindex import hevc_index
@ -16,6 +15,24 @@ HEVC_SLICE_P = 1
HEVC_SLICE_I = 2 HEVC_SLICE_I = 2
class LRUCache:
def __init__(self, capacity: int):
self._cache: OrderedDict = OrderedDict()
self.capacity = capacity
def __getitem__(self, key):
self._cache.move_to_end(key)
return self._cache[key]
def __setitem__(self, key, value):
self._cache[key] = value
if len(self._cache) > self.capacity:
self._cache.popitem(last=False)
def __contains__(self, key):
return key in self._cache
def assert_hvec(fn: str) -> None: def assert_hvec(fn: str) -> None:
with FileReader(fn) as f: with FileReader(fn) as f:
header = f.read(4) header = f.read(4)
@ -135,7 +152,7 @@ class FrameReader:
cache_size: int = 30, pix_fmt: str = "rgb24"): cache_size: int = 30, pix_fmt: str = "rgb24"):
self.decoder = FfmpegDecoder(fn, index_data, pix_fmt) self.decoder = FfmpegDecoder(fn, index_data, pix_fmt)
self.iframes = self.decoder.iframes self.iframes = self.decoder.iframes
self._cache: LRU[int, np.ndarray] = LRU(cache_size) self._cache: LRUCache = LRUCache(cache_size)
self.w, self.h, self.frame_count, = self.decoder.w, self.decoder.h, self.decoder.frame_count self.w, self.h, self.frame_count, = self.decoder.w, self.decoder.h, self.decoder.frame_count
self.pix_fmt = pix_fmt self.pix_fmt = pix_fmt

4391
uv.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save