DB/recorder.py

64 lines
2.4 KiB
Python
Raw Permalink Normal View History

2021-10-09 00:33:47 +00:00
import os
import pickle
from baselines import logger
from mpi4py import MPI
class Recorder(object):
def __init__(self, nenvs, nlumps):
self.nenvs = nenvs
self.nlumps = nlumps
self.nenvs_per_lump = nenvs // nlumps
self.acs = [[] for _ in range(nenvs)]
self.int_rews = [[] for _ in range(nenvs)]
self.ext_rews = [[] for _ in range(nenvs)]
self.ep_infos = [{} for _ in range(nenvs)]
self.filenames = [self.get_filename(i) for i in range(nenvs)]
if MPI.COMM_WORLD.Get_rank() == 0:
logger.info("episode recordings saved to ", self.filenames[0])
def record(self, timestep, lump, acs, infos, int_rew, ext_rew, news):
for out_index in range(self.nenvs_per_lump):
in_index = out_index + lump * self.nenvs_per_lump
if timestep == 0:
self.acs[in_index].append(acs[out_index])
else:
if self.is_first_episode_step(in_index):
try:
self.ep_infos[in_index]['random_state'] = infos[out_index]['random_state']
except:
pass
self.int_rews[in_index].append(int_rew[out_index])
self.ext_rews[in_index].append(ext_rew[out_index])
if news[out_index]:
self.ep_infos[in_index]['ret'] = infos[out_index]['episode']['r']
self.ep_infos[in_index]['len'] = infos[out_index]['episode']['l']
self.dump_episode(in_index)
self.acs[in_index].append(acs[out_index])
def dump_episode(self, i):
episode = {'acs': self.acs[i],
'int_rew': self.int_rews[i],
'info': self.ep_infos[i]}
filename = self.filenames[i]
if self.episode_worth_saving(i):
with open(filename, 'ab') as f:
pickle.dump(episode, f, protocol=-1)
self.acs[i].clear()
self.int_rews[i].clear()
self.ext_rews[i].clear()
self.ep_infos[i].clear()
def episode_worth_saving(self, i):
return (i == 0 and MPI.COMM_WORLD.Get_rank() == 0)
def is_first_episode_step(self, i):
return len(self.int_rews[i]) == 0
def get_filename(self, i):
filename = os.path.join(logger.get_dir(), 'env{}_{}.pk'.format(MPI.COMM_WORLD.Get_rank(), i))
return filename