gym_recording/playback.py (62 lines of code) (raw):

import os import time import json import glob import mmap import logging import numpy as np from gym import error logger = logging.getLogger(__name__) __all__ = ['scan_recorded_traces', 'TraceRecordingReader'] class TraceRecordingReader: def __init__(self, directory): self.directory = directory self.binfiles = {} def close(self): for k in self.binfiles.keys(): if self.binfiles[k] is not None: self.binfiles[k].close() self.binfiles[k] = None def get_binfile(self, fn): mm = self.binfiles.get(fn, None) if mm: return mm f = open(os.path.join(self.directory, fn), 'rb') mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) self.binfiles[fn] = mm return mm def load_npy(self, o): mm = self.get_binfile(o['npyfile']) arr = np.ndarray.__new__(np.ndarray, o['shape'], dtype=o['dtype'], buffer=mm, offset=o['npyoff'], order='C') return arr def json_decode(self, o): o_type = o.get('__type', None) if o_type == 'ndarray': return self.load_npy(o) else: return o def get_recorded_batches(self): ret = [] manifest_ptn = os.path.join(self.directory, 'openaigym.trace.*.manifest.json') trace_manifest_fns = glob.glob(manifest_ptn) logger.debug('Trace manifests %s %s', manifest_ptn, trace_manifest_fns) for trace_manifest_fn in trace_manifest_fns: trace_manifest_f = open(trace_manifest_fn, 'r') trace_manifest = json.load(trace_manifest_f) trace_manifest_f.close() ret += trace_manifest['batches'] return ret def get_recorded_episodes(self, batch): batch_fn = os.path.join(self.directory, batch['fn']) batch_f = open(batch_fn, 'r') batch_d = json.load(batch_f, object_hook=self.json_decode) batch_f.close() return batch_d['episodes'] def scan_recorded_traces(directory, episode_cb=None, max_episodes=None): """ Go through all the traces recorded to directory, and call episode_cb for every episode. Set max_episodes to end after a certain number (or you can just throw an exception from episode_cb if you want to end the iteration early) """ rdr = TraceRecordingReader(directory) added_episode_count = 0 for batch in rdr.get_recorded_batches(): for ep in rdr.get_recorded_episodes(batch): episode_cb(ep['observations'], ep['actions'], ep['rewards']) added_episode_count += 1 if max_episodes is not None and added_episode_count >= max_episodes: return rdr.close()