Beispiel #1
0
def xml2csv(experiment_root_path=None):

    if not experiment_root_path:
        # Parse command line.
        args = get_arguments()
        experiment_root_path = args.experiment_dir
        num_processors = mp.cpu_count()
    else:
        num_processors, _, _ = config_parser.parse_run_params(print_params=False)

    print('\nConverting .xml files to .csv ...\n')

    # Get all .xml files recursively.
    xml_paths = list(Path(experiment_root_path).rglob('*.xml'))
    xml_paths = [str(p) for p in xml_paths]

    # Convert files.
    if num_processors > 1:
        pool = mp.Pool(num_processors)
        pool.map(convert, xml_paths)
    else:
        for xml_path in xml_paths:
            convert(xml_path)
Beispiel #2
0
def preprocess_batch(tls_type='webster'):
    # Preprocess is a run with some presets
    # Read script arguments from run.config file.

    data = {}
    if do_preprocess():
        num_processors, num_runs, seeds = config_parser.parse_run_params(print_params=False)

        if len(seeds) != num_runs:
            raise configparser.Error('Number of seeds in run.config `seeds`'
                            ' must match the number of runs (`num_runs`) argument.')

        # Assess total number of processors.
        processors_total = mp.cpu_count()
        print(f'Total number of processors available: {processors_total}\n')

        # Adjust number of processors.
        if num_processors > processors_total:
            num_processors = processors_total
            print(f'Number of processors downgraded to {num_processors}\n')
        # num_processors should be <= num_runs
        seeds = seeds[:num_processors]

        print('Arguments (preprocess):')
        print('-----------------------')
        print(f'Number of runs: {num_runs}')
        print(f'Number of processors: {num_processors}')
        print(f'Number of preprocess trails: {num_processors}\n')


        # Read train.py arguments from train.config file.
        preprocess_config = configparser.ConfigParser()
        preprocess_path = CONFIG_PATH / 'train.config'
        preprocess_config.read(str(preprocess_path))

        # Setup sumo-tls-type.
        preprocess_config.set('train_args', 'tls_type', tls_type)
        preprocess_config.set('train_args', 'experiment_save_agent', str(False))
        preprocess_config.set('mdp_args', 'discretize_state_space', str(False))

        # Get feature & network information
        network = preprocess_config.get('train_args', 'network')
        features = eval(preprocess_config.get('mdp_args', 'features'))

        if eval(preprocess_config.get('mdp_args', 'time_period')) is not None:
            features = ('time',) + features

        # Remove lag from features
        features = tuple(rmlag(f) for f in features)

        # Override train configurations with test parameters.
        test_config = configparser.ConfigParser()
        test_path = CONFIG_PATH / 'test.config'
        test_config.read(test_path.as_posix())

        horizon = int(test_config.get('test_args', 'rollout-time'))
        preprocess_config.set('train_args', 'experiment_time', str(horizon))

        # Write .xml files for test plots creation.
        preprocess_config.set('train_args', 'sumo_emission', str(False))

        timestamp = datetime.now().strftime('%Y%m%d%H%M%S.%f')
        print(f'Experiment timestamp: {timestamp}')

        with tempfile.TemporaryDirectory() as tmp_dir:
            # Create a config file for each train.py
            # with the respective seed. These config
            # files are stored in a temporary directory.
            tmp_path = Path(tmp_dir)
            preprocess_configs = []
            for seed in seeds:

                cfg_path = tmp_path / f'{tls_type}-{seed}.config'
                preprocess_configs.append(cfg_path)

                # Setup train seed.
                preprocess_config.set("train_args", "experiment_seed", str(seed + 1))

                # Write temporary train config file.
                with cfg_path.open('w') as ft:
                    preprocess_config.write(ft)

            # rvs: directories' names holding experiment data
            if num_processors > 1:
                ind = range(num_processors)
                cfgs = preprocess_configs
                packed_args = zip(ind, cfgs)
                pool = NonDaemonicPool(num_processors)
                rvs = pool.map(delay_preprocess, packed_args)
                pool.close()
                pool.join()
            else:
                rvs = []
                for cfg in preprocess_configs:
                    rvs.append(delay_preprocess((0.0, cfg)))


        data = defaultdict(list)
        for ret in rvs:
            data[(network, features)] += ret['observation_spaces']
        data = digitize2(data)

    return data
Beispiel #3
0
def baseline_batch():

    flags = get_arguments()

    # Read script arguments from run.config file.

    num_processors, num_runs, seeds = config_parser.parse_run_params(
        print_params=False)

    if len(seeds) != num_runs:
        raise configparser.Error(
            'Number of seeds in run.config `seeds`'
            ' must match the number of runs (`num_runs`) argument.')

    print('Arguments (baseline.py):')
    print('-----------------------')
    print('Number of runs: {0}'.format(num_runs))
    print('Number of processors: {0}'.format(num_processors))
    print('Train seeds: {0}\n'.format(seeds))

    # Assess total number of processors.
    processors_total = mp.cpu_count()
    print(f'Total number of processors available: {processors_total}\n')

    # Adjust number of processors.
    if num_processors > processors_total:
        num_processors = processors_total
        print(f'Number of processors downgraded to {num_processors}\n')

    # Read train.py arguments from train.config file.
    baseline_config = configparser.ConfigParser()
    baseline_path = CONFIG_PATH / 'train.config'
    baseline_config.read(str(baseline_path))

    # Setup sumo-tls-type.
    baseline_config.set('train_args', 'tls_type', flags.tls_type)
    baseline_config.set('train_args', 'experiment_save_agent', str(False))

    # Override train configurations with test parameters.
    test_config = configparser.ConfigParser()
    test_path = CONFIG_PATH / 'test.config'
    test_config.read(test_path.as_posix())

    horizon = int(test_config.get('test_args', 'rollout-time'))
    baseline_config.set('train_args', 'experiment_time', str(horizon))

    # Write .xml files for test plots creation.
    baseline_config.set('train_args', 'sumo_emission', str(True))

    timestamp = datetime.now().strftime('%Y%m%d%H%M%S.%f')
    print(f'Experiment timestamp: {timestamp}')

    with tempfile.TemporaryDirectory() as tmp_dir:
        # Create a config file for each train.py
        # with the respective seed. These config
        # files are stored in a temporary directory.
        tmp_path = Path(tmp_dir)
        baseline_configs = []
        for seed in seeds:

            cfg_path = tmp_path / f'{flags.tls_type}-{seed}.config'
            baseline_configs.append(cfg_path)

            # Setup train seed.
            baseline_config.set("train_args", "experiment_seed", str(seed + 1))

            # Write temporary train config file.
            with cfg_path.open('w') as ft:
                baseline_config.write(ft)

        # rvs: directories' names holding experiment data
        if num_processors > 1:
            packed_args = [(delay, cfg) for (
                delay,
                cfg) in zip(range(len(baseline_configs)), baseline_configs)]
            pool = NonDaemonicPool(num_processors)
            rvs = pool.map(delay_baseline, packed_args)
            pool.close()
            pool.join()
        else:
            rvs = []
            for cfg in baseline_configs:
                rvs.append(delay_baseline((0.0, cfg)))

        # Create a directory and move newly created files
        paths = [Path(f) for f in rvs]
        commons = [p.parent for p in paths]
        if len(set(commons)) > 1:
            raise ValueError(
                f'Directories {set(commons)} must have the same root')
        dirpath = commons[0]
        batchpath = dirpath / timestamp
        if not batchpath.exists():
            batchpath.mkdir()

        # Move files
        for src in paths:
            dst = batchpath / src.parts[-1]
            src.replace(dst)

    sys.stdout.write(str(batchpath))

    return str(batchpath)
Beispiel #4
0
def train_batch(categories={}):

    print('\nRUNNING jobs/train.py\n')
    num_processors, num_runs, train_seeds = config_parser.parse_run_params(
        print_params=False)

    if len(train_seeds) != num_runs:
        raise configparser.Error(
            'Number of seeds in run.config `train_seeds`'
            ' must match the number of runs (`num_runs`) argument.')

    print('\nArguments (jobs/train.py):')
    print('------------------------')
    print('Number of runs: {0}'.format(num_runs))
    print('Number of processors: {0}'.format(num_processors))
    print('Train seeds: {0}\n'.format(train_seeds))

    # Assess total number of processors.
    processors_total = mp.cpu_count()
    print(f'Total number of processors available: {processors_total}\n')

    # Adjust number of processors.
    if num_processors > processors_total:
        num_processors = processors_total
        print(
            f'WARNING: Number of processors downgraded to {num_processors}\n')

    # Read train.py arguments from train.config file.
    train_config = configparser.ConfigParser()
    train_config.read(os.path.join(CONFIG_PATH, 'train.config'))

    timestamp = datetime.now().strftime('%Y%m%d%H%M%S.%f')
    print(f'Experiment timestamp: {timestamp}\n')

    with tempfile.TemporaryDirectory() as tmp_dir:

        # Create a config file for each train.py
        # with the respective seed. These config
        # files are stored in a temporary directory.
        train_configs = []
        for seed in train_seeds:

            tmp_train_cfg_path = os.path.join(tmp_dir,
                                              'train-{0}.config'.format(seed))
            train_configs.append(tmp_train_cfg_path)

            # Setup train seed.
            train_config.set("train_args", "experiment_seed", str(seed))
            if any(categories):
                train_config.set("mdp_args", "category", str(categories))

            # Write temporary train config file.
            tmp_cfg_file = open(tmp_train_cfg_path, "w")
            train_config.write(tmp_cfg_file)
            tmp_cfg_file.close()

        # Run.
        # rvs: directories' names holding experiment data
        if num_processors > 1:
            train_args = zip(range(num_runs), train_configs)
            pool = NonDaemonicPool(num_processors, maxtasksperchild=1)
            rvs = pool.map(delay_train, train_args)
            pool.close()
            pool.join()
        else:
            rvs = []
            for cfg in train_configs:
                rvs.append(delay_train((0.0, cfg)))

        # Create a directory and move newly created files.
        paths = [Path(f) for f in rvs]
        commons = [p.parent for p in paths]
        if len(set(commons)) > 1:
            raise ValueError(
                f'Directories {set(commons)} must have the same root')
        dirpath = commons[0]
        batchpath = dirpath / timestamp
        if not batchpath.exists():
            batchpath.mkdir()

        # Move files
        for src in paths:
            dst = batchpath / src.parts[-1]
            src.replace(dst)

    sys.stdout.write(str(batchpath))

    return str(batchpath)
Beispiel #5
0
def rollout_batch(test=False, experiment_dir=None):

    print('\nRUNNING jobs/rollouts.py\n')

    if not experiment_dir:

        # Read script arguments.
        args = get_arguments()
        # Clear command line arguments after parsing.

        batch_path = Path(args.experiment_dir)
        test = args.test

    else:
        batch_path = Path(experiment_dir)

    chkpt_pattern = 'checkpoints'

    # Get names of train runs.
    experiment_names = list({p.parents[0] for p in batch_path.rglob(chkpt_pattern)})

    # Get checkpoints numbers.
    chkpts_dirs = [p for p in batch_path.rglob(chkpt_pattern)]
    chkpts_nums = [int(n.name) for n in chkpts_dirs[0].iterdir()]
    if len(chkpts_nums) == 0:
        raise ValueError('No checkpoints found.')

    chkpts_nums = sorted(chkpts_nums)

    # If test then pick only the last checkpoints.
    if test:
        chkpts_nums = [chkpts_nums[-1]]
        rollouts_paths = list(itertools.product(experiment_names, chkpts_nums))
    
        print('jobs/rollouts.py (test mode): using checkpoints'
                ' number {0}'.format(chkpts_nums[0]))
    else:
        rollouts_paths = list(itertools.product(experiment_names, chkpts_nums))

    # print(rollouts_paths)

    num_processors, num_runs, train_seeds = config_parser.parse_run_params(print_params=False)


    if len(train_seeds) != num_runs:
        raise configparser.Error('Number of seeds in run.config `train_seeds`'
                        'must match the number of runs (`num_runs`) argument.')

    # Assess total number of processors.
    processors_total = mp.cpu_count()
    print(f'Total number of processors available: {processors_total}\n')

    # Adjust number of processors.
    if num_processors > processors_total:
        num_processors = processors_total
        print(f'Number of processors downgraded to {num_processors}\n')

    # Read rollouts arguments from rollouts.config file.
    rollouts_config = configparser.ConfigParser()
    rollouts_config.read(str(CONFIG_PATH / 'rollouts.config'))

    rollout_time, num_rollouts = config_parser.parse_rollout_params()

    if test:
        # Override rollouts config files with test.config file parameters.
        test_config = configparser.ConfigParser()
        test_config.read(str(CONFIG_PATH / 'test.config'))

        rollout_time, num_rollouts = config_parser.parse_rollout_params(test_file=True)

        # Overwrite defaults.
        rollouts_config.set('rollouts_args', 'rollout-time', str(rollout_time))

        token = 'test'

        # Test mode defaults below (DO NOT CHANGE THESE).
        # Write .xml files for test plots creation.
        rollouts_config.set('rollouts_args', 'sumo-emission', str(True))

    else:

        token = 'rollouts'

        # Non-test mode defaults below (DO NOT CHANGE THESE).
        # Do not write .xml files due to performance and memory issues.
        rollouts_config.set('rollouts_args', 'sumo-emission', str(False))

    print(f'\nArguments (jobs/{token}.py):')
    print('-------------------------')
    print(f'Experiment dir: {batch_path}')
    print(f'Number of processors: {num_processors}')
    print(f'Num. rollout files: {len(rollouts_paths)}')
    print(f'Num. rollout repetitions: {num_rollouts}')
    print(f'Num. rollout total: {len(rollouts_paths) * num_rollouts}')
    print(f'Rollout time: {rollout_time}\n')

    # Allocate seeds.
    custom_configs = []
    for rn, rp in enumerate(rollouts_paths):
        base_seed = max(train_seeds) + num_rollouts * rn
        for rr in range(num_rollouts):
            seed = base_seed + rr + 1
            custom_configs.append((rp, seed))

    with tempfile.TemporaryDirectory() as f:

        tmp_path = Path(f)
        # Create a config file for each rollout
        # with the respective seed. These config
        # files are stored in a temporary directory.
        rollouts_cfg_paths = []
        cfg_key = "rollouts_args"
        for cfg in custom_configs:
            run_path, chkpt_num = cfg[0]
            seed = cfg[1]

            # Setup custom rollout settings.
            rollouts_config.set(cfg_key, "run-path", str(run_path))
            rollouts_config.set(cfg_key, "chkpt-number", str(chkpt_num))
            rollouts_config.set(cfg_key, "seed", str(seed))
            
            # Write temporary train config file.
            cfg_path = tmp_path / f'rollouts-{run_path.name}-{chkpt_num}-{seed}.config'
            rollouts_cfg_paths.append(str(cfg_path))
            with cfg_path.open('w') as fw:
                rollouts_config.write(fw)

        # rvs: directories' names holding experiment data
        if num_processors > 1:
            pool = NonDaemonicPool(num_processors)
            rvs = pool.map(delay_roll, [(delay, [cfg])
                            for (delay, cfg) in zip(range(len(rollouts_cfg_paths)), rollouts_cfg_paths)])
            pool.close()
        else:
            rvs = []
            for cfg in rollouts_cfg_paths:
                rvs.append(delay_roll((0.0, [cfg])))

    res = concat(rvs)
    filepart = 'test' if test else 'eval'
    filename = f'rollouts_{filepart}.json'
    target_path = batch_path / filename
    with target_path.open('w') as fj:
        json.dump(res, fj)

    sys.stdout.write(str(batch_path))

    return str(batch_path)