diff --git a/simso/configuration/Configuration.py b/simso/configuration/Configuration.py index 1637967..e81a812 100644 --- a/simso/configuration/Configuration.py +++ b/simso/configuration/Configuration.py @@ -92,9 +92,6 @@ class Configuration(object): old_dir = self._cur_dir self._cur_dir = os.path.split(simulation_file)[0] or '.' - # Update relative paths. - self._scheduler_info.set_name( - old_dir + '/' + self._scheduler_info.name, self._cur_dir) for task in self._task_info_list: if task.stack_file: task.set_stack_file( diff --git a/simso/configuration/GenerateConfiguration.py b/simso/configuration/GenerateConfiguration.py index f5dc5a3..faba105 100644 --- a/simso/configuration/GenerateConfiguration.py +++ b/simso/configuration/GenerateConfiguration.py @@ -4,6 +4,7 @@ from xml.etree.ElementTree import Element, SubElement from xml.etree import ElementTree from xml.dom import minidom +import os def prettify(elem): @@ -23,7 +24,7 @@ def generate(configuration): 'etm': str(configuration.etm)} top = Element('simulation', attrs) - generate_sched(top, configuration.scheduler_info) + generate_sched(configuration, top, configuration.scheduler_info) generate_cache( top, configuration.caches_list, configuration.memory_access_time) generate_processors( @@ -34,13 +35,19 @@ def generate(configuration): return prettify(top) -def generate_sched(top, sched_info): - sched = SubElement(top, 'sched', { - 'className': sched_info.name, +def generate_sched(configuration, top, sched_info): + attrs = { 'overhead': str(sched_info.overhead), 'overhead_activate': str(sched_info.overhead_activate), 'overhead_terminate': str(sched_info.overhead_terminate) - }) + } + + if sched_info.filename: + attrs['className'] = os.path.relpath(sched_info.filename, + configuration.cur_dir) + if sched_info.clas: + attrs['class'] = sched_info.clas + sched = SubElement(top, 'sched', attrs) for field_name in sched_info.data.keys(): SubElement(sched, 'field', {'name': field_name, 'value': str(sched_info.data[field_name]), diff --git a/simso/configuration/parser.py b/simso/configuration/parser.py index e57549e..51d5f5b 100644 --- a/simso/configuration/parser.py +++ b/simso/configuration/parser.py @@ -84,7 +84,8 @@ class Parser(object): task_type = 'APeriodic' list_activation_dates = [] - if 'list_activation_dates' in attr and attr['list_activation_dates'].value != '': + if ('list_activation_dates' in attr and + attr['list_activation_dates'].value != ''): list_activation_dates = sorted( map(float, attr['list_activation_dates'].value.split(','))) @@ -214,7 +215,16 @@ class Parser(object): overhead_terminate = 0 sched = self._dom.getElementsByTagName('sched')[0] attr = sched.attributes - filename = attr['className'].value + if 'class' in attr: + clas = attr['class'].value + else: + clas = '' + + if 'className' in attr: + filename = attr['className'].value + else: + filename = '' + if 'overhead' in attr: overhead = int(float(attr['overhead'].value)) if 'overhead_activate' in attr: @@ -231,8 +241,8 @@ class Parser(object): data[name] = (convert_function[type_](value), type_) self.scheduler_info = SchedulerInfo( - overhead=overhead, overhead_activate=overhead_activate, + clas=clas, overhead=overhead, overhead_activate=overhead_activate, overhead_terminate=overhead_terminate, fields=data) - if filename[0] != '/': + if filename and filename[0] != '/': filename = self.cur_dir + '/' + filename - self.scheduler_info.set_name(filename, self.cur_dir) + self.scheduler_info.filename = filename diff --git a/simso/core/Scheduler.py b/simso/core/Scheduler.py index e3d443c..55e6840 100644 --- a/simso/core/Scheduler.py +++ b/simso/core/Scheduler.py @@ -2,6 +2,9 @@ from __future__ import print_function import sys import imp import os.path +import importlib +import pkgutil +import inspect from simso.core.SchedulerEvent import SchedulerBeginScheduleEvent, \ SchedulerEndScheduleEvent, SchedulerBeginActivateEvent, \ @@ -15,7 +18,7 @@ class SchedulerInfo(object): SchedulerInfo groups the data that characterize a Scheduler (such as the scheduling overhead) and do the dynamic loading of the scheduler. """ - def __init__(self, name='', overhead=0, overhead_activate=0, + def __init__(self, clas='', overhead=0, overhead_activate=0, overhead_terminate=0, fields=None): """ Args: @@ -25,8 +28,8 @@ class SchedulerInfo(object): Methods: """ - self._name = name - self._filename = None + self.filename = '' + self.clas = clas self.overhead = overhead self.overhead_activate = overhead_activate self.overhead_terminate = overhead_terminate @@ -43,56 +46,35 @@ class SchedulerInfo(object): self.data[key] = value[0] self.fields_types[key] = value[1] - def set_name(self, filename, cur_dir=None): - """ - Set the scheduler from a file. - - Args: - - `filename`: relative path to the Python source containing the \ - Scheduler. - - `cur_dir`: current directory. Used to set the name relatively \ - to the simulation file. - """ - if cur_dir is None: - cur_dir = os.curdir - self._name = os.path.relpath(filename, cur_dir) - self._filename = filename - - @property - def name(self): - """ - The name of the Scheduler (its relative path to the XML). - """ - return self._name - - @property - def filename(self): - """ - Path of the scheduler (absolute or relative to simso's working - directory). - """ - return self._filename - def get_cls(self): """ Get the class of this scheduler. """ - if self._filename: - (path, name) = os.path.split(self._filename) - name = os.path.splitext(name)[0] + try: + clas = None + if self.clas: + name = self.clas.rsplit('.', 1)[1] + importlib.import_module(self.clas) + clas = getattr(importlib.import_module(self.clas), name) + elif self.filename: + path, name = os.path.split(self.filename) + name = os.path.splitext(name)[0] - try: fp, pathname, description = imp.find_module(name, [path]) if path not in sys.path: sys.path.append(path) clas = getattr(imp.load_module(name, fp, pathname, description), name) fp.close() - return clas - except ImportError as e: - print("ImportError: ", e) - print("name: ", name, "path: ", path) - return None + + return clas + except Exception as e: + print("ImportError: ", e) + if self.clas: + print("Class: {}".format(self.clas)) + else: + print("Path: {}".format(self.filename)) + return None def instantiate(self, model): """ @@ -256,3 +238,17 @@ class Scheduler(object): def monitor_end_terminate(self, cpu): self.monitor.observe(SchedulerEndTerminateEvent(cpu)) + + +def get_schedulers(): + package = importlib.import_module('simso.schedulers') + for importer, modname, ispkg in pkgutil.walk_packages( + path=package.__path__, + prefix=package.__name__ + '.', + onerror=lambda x: None): + m = importlib.import_module(modname) + for name in dir(m): + c = m.__getattribute__(name) + if inspect.isclass(c) and issubclass(c, Scheduler): + yield modname + break