def acquire_source(self, reuse_archive=True):
        """Acquires package source code archive file via download or file copy.

        If the package is configured to use an existing installation as the source then
        this routine does nothing.
        
        Args:
            reuse_archive (bool): If True don't download, just confirm that the archive exists.
            
        Returns:
            str: Absolute path to the source archive.
            
        Raises:
            ConfigurationError: Package source code not provided or couldn't be acquired.
        """
        if not self.src:
            raise ConfigurationError("No source code provided for %s" %
                                     self.title)
        if self.unmanaged:
            return self.src
        archive = self._acquire_source(reuse_archive)
        # Check that archive is valid by getting archive top-level directory
        try:
            util.archive_toplevel(archive)
        except IOError:
            if not reuse_archive:
                raise ConfigurationError(
                    "Unable to acquire %s source package '%s'" %
                    (self.name, self.src))
            return self.acquire_source(reuse_archive=False)
        return archive
Exemple #2
0
    def callback(lhs, lhs_attr, lhs_value, rhs, rhs_attr):
        """Compatibility checking callback for use with data models.

        Requires ``rhs[rhs_attr]`` to be a compiler in a certain compiler family.
        
        Args:
            lhs (Model): The model invoking `check_compatibility`.
            lhs_attr (str): Name of the attribute that defines the 'compat' property.
            lhs_value: Value of the attribute that defines the 'compat' property.
            rhs (Model): Model we are checking against (argument to `check_compatibility`).
            rhs_attr (str): The right-hand side attribute we are checking for compatibility.
            
        Raises:
            ConfigurationError: Invalid compiler family specified in target configuration.
        """
        lhs_name = lhs.name.lower()
        rhs_name = rhs.name.lower()
        msg = ("%s = %s in %s requires %s in %s to be a %s compiler" %
               (lhs_attr, lhs_value, lhs_name, rhs_attr, rhs_name, family))
        try:
            compiler_record = rhs.populate(rhs_attr)
        except KeyError:
            raise ConfigurationError("%s but it is undefined" % msg)
        given_family_name = compiler_record['family']
        if given_family_name != family.name:
            raise ConfigurationError(
                "%s but it is a %s compiler" % (msg, given_family_name),
                *hints)
Exemple #3
0
    def trials(self, trial_numbers=None):
        """Get a list of modeled trial records.

        If `bool(trial_numbers)` is False, return the most recent trial.
        Otherwise return a list of Trial objects for the given trial numbers.

        Args:
            trial_numbers (list): List of numbers of trials to retrieve.

        Returns:
            list: Modeled trial records.

        Raises:
            ConfigurationError: Invalid trial number or no trials in selected experiment.
        """
        trials = self.populate('trials')
        if not trials:
            raise ConfigurationError("No trials in experiment %s" % self['name'])
        if trial_numbers:
            all_numbers = set(trial['number'] for trial in trials)
            not_found = [i for i in trial_numbers if i not in all_numbers]
            if not_found:
                raise ConfigurationError("Experiment '%s' has no trial with number(s): %s." % 
                                         (self['name'], ", ".join(not_found)))
            return [trial for trial in trials if trial['number'] in trial_numbers]
        else:
            found = trials[0]
            for trial in trials[1:]:
                if trial['begin_time'] > found['begin_time']:
                    found = trial
            return [found]
 def _probe_wrapper(self):
     if not self.info.family.show_wrapper_flags:
         return None
     LOGGER.debug("Probing %s wrapper '%s'", self.info.short_descr,
                  self.absolute_path)
     cmd = [self.absolute_path] + self.info.family.show_wrapper_flags
     try:
         stdout = util.get_command_output(cmd)
     except CalledProcessError:
         # If this command didn't accept show_wrapper_flags then it's not a compiler wrapper to begin with,
         # i.e. another command just happens to be the same as a known compiler command.
         raise ConfigurationError(
             "'%s' isn't actually a %s since it doesn't accept arguments %s."
             % (self.absolute_path, self.info.short_descr,
                self.info.family.show_wrapper_flags))
     # Assume the longest line starting with a known compiler command is the wrapped compiler followed by arguments.
     known_commands = set(info.command for info in _CompilerInfo.all())
     for line in sorted(stdout.split('\n'), key=len, reverse=True):
         if not line:
             continue
         parts = line.split()
         wrapped_command = parts[0]
         wrapped_args = parts[1:]
         if os.path.basename(wrapped_command) not in known_commands:
             continue
         wrapped_absolute_path = util.which(wrapped_command)
         if not wrapped_absolute_path:
             continue
         if wrapped_absolute_path == self.absolute_path:
             # A wrapper that wraps itself isn't a wrapper, e.g. compilers that ignore invalid arguments
             # when version flags are present.
             return None
         try:
             wrapped = InstalledCompiler.probe(wrapped_command)
         except ConfigurationError:
             # wrapped_command might not be a real compiler command so keep trying
             continue
         # The wrapper must be able to perform the same role as the wrapped compiler
         role = self.info.role.keyword.split('_')[1:]
         wrapped_role = wrapped.info.role.keyword.split('_')[1:]
         if role != wrapped_role:
             raise ConfigurationError(
                 "Cannot use '%s' as a %s: wrapped compiler '%s' is a %s" %
                 (self.command, self.info.short_descr, wrapped.command,
                  wrapped.info.short_descr))
         LOGGER.info("%s '%s' wraps '%s'", self.info.short_descr,
                     self.absolute_path, wrapped.absolute_path)
         try:
             self._parse_wrapped_args(wrapped_args)
         except IndexError:
             LOGGER.warning(
                 "Unexpected output from compiler wrapper '%s'."
                 " TAU will attempt to continue but may fail later on.",
                 self.absolute_path)
         return wrapped
     return None
Exemple #5
0
 def main(self, argv):
     args = self._parse_args(argv)
     rewrite_packages = []
     if args.maqao:
         rewrite_packages.append('maqao')
     if args.dyninst:
         rewrite_packages.append('dyninst')
     if args.pebil:
         rewrite_packages.append('pebil')
     if len(rewrite_packages) == 0:
         raise ConfigurationError('Instrumentation package not specified.', 'Specify one of --dyninst, --maqao, or --pebil.')
     elif len(rewrite_packages) > 1:
         raise ConfigurationError('Only one instrumentation paclages should be specified.')
     expr = Project.selected().experiment()
     return expr.managed_rewrite(rewrite_packages[0], args.executable, args.inst_file)
Exemple #6
0
    def acquire_source(self, reuse_archive=True):
        """Acquires package source code archive file via download or file copy.

        If the package is configured to use an existing installation as the source then
        this routine does nothing.

        Args:
            reuse_archive (bool): If True don't download, just confirm that the archive exists.

        Returns:
            str: Absolute path to the source archive.

        Raises:
            ConfigurationError: Package source code not provided or couldn't be acquired.
        """
        if not self.src:
            raise ConfigurationError("No source code provided for %s" %
                                     self.title)
        if self.unmanaged:
            return self.src
        # Check that archive is valid by getting archive top-level directory
        while self.src:
            archive = self._acquire_source(reuse_archive)
            try:
                util.archive_toplevel(archive)
            except IOError:
                if reuse_archive:
                    archive = self.acquire_source(reuse_archive=False)
                    try:
                        util.archive_toplevel(archive)
                        return archive
                    except IOError:
                        pass
                try:
                    LOGGER.warning("Unable to acquire %s source package '%s'",
                                   self.name, self.src)
                    self.src = self.srcs.pop(0)
                    LOGGER.warning("falling back to '%s'", self.src)
                except IndexError:
                    self.src = None
            else:
                return archive
        if self.src is None:
            raise ConfigurationError(
                "Unable to acquire %s source package '%s'" %
                (self.name, ', '.join(self.srcs_avail)))
        else:
            return archive
Exemple #7
0
 def on_update(self, changes):
     from taucmdr.error import ImmutableRecordError
     from taucmdr.model.experiment import Experiment
     expr_ctrl = Experiment.controller()
     found = expr_ctrl.search({'target': self.eid})
     used_by = [expr['name'] for expr in found if expr.data_size() > 0]
     if used_by:
         raise ImmutableRecordError(
             "Target '%s' cannot be modified because "
             "it is used by these experiments: %s" %
             (self['name'], ', '.join(used_by)))
     for expr in found:
         try:
             expr.verify()
         except IncompatibleRecordError as err:
             raise ConfigurationError(
                 "Changing measurement '%s' in this way will create an invalid condition "
                 "in experiment '%s':\n    %s." %
                 (self['name'], expr['name'], err),
                 "Delete experiment '%s' and try again." % expr['name'])
     if self.is_selected():
         for attr, change in changes.iteritems():
             props = self.attributes[attr]
             if props.get('rebuild_required'):
                 if props.get('model', None) == Compiler:
                     old_comp = Compiler.controller(self.storage).one(
                         change[0])
                     new_comp = Compiler.controller(self.storage).one(
                         change[1])
                     message = {attr: (old_comp['path'], new_comp['path'])}
                 else:
                     message = {attr: change}
                 self.controller(self.storage).push_to_topic(
                     'rebuild_required', message)
    def __init__(self, total_size=0, block_size=1, show_cpu=True, mode=None):
        """ Initialize the ProgressBar object.

        Args:
            total_size (int): Total amount of work to be completed.
            block_size (int): Size of a work block.
            show_cpu (bool): If True, show CPU load average as well as progress.
            mode (str): One of 'full', 'minimal', 'disabled', or None.
                        If ``mode == None`` then the default value for ``mode`` is taken from  
                            the __TAUCMDR_PROGRESS_BARS__ environment variable. If that variable is not set 
                            then the default is 'full'.
                        If ``mode == 'full'`` then all output is written to :any:`sys.stdout`.
                        If ``mode == 'minimal'`` then a single '.' character is written to sys.stdout approximately
                            every five seconds without erasing the line (best for Travis regression test).
                        If ``mode == 'disabled'`` then no output is written to stdout.
        """
        if mode is None:
            mode = os.environ.get('__TAUCMDR_PROGRESS_BARS__', 'full').lower()
        if mode not in ('none', 'disabled', 'minimal', 'full'):
            raise ConfigurationError('Invalid value for __TAUCMDR_PROGRESS_BARS__ environment variable: %s' % mode)               
        self.count = 0
        self.total_size = total_size
        self.block_size = block_size
        self.show_cpu = show_cpu
        self.mode = mode
        self._last_time = datetime.now()
        self._start_time = None
        self._line_remaining = 0
 def __init__(self, family):
     self.family = family
     self.members = {}
     LOGGER.debug("Detecting %s compiler installation", family.name)
     for role, info_list in family.members.iteritems():
         for info in info_list:
             absolute_path = util.which(info.command)
             if absolute_path:
                 LOGGER.debug("%s %s compiler is '%s'", family.name,
                              info.role.language, absolute_path)
                 try:
                     installed = InstalledCompiler(absolute_path, info)
                 except ConfigurationError as err:
                     LOGGER.warning(err)
                     continue
                 self.members.setdefault(role, []).append(installed)
     if not self.members:
         cmds = [
             info.command for info_list in family.members.itervalues()
             for info in info_list
         ]
         raise ConfigurationError(
             "%s %s not found." %
             (self.family.name, self.family.kbase.description),
             "Check that these commands are in your PATH: %s" %
             ', '.join(cmds))
Exemple #10
0
 def detect(cls):
     """Detect the operating system we are currently running on.
     
     Mostly relies on Python's platform module but may also probe 
     environment variables and file systems in cases where the arch
     isn't immediately known to Python.  These tests may be expensive
     so the detected value is cached to improve performance.
     
     Returns:
         OperatingSystem: The matching operating system description.
         
     Raises:
         ConfigurationError: Host operating system not supported.
     """
     try:
         return cls._detect
     except AttributeError:
         if 'CRAYOS_VERSION' in os.environ or 'PE_ENV' in os.environ:
             inst = CRAY_CNL
         elif HOST_ARCH.is_bluegene():
             inst = IBM_CNK
         else:
             import platform
             python_os = platform.system()
             try:
                 inst = OperatingSystem.find(python_os)
             except KeyError:
                 raise ConfigurationError(
                     "Host operating system '%s' is not yet supported" %
                     python_os)
         cls._detect = inst
         return cls._detect
Exemple #11
0
 def __init__(self,
              label,
              total_size=0,
              block_size=1,
              show_cpu=True,
              auto_refresh=0.25):
     mode = os.environ.get('__TAUCMDR_PROGRESS_BARS__', 'full').lower()
     if mode not in ('full', 'disabled'):
         raise ConfigurationError(
             'Invalid value for __TAUCMDR_PROGRESS_BARS__ environment variable: %s'
             % mode)
     self.label = label
     self.count = 0
     self.total_size = total_size
     self.block_size = block_size
     self.show_cpu = show_cpu if load_average() is not None else False
     self.auto_refresh = auto_refresh if mode != 'disabled' else 0
     self._mode = mode
     self._line_remaining = 0
     self._phases = []
     self._phase_count = 0
     self._phase_depth = 0
     self._phase_base = 0
     self._thread = None
     self._exiting = None
     self._updating = None
Exemple #12
0
    def check_compiler(self, compilers):
        """Checks a list of compilers for compatibility with this application configuration.

        Args:
            compilers (list): :any:`Compiler` instances that could possibly be compatible with this application.

        Returns:
            Compiler: A compiler from `compilers` that can be used to build the application.

        Raises:
            ConfigurationError: No compiler in `compilers` is compatible with this application.
        """
        found = []
        for compiler in compilers:
            is_host = compiler['role'].startswith(HOST_COMPILERS.keyword)
            is_mpi = compiler['role'].startswith(
                MPI_COMPILERS.keyword) and self['mpi']
            is_shmem = compiler['role'].startswith(
                SHMEM_COMPILERS.keyword) and self['shmem']
            is_cuda = compiler['role'].startswith(
                CUDA_COMPILERS.keyword) and self['cuda']
            is_caf = compiler['role'].startswith(
                CAF_COMPILERS.keyword) and self['caf']
            if is_host or is_mpi or is_shmem or is_cuda or is_caf:
                found.append(compiler)
        if not found:
            raise ConfigurationError(
                "Application '%s' is not compatible with any of these compilers:\n  %s"
                % (self['name'], '\n  '.join(compiler['path']
                                             for compiler in compilers)))
        # If more than one compiler is compatible then choose the first one
        return found[0]
Exemple #13
0
 def on_create(self):
     self.verify()
     try:
         util.mkdirp(self.prefix)
     except:
         raise ConfigurationError('Cannot create directory %r' % self.prefix,
                                  'Check that you have `write` access')
Exemple #14
0
    def _prepare_src(self, reuse_archive=True):
        """Prepares source code for installation.
        
        Acquires package source code archive file via download or file copy,
        unpacks the archive, and verifies that required paths exist.
        
        Args:
            reuse_archive (bool): If True, attempt to reuse archive files.
            
        Returns:
            str: The path to the unpacked source code files.

        Raises:
            ConfigurationError: The source code couldn't be acquired or unpacked.
        """
        archive = self.acquire_source(reuse_archive)
        LOGGER.info("Using %s source archive '%s'", self.title, archive)
        try:
            return util.extract_archive(archive, tmpfs_prefix())
        except IOError as err:
            if reuse_archive:
                LOGGER.info(
                    "Unable to extract source archive '%s'.  Downloading a new copy.",
                    archive)
                return self._prepare_src(reuse_archive=False)
            raise ConfigurationError(
                "Cannot extract source archive '%s': %s" % (archive, err),
                "Check that the file or directory is accessible")
Exemple #15
0
 def on_create(self):
     try:
         util.mkdirp(self.prefix)
     except Exception as err:
         raise ConfigurationError(
             'Cannot create directory %r: %s' % (self.prefix, err),
             'Check that you have write access')
Exemple #16
0
 def on_update(self, changes):
     from taucmdr.error import ImmutableRecordError
     from taucmdr.model.experiment import Experiment
     expr_ctrl = Experiment.controller(self.storage)
     found = expr_ctrl.search({'application': self.eid})
     using_app = [expr['name'] for expr in found if expr.data_size() > 0]
     if using_app:
         raise ImmutableRecordError(
             "Application '%s' cannot be modified because "
             "it is used by these experiments: %s" %
             (self['name'], ', '.join(using_app)))
     for expr in found:
         try:
             expr.verify()
         except IncompatibleRecordError as err:
             raise ConfigurationError(
                 "Changing application '%s' in this way will create an invalid condition "
                 "in experiment '%s':\n    %s." %
                 (self['name'], expr['name'], err),
                 "Delete experiment '%s' and try again." % expr['name'])
     if self.is_selected():
         for attr, change in changes.iteritems():
             if self.attributes[attr].get('rebuild_required'):
                 self.controller(self.storage).push_to_topic(
                     'rebuild_required', {attr: change})
Exemple #17
0
 def __init__(self, name, title, sources, target_arch, target_os, compilers,
              repos, commands, libraries, headers):
     """Initializes the installation object.
     
     To set up a new installation, pass a URL, file path, or the special keyword 'download' as the package source.       
     To set up an interface to an existing installation, pass the path to that installation as the package source. 
     
     Args:
         name (str): The package name, lowercase, alphanumeric with underscores.  All packages have a
                     corresponding ``taucmdr.cf.software.<name>_installation`` module. 
         title (str): Human readable name of the software package, e.g. 'TAU Performance System' or 'Score-P'.
         sources (dict): Packages sources as strings indexed by package names as strings.  A source may be a 
                         path to a directory where the software has already been installed, or a path to a source
                         archive file, or the special keyword 'download'.
         target_arch (Architecture): Target architecture.
         target_os (OperatingSystem): Target operating system.
         compilers (InstalledCompilerSet): Compilers to use if software must be compiled.
         repos (dict): Dictionary of URLs for source code archives indexed by architecture and OS.  
                       The None key specifies the default (i.e. universal) source.
         commands (dict): Dictionary of commands, indexed by architecture and OS, that must be installed.
         libraries (dict): Dictionary of libraries, indexed by architecture and OS, that must be installed.
         headers (dict): Dictionary of headers, indexed by architecture and OS, that must be installed.
     """
     # pylint: disable=too-many-arguments
     assert isinstance(name, basestring)
     assert isinstance(title, basestring)
     assert isinstance(sources, dict)
     assert isinstance(target_arch, Architecture)
     assert isinstance(target_os, OperatingSystem)
     assert isinstance(compilers, InstalledCompilerSet)
     assert isinstance(repos, dict) or repos is None
     assert isinstance(commands, dict) or commands is None
     assert isinstance(libraries, dict) or libraries is None
     assert isinstance(headers, dict) or headers is None
     self._src_prefix = None
     self._install_prefix = None
     self._include_subdir = 'include'
     self._bin_subdir = 'bin'
     self._lib_subdir = 'lib'
     self._uid = None
     self.dependencies = {}
     self.name = name
     self.title = title
     self.target_arch = target_arch
     self.target_os = target_os
     self.compilers = compilers
     self.verify_commands = self._lookup_target_os_list(commands)
     self.verify_libraries = self._lookup_target_os_list(libraries)
     self.verify_headers = self._lookup_target_os_list(headers)
     src = sources[name]
     if src.lower() == 'download':
         self.src = self._lookup_target_os_list(repos)
     elif src.lower() == 'download-tr6':
         raise ConfigurationError(
             "download-tr6 is not a valid source for %s" % self.title)
     else:
         self.src = src
     self.unmanaged = os.path.isdir(self.src)
Exemple #18
0
 def _check_select_file(self):
     try:
         select_file = self['select_file']
     except KeyError:
         pass
     else:
         if select_file and not os.path.exists(select_file):
             raise ConfigurationError(
                 "Selective instrumentation file '%s' not found" %
                 select_file)
Exemple #19
0
 def find_any(cls, role):
     for family in role.kbase.iterfamilies():
         for info in family.members[role]:
             try:
                 comp = InstalledCompiler.probe(info.command, family=family, role=role)
             except ConfigurationError:
                 continue
             else:
                 return comp
     raise ConfigurationError("Cannot find any installed compiler to fill the %s role" % role)
Exemple #20
0
    def probe(cls, command, family=None, role=None):
        """Probe the system to discover information about an installed compiler.
        
        Args:
            command (str): Absolute or relative path to an installed compiler command.
            family (_CompilerFamily): Installed compiler's family if known, None otherwise.
            role (_CompilerRole): Installed compiler's role if known, None otherwise.

        Raises:
            ConfigurationError: Unknown compiler command or not enough information given to perform the probe.

        Returns:
            InstalledCompiler: A new InstalledCompiler instance describing the compiler.
        """
        assert isinstance(command, basestring)
        assert isinstance(family, _CompilerFamily) or family is None
        assert isinstance(role, _CompilerRole) or role is None
        absolute_path = util.which(command)
        if not absolute_path:
            raise ConfigurationError("Compiler '%s' not found on PATH" %
                                     command)
        command = os.path.basename(absolute_path)
        LOGGER.debug(
            "Probe: command='%s', abspath='%s', family='%s', role='%s'",
            command, absolute_path, family, role)
        # Try to identify without probing
        info_list = _CompilerInfo.find(command, family, role)
        if len(info_list) == 1:
            return InstalledCompiler(absolute_path, info_list[0])
        # Probe and try again
        family = _CompilerFamily.probe(absolute_path,
                                       [info.family for info in info_list])
        info_list = _CompilerInfo.find(command, family, role)
        if len(info_list) == 1:
            return InstalledCompiler(absolute_path, info_list[0])
        msg_parts = [
            "Unable to identify ", (family.name + " " if family else ""),
            (role.language + " " if role else ""),
            "compiler '%s'" % absolute_path
        ]
        raise ConfigurationError(''.join(msg_parts))
Exemple #21
0
 def _get_cmake(self):
     cmake = util.which('cmake')
     if not cmake:
         raise ConfigurationError("'cmake' not found in PATH.")
     try:
         stdout = util.get_command_output([cmake, '--version'])
     except (CalledProcessError, OSError) as err:
         raise ConfigurationError("Failed to get CMake version: %s" % err)
     for line in stdout.split('\n'):
         if 'cmake version' in line:
             verstr = (line.split('cmake version ')[1]).split('-')[0]
             version = tuple(int(x) for x in verstr.split('.'))
             if version < (2, 8):
                 raise ConfigurationError(
                     "CMake version 2.8 or higher required.")
             break
     else:
         LOGGER.warning(
             "Cannot determine CMake version.  CMake 2.8 or higher is required."
         )
     return cmake
Exemple #22
0
 def _parse_args(self, argv):
     args = super(TargetCreateCommand, self)._parse_args(argv)
     # Check that all required compilers were found
     for role in TAU_MINIMAL_COMPILERS:
         if role.keyword not in args:
             raise ConfigurationError(
                 "%s compiler is required but could not be found" %
                 role.language,
                 "See 'compiler arguments' under `%s --help`" % COMMAND)
     if FC.keyword not in args:
         args.scorep_source = None
     return args
Exemple #23
0
 def version_string(self):
     """Get the compiler's self-reported version info.
     
     Usually whatever the compiler prints when the --version flag is provided.
     
     Returns:
         str: The compilers' version string.
     """
     if self._version_string is None:
         cmd = [self.absolute_path] + self.info.family.version_flags
         try:
             self._version_string = util.get_command_output(cmd)
         except CalledProcessError:
             raise ConfigurationError("Compiler command '%s' failed." % ' '.join(cmd),
                                      "Check that this command works outside of TAU.",
                                      "Check loaded modules and environment variables.",
                                      "Verify that the compiler's license is valid.")
         except OSError:
             raise ConfigurationError("Compiler '%s' no longer exists or is not executable" % 
                                      self.absolute_path)
     return self._version_string
Exemple #24
0
 def verify(self):
     """Checks that the system state matches the recorded compiler information.
     
     May execute the compiler or other commands, check filesystem paths, and check environment variables
     to determine if this compiler record is still valid.  This operation may be expensive.
     
     Returns:
         InstalledCompiler: Information on the compiler installation matching this record.
     
     Raises:
         ConfigurationError: This compiler record is no longer valid.
     """
     comp = InstalledCompiler(self['path'], self._compiler_info())
     if comp.uid == self['uid']:
         return comp
     msg_parts = ["%s '%s' has changed:" % (comp.info.short_descr, comp.absolute_path)]
     fatal = self._verify_core_attrs(comp, msg_parts)
     if not fatal:
         self_wrapped = self.get('wrapped', False)
         if comp.wrapped and not self_wrapped:
             fatal = True
             msg_parts.append("It has changed to a compiler wrapper.")
         elif not comp.wrapped and self_wrapped:
             fatal = True
             msg_parts.append("It has changed from a compiler wrapper to a regular compiler.")
         elif comp.wrapped and self_wrapped:
             new_wrapped = comp.wrapped.unwrap()
             old_wrapped = self.populate('wrapped')
             while 'wrapped' in old_wrapped:
                 old_wrapped = self.populate('wrapped')
             # old_wrapped is a Compiler instance so this isn't really a protected access violation 
             # pylint: disable=protected-access
             fatal = fatal or old_wrapped._verify_core_attrs(new_wrapped, msg_parts)
             if not fatal:
                 if sorted(comp.include_path) != sorted(self['include_path']):
                     msg_parts.append("Include path has changed.")
                 if sorted(comp.library_path) != sorted(self['library_path']):
                     msg_parts.append('Library path has changed.')
                 if sorted(comp.compiler_flags) != sorted(self['compiler_flags']):
                     msg_parts.append('Compiler flags have changed.')
                 if sorted(comp.libraries) != sorted(self['libraries']):
                     msg_parts.append('Linked libraries have changed.')
     msg = "\n  ".join(msg_parts)
     if fatal:
         raise ConfigurationError(msg, 
                                  "Check loaded environment modules", 
                                  "Check environment variables, especially PATH",
                                  "Contact your system administrator")
     else:
         LOGGER.warning(msg + ("\n\nCheck loaded environment modules and environment variables.\n"
                               "Attempting to continue.  Compilation may fail later on."))
     return comp
Exemple #25
0
    def check_metrics(self, metrics):
        """Checks compatibility of PAPI metrics.

        Extracts all PAPI metrics from `metrics` and executes papi_event_chooser to check compatibility.

        Args:
            metrics (list): List of metrics.

        Raises:
            ConfigurationError: PAPI metrics are not compatible on the current host.
        """
        papi_metrics = self.parse_metrics(metrics)
        if not papi_metrics:
            return
        self.install()
        event_chooser_cmd = os.path.join(self.bin_path, 'papi_event_chooser')
        cmd = [event_chooser_cmd, 'PRESET'] + papi_metrics
        try:
            util.get_command_output(cmd)
        except CalledProcessError as err:
            for line in err.output.split('\n'):
                if "can't be counted with others" in line:
                    parts = line.split()
                    try:
                        event = parts[1]
                        code = int(parts[-1])
                    except (IndexError, ValueError):
                        continue
                    if code == -1:
                        why = ": %s is not compatible with other events" % event
                    elif code == -8:
                        why = ": %s cannot be counted due to resource limitations" % event
                    else:
                        why = ": %s is not supported on this host" % event
                    break
                elif "can't be found" in line:
                    parts = line.split()
                    try:
                        event = parts[1]
                    except IndexError:
                        continue
                    why = ": event %s is not available on the current host" % event
                    break
            else:
                why = ', and output from papi_event_chooser was not parsable.'
            raise ConfigurationError(
                ("PAPI metrics [%s] are not compatible on the current host%s.")
                % (', '.join(papi_metrics), why),
                "Use papi_avail to check metric availability.",
                "Spread the desired metrics over multiple measurements.",
                "Choose fewer metrics.",
                "You may ignore this if you are cross-compiling.")
Exemple #26
0
 def _check_metrics(self):
     """Check for TIME in metrics, add it if missing, ensure it is first"""
     try:
         self['metrics'].remove('TIME')
     except KeyError:
         raise ConfigurationError(
             "The metrics attribute should always exist with at least TIME present!"
         )
     except ValueError:
         LOGGER.warning(
             "'TIME' must always be present as the first metric!")
     finally:
         self['metrics'].insert(0, 'TIME')
    def trials(self, trial_numbers=None):
        """Get a list of modeled trial records.

        If `bool(trial_numbers)` is False, return the most recent trial.
        Otherwise return a list of Trial objects for the given trial numbers.

        Args:
            trial_numbers (list): List of numbers of trials to retrieve.

        Returns:
            list: Modeled trial records.

        Raises:
            ConfigurationError: Invalid trial number or no trials in selected experiment.
        """
        if trial_numbers:
            for num in trial_numbers:
                trials = []
                found = Trial.controller(self.storage).one({
                    'experiment': self.eid,
                    'number': num
                })
                if not found:
                    raise ConfigurationError(
                        "Experiment '%s' has no trial with number %s" %
                        (self.name, num))
                trials.append(found)
            return trials
        else:
            trials = self.populate('trials')
            if not trials:
                raise ConfigurationError("No trials in experiment %s" %
                                         self['name'])
            found = trials[0]
            for trial in trials[1:]:
                if trial['begin_time'] > found['begin_time']:
                    found = trial
            return [found]
Exemple #28
0
 def _separate_launcher_cmd(cls, cmd):
     """Separate the launcher command and it's arguments from the application command(s) and arguments.
     
     Args:
         cmd (list): Command line.
     
     Returns:
         tuple: (Launcher command, Remainder of command line)
         
     Raises:
         ConfigurationError: No application config files or executables found after a recognized launcher command.
     """
     # If '--' appears in the command then everything before it is a launcher + args
     # and everything after is the application + args
     try:
         idx = cmd.index('--')
     except ValueError:
         pass
     else:
         return cmd[:idx], cmd[idx + 1:]
     cmd0 = cmd[0]
     for launcher, appfile_flags in PROGRAM_LAUNCHERS.iteritems():
         if launcher not in cmd0:
             continue
         # No '--' to indicate start of application, so look for first executable
         for idx, exe in enumerate(cmd[1:], 1):
             if util.which(exe):
                 return cmd[:idx], cmd[idx:]
         # No exectuables, so look for application config file
         if appfile_flags:
             for i, arg in enumerate(cmd[1:], 1):
                 try:
                     arg, appfile = arg.split('=')
                 except ValueError:
                     try:
                         appfile = cmd[i + 1]
                     except IndexError:
                         # Reached the end of the command line without finding an application config file
                         break
                 if arg in appfile_flags and util.path_accessible(appfile):
                     return cmd, []
         raise ConfigurationError(
             ("TAU is having trouble parsing the command line: no executable "
              "commands or %s application files were found after "
              "the launcher command '%s'") % (cmd0, cmd0),
             "Check that the command is correct. Does it work without TAU?",
             ("Use '--' to seperate '%s' and its arguments from the application "
              "command, e.g. `mpirun -np 4 -- ./a.out -l hello`" % cmd0))
     # No launcher command, just an application command
     return [], cmd
 def configure(self, flags):
     from taucmdr.cf.platforms import DARWIN, IBM_BGP, IBM_BGQ, INTEL_KNC
     flags.extend(['--disable-nls', '--disable-werror'])
     for var in 'CPP', 'CC', 'CXX', 'FC', 'F77', 'F90':
         os.environ.pop(var, None)
     if self.target_os is DARWIN:
         flags.append(
             'CFLAGS=-Wno-error=unused-value -Wno-error=deprecated-declarations -fPIC'
         )
         flags.append(
             'CXXFLAGS=-Wno-error=unused-value -Wno-error=deprecated-declarations -fPIC'
         )
     else:
         flags.append('CFLAGS=-fPIC')
         flags.append('CXXFLAGS=-fPIC')
     if self.target_arch is IBM_BGP:
         flags.append(
             'CC=/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc-bgp-linux-gcc'
         )
         flags.append(
             'CXX=/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc-bgp-linux-g++'
         )
     elif self.target_arch is IBM_BGQ:
         flags.append(
             'CC=/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc64-bgq-linux-gcc'
         )
         flags.append(
             'CXX=/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc64-bgq-linux-g++'
         )
     elif self.target_arch.is_ibm():
         flags.append('--disable-largefile')
     elif self.target_arch is INTEL_KNC:
         k1om_ar = util.which('x86_64-k1om-linux-ar')
         if not k1om_ar:
             for path in glob.glob('/usr/linux-k1om-*'):
                 k1om_ar = util.which(
                     os.path.join(path, 'bin', 'x86_64-k1om-linux-ar'))
                 if k1om_ar:
                     break
             else:
                 raise ConfigurationError(
                     "Cannot find KNC native compilers in /usr/linux-k1om-*"
                 )
         os.environ['PATH'] = os.pathsep.join(
             (os.path.dirname(k1om_ar), os.environ['PATH']))
         flags.append('--host=x86_64-k1om-linux')
     return super(BinutilsInstallation, self).configure(flags)
Exemple #30
0
 def detect(cls):
     """Detect the processor architecture we are currently executing on.
         
     Mostly relies on Python's platform module but may also probe 
     environment variables and file systems in cases where the arch 
     isn't immediately known to Python.  These tests may be expensive
     so the detected value is cached to improve performance. 
     
     Returns:
         Architecture: The matching architecture description.
         
     Raises:
         ConfigurationError: Host architecture not supported.
     """
     try:
         return cls._detect
     except AttributeError:
         inst = None
         if os.path.exists(
                 "/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc-bgp-linux-gcc"
         ):
             inst = IBM_BGP
         elif os.path.exists(
                 "/bgsys/drivers/ppcfloor/gnu-linux/bin/powerpc64-bgq-linux-gcc"
         ):
             inst = IBM_BGQ
         elif os.path.exists("/proc/cpuinfo"):
             core0 = cls._parse_proc_cpuinfo()[0]
             if 'GenuineIntel' in core0.get('vendor_id', ''):
                 model_name = core0.get('model name', '')
                 if 'CoCPU' in model_name:
                     inst = INTEL_KNC
                 elif 'Xeon Phi' in model_name:
                     inst = INTEL_KNL
         # If all else fails ask Python
         if inst is None:
             import platform
             python_arch = platform.machine()
             try:
                 inst = Architecture.find(python_arch)
             except KeyError:
                 raise ConfigurationError(
                     "Host architecture '%s' is not yet supported" %
                     python_arch)
         cls._detect = inst
         return cls._detect