def test_update_param_info(self):
     pi = {}
     ConfigurationLoader.update_param_info(
         pi, {
             'parameters': {
                 'p1': 1,
                 'p2': u'2',
                 'p3': '3',
                 'p4': ['1', '2', '3', '4'],
                 'p5': False,
                 'p6': -3.33,
                 'p7': {
                     'val': '34',
                     'type': 'str',
                     'desc': 'Some desc'
                 }
             }
         })
     for p in ('p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7'):
         self.assertIn(p, pi)
         for f in ('val', 'type', 'desc'):
             self.assertIn(f, pi[p])
     for s in (('p1', 'int', 1), ('p2', 'str', u'2'), ('p3', 'str', '3'),
               ('p4', 'str', ['1', '2', '3', '4']), ('p5', 'bool', False),
               ('p6', 'float', -3.33), ('p7', 'str', '34')):
         self.assertEqual(pi[s[0]]['type'], s[1])
         self.assertEqual(pi[s[0]]['val'], s[2])
    def load_configuration(self):
        """Loads configuration specified by a user on a command line.

        At this moment, DLBS has already loaded standard configuration (if `discard_default_config` flag is not
        present). DLBS will try to load user configuration from `config` file (if not None) overwriting default
        parameters. Then, it will try to load user provided parameters (`params`, `vars` and `extensions`) that will
        overwrite existing configuration.

        If `plan` file is present, it will be loaded if `action` is `run`.
        """
        if self.config_file is not None:
            logging.debug('Loading configuration from: %s', self.config_file)
            with open(self.config_file) as file_obj:
                user_config = json.load(file_obj)
                # Update parameter information from user configuration.
                ConfigurationLoader.update_param_info(self.param_info,
                                                      user_config,
                                                      is_user_config=True)
                # Update existing benchmark configuration.
                ConfigurationLoader.update(
                    self.config, ConfigurationLoader.remove_info(user_config))
        if self.plan_file is not None and self.action == 'run':
            logging.debug('Loading plan from: %s', self.plan_file)
            with open(self.plan_file) as plan_file:
                self.plan = json.load(plan_file)
 def test(self):
     """dlbs  ->  TestConfigurationLoader::test                       [Loading default configuration.]"""
     files, config, param_info = ConfigurationLoader.load(self.config_path)
     # Check method returns object of expected type
     self.assertIs(type(files), list)
     self.assertIs(type(config), dict)
     self.assertIs(type(param_info), dict)
     # Check we load all configuration files
     file_names = [os.path.basename(f) for f in files]
     file_names.sort()
     self.assertEqual(file_names, self.config_files)
     # Check we have parameters and extensions sections
     self.assertIn('parameters', config)
     self.assertIn('extensions', config)
     # Check presence of standard parameters
     for ns in TestConfigurationLoader.params:
         for param in TestConfigurationLoader.params[ns]:
             self.assertIn(ns + '.' + param, config['parameters'])
     # Check that values in configuration are not dictionaries and always have
     # a parameter info object for every parameter
     for param in config['parameters']:
         self.assertFalse(
             isinstance(config['parameters'][param], dict),
             "In configuration dictionary parameter value cannot be a ditionary"
         )
         self.assertIn(param, param_info,
                       "Missing parameter in parameter info dictionary.")
     # Check values in paramter info object are always dictionaries containing
     # three mandatory fields.
     for param in param_info:
         self.assertTrue(
             isinstance(param_info[param], dict),
             "In parameter info dictionary a value must be a ditionary.")
         for field in ('val', 'type', 'desc'):
             self.assertIn(field, param_info[param])
示例#4
0
 def setUpBase(self, files=None):
     if files is None:
         files = ['base.json']
     _, self.config, self.param_info = ConfigurationLoader.load(
         os.path.join(os.path.dirname(dlbs.__file__), 'configs'),
         files=files)
     self.plan = None
 def load_configuration(self):
     """Loads configuration specified by a user on a command line."""
     if self.config_file is not None:
         logging.debug('Loading configuration from: %s', self.config_file)
         with open(self.config_file) as file_obj:
             user_config = json.load(file_obj)
             # Update parameter information from user configuration.
             ConfigurationLoader.update_param_info(self.param_info,
                                                   user_config,
                                                   is_user_config=True)
             # Update existing benchmark configuration.
             ConfigurationLoader.update(
                 self.config, ConfigurationLoader.remove_info(user_config))
     if self.plan_file is not None and self.action == 'run':
         logging.debug('Loading plan from: %s', self.plan_file)
         with open(self.plan_file) as plan_file:
             self.plan = json.load(plan_file)
示例#6
0
    def __init__(self):
        """Initialize helper by parsing command line arguments.

        It's easier to do it manually. The format of command line is:
        experimenter.py action command command_parameters
        """
        _, _, self.param_info = ConfigurationLoader.load(
            os.path.join(os.path.dirname(__file__), '..', 'configs'))
        for key in self.param_info:
            pi = self.param_info[key]
            if 'desc' in pi and isinstance(pi['desc'], Six.string_types):
                pi['desc'] = [pi['desc']]
        with open(os.path.join(os.path.dirname(__file__),
                               'frameworks.json')) as file_obj:
            self.frameworks_help = json.load(file_obj)
 def test_path_none(self):
     # None path must throw error
     with self.assertRaises(ValueError):
         ConfigurationLoader.load(None)
     # Non existing directory must trigger Value Error
     with self.assertRaises(ValueError):
         ConfigurationLoader.load('/dr3/f2t23f/tfwegh5/sgh3gw4/hh/')
     # Existing directory and non existing file must trigger ValueError
     with self.assertRaises(ValueError):
         ConfigurationLoader.load('/', files=['sfasdf23r23r23r2r23r.json'])
    def init(self, **kwargs):
        """Initializes experimenter.

        Args:
            **kwargs (dict): Optional initialization parameters:
                - action (str): Action to perform.
                - config (str): A user-provided configuration file.
                - plan (str): A file for generated benchmark plan.
                - no_validation (bool): If true, do not perform validation
                - progress_file (str): A path to progress file (if not None, enables progress reporting).
                - params (dict): User defined parameters.
                - vars (dict): User defined variables.
                - discard_default_config (bool): If True, do not load standard DLBS config.
                - extensions (dict): User provided extensions.

        User provided parameters (`params`), variables (`vars`) and extensions (`extensions`) overwrite values defined
        in user configuration files (`config`) if it is present.
        Information defined in a uses-provided configuration file (`config`) overwrites standard DLBS configuration.
        """
        if self.__initialized:
            raise RuntimeError("Experimenter can only be initialized once.")

        self.action = DictUtils.get(kwargs, 'action', 'run')
        self.config_file = DictUtils.get(kwargs, 'config', None)
        self.plan_file = DictUtils.get(kwargs, 'plan', None)
        self.validation = not DictUtils.get(kwargs, 'no_validation', False)
        self.__progress_file = DictUtils.get(kwargs, 'progress_file', None)
        # Get parameters and variables from a command line/user-provided
        self.params.update(DictUtils.get(kwargs, 'params', {}))
        self.variables.update(DictUtils.get(kwargs, 'vars', {}))

        # Load default configuration
        if not DictUtils.get(kwargs, 'discard_default_config', False):
            logging.debug("Loading default configuration")
            _, self.config, self.param_info = ConfigurationLoader.load(
                os.path.join(os.path.dirname(__file__), 'configs'))
        # Load configurations specified on a command line
        self.load_configuration()
        # Add extensions from command line
        DictUtils.ensure_exists(self.config, 'extensions', [])
        self.config['extensions'].extend(
            DictUtils.get(kwargs, 'extensions', []))
        # All's done
        self.__initialized = True
 def __init__(self, tmp_folder):
     # Check folder does not exist or empty
     if not os.path.isdir(tmp_folder):
         os.makedirs(tmp_folder)
     else:
         assert len(os.listdir(tmp_folder)) == 0,\
                "Folder %s must be empty." % tmp_folder
     self.tmp_folder = tmp_folder
     # Load configuration
     _, _, self.param_info = ConfigurationLoader.load(
         os.path.join(os.path.dirname(__file__), '..', 'configs'))
     # If a parameter contains description and it is string, convert to array
     for key in self.param_info:
         pi = self.param_info[key]
         if 'desc' in pi and isinstance(pi['desc'], basestring):
             pi['desc'] = [pi['desc']]
     # Load common and framework specific params
     with open(os.path.join(os.path.dirname(__file__),
                            'frameworks.json')) as file_obj:
         self.framework_info = json.load(file_obj)
 def test_remove_info(self):
     config = ConfigurationLoader.remove_info({
         'parameters': {
             'p1': 1,
             'p2': u'2',
             'p3': '3',
             'p4': ['1', '2', '3', '4'],
             'p5': False,
             'p6': -3.33,
             'p7': {
                 'val': '34',
                 'type': 's3tr',
                 'desc': 'Some desc'
             }
         }
     })
     for p in ('p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7'):
         self.assertIn(p, config['parameters'])
     for s in (('p1', 1), ('p2', u'2'), ('p3', '3'),
               ('p4', ['1', '2', '3',
                       '4']), ('p5', False), ('p6', -3.33), ('p7', '34')):
         self.assertEqual(config['parameters'][s[0]], s[1])
    def init(self,
             init_logger=False,
             load_default_config=True,
             load_config=True):
        """Initializes experimenter.

        :param bool init_logger: If True, initializes loggers
        :param bool load_default_config: If false, does not load standard configuration.
        :param bool load_config: If true, loads configuration specified on a command line
        """
        # Parse command line arguments
        parser = argparse.ArgumentParser()
        parser.add_argument(
            'action',
            type=str,
            help=
            'Action to perform. Valid actions: "print-config", "run", "build" and "analyze-plan".'
        )
        parser.add_argument('--config',
                            required=False,
                            type=str,
                            help='Configuration file (json) of an experiment.\
                                                                        Will override values from default configuration.'
                            )
        parser.add_argument('--plan',
                            required=False,
                            type=str,
                            help='Pre-built plan of an experiment (json).\
                                                                      If action is "build", a file name to write plan to.\
                                                                      If action is "run", a file name to read plan from.'
                            )
        parser.add_argument('--progress_file', '--progress-file', required=False, type=str, default=None,
                            help='A JSON file that experimenter will be updating on its progress.'\
                                 'If not present, no progress info will be available.'\
                                 'Put it somewhere in /dev/shm')
        parser.add_argument(
            '-P',
            action='append',
            required=False,
            default=[],
            help='Parameters that override parameters in configuration file.\
                                                                                     For instance, -Pexp.phase=2. Values must be json parsable (json.loads()).'
        )
        parser.add_argument(
            '-V',
            action='append',
            required=False,
            default=[],
            help=
            'Variables that override variables in configuration file in section "variables". \
                                                                                     These variables are used to generate different combinations of experiments.\
                                                                                     For instance: -Vexp.framework=\'["tensorflow", "caffe2"]\'.\
                                                                                     Values must be json parsable (json.loads()).'
        )
        parser.add_argument(
            '--log_level',
            '--log-level',
            required=False,
            default='info',
            help=
            'Python logging level. Valid values: "critical", "error", "warning", "info" and "debug"'
        )
        parser.add_argument('--discard_default_config',
                            '--discard-default-config',
                            required=False,
                            default=False,
                            action='store_true',
                            help='Do not load default configuration.')
        parser.add_argument(
            '--no_validation',
            '--no-validation',
            required=False,
            default=False,
            action='store_true',
            help='Do not perform config validation before running benchmarks.')
        parser.add_argument(
            '-E',
            action='append',
            required=False,
            default=[],
            help=
            'Extensions to add. Can be usefull to quickly customize experiments.\
                                                                                     Must be valid json parsable array element for "extension" array.'
        )
        args = parser.parse_args()

        log_level = logging.getLevelName(args.log_level.upper())
        self.action = args.action
        self.config_file = args.config
        self.plan_file = args.plan
        self.validation = not args.no_validation
        self.__progress_file = args.progress_file

        # Initialize logger
        if init_logger:
            logging.debug("Initializing logger to level %s", args.log_level)
            root = logging.getLogger()
            root.setLevel(log_level)
            handler = logging.StreamHandler(sys.stdout)
            handler.setLevel(log_level)
            root.addHandler(handler)

        logging.debug("Parsing parameters on a command line")
        DictUtils.add(self.params,
                      args.P,
                      pattern='(.+?(?=[=]))=(.+)',
                      must_match=True)
        logging.debug("Parsing variables on a command line")
        DictUtils.add(self.variables,
                      args.V,
                      pattern='(.+?(?=[=]))=(.+)',
                      must_match=True)

        # Load default configuration
        if load_default_config and not args.discard_default_config:
            logging.debug("Loading default configuration")
            _, self.config, self.param_info = ConfigurationLoader.load(
                os.path.join(os.path.dirname(__file__), 'configs'))

        # Load configurations specified on a command line
        if load_config:
            logging.debug("Loading user configuration")
            self.load_configuration()

        # Add extensions from command line
        DictUtils.ensure_exists(self.config, 'extensions', [])
        if len(args.E) > 0:
            logging.debug("Parsing extensions on a command line")
        for extension in args.E:
            try:
                ext = json.loads(extension)
                logging.debug('Found extension: %s', str(ext))
                self.config['extensions'].append(ext)
            except Exception as err:
                logging.warn("Found non-json parsable extension: %s",
                             extension)
                raise err