def _parse_implicit(self, args, targets, applications, measurements): targ_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) for flag in 'impl_targets', 'impl_applications', 'impl_measurements': for name in getattr(args, flag, []): tar = targ_ctrl.one({"name": name}) app = app_ctrl.one({"name": name}) mes = meas_ctrl.one({"name": name}) tam = set([tar, app, mes]) - set([None]) if len(tam) > 1: self.parser.error( "'%s' is ambiguous. Please use --target, --application," " or --measurement to specify configuration type" % name) elif len(tam) == 0: self.parser.error( "'%s' is not a target, application, or measurement" % name) elif tar: targets.add(tar) elif app: applications.add(app) elif mes: measurements.add(mes)
def _parse_implicit(self, args): targets = set() applications = set() measurements = set() experiments = set() targ_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) expr_ctrl = Experiment.controller(PROJECT_STORAGE) for flag in 'impl_experiment', 'impl_project', 'impl_target', 'impl_application', 'impl_measurement': for name in getattr(args, flag, []): tar = targ_ctrl.one({"name": name}) app = app_ctrl.one({"name": name}) mes = meas_ctrl.one({"name": name}) expr = expr_ctrl.one({"name": name}) found = set([tar, app, mes, expr]) - set([None]) if len(found) > 1: self.parser.error("'%s' is ambiguous. " "Please use a command line flag to specify configuration type." % name) elif len(found) == 0: self.parser.error("'%s' is not an experiment, target, application, or measurement." % name) elif tar: targets.add(tar) elif app: applications.add(app) elif mes: measurements.add(mes) elif expr: experiments.add(expr) return targets, applications, measurements, experiments
def main(self, argv): args = self._parse_args(argv) proj_ctrl = Project.controller() proj = proj_ctrl.selected() targ = Target.controller(proj_ctrl.storage).one({'name': args.target}) if targ is None: self.parser.error("A target with name %s does not exist." % args.target) app = Application.controller(proj_ctrl.storage).one( {'name': args.application}) if app is None: self.parser.error("An application with name %s does not exist." % args.application) meas = Measurement.controller(proj_ctrl.storage).one( {'name': args.measurement}) if meas is None: self.parser.error("A measurement with name %s does not exist." % args.measurement) data = { 'name': args.name, 'project': proj.eid, 'target': targ.eid, 'application': app.eid, 'measurement': meas.eid } return self._create_record(PROJECT_STORAGE, data)
def _parse_implicit(self, args): targets = set() applications = set() measurements = set() experiments = set() targ_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) expr_ctrl = Experiment.controller(PROJECT_STORAGE) for flag in 'impl_experiment', 'impl_project', 'impl_target', 'impl_application', 'impl_measurement': for name in getattr(args, flag, []): tar = targ_ctrl.one({"name": name}) app = app_ctrl.one({"name": name}) mes = meas_ctrl.one({"name": name}) expr = expr_ctrl.one({"name": name}) found = {tar, app, mes, expr} - {None} if len(found) > 1: self.parser.error( "'%s' is ambiguous. " "Please use a command line flag to specify configuration type." % name) elif not found: self.parser.error( "'%s' is not an experiment, target, application, or measurement." % name) elif tar: targets.add(tar) elif app: applications.add(app) elif mes: measurements.add(mes) elif expr: experiments.add(expr) return targets, applications, measurements, experiments
def main(self, argv): from taucmdr.cli.commands.project.list import COMMAND as project_list args = self._parse_args(argv) tar_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) proj_ctrl = Project.controller() project_name = args.name project = proj_ctrl.one({'name': project_name}) if not project: self.parser.error("'%s' is not a project name. Type `%s` to see valid names." % (project_name, project_list.command)) updates = dict(project.element) updates['name'] = getattr(args, 'new_name', project_name) targets = set(project['targets']) applications = set(project['applications']) measurements = set(project['measurements']) added = self._parse_add_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) removed = self._parse_remove_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) updates['targets'] = list(targets) updates['applications'] = list(applications) updates['measurements'] = list(measurements) try: force_tau_options = args.force_tau_options except AttributeError: pass else: # Unset force_tau_options if it was already set and --force-tau-options=none if updates.pop('force_tau_options', False) and [i.lower().strip() for i in force_tau_options] == ['none']: proj_ctrl.unset(['force_tau_options'], {'name': project_name}) self.logger.info("Removed 'force-tau-options' from project configuration '%s'.", project_name) else: updates['force_tau_options'] = force_tau_options self.logger.info("Added 'force-tau-options' to project configuration '%s'.", project_name) proj_ctrl.update(updates, {'name': project_name}) for model in added: self.logger.info("Added %s '%s' to project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) for model in removed: self.logger.info("Removed %s '%s' from project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) return EXIT_SUCCESS
def main(self, argv): args = self._parse_args(argv) proj_ctrl = Project.controller() proj = proj_ctrl.selected() targ = Target.controller(proj_ctrl.storage).one({'name': args.target}) if targ is None: self.parser.error("A target with name %s does not exist." %args.target) app = Application.controller(proj_ctrl.storage).one({'name': args.application}) if app is None: self.parser.error("An application with name %s does not exist." %args.application) meas = Measurement.controller(proj_ctrl.storage).one({'name': args.measurement}) if meas is None: self.parser.error("A measurement with name %s does not exist." %args.measurement) data = {'name': args.name, 'project': proj.eid, 'target': targ.eid, 'application': app.eid, 'measurement': meas.eid} return self._create_record(PROJECT_STORAGE, data)
def main(self, argv): from taucmdr.cli.commands.project.list import COMMAND as project_list args = self._parse_args(argv) tar_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) proj_ctrl = Project.controller() project_name = args.name project = proj_ctrl.one({'name': project_name}) if not project: self.parser.error( "'%s' is not a project name. Type `%s` to see valid names." % (project_name, project_list.command)) updates = dict(project) updates['name'] = getattr(args, 'new_name', project_name) targets = set(project['targets']) applications = set(project['applications']) measurements = set(project['measurements']) added = self._parse_add_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) removed = self._parse_remove_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) updates['targets'] = list(targets) updates['applications'] = list(applications) updates['measurements'] = list(measurements) proj_ctrl.update(updates, {'name': project_name}) for model in added: self.logger.info("Added %s '%s' to project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) for model in removed: self.logger.info( "Removed %s '%s' from project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) return EXIT_SUCCESS
def _parse_implicit(self, args, targets, applications, measurements): targ_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) for flag in 'impl_targets', 'impl_applications', 'impl_measurements': for name in getattr(args, flag, []): tar = targ_ctrl.one({"name": name}) app = app_ctrl.one({"name": name}) mes = meas_ctrl.one({"name": name}) tam = set([tar, app, mes]) - set([None]) if len(tam) > 1: self.parser.error("'%s' is ambiguous. Please use --target, --application," " or --measurement to specify configuration type" % name) elif len(tam) == 0: self.parser.error("'%s' is not a target, application, or measurement" % name) elif tar: targets.add(tar) elif app: applications.add(app) elif mes: measurements.add(mes)
def main(self, argv): from taucmdr.cli.commands.project.list import COMMAND as project_list args = self._parse_args(argv) tar_ctrl = Target.controller(PROJECT_STORAGE) app_ctrl = Application.controller(PROJECT_STORAGE) meas_ctrl = Measurement.controller(PROJECT_STORAGE) proj_ctrl = Project.controller() project_name = args.name project = proj_ctrl.one({'name': project_name}) if not project: self.parser.error("'%s' is not a project name. Type `%s` to see valid names." % (project_name, project_list.command)) updates = dict(project) updates['name'] = getattr(args, 'new_name', project_name) targets = set(project['targets']) applications = set(project['applications']) measurements = set(project['measurements']) added = self._parse_add_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) removed = self._parse_remove_args(args, tar_ctrl, app_ctrl, meas_ctrl, targets, applications, measurements) updates['targets'] = list(targets) updates['applications'] = list(applications) updates['measurements'] = list(measurements) proj_ctrl.update(updates, {'name': project_name}) for model in added: self.logger.info("Added %s '%s' to project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) for model in removed: self.logger.info("Removed %s '%s' from project configuration '%s'.", model.name.lower(), model[model.key_attribute], project_name) return EXIT_SUCCESS
def _populate_project(self, args): # Create default application application_name = args.application_name cmd_args = Application.filter_arguments(args) cmd_args.name = application_name cmd_args.openmp = bool(args.openmp) if args.openmp is None: args.openmp = 'ignore' self._safe_execute(application_create_cmd, cmd_args) # Create default target target_name = args.target_name cmd_args = Target.filter_arguments(args) cmd_args.name = target_name self._safe_execute(target_create_cmd, cmd_args) # Target was created so let's see if we can use binutils on this target. targ = Target.controller(PROJECT_STORAGE).one({'name': target_name}) if not targ['binutils_source']: self.logger.info("GNU binutils unavailable: disabling sampling and compiler-based instrumentation") args.sample = False args.compiler_inst = 'never' # Create default measurements measurements = [] if args.profile != 'none': self._create_measurement( 'baseline', args, baseline=True, profile='tau', trace='none', sample=False, source_inst='never', compiler_inst='never', mpi=False, cuda=False, opencl=False, openmp='ignore', shmem=False, track_memory_footprint=False, callsite=False, comm_matrix=False, heap_usage=False, memory_alloc=False) if args.sample: measurements.append(self._create_measurement( 'sample', args, profile=args.profile, trace='none', sample=True, source_inst='never', compiler_inst='never')) if args.source_inst != 'never' or args.compiler_inst != 'never': measurements.append(self._create_measurement( 'profile', args, profile=args.profile, trace='none', sample=False, source_inst=args.source_inst, compiler_inst=args.compiler_inst)) if args.source_inst != 'never': measurements.append(self._create_measurement( 'source-inst', args, profile=args.profile, trace='none', sample=False, source_inst=args.source_inst, compiler_inst='never')) if args.compiler_inst != 'never': measurements.append(self._create_measurement( 'compiler-inst', args, profile=args.profile, trace='none', sample=False, source_inst='never', compiler_inst='always')) if args.trace != 'none': if args.source_inst != 'never' or args.compiler_inst != 'never': measurements.append(self._create_measurement( 'trace', args, profile='none', trace=args.trace, callpath=0, sample=False, source_inst=args.source_inst, compiler_inst=args.compiler_inst)) try: measurement_name = measurements[0] except IndexError: measurement_name = 'baseline' # Create default experiment select_cmd.main(['--target', target_name, '--application', application_name, '--measurement', measurement_name])
def attributes(): """Construct attributes dictionary for the measurement model. We build the attributes in a function so that classes like ``taucmdr.module.project.Project`` are fully initialized and usable in the returned dictionary. Returns: dict: Attributes dictionary. """ from taucmdr.model.project import Project from taucmdr.model.target import Target from taucmdr.model.application import Application from taucmdr.cf.platforms import HOST_OS, DARWIN, IBM_CNK from taucmdr.cf.compiler.mpi import MPI_CC, MPI_CXX, MPI_FC from taucmdr.cf.compiler.shmem import SHMEM_CC, SHMEM_CXX, SHMEM_FC def _merged_profile_compat(lhs, lhs_attr, lhs_value, rhs): if isinstance(rhs, Application): if not (rhs['mpi'] or rhs['shmem']): lhs_name = lhs.name.lower() rhs_name = rhs.name.lower() raise IncompatibleRecordError( "%s = %s in %s requires either mpi = True or shmem = True in %s" % (lhs_attr, lhs_value, lhs_name, rhs_name)) def _discourage_callpath(lhs, lhs_attr, lhs_value, rhs): if isinstance(rhs, Measurement): if rhs.get('callpath', 0) > 0: lhs_name = lhs.name.lower() rhs_name = rhs.name.lower() LOGGER.warning( "%s = %s in %s recommends against callpath > 0 in %s", lhs_attr, lhs_value, lhs_name, rhs_name) def _ensure_instrumented(lhs, lhs_attr, lhs_value, rhs): if isinstance(rhs, Measurement): if rhs.get('source_inst') == 'never' and rhs.get( 'compiler_inst') == 'never': lhs_name = lhs.name.lower() rhs_name = rhs.name.lower() raise IncompatibleRecordError( "%s = %s in %s requires source_inst and compiler_inst are not both 'never' in %s" % (lhs_attr, lhs_value, lhs_name, rhs_name)) return { 'projects': { 'collection': Project, 'via': 'measurements', 'description': "projects using this measurement" }, 'name': { 'primary_key': True, 'type': 'string', 'unique': True, 'description': "measurement configuration name", }, 'baseline': { 'type': 'boolean', 'default': False, 'description': "completely disable all instrumentation and measure wall clock time via the OS", 'argparse': { 'flags': ('--baseline', ), 'group': 'instrumentation' }, 'compat': { True: (Measurement.require('profile', 'tau'), Measurement.require('trace', 'none')) } }, 'profile': { 'type': 'string', 'default': 'tau', 'description': "generate application profiles", 'argparse': { 'flags': ('--profile', ), 'group': 'output format', 'metavar': '<format>', 'nargs': '?', 'choices': ('tau', 'merged', 'cubex', 'none'), 'const': 'tau' }, 'compat': { 'cubex': Target.exclude('scorep_source', None), 'merged': _merged_profile_compat }, 'rebuild_required': True }, 'trace': { 'type': 'string', 'default': 'none', 'description': "generate application traces", 'argparse': { 'flags': ('--trace', ), 'group': 'output format', 'metavar': '<format>', 'nargs': '?', 'choices': ('slog2', 'otf2', 'none'), 'const': 'otf2' }, 'compat': { 'otf2': Target.exclude('libotf2_source', None), lambda x: x != 'none': _discourage_callpath }, 'rebuild_required': True }, 'sample': { 'type': 'boolean', 'default': HOST_OS not in (DARWIN, IBM_CNK), 'description': "use event-based sampling to gather performance data", 'argparse': { 'flags': ('--sample', ), 'group': 'instrumentation' }, 'compat': { True: (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.encourage('libunwind_source'), Target.discourage('libunwind_source', None), Target.exclude('host_os', DARWIN), Measurement.exclude('baseline', True)) } }, 'source_inst': { 'type': 'string', 'default': 'never' if HOST_OS is not DARWIN else 'automatic', 'description': "use hooks inserted into the application source code to gather performance data", 'argparse': { 'flags': ('--source-inst', ), 'group': 'instrumentation', 'metavar': 'mode', 'nargs': '?', 'choices': ('automatic', 'manual', 'never'), 'const': 'automatic' }, 'compat': { lambda x: x in ('automatic', 'manual'): (Target.exclude('pdt_source', None), Measurement.exclude('baseline', True)) }, 'rebuild_required': True }, 'compiler_inst': { 'type': 'string', 'default': 'never', 'description': "use compiler-generated callbacks to gather performance data", 'argparse': { 'flags': ('--compiler-inst', ), 'group': 'instrumentation', 'metavar': 'mode', 'nargs': '?', 'choices': ('always', 'fallback', 'never'), 'const': 'always' }, 'compat': { lambda x: x in ('always', 'fallback'): (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.require('libunwind_source'), Target.exclude('libunwind_source', None), Target.exclude('host_os', DARWIN), Measurement.exclude('baseline', True)) }, 'rebuild_required': True }, 'mpi': { 'type': 'boolean', 'default': False, 'description': 'use MPI library wrapper to measure time spent in MPI methods', 'argparse': { 'flags': ('--mpi', ) }, 'compat': { True: (Target.require(MPI_CC.keyword), Target.require(MPI_CXX.keyword), Target.require(MPI_FC.keyword), Application.require('mpi', True), Measurement.exclude('baseline', True)) }, 'rebuild_required': True }, 'openmp': { 'type': 'string', 'default': 'ignore', 'description': 'use specified library to measure time spent in OpenMP directives', 'argparse': { 'flags': ('--openmp', ), 'metavar': 'library', 'choices': ('ignore', 'opari', 'ompt'), 'nargs': '?', 'const': 'ompt' }, 'compat': { 'opari': (Application.require('openmp', True), Measurement.exclude('baseline', True)), 'ompt': (Application.require('openmp', True), Measurement.exclude('baseline', True)) }, 'rebuild_required': True }, 'cuda': { 'type': 'boolean', 'default': False, 'description': 'measure cuda events via the CUPTI interface', 'argparse': { 'flags': ('--cuda', ) }, 'compat': { True: (Target.require('cuda_toolkit'), Application.require('cuda', True), Measurement.exclude('baseline', True)) }, }, 'shmem': { 'type': 'boolean', 'default': False, 'description': 'use SHMEM library wrapper to measure time spent in SHMEM methods', 'argparse': { 'flags': ('--shmem', ) }, 'compat': { True: (Target.require(SHMEM_CC.keyword), Target.require(SHMEM_CXX.keyword), Target.require(SHMEM_FC.keyword), Application.require('shmem', True), Measurement.exclude('baseline', True)) }, 'rebuild_required': True }, 'opencl': { 'type': 'boolean', 'default': False, 'description': 'measure OpenCL events', 'argparse': { 'flags': ('--opencl', ) }, 'compat': { True: (Target.require('cuda_toolkit'), Application.require('opencl', True), Measurement.exclude('baseline', True)) }, }, 'callpath': { 'type': 'integer', 'default': 100, 'description': 'maximum depth for callpath recording', 'argparse': { 'flags': ('--callpath', ), 'group': 'data', 'metavar': 'depth', 'nargs': '?', 'const': 100 } }, 'unwind_depth': { 'type': 'integer', 'default': 0, 'description': 'Record callstack to specified depth', 'argparse': { 'flags': ('--unwind-depth', ), 'group': 'data', 'metavar': 'depth', 'nargs': '?', 'const': 10 }, 'compat': { (lambda unwind: unwind > 0): Measurement.exclude('sample', False) } }, 'io': { 'type': 'boolean', 'default': False, 'description': 'measure time spent in POSIX I/O calls', 'argparse': { 'flags': ('--io', ) }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'heap_usage': { 'type': 'boolean', 'default': False, 'description': 'measure heap memory usage', 'argparse': { 'flags': ('--heap-usage', ), 'group': 'memory' }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'system_load': { 'type': 'boolean', 'default': False, 'description': 'measure system load', 'argparse': { 'flags': ('--system-load', ), 'group': 'data' }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'memory_alloc': { 'type': 'boolean', 'default': False, 'description': 'record memory allocation/deallocation events and detect leaks', 'argparse': { 'flags': ('--memory-alloc', ), 'group': 'memory' }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'metrics': { 'type': 'array', 'default': ['TIME'], 'description': 'a space separated list of performance metrics to gather, e.g. TIME PAPI_FP_INS', 'argparse': { 'flags': ('--metrics', ), 'group': 'data', 'metavar': '<metric>' }, 'compat': { lambda metrics: bool( len([met for met in metrics if 'PAPI' in met])): (Target.require('papi_source'), Target.exclude('papi_source', None)), lambda x: x != ['TIME']: Measurement.exclude('baseline', True) }, 'rebuild_required': True }, 'keep_inst_files': { 'type': 'boolean', 'default': False, 'description': "don't remove instrumented files after compilation", 'argparse': { 'flags': ('--keep-inst-files', ), 'group': 'instrumentation' }, 'compat': { True: Measurement.exclude('source_inst', 'never') } }, 'reuse_inst_files': { 'type': 'boolean', 'default': False, 'description': 'reuse and preserve instrumented files after compilation', 'argparse': { 'flags': ('--reuse-inst-files', ), 'group': 'instrumentation' }, 'compat': { True: Measurement.exclude('source_inst', 'never') } }, 'comm_matrix': { 'type': 'boolean', 'default': False, 'description': 'record the point-to-point communication matrix', 'argparse': { 'flags': ('--comm-matrix', ) }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'throttle': { 'type': 'boolean', 'default': True, 'description': 'throttle lightweight events to reduce overhead', 'argparse': { 'flags': ('--throttle', ) }, }, 'throttle_per_call': { 'type': 'integer', 'default': 10, 'description': 'lightweight event duration threshold in microseconds', 'argparse': { 'flags': ('--throttle-per-call', ), 'metavar': 'us', 'nargs': '?', 'const': 10 }, }, 'throttle_num_calls': { 'type': 'integer', 'default': 100000, 'description': 'lightweight event call count threshold', 'argparse': { 'flags': ('--throttle-num-calls', ), 'metavar': 'count', 'nargs': '?', 'const': 100000 }, }, 'sampling_period': { 'type': 'integer', 'default': 5000, 'description': 'default sampling period in microseconds', 'argparse': { 'flags': ('--sampling-period', ), 'metavar': 'us', 'nargs': '?', 'const': 5000 }, 'compat': { True: (Measurement.require('sample', True)) }, }, 'track_memory_footprint': { 'type': 'boolean', 'default': False, 'description': 'track memory footprint', 'argparse': { 'flags': ('--track-memory-footprint', ), 'group': 'memory' }, 'compat': { True: Measurement.exclude('baseline', True) }, }, 'metadata_merge': { 'type': 'boolean', 'default': True, 'description': 'merge metadata of TAU profiles', 'argparse': { 'flags': ('--metadata-merge', ) }, }, 'callsite': { 'type': 'boolean', 'default': False, 'description': 'record event callsites', 'argparse': { 'flags': ('--callsite', ) }, 'compat': { True: (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.encourage('libunwind_source'), Target.discourage('libunwind_source', None), Target.exclude('host_os', DARWIN), Measurement.exclude('baseline', True)) } }, 'select_file': { 'type': 'string', 'description': 'specify selective instrumentation file', 'argparse': { 'flags': ('--select-file', ), 'metavar': 'path' }, 'compat': { bool: (_ensure_instrumented, Application.discourage('linkage', 'static'), Measurement.discourage('throttle', True)) }, 'rebuild_required': True }, 'update_nightly': { 'type': 'boolean', 'default': False, 'description': 'Download newest TAU nightly', 'argparse': { 'flags': ('--update-nightly', ) }, 'compat': { bool: (Target.require('tau_source', 'nightly')) }, }, 'ptts': { 'type': 'boolean', 'default': False, 'description': 'enable support for PTTS', 'argparse': { 'flags': ('--ptts', ) }, }, 'ptts_post': { 'type': 'boolean', 'default': False, 'description': 'skip application sampling and post-process existing PTTS sample files', 'argparse': { 'flags': ('--ptts-post', ) }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'ptts_sample_flags': { 'type': 'string', 'default': '', #None, 'description': 'flags to pass to PTTS sample_ts command', 'argparse': { 'flags': ('--ptts-sample-flags', ), 'metavar': 'sample_flags' }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'ptts_restart': { 'type': 'boolean', 'default': False, 'description': 'enable restart support within PTTS, allowing application to continue running and be reinstrumented after stop', 'argparse': { 'flags': ('--ptts-restart', ) }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'ptts_start': { 'type': 'string', 'default': '', #None, 'description': 'address at which to start a PTTS sampling region', 'argparse': { 'flags': ('--ptts-start', ) }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'ptts_stop': { 'type': 'string', 'default': '', #None, 'description': 'address at which to stop a PTTS sampling region', 'argparse': { 'flags': ('--ptts-stop', ) }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'ptts_report_flags': { 'type': 'string', 'default': '', #None, 'description': 'flags to pass to PTTS report_ts command', 'argparse': { 'flags': ('--ptts-report-flags', ) }, 'compat': { bool: (Measurement.require('ptts', True)) }, }, 'extra_tau_options': { 'type': 'string', 'description': 'forcibly add to the TAU_OPTIONS environment variable (not recommended)', 'rebuild_on_change': True, 'argparse': { 'flags': ('--extra-tau-options', ), 'nargs': '+', 'metavar': '<option>' }, 'compat': { bool: (Measurement.discourage('extra_tau_options'), Measurement.exclude('baseline', True)) } }, 'mpit': { 'type': 'boolean', 'default': False, 'description': 'MPI-T profiling interface', 'argparse': { 'flags': ('--mpit', ) }, }, 'force_tau_options': { 'type': 'array', 'description': "forcibly set the TAU_OPTIONS environment variable (not recommended)", 'rebuild_on_change': True, 'argparse': { 'flags': ('--force-tau-options', ), 'nargs': '+', 'metavar': '<option>' }, 'compat': { bool: (Measurement.discourage('force_tau_options'), Measurement.exclude('extra_tau_options'), Measurement.exclude('baseline', True)) } }, 'tag': { 'type': 'string', 'description': "Narrow search for tags", 'default': '', #None, 'argparse': { 'flags': ('--tag', ), 'nargs': '+', 'metavar': '<tags>' } }, 'extra_tau_options': { 'type': 'array', 'description': "append extra options to TAU_OPTIONS environment variable (not recommended)", 'rebuild_on_change': True, 'argparse': { 'flags': ('--extra-tau-options', ), 'nargs': '+', 'metavar': '<option>' }, 'compat': { bool: (Measurement.discourage('extra_tau_options'), Measurement.exclude('force_tau_options'), Measurement.exclude('baseline', True)) } } }
def attributes(): """Construct attributes dictionary for the measurement model. We build the attributes in a function so that classes like ``taucmdr.module.project.Project`` are fully initialized and usable in the returned dictionary. Returns: dict: Attributes dictionary. """ from taucmdr.model.project import Project from taucmdr.model.target import Target from taucmdr.model.application import Application from taucmdr.cf.platforms import HOST_OS, DARWIN, IBM_CNK from taucmdr.cf.compiler.mpi import MPI_CC, MPI_CXX, MPI_FC from taucmdr.cf.compiler.shmem import SHMEM_CC, SHMEM_CXX, SHMEM_FC def _merged_profile_compat(lhs, lhs_attr, lhs_value, rhs): if isinstance(rhs, Application): if not (rhs['mpi'] or rhs['shmem']): lhs_name = lhs.name.lower() rhs_name = rhs.name.lower() raise IncompatibleRecordError("%s = %s in %s requires either mpi = True or shmem = True in %s" % (lhs_attr, lhs_value, lhs_name, rhs_name)) def _discourage_callpath(lhs, lhs_attr, lhs_value, rhs): if isinstance(rhs, Measurement): if rhs.get('callpath', 0) > 0: lhs_name = lhs.name.lower() rhs_name = rhs.name.lower() LOGGER.warning("%s = %s in %s recommends against callpath > 0 in %s", lhs_attr, lhs_value, lhs_name, rhs_name) return { 'projects': { 'collection': Project, 'via': 'measurements', 'description': "projects using this measurement" }, 'name': { 'primary_key': True, 'type': 'string', 'unique': True, 'description': "measurement configuration name", }, 'profile': { 'type': 'string', 'default': 'tau', 'description': "generate application profiles", 'argparse': {'flags': ('--profile',), 'group': 'output format', 'metavar': '<format>', 'nargs': '?', 'choices': ('tau', 'merged', 'cubex', 'none'), 'const': 'tau'}, 'compat': {'cubex': (Target.exclude('scorep_source', None), Application.require('mpi', True), Measurement.require('mpi', True)), 'merged': _merged_profile_compat}, }, 'trace': { 'type': 'string', 'default': 'none', 'description': "generate application traces", 'argparse': {'flags': ('--trace',), 'group': 'output format', 'metavar': '<format>', 'nargs': '?', 'choices':('slog2', 'otf2', 'none'), 'const': 'otf2'}, 'compat': {'otf2': Target.exclude('libotf2_source', None), lambda x: x != 'none': _discourage_callpath} }, 'sample': { 'type': 'boolean', 'default': HOST_OS not in (DARWIN, IBM_CNK), 'description': "use event-based sampling to gather performance data", 'argparse': {'flags': ('--sample',), 'group': 'instrumentation'}, 'compat': {True: (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.encourage('libunwind_source'), Target.discourage('libunwind_source', None), Target.exclude('host_os', DARWIN))} }, 'source_inst': { 'type': 'string', 'default': 'never' if HOST_OS is not DARWIN else 'automatic', 'description': "use hooks inserted into the application source code to gather performance data", 'argparse': {'flags': ('--source-inst',), 'group': 'instrumentation', 'metavar': 'mode', 'nargs': '?', 'choices': ('automatic', 'manual', 'never'), 'const': 'automatic'}, 'compat': {'automatic': Target.exclude('pdt_source', None)}, 'rebuild_required': True }, 'compiler_inst': { 'type': 'string', 'default': 'never', 'description': "use compiler-generated callbacks to gather performance data", 'argparse': {'flags': ('--compiler-inst',), 'group': 'instrumentation', 'metavar': 'mode', 'nargs': '?', 'choices': ('always', 'fallback', 'never'), 'const': 'always'}, 'compat': {lambda x: x in ('always', 'fallback'): (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.require('libunwind_source'), Target.exclude('libunwind_source', None), Target.exclude('host_os', DARWIN))}, 'rebuild_required': True }, 'link_only': { 'type': 'boolean', 'default': False, 'description': "don't instrument, only link the TAU library to the application", 'argparse': {'flags': ('--link-only',), 'group': 'instrumentation'}, 'rebuild_required': True }, 'mpi': { 'type': 'boolean', 'default': False, 'description': 'use MPI library wrapper to measure time spent in MPI methods', 'argparse': {'flags': ('--mpi',)}, 'compat': {True: (Target.require(MPI_CC.keyword), Target.require(MPI_CXX.keyword), Target.require(MPI_FC.keyword))}, 'rebuild_required': True }, 'openmp': { 'type': 'string', 'default': 'ignore', 'description': 'use specified library to measure time spent in OpenMP directives', 'argparse': {'flags': ('--openmp',), 'metavar': 'library', 'choices': ('ignore', 'opari', 'ompt')}, 'compat': {'opari': (Application.require('openmp', True), Measurement.discourage('source_inst', 'never')), 'ompt': Application.require('openmp', True)}, 'rebuild_required': True }, 'cuda': { 'type': 'boolean', 'default': False, 'description': 'measure cuda events via the CUPTI interface', 'argparse': {'flags': ('--cuda',)}, 'compat': {True: Target.require('cuda_toolkit')}, }, 'shmem': { 'type': 'boolean', 'default': False, 'description': 'use SHMEM library wrapper to measure time spent in SHMEM methods', 'argparse': {'flags': ('--shmem',)}, 'compat': {True: (Target.require(SHMEM_CC.keyword), Target.require(SHMEM_CXX.keyword), Target.require(SHMEM_FC.keyword))}, 'rebuild_required': True }, 'opencl': { 'type': 'boolean', 'default': False, 'description': 'measure OpenCL events', 'argparse': {'flags': ('--opencl',)}, 'compat': {True: (Target.require('cuda_toolkit'), Application.require('opencl'))}, }, 'callpath': { 'type': 'integer', 'default': 100, 'description': 'maximum depth for callpath recording', 'argparse': {'flags': ('--callpath',), 'group': 'data', 'metavar': 'depth', 'nargs': '?', 'const': 100} }, 'io': { 'type': 'boolean', 'default': False, 'description': 'measure time spent in POSIX I/O calls', 'argparse': {'flags': ('--io',)}, }, 'heap_usage': { 'type': 'boolean', 'default': False, 'description': 'measure heap memory usage', 'argparse': {'flags': ('--heap-usage',), 'group': 'memory'}, }, 'memory_alloc': { 'type': 'boolean', 'default': False, 'description': 'record memory allocation/deallocation events and detect leaks', 'argparse': {'flags': ('--memory-alloc',), 'group': 'memory'}, }, 'metrics': { 'type': 'array', 'default': ['TIME'], 'description': 'performance metrics to gather, e.g. TIME, PAPI_FP_INS', 'argparse': {'flags': ('--metrics',), 'group': 'data', 'metavar': '<metric>'}, 'compat': {lambda metrics: bool(len([met for met in metrics if 'PAPI' in met])): (Target.require('papi_source'), Target.exclude('papi_source', None))}, 'rebuild_required': True }, 'keep_inst_files': { 'type': 'boolean', 'default': False, 'description': "don't remove instrumented files after compilation", 'argparse': {'flags': ('--keep-inst-files',), 'group': 'instrumentation'}, 'compat': {True: Measurement.exclude('source_inst', 'never')} }, 'reuse_inst_files': { 'type': 'boolean', 'default': False, 'description': 'reuse and preserve instrumented files after compilation', 'argparse': {'flags': ('--reuse-inst-files',), 'group': 'instrumentation'}, 'compat': {True: Measurement.exclude('source_inst', 'never')} }, 'comm_matrix': { 'type': 'boolean', 'default': False, 'description': 'record the point-to-point communication matrix', 'argparse': {'flags': ('--comm-matrix',)} }, 'throttle': { 'type': 'boolean', 'default': True, 'description': 'throttle lightweight events to reduce overhead', 'argparse': {'flags': ('--throttle',)}, }, 'throttle_per_call': { 'type': 'integer', 'default': 10, 'description': 'lightweight event duration threshold in microseconds', 'argparse': {'flags': ('--throttle-per-call',), 'metavar': 'us', 'nargs': '?', 'const': 10}, }, 'throttle_num_calls': { 'type': 'integer', 'default': 100000, 'description': 'lightweight event call count threshold', 'argparse': {'flags': ('--throttle-num-calls',), 'metavar': 'count', 'nargs': '?', 'const': 100000}, }, 'metadata_merge': { 'type': 'boolean', 'default': True, 'description': 'merge metadata of TAU profiles', 'argparse': {'flags': ('--metadata-merge',)}, }, 'callsite': { 'type': 'boolean', 'default': False, 'description': 'record event callsites', 'argparse': {'flags': ('--callsite',)}, 'compat': {True: (Target.require('binutils_source'), Target.exclude('binutils_source', None), Target.encourage('libunwind_source'), Target.discourage('libunwind_source', None), Target.exclude('host_os', DARWIN))} }, }