コード例 #1
0
ファイル: base.py プロジェクト: sahwar/wapiti
class OperationQueue(object):
    # TODO: chunking/batching should probably happen here
    # with the assistance of another queue for prioritized params
    # (i.e., don't create subops so eagerly)
    def __init__(self, qid, op_type, default_limit=ALL):
        self.qid = qid
        options, unwrapped = get_unwrapped_options(op_type)
        self.op_type = op_type
        self.unwrapped_type = unwrapped
        self.options = options

        self.unique_key = options.get('unique_key', 'unique_key')
        self.unique_func = get_unique_func(self.unique_key)
        self.priority = options.get('priority', 0)
        self.priority_func = get_priority_func(self.priority)
        self.default_limit = default_limit

        self.param_set = set()
        self.op_queue = PriorityQueue()
        self._dup_params = []

    def enqueue(self, param, **kw):
        unique_key = self.unique_func(param)
        if unique_key in self.param_set:
            self._dup_params.append(unique_key)
            return
        priority = self.priority_func(param)
        kwargs = {'limit': self.default_limit}
        kwargs.update(kw)
        new_subop = self.op_type(param, **kwargs)
        new_subop._origin_queue = self.qid
        self.op_queue.add(new_subop, priority)
        self.param_set.add(unique_key)

    def enqueue_many(self, param_list, **kw):
        for param in param_list:
            self.enqueue(param, **kw)
        return

    def __len__(self):
        return len(self.op_queue)

    def peek(self, *a, **kw):
        return self.op_queue.peek(*a, **kw)

    def pop(self, *a, **kw):
        return self.op_queue.pop(*a, **kw)
コード例 #2
0
ファイル: base.py プロジェクト: bryanoltman/wapiti
class OperationQueue(object):
    # TODO: chunking/batching should probably happen here
    # with the assistance of another queue for prioritized params
    # (i.e., don't create subops so eagerly)
    def __init__(self, qid, op_type, default_limit=ALL):
        self.qid = qid
        options, unwrapped = get_unwrapped_options(op_type)
        self.op_type = op_type
        self.unwrapped_type = unwrapped
        self.options = options

        self.unique_key = options.get('unique_key', 'unique_key')
        self.unique_func = get_unique_func(self.unique_key)
        self.priority = options.get('priority', 0)
        self.priority_func = get_priority_func(self.priority)
        self.default_limit = default_limit

        self.param_set = set()
        self.op_queue = PriorityQueue()
        self._dup_params = []

    def enqueue(self, param, **kw):
        unique_key = self.unique_func(param)
        if unique_key in self.param_set:
            self._dup_params.append(unique_key)
            return
        priority = self.priority_func(param)
        kwargs = {'limit': self.default_limit}
        kwargs.update(kw)
        new_subop = self.op_type(param, **kwargs)
        new_subop._origin_queue = self.qid
        self.op_queue.add(new_subop, priority)
        self.param_set.add(unique_key)

    def enqueue_many(self, param_list, **kw):
        for param in param_list:
            self.enqueue(param, **kw)
        return

    def __len__(self):
        return len(self.op_queue)

    def peek(self, *a, **kw):
        return self.op_queue.peek(*a, **kw)

    def pop(self, *a, **kw):
        return self.op_queue.pop(*a, **kw)
コード例 #3
0
ファイル: uamp_sim.py プロジェクト: SuWilliam/uAMP-sim
class Simulator(SimulatorBase):
    EVENT_QUEUE_THRESHOLD = 100

    def __init__(self):
        self.modules = {}
        self.module_type_map = defaultdict(deque)

        self.device_state = DeviceState()
        self.event_queue = PriorityQueue()
        self.alarms = []
        self.modules = {}
        self.event_listeners = defaultdict(deque)
        self.trace_reader = None
        self.verbose = False
        self.debug_mode = False
        self.debug_interval = 1
        self.debug_interval_cnt = 0

    def has_module_instance(self, name):
        return name in self.modules

    def get_module_instance(self, name):
        return self.modules[name]

    def get_module_for_type(self, module_type):
        if module_type in self.module_type_map:
            return self.module_type_map[module_type.value][0]
        else:
            return None

    def register(self, sim_module, override=False):
        if not isinstance(sim_module, SimModule):
            raise TypeError("Expected SimModule object")

        if sim_module.get_name() in self.modules:
            raise Exception("Module %s already exists" % sim_module.get_name())

        self.modules[sim_module.get_name()] = sim_module

        if override:
            self.module_type_map[sim_module.get_type().value].appendleft(
                sim_module)
        else:
            self.module_type_map[sim_module.get_type().value].append(
                sim_module)

    def build(self, args):
        self.verbose = args.verbose
        self.debug_mode = args.debug

        # Instantiate necessary modules based on config files
        config = configparser.ConfigParser()
        config.read(args.sim_config)

        config['DEFAULT'] = {'modules': ''}

        if 'Simulator' not in config:
            raise Exception("Simulator section missing from config file")

        sim_settings = config['Simulator']
        modules_str = sim_settings['modules']
        modules_list = modules_str.split(' ')

        for module_name in modules_list:
            module_settings = {}
            if module_name in config:
                module_settings = config[module_name]

            self.register(
                get_simulator_module(module_name, self, module_settings))

        # Build list of modules
        for module in self.modules.values():
            module.build()

    def run(self, trace_file):
        self.trace_reader = get_trace_reader(trace_file)
        self.trace_reader.build()

        if self.debug_mode:
            self.debug_interval_cnt = 0
            self.debug()

        while not self.trace_reader.end_of_trace(
        ) or not self.event_queue.empty():
            # Populate event queue if it is below the threshold number of events
            if self.event_queue.size() < Simulator.EVENT_QUEUE_THRESHOLD \
                    and not self.trace_reader.end_of_trace():
                self.populate_event_queue_from_trace()
                continue

            cur_event = self.event_queue.peek()
            trace_event = self.trace_reader.peek_event()
            if trace_event and cur_event.timestamp > trace_event.timestamp:
                self.populate_event_queue_from_trace()
                continue

            self.event_queue.pop()
            if self.verbose:
                print(cur_event)

            if self.debug_mode:
                self.debug_interval_cnt += 1
                if self.debug_interval_cnt == self.debug_interval:
                    self.debug()
                    self.debug_interval_cnt = 0

            self.broadcast(cur_event)
        self.finish()

    def populate_event_queue_from_trace(self):
        # Fill in event queue from trace
        events = self.trace_reader.get_events(
            count=Simulator.EVENT_QUEUE_THRESHOLD)
        [self.event_queue.push(x) for x in events]

    def finish(self):
        # Call finish for all modules
        for module in self.modules.values():
            module.finish()

    def subscribe(self, event_type, handler, event_filter=None):
        if event_type not in self.event_listeners:
            self.event_listeners[event_type] = []
        self.event_listeners[event_type].append((event_filter, handler))

    def broadcast(self, event):
        # Get the set of listeners for the given event type
        listeners = self.event_listeners[event.event_type]
        for (event_filter, handler) in listeners:
            # Send event to each subscribed listener
            if not event_filter or event_filter(event):
                handler(event)

    def register_alarm(self, alarm, handler):
        pass

    def debug(self):
        while True:
            command = input("(uamp-sim debug) $ ")
            if command:
                tokens = command.split(sep=' ')
                cmd = tokens[0]
                args = tokens[1:]
                if cmd == 'quit' or cmd == 'exit' or cmd == 'q':
                    # TODO(dmanatunga): Handle simulation quitting better
                    print("Terminating Simulation")
                    exit(1)
                elif cmd == 'interval':
                    if len(args) == 1:
                        try:
                            self.debug_interval = int(args[0])
                        except ValueError:
                            print(
                                "Command Usage Error: interval command expects one numerical value"
                            )
                    else:
                        print(
                            "Command Usage Error: interval command expects one numerical value"
                        )
                elif cmd == 'verbose':
                    if len(args) == 0:
                        self.verbose = True
                    elif len(args) == 1:
                        if args[0] == 'on':
                            self.verbose = True
                        elif args[0] == 'off':
                            self.verbose = False
                        else:
                            print(
                                "Command Usage Error: verbose command expects 'on' or 'off' for argument"
                            )

                    else:
                        print(
                            "Command Usage Error: verbose command expects at most one argument"
                        )
            else:
                break
コード例 #4
0
class Simulator(SimulatorBase):
    EVENT_QUEUE_THRESHOLD = 100

    def __init__(self):
        self._sim_modules = {}
        self._module_type_map = defaultdict(deque)

        self._device_state = DeviceState()
        self._event_queue = PriorityQueue()

        self._current_time = None
        self._warmup_period = None

        self._event_listeners = defaultdict(deque)
        self._trace_reader = None
        self._trace_executed = False
        self._verbose = False
        self._debug_mode = False
        self._debug_interval = 1
        self._debug_interval_cnt = 0

    def has_module_instance(self, name):
        return name in self._sim_modules

    def get_module_instance(self, name):
        return self._sim_modules[name]

    def get_module_for_type(self, module_type):
        if module_type in self._module_type_map:
            return self._module_type_map[module_type.value][0]
        else:
            return None

    def register(self, sim_module, override=False):
        if not isinstance(sim_module, SimModule):
            raise TypeError("Expected SimModule object")

        if sim_module.get_name() in self._sim_modules:
            raise Exception("Module %s already exists" % sim_module.get_name())

        self._sim_modules[sim_module.get_name()] = sim_module

        if override:
            self._module_type_map[sim_module.get_type().value].appendleft(sim_module)
        else:
            self._module_type_map[sim_module.get_type().value].append(sim_module)

    def build(self, args):
        self._verbose = args.verbose
        self._debug_mode = args.debug

        # Instantiate necessary modules based on config files
        config = configparser.ConfigParser()
        config.read(args.sim_config)

        config['DEFAULT'] = {'modules': '', 'warmup_period': ''}

        if 'Simulator' not in config:
            raise Exception("Simulator section missing from config file")

        sim_settings = config['Simulator']

        # Identify the set of modules to include
        modules_str = sim_settings['modules']
        if modules_str:
            modules_list = modules_str.split(' ')
        else:
            modules_list = []

        self._warmup_period = \
            self.__parse_warmup_setting(sim_settings['warmup_period'])

        # Setup the trace file reader and initial simulator time
        self._trace_reader = get_trace_reader(args.trace)
        self._trace_reader.build()
        self._trace_executed = False
        self._current_time = self._trace_reader.get_start_time()

        for module_name in modules_list:
            module_settings = {}
            if module_name in config:
                module_settings = config[module_name]

            self.register(get_simulator_module(module_name, self, module_settings))

        # Build list of modules
        for sim_module in self._sim_modules.values():
            sim_module.build()

    def run(self):
        # Check if we need to enter debug mode immediately
        if self._debug_mode:
            self._debug_interval_cnt = 0
            self.__debug()

        # Add alarm event for the warmup period
        warmup_finish_alarm = SimAlarm(
            timestamp=self._trace_reader.get_start_time() + self._warmup_period,
            handler=self.__enable_stats_collection,
            name='Warmup Period Alarm')
        self._event_queue.push(warmup_finish_alarm,
                               (warmup_finish_alarm.timestamp, Priority.SIMULATOR))

        while not self._trace_reader.end_of_trace() \
                or not self._event_queue.empty():

            # Populate event queue if it is below the threshold number of events
            if self._event_queue.size() < Simulator.EVENT_QUEUE_THRESHOLD \
                    and not self._trace_reader.end_of_trace():
                self.__populate_event_queue_from_trace()
                continue

            # Look at next event to execute
            cur_event = self._event_queue.peek()

            # Look at next event from trace file
            trace_event = self._trace_reader.peek_event()

            # If trace event is supposed to occur before current
            # event, than we should populate event queue with more
            # events from the trace file
            if trace_event and cur_event.timestamp > trace_event.timestamp:
                self.__populate_event_queue_from_trace()
                continue

            self._event_queue.pop()

            # Set current time of simulator
            self._current_time = cur_event.timestamp
            if self._verbose:
                print(cur_event)

            if self._debug_mode:
                self._debug_interval_cnt += 1
                if self._debug_interval_cnt == self._debug_interval:
                    self.__debug()
                    self._debug_interval_cnt = 0

            self.__execute_event(cur_event)
        self.__finish()

    def subscribe(self, event_type, handler, event_filter=None):
        if event_type not in self._event_listeners:
            self._event_listeners[event_type] = []
        self._event_listeners[event_type].append((event_filter, handler))

    def broadcast(self, event):
        if event.timestamp:
            if event.timestamp != self._current_time:
                raise Exception("Broadcasting event with invalid timestamp.")
        else:
            event.timestamp = self._current_time

        # Get the set of listeners for the given event type
        listeners = self._event_listeners[event.event_type]
        for (event_filter, handler) in listeners:
            # Send event to each subscribed listener
            if not event_filter or event_filter(event):
                handler(event)

    def register_alarm(self, alarm):
        self._event_queue.push(alarm, (alarm.timestamp, Priority.ALARM))

    def get_current_time(self):
        return self._current_time

    def get_device_state(self):
        return self._device_state

    def __parse_warmup_setting(self, setting_value):
        if setting_value:
            if setting_value.endswith('h'):
                num_hours = int(setting_value[:-1])
                return datetime.timedelta(hours=num_hours)
            raise Exception("Invalid warmup period setting format")
        else:
            return datetime.timedelta()

    def __enable_stats_collection(self):
        for sim_module in self._sim_modules.values():
            sim_module.enable_stats_collection()

    def __disable_stats_collection(self):
        for sim_module in self._sim_modules.values():
            sim_module.disable_stats_collection()

    """
        Private method that handles execution of
        an event object.
    """
    def __execute_event(self, event):
        if event.event_type == EventType.SIM_DEBUG:
            self.__debug()
        elif event.event_type == EventType.SIM_ALARM:
            if not self._trace_executed:
                event.fire()
                if event.is_repeating():
                    self._event_queue.push(event, (event.timestamp, Priority.ALARM))
        elif event.event_type == EventType.TRACE_END:
            self._trace_executed = True
        else:
            self.broadcast(event)

    def __populate_event_queue_from_trace(self):
        # Fill in event queue from trace
        events = self._trace_reader.get_events(count=Simulator.EVENT_QUEUE_THRESHOLD)
        for x in events:
            self._event_queue.push(x, (x.timestamp, Priority.TRACE))

    def __finish(self):
        output_file = sys.stdout
        # Print status from all modules
        for sim_module in self._sim_modules.values():
            header = "======== %s Stats ========\n" % sim_module.get_name()
            footer = "=" * (len(header) - 1) + '\n'
            output_file.write(header)
            sim_module.print_stats(output_file)
            output_file.write(footer)

        # Call finish for all modules
        for sim_module in self._sim_modules.values():
            sim_module.finish()

    def __debug(self):
        while True:
            command = input("(uamp-sim debug) $ ")
            if command:
                tokens = command.split(sep=' ')
                cmd = tokens[0]
                args = tokens[1:]
                if cmd == 'quit' or cmd == 'exit' or cmd == 'q':
                    # TODO(dmanatunga): Handle simulation quitting better
                    print("Terminating Simulation")
                    exit(1)
                elif cmd == 'interval':
                    if len(args) == 1:
                        try:
                            self._debug_interval = int(args[0])
                        except ValueError:
                            print("Command Usage Error: interval command expects one numerical value")
                    else:
                        print("Command Usage Error: interval command expects one numerical value")
                elif cmd == 'verbose':
                    if len(args) == 0:
                        self._verbose = True
                    elif len(args) == 1:
                        if args[0] == 'on':
                            self._verbose = True
                        elif args[0] == 'off':
                            self._verbose = False
                        else:
                            print("Command Usage Error: verbose command expects 'on' or 'off' for argument")

                    else:
                        print("Command Usage Error: verbose command expects at most one argument")
            else:
                break