diff options
Diffstat (limited to 'libs/wlgen/wlgen/rta.py')
-rw-r--r-- | libs/wlgen/wlgen/rta.py | 131 |
1 files changed, 25 insertions, 106 deletions
diff --git a/libs/wlgen/wlgen/rta.py b/libs/wlgen/wlgen/rta.py index 496435e..5223f6f 100644 --- a/libs/wlgen/wlgen/rta.py +++ b/libs/wlgen/wlgen/rta.py @@ -184,104 +184,25 @@ class RTA(Workload): for line in self.output['executor'].split('\n'): ofile.write(line+'\n') - def _getFirstBiggest(self, cpus): - # Non big.LITTLE system: - if 'bl' not in self.target.modules: - # return the first CPU of the last cluster - platform = self.target.platform - cluster_last = list(set(platform.core_clusters))[-1] - cluster_cpus = [cpu_id - for cpu_id, cluster_id in enumerate(platform.core_clusters) - if cluster_id == cluster_last] - # If CPUs have been specified': return the fist in the last cluster - if cpus: - for cpu_id in cpus: - if cpu_id in cluster_cpus: - return cpu_id - # Otherwise just return the first cpu of the last cluster - return cluster_cpus[0] - - # big.LITTLE system: - for c in cpus: - if c not in self.target.bl.bigs: - continue - return c - # Only LITTLE CPUs, thus: - # return the first possible cpu - return cpus[0] - - def _getFirstBig(self, cpus=None): - # Non big.LITTLE system: - if 'bl' not in self.target.modules: - return self._getFirstBiggest(cpus) - if cpus: - for c in cpus: - if c not in self.target.bl.bigs: - continue - return c - # Only LITTLE CPUs, thus: - # return the first big core of the system - if self.target.big_core: - # Big.LITTLE system - return self.target.bl.bigs[0] - return 0 - - def _getFirstLittle(self, cpus=None): - # Non big.LITTLE system: - if 'bl' not in self.target.modules: - # return the first CPU of the first cluster - platform = self.target.platform - cluster_first = list(set(platform.core_clusters))[0] - cluster_cpus = [cpu_id - for cpu_id, cluster_id in enumerate(platform.core_clusters) - if cluster_id == cluster_first] - # If CPUs have been specified': return the fist in the first cluster - if cpus: - for cpu_id in cpus: - if cpu_id in cluster_cpus: - return cpu_id - # Otherwise just return the first cpu of the first cluster - return cluster_cpus[0] - - # Try to return one LITTLE CPUs among the specified ones - if cpus: - for c in cpus: - if c not in self.target.bl.littles: - continue - return c - # Only big CPUs, thus: - # return the first LITTLE core of the system - if self.target.little_core: - # Big.LITTLE system - return self.target.bl.littles[0] - return 0 - - def getTargetCpu(self, loadref): + def getCalibrationConf(self): # Select CPU for task calibration, which is the first little # of big depending on the loadref tag if self.pload is not None: - if loadref and loadref.upper() == 'LITTLE': - target_cpu = self._getFirstLittle() - self._log.debug('ref on LITTLE cpu: %d', target_cpu) + if self.loadref and self.loadref.upper() == 'LITTLE': + return max(self.pload.values()) else: - target_cpu = self._getFirstBig() - self._log.debug('ref on big cpu: %d', target_cpu) - return target_cpu - - # These options are selected only when RTApp has not been - # already calibrated - if self.cpus is None: - target_cpu = self._getFirstBig() - self._log.debug('ref on cpu: %d', target_cpu) + return min(self.pload.values()) else: - target_cpu = self._getFirstBiggest(self.cpus) - self._log.debug('ref on (possible) biggest cpu: %d', target_cpu) - return target_cpu + cpus = self.cpus or range(self.target.number_of_cpus) + + target_cpu = cpus[-1] + if 'bl'in self.target.modules: + cluster = self.target.bl.bigs + candidates = sorted(set(self.target.bl.bigs).intersection(cpus)) + if candidates: + target_cpu = candidates[0] - def getCalibrationConf(self, target_cpu=0): - if self.pload is None: return 'CPU{0:d}'.format(target_cpu) - return self.pload[target_cpu] def _confCustom(self): @@ -294,18 +215,13 @@ class RTA(Workload): raise ValueError('value specified for \'params\' is not ' 'a valid rt-app JSON configuration file') - if self.duration is None: - raise ValueError('Workload duration not specified') - - target_cpu = self.getTargetCpu(self.loadref) - calibration = self.getCalibrationConf(target_cpu) - self._log.info('Loading custom configuration:') self._log.info(' %s', rtapp_conf) self.json = '{0:s}_{1:02d}.json'.format(self.name, self.exc_id) ofile = open(self.json, 'w') ifile = open(rtapp_conf, 'r') + calibration = self.getCalibrationConf() # Calibration can either be a string like "CPU1" or an integer, if the # former we need to quote it. if type(calibration) != int: @@ -319,6 +235,8 @@ class RTA(Workload): } for line in ifile: + if '__DURATION__' in line and self.duration is None: + raise ValueError('Workload duration not specified') for src, target in replacements.iteritems(): line = line.replace(src, target) ofile.write(line) @@ -344,7 +262,6 @@ class RTA(Workload): raise ValueError(msg) # Task configuration - target_cpu = self.getTargetCpu(self.loadref) self.rta_profile = { 'tasks': {}, 'global': {} @@ -354,13 +271,10 @@ class RTA(Workload): global_conf = { 'default_policy': 'SCHED_OTHER', 'duration': -1, - 'calibration': 'CPU'+str(target_cpu), + 'calibration': self.getCalibrationConf(), 'logdir': self.run_dir, } - # Setup calibration data - calibration = self.getCalibrationConf(target_cpu) - global_conf['calibration'] = calibration if self.duration is not None: global_conf['duration'] = self.duration self._log.warn('Limiting workload duration to %d [s]', @@ -411,13 +325,10 @@ class RTA(Workload): if 'delay' in task.keys(): if task['delay'] > 0: - task_conf['phases']['p000000'] = {} - task_conf['phases']['p000000']['delay'] = int(task['delay'] * 1e6) + task_conf['delay'] = int(task['delay'] * 1e6) self._log.info(' | start delay: %.6f [s]', task['delay']) - self._log.info(' | calibration CPU: %d', target_cpu) - if 'loops' not in task.keys(): task['loops'] = 1 task_conf['loop'] = task['loops'] @@ -607,6 +518,14 @@ class RTATask(object): return self._task def __add__(self, next_phases): + if next_phases._task.get('delay', 0): + # This won't work, because rt-app's "delay" field is per-task and + # not per-phase. We might be able to implement it by adding a + # "sleep" event here, but let's not bother unless such a need + # arises. + raise ValueError("Can't compose rt-app tasks " + "when the second has nonzero 'delay_s'") + self._task['phases'].extend(next_phases._task['phases']) return self |