<commit_before># Copyright 2017 reinforce.io. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""
TensorForce benchmarking.

Usage:

```bash
python benchmark.py [--output output] [--append] <algorithm> <gym_id>
```

`algorithm` specifies which config file to use. You can pass the path to a valid json config file, or a string
indicating which prepared config to use (e.g. `dqn2015`).

`gym_id` should be a valid [OpenAI gym ID](https://gym.openai.com/envs)

`output` is an optional parameter to set the output (pickle) file. If omitted, output will be saved in `./benchmarks`.

`append` is an optional parameter which indicates if data should be appended to an existing output file.

The resulting output file is a pickled python list, where each item is a dict containing benchmark data.

The dict has the following keys:

* `episode_rewards`: list containing observed total rewards for each episode.
* `episode_lengths`: list containing total timesteps for each episode.
* `initial_reset_time`: integer indicating starting timestamp (usually 0).
* `episode_end_times`: list containing observed end times relativ to `initial_reset_time` (not working at the moment).
* `info`: dict containing meta information about the experiment:
    * `agent`: TensorForce agent used in the experiment.
    * `episodes`: Episode count configuration item.
    * `max_timesteps`: Max timesteps configuration item.
    * `environment_name`: Environment name configuration item.
* `config`: `Configuration` object containing the original configuration passed to the benchmarking script.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import logging
import os
import pickle

from tensorforce import Configuration
from tensorforce.agents import agents
from tensorforce.core.networks import layered_network_builder
from tensorforce.execution import Runner
from tensorforce.contrib.openai_gym import OpenAIGym


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('algorithm', help="Algorithm name (config file)")
    parser.add_argument('gym_id', help="ID of the gym environment")
    parser.add_argument('-o', '--output', help="output file (pickle pkl)")
    parser.add_argument('-a', '--append', action='store_true', default=False,
                        help="Append data to existing pickle file?")

    args = parser.parse_args()

    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    root = os.path.dirname(os.path.realpath(__file__))

    config_file = os.path.join(root, args.algorithm)
    if not os.path.exists(config_file):
        config_file = os.path.join(root, 'configs', '{}.json'.format(args.algorithm))
        if not os.path.exists(config_file):
            raise ValueError("No configuration found: {}".format(args.algorithm))
        benchmark_file = os.path.join(root, 'benchmarks', '{}_{}.pkl'.format(
            args.algorithm, args.gym_id
        ))
    else:
        benchmark_file = os.path.join(root, 'benchmarks', '{}_{}.pkl'.format(
            args.algorithm.replace('.', '_').replace('/', '__'), args.gym_id
        ))

    if args.output:
        benchmark_file = args.output
    else:
        if not os.path.isdir(os.path.join(root, 'benchmarks')):
            os.mkdir(os.path.join(root, 'benchmarks'), 0o755)

    if os.path.isfile(benchmark_file):
        logger.debug("Found existing benchmark file: {}".format(benchmark_file))

        if not args.append:
            raise ValueError("Output file already exists (and --apend was not passed), aborting.")

        logger.info("Loading data from output file to append to...")
        with open(benchmark_file, 'rb') as f:
            pickle_data = pickle.load(f)
    else:
        pickle_data = list()

    config = Configuration.from_json(config_file)

    original_config = config.copy()  # Until reinforceio/tensorforce#54 is fixed, use a copy of the config

    config.network = layered_network_builder(config.network)
    environment = OpenAIGym(args.gym_id)<commit_msg>fixed typo<commit_after># Copyright 2017 reinforce.io. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================

"""
TensorForce benchmarking.

Usage:

```bash
python benchmark.py [--output output] [--append] <algorithm> <gym_id>
```

`algorithm` specifies which config file to use. You can pass the path to a valid json config file, or a string
indicating which prepared config to use (e.g. `dqn2015`).

`gym_id` should be a valid [OpenAI gym ID](https://gym.openai.com/envs)

`output` is an optional parameter to set the output (pickle) file. If omitted, output will be saved in `./benchmarks`.

`append` is an optional parameter which indicates if data should be appended to an existing output file.

The resulting output file is a pickled python list, where each item is a dict containing benchmark data.

The dict has the following keys:

* `episode_rewards`: list containing observed total rewards for each episode.
* `episode_lengths`: list containing total timesteps for each episode.
* `initial_reset_time`: integer indicating starting timestamp (usually 0).
* `episode_end_times`: list containing observed end times relativ to `initial_reset_time` (not working at the moment).
* `info`: dict containing meta information about the experiment:
    * `agent`: TensorForce agent used in the experiment.
    * `episodes`: Episode count configuration item.
    * `max_timesteps`: Max timesteps configuration item.
    * `environment_name`: Environment name configuration item.
* `config`: `Configuration` object containing the original configuration passed to the benchmarking script.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import logging
import os
import pickle

from tensorforce import Configuration
from tensorforce.agents import agents
from tensorforce.core.networks import layered_network_builder
from tensorforce.execution import Runner
from tensorforce.contrib.openai_gym import OpenAIGym


def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('algorithm', help="Algorithm name (config file)")
    parser.add_argument('gym_id', help="ID of the gym environment")
    parser.add_argument('-o', '--output', help="output file (pickle pkl)")
    parser.add_argument('-a', '--append', action='store_true', default=False,
                        help="Append data to existing pickle file?")

    args = parser.parse_args()

    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    root = os.path.dirname(os.path.realpath(__file__))

    config_file = os.path.join(root, args.algorithm)
    if not os.path.exists(config_file):
        config_file = os.path.join(root, 'configs', '{}.json'.format(args.algorithm))
        if not os.path.exists(config_file):
            raise ValueError("No configuration found: {}".format(args.algorithm))
        benchmark_file = os.path.join(root, 'benchmarks', '{}_{}.pkl'.format(
            args.algorithm, args.gym_id
        ))
    else:
        benchmark_file = os.path.join(root, 'benchmarks', '{}_{}.pkl'.format(
            args.algorithm.replace('.', '_').replace('/', '__'), args.gym_id
        ))

    if args.output:
        benchmark_file = args.output
    else:
        if not os.path.isdir(os.path.join(root, 'benchmarks')):
            os.mkdir(os.path.join(root, 'benchmarks'), 0o755)

    if os.path.isfile(benchmark_file):
        logger.debug("Found existing benchmark file: {}".format(benchmark_file))

        if not args.append:
            raise ValueError("Output file already exists (and --append was not passed), aborting.")

        logger.info("Loading data from output file to append to...")
        with open(benchmark_file, 'rb') as f:
            pickle_data = pickle.load(f)
    else:
        pickle_data = list()

    config = Configuration.from_json(config_file)

    original_config = config.copy()  # Until reinforceio/tensorforce#54 is fixed, use a copy of the config

    config.network = layered_network_builder(config.network)
    environment = OpenAIGym(args.gym_id)
{'fraction_non_alphanumeric': 0.11711904253045523, 'fraction_numerical': 0.004060696730070528, 'mean_word_length': 3.9, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '287561', 'n_tokens_mistral': 2650, 'n_tokens_neox': 2526, 'n_words': 904}