def _upload(training_dir, algorithm_id=None, writeup=None, benchmark_run_id=None, api_key=None, ignore_open_monitors=False, skip_videos=False): if not ignore_open_monitors: open_monitors = monitoring._open_monitors() if len(open_monitors) > 0: envs = [ m.env.spec.id if m.env.spec else '(unknown)' for m in open_monitors ] raise error.Error( "Still have an open monitor on {}. You must run 'env.close()' before uploading." .format(', '.join(envs))) env_info, training_episode_batch, training_video = upload_training_data( training_dir, api_key=api_key, skip_videos=skip_videos) env_id = env_info['env_id'] training_episode_batch_id = training_video_id = None if training_episode_batch: training_episode_batch_id = training_episode_batch.id if training_video: training_video_id = training_video.id if logger.level <= logging.INFO: if training_episode_batch_id is not None and training_video_id is not None: logger.info( '[%s] Creating evaluation object from %s with learning curve and training video', env_id, training_dir) elif training_episode_batch_id is not None: logger.info( '[%s] Creating evaluation object from %s with learning curve', env_id, training_dir) elif training_video_id is not None: logger.info( '[%s] Creating evaluation object from %s with training video', env_id, training_dir) else: raise error.Error( "[%s] You didn't have any recorded training data in %s. Once you've used 'env = gym.wrappers.Monitor(env, directory)' to start recording, you need to actually run some rollouts. Please join the community chat on https://gym.openai.com if you have any issues." % (env_id, training_dir)) evaluation = resource.Evaluation.create( training_episode_batch=training_episode_batch_id, training_video=training_video_id, env=env_info['env_id'], algorithm={ 'id': algorithm_id, }, benchmark_run_id=benchmark_run_id, writeup=writeup, gym_version=env_info['gym_version'], api_key=api_key, ) return evaluation
def make(self, options={}): """Instantiates an instance of the environment with appropriate kwargs""" if self._entry_point is None: raise error.Error( 'Attempting to make deprecated env {}. (HINT: is there a newer registered version of this env?)' .format(self.id)) elif callable(self._entry_point): env = self._entry_point() else: try: cls = load(self._entry_point) #env = cls(**self._kwargs) #TODO merge use of kwargs and options env = cls(options) except ModuleNotFoundError: #load envs directory if it exists import os, sys, importlib lib_path = os.getcwd() + os.sep + 'envs' sys.path.insert(0, lib_path) def snake(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() mod = importlib.import_module(snake(self._entry_point)) my_class = getattr(mod, self._entry_point) env = my_class(options) # Make the enviroment aware of which spec it came from. env.unwrapped._spec = self return env
def spec(self, id): match = env_id_re.search(id) if not match: raise error.Error( 'Attempted to look up malformed environment ID: {}. (Currently all IDs must be of the form {}.)' .format(id.encode('utf-8'), env_id_re.pattern)) try: return self.env_specs[id] except KeyError: # Parse the env name and check to see if it matches the non-version # part of a valid env (could also check the exact number here) env_name = match.group(1) matching_envs = [ valid_env_name for valid_env_name, valid_env_spec in self.env_specs.items() if env_name == valid_env_spec._env_name ] if matching_envs: raise error.DeprecatedEnv( 'Env {} not found (valid versions include {})'.format( id, matching_envs)) else: raise error.UnregisteredEnv( 'No registered env with id: {}'.format(id))
def __init__(self, id, entry_point=None, trials=100, reward_threshold=None, local_only=False, kwargs=None, nondeterministic=False, tags=None, max_episode_steps=None, max_episode_seconds=None, timestep_limit=None): self.id = id # Evaluation parameters self.trials = trials self.reward_threshold = reward_threshold # Environment properties self.nondeterministic = nondeterministic if tags is None: tags = {} self.tags = tags # BACKWARDS COMPAT 2017/1/18 if tags.get('wrapper_config.TimeLimit.max_episode_steps'): max_episode_steps = tags.get( 'wrapper_config.TimeLimit.max_episode_steps') # TODO: Add the following deprecation warning after 2017/02/18 # warnings.warn("DEPRECATION WARNING wrapper_config.TimeLimit has been deprecated. Replace any calls to `register(tags={'wrapper_config.TimeLimit.max_episode_steps': 200)}` with `register(max_episode_steps=200)`. This change was made 2017/1/31 and is included in gym version 0.8.0. If you are getting many of these warnings, you may need to update universe past version 0.21.3") tags['wrapper_config.TimeLimit.max_episode_steps'] = max_episode_steps ###### # BACKWARDS COMPAT 2017/1/31 if timestep_limit is not None: max_episode_steps = timestep_limit # TODO: Add the following deprecation warning after 2017/03/01 # warnings.warn("register(timestep_limit={}) is deprecated. Use register(max_episode_steps={}) instead.".format(timestep_limit, timestep_limit)) ###### self.max_episode_steps = max_episode_steps self.max_episode_seconds = max_episode_seconds # We may make some of these other parameters public if they're # useful. match = env_id_re.search(id) if not match: raise error.Error( 'Attempted to register malformed environment ID: {}. (Currently all IDs must be of the form {}.)' .format(id, env_id_re.pattern)) self._env_name = match.group(1) self._entry_point = entry_point self._local_only = local_only self._kwargs = {} if kwargs is None else kwargs
def upload_training_data(training_dir, api_key=None, skip_videos=False): # Could have multiple manifests results = monitoring.load_results(training_dir) if not results: raise error.Error('''Could not find any manifest files in {}. (HINT: this usually means you did not yet close() your env.monitor and have not yet exited the process. You should call 'env.monitor.start(training_dir)' at the start of training and 'env.close()' at the end, or exit the process.)''' .format(training_dir)) manifests = results['manifests'] env_info = results['env_info'] data_sources = results['data_sources'] timestamps = results['timestamps'] episode_lengths = results['episode_lengths'] episode_rewards = results['episode_rewards'] episode_types = results['episode_types'] initial_reset_timestamps = results['initial_reset_timestamps'] videos = results['videos'] if not skip_videos else [] env_id = env_info['env_id'] logger.debug('[%s] Uploading data from manifest %s', env_id, ', '.join(manifests)) # Do the relevant uploads if len(episode_lengths) > 0: training_episode_batch = upload_training_episode_batch( data_sources, episode_lengths, episode_rewards, episode_types, initial_reset_timestamps, timestamps, api_key, env_id=env_id) else: training_episode_batch = None if len(videos) > MAX_VIDEOS: logger.warning( '[%s] You recorded videos for %s episodes, but the scoreboard only supports up to %s. We will automatically subsample for you, but you also might wish to adjust your video recording rate.', env_id, len(videos), MAX_VIDEOS) subsample_inds = np.linspace(0, len(videos) - 1, MAX_VIDEOS).astype('int') #pylint: disable=E1101 videos = [videos[i] for i in subsample_inds] if len(videos) > 0: training_video = upload_training_video(videos, api_key, env_id=env_id) else: training_video = None return env_info, training_episode_batch, training_video
def register(self, id, **kwargs): if id in self.env_specs: raise error.Error('Cannot re-register id: {}'.format(id)) self.env_specs[id] = EnvSpec(id, **kwargs)
def _upload_benchmark(training_dir, algorithm_id, benchmark_id, benchmark_run_tags, api_key, ignore_open_monitors, skip_videos): # We're uploading a benchmark run. directories = [] env_ids = [] for name, _, files in os.walk(training_dir): manifests = monitoring.detect_training_manifests(name, files=files) if manifests: env_info = monitoring.load_env_info_from_manifests( manifests, training_dir) env_ids.append(env_info['env_id']) directories.append(name) # Validate against benchmark spec try: spec = benchmark_spec(benchmark_id) except error.UnregisteredBenchmark: raise error.Error( "Invalid benchmark id: {}. Are you using a benchmark registered in gym/benchmarks/__init__.py?" .format(benchmark_id)) spec_env_ids = [ task.env_id for task in spec.tasks for _ in range(task.trials) ] if not env_ids: raise error.Error( "Could not find any evaluations in {}".format(training_dir)) # This could be more stringent about mixing evaluations if sorted(env_ids) != sorted(spec_env_ids): logger.info( "WARNING: Evaluations do not match spec for benchmark %s. In %s, we found evaluations for %s, expected %s", benchmark_id, training_dir, sorted(env_ids), sorted(spec_env_ids)) tags = json.dumps(benchmark_run_tags) _create_with_retries = util.retry_exponential_backoff( resource.BenchmarkRun.create, (error.APIConnectionError, ), max_retries=5, interval=3, ) benchmark_run = _create_with_retries(benchmark_id=benchmark_id, algorithm_id=algorithm_id, tags=tags) benchmark_run_id = benchmark_run.id # Actually do the uploads. for training_dir in directories: # N.B. we don't propagate algorithm_id to Evaluation if we're running as part of a benchmark _upload_with_retries = util.retry_exponential_backoff( _upload, (error.APIConnectionError, ), max_retries=5, interval=3, ) _upload_with_retries(training_dir, None, None, benchmark_run_id, api_key, ignore_open_monitors, skip_videos) logger.info( """ **************************************************** You successfully uploaded your benchmark on %s to SenseNet! You can find it at: %s **************************************************** """.rstrip(), benchmark_id, benchmark_run.web_url()) return benchmark_run_id
def write_archive(videos, archive_file, env_id=None): if len(videos) > MAX_VIDEOS: raise error.Error( '[{}] Trying to upload {} videos, but there is a limit of {} currently. If you actually want to upload this many videos, please email [email protected] with your use-case.' .format(env_id, MAX_VIDEOS, len(videos))) logger.debug('[%s] Preparing an archive of %d videos: %s', env_id, len(videos), videos) # Double check that there are no collisions basenames = set() manifest = {'version': 0, 'videos': []} with tarfile.open(fileobj=archive_file, mode='w:gz') as tar: for video_path, metadata_path in videos: video_name = os.path.basename(video_path) metadata_name = os.path.basename(metadata_path) if not os.path.exists(video_path): raise error.Error( '[{}] No such video file {}. (HINT: Your video recorder may have broken midway through the run. You can check this with `video_recorder.functional`.)' .format(env_id, video_path)) elif not os.path.exists(metadata_path): raise error.Error( '[{}] No such metadata file {}. (HINT: this should be automatically created when using a VideoRecorder instance.)' .format(env_id, video_path)) # Do some sanity checking if video_name in basenames: raise error.Error( '[{}] Duplicated video name {} in video list: {}'.format( env_id, video_name, videos)) elif metadata_name in basenames: raise error.Error( '[{}] Duplicated metadata file name {} in video list: {}'. format(env_id, metadata_name, videos)) elif not video_name_re.search(video_name): raise error.Error( '[{}] Invalid video name {} (must match {})'.format( env_id, video_name, video_name_re.pattern)) elif not metadata_name_re.search(metadata_name): raise error.Error( '[{}] Invalid metadata file name {} (must match {})'. format(env_id, metadata_name, metadata_name_re.pattern)) # Record that we've seen these names; add to manifest basenames.add(video_name) basenames.add(metadata_name) manifest['videos'].append((video_name, metadata_name)) # Import the files into the archive tar.add(video_path, arcname=video_name, recursive=False) tar.add(metadata_path, arcname=metadata_name, recursive=False) f = tempfile.NamedTemporaryFile(mode='w+', delete=False) try: json.dump(manifest, f) f.close() tar.add(f.name, arcname='manifest.json') finally: f.close() os.remove(f.name)