def _compiler_info(self):
     command = os.path.basename(self['path'])
     role = Knowledgebase.find_role(self['role'])
     family = role.kbase.families[self['family']]
     info_list = Knowledgebase.find_compiler(command, family, role)
     if len(info_list) != 1:
         raise InternalError("Zero or more than one known compilers match '%s'" % self)
     return info_list[0]
Exemple #2
0
 def check_compiler(self, compiler_cmd, compiler_args):
     """Checks a compiler command its arguments for compatibility with this target configuration.
     
     Checks that the given compiler matches at least one, **but possibly more**, of the compilers 
     used in the target. Also performs any special checkes for invalid compiler arguments, 
     e.g. -mmic is only for native KNC.
     
     If the given compiler command and arguments are compatible with this target then information about
     matching compiler installations is returned as a list of n :any:`InstalledCompiler` instances.
     
     Args:
         compiler_cmd (str): The compiler command as passed by the user.
         compiler_args (list): Compiler command line arguments.
         
     Returns:
         list: Information about matching installed compilers as :any:`Compiler` instances.
         
     Raises:
         ConfigurationError: The compiler or command line arguments are incompatible with this target.
     """
     if '-mmic' in compiler_args and self['host_arch'] != str(INTEL_KNC):
         raise ConfigurationError("Host architecture of target '%s' is '%s'"
                                  " but the '-mmic' compiler argument requires '%s'" %
                                  (self['name'], self['host_arch'], INTEL_KNC),
                                  "Select a different target",
                                  "Create a new target with host architecture '%s'" % INTEL_KNC)
     compiler_ctrl = Compiler.controller(self.storage)
     absolute_path = util.which(compiler_cmd)
     compiler_cmd = os.path.basename(compiler_cmd)
     found = []
     known_compilers = [comp for comp in self.compilers().itervalues()]
     for info in Knowledgebase.find_compiler(command=compiler_cmd):
         try:
             compiler_record = self.populate(info.role.keyword)
         except KeyError:
             # Target was not configured with a compiler in this role
             continue
         compiler_path = compiler_record['path']
         if (absolute_path and (compiler_path == absolute_path) or 
                 (not absolute_path and (os.path.basename(compiler_path) == compiler_cmd))):
             found.append(compiler_record)
         else:
             # Target was configured with a wrapper compiler so check if that wrapper wraps this compiler
             while 'wrapped' in compiler_record:
                 compiler_record = compiler_ctrl.one(compiler_record['wrapped'])
                 known_compilers.append(compiler_record.installation())
                 compiler_path = compiler_record['path']
                 if (absolute_path and (compiler_path == absolute_path) or 
                         (not absolute_path and (os.path.basename(compiler_path) == compiler_cmd))):
                     found.append(compiler_record)
                     break
     if not found:
         parts = ["No compiler in target '%s' matches '%s'." % (self['name'], absolute_path or compiler_cmd),
                  "The known compiler commands are:"]
         parts.extend('  %s (%s)' % (comp.absolute_path, comp.info.short_descr) for comp in known_compilers)
         hints = ("Try one of the valid compiler commands",
                  "Create and select a new target configuration that uses the '%s' compiler" % (absolute_path or compiler_cmd),
                  "Check loaded modules and the PATH environment variable")
         raise ConfigurationError('\n'.join(parts), *hints)
     return found
Exemple #3
0
    def is_compatible(cmd):
        """Check if this subcommand can work with the given command.
        
        Args:
            cmd (str): A command from the command line, e.g. sys.argv[1].

        Returns:
            bool: True if this subcommand is compatible with `cmd`.
        """
        return os.path.basename(cmd) in [info.command for info in Knowledgebase.all_compilers()]
Exemple #4
0
    def is_compatible(cmd):
        """Check if this subcommand can work with the given command.
        
        Args:
            cmd (str): A command from the command line, e.g. sys.argv[1].

        Returns:
            bool: True if this subcommand is compatible with `cmd`.
        """
        return os.path.basename(cmd) in [
            info.command for info in Knowledgebase.all_compilers()
        ]
Exemple #5
0
 def _construct_parser(self):
     parts = ['  %s  %s' % ('{:<15}'.format(comp.command), comp.short_descr) 
              for comp in Knowledgebase.all_compilers()]
     epilog = "known compiler commands and their roles:\n%s\n" % '\n'.join(sorted(parts))
     usage = "%s <command> [arguments]" % self.command
     parser = arguments.get_parser(prog=self.command, usage=usage, description=self.summary, epilog=epilog)
     parser.add_argument('cmd',
                         help="Compiler or linker command, e.g. 'gcc'",
                         metavar='<command>')
     parser.add_argument('cmd_args', 
                         help="Compiler arguments",
                         metavar='[arguments]',
                         nargs=arguments.REMAINDER)
     return parser
Exemple #6
0
 def _construct_parser(self):
     parts = [
         '  %s  %s' % ('{:<15}'.format(comp.command), comp.short_descr)
         for comp in Knowledgebase.all_compilers()
     ]
     epilog = "known compiler commands and their roles:\n%s\n" % '\n'.join(
         sorted(parts))
     usage = "%s <command> [arguments]" % self.command
     parser = arguments.get_parser(prog=self.command,
                                   usage=usage,
                                   description=self.summary,
                                   epilog=epilog)
     parser.add_argument('cmd',
                         help="Compiler or linker command, e.g. 'gcc'",
                         metavar='<command>')
     parser.add_argument('cmd_args',
                         help="Compiler arguments",
                         metavar='[arguments]',
                         nargs=arguments.REMAINDER)
     return parser
Exemple #7
0
 def compilers(self):
     """Get information about the compilers used by this target configuration.
     
     Returns:
         InstalledCompilerSet: Collection of installed compilers used by this target.
     """
     if not self._compilers:
         eids = []
         compilers = {}
         for role in Knowledgebase.all_roles():
             try:
                 with fasteners.InterProcessLock(os.path.join(PROJECT_STORAGE.prefix, '.lock')):
                     compiler_record = self.populate(role.keyword)
             except KeyError:
                 continue
             compilers[role.keyword] = compiler_record.installation()
             LOGGER.debug("compilers[%s] = '%s'", role.keyword, compilers[role.keyword].absolute_path)
             eids.append(compiler_record.eid)
         self._compilers = InstalledCompilerSet('_'.join([str(x) for x in sorted(eids)]), **compilers)
     return self._compilers
Exemple #8
0
 def compilers(self):
     """Get information about the compilers used by this target configuration.
     
     Returns:
         InstalledCompilerSet: Collection of installed compilers used by this target.
     """
     if not self._compilers:
         eids = []
         compilers = {}
         for role in Knowledgebase.all_roles():
             try:
                 with fasteners.InterProcessLock(
                         os.path.join(PROJECT_STORAGE.prefix, '.lock')):
                     compiler_record = self.populate(role.keyword)
             except KeyError:
                 continue
             compilers[role.keyword] = compiler_record.installation()
             LOGGER.debug("compilers[%s] = '%s'", role.keyword,
                          compilers[role.keyword].absolute_path)
             eids.append(compiler_record.eid)
         self._compilers = InstalledCompilerSet(
             '_'.join([str(x) for x in sorted(eids)]), **compilers)
     return self._compilers
Exemple #9
0
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""CUDA compiler knowledgebase."""

from taucmdr.cf.compiler import Knowledgebase

CUDA_COMPILERS = Knowledgebase('CUDA',
                               'Compilers supporting CUDA',
                               CXX=('CUDA', 'CU'),
                               FC=('CUDA Fortran', 'CUF'))

NVIDIA = CUDA_COMPILERS.add('NVIDIA', CXX='nvcc')

IBM = CUDA_COMPILERS.add('IBM',
                         family_regex=r'^IBM XL',
                         version_flags=['-qversion'],
                         FC='xlcuf')

CUDA_CXX = CUDA_COMPILERS.roles['CXX']
CUDA_FC = CUDA_COMPILERS.roles['FC']
Exemple #10
0
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""SHMEM compiler knowledgebase.

Keep a separate knowledge base for SHMEM compilers to simplify compiler
identification and because TAU doesn't require SHMEM for all configurations.
"""
from taucmdr.cf.compiler import Knowledgebase

SHMEM_COMPILERS = Knowledgebase(
    'SHMEM',
    'Compilers supporting Symmetric Hierarchical Memory',
    CC=('SHMEM C', 'SHMEM_CC'),
    CXX=('SHMEM C++', 'SHMEM_CXX'),
    FC=('SHMEM Fortran', ('SHMEM_FC', 'SHMEM_F77', 'SHMEM_F90')))

OPENSHMEM = SHMEM_COMPILERS.add('OpenSHMEM',
                                CC='oshcc',
                                CXX=('oshcxx', 'oshc++', 'oshCC'),
                                FC='oshfort')

SOS = SHMEM_COMPILERS.add('SOS',
                          show_wrapper_flags=['-show'],
                          CC='oshcc',
                          CXX=('oshc++', 'oshCC'),
                          FC='oshfort')

CRAY_SHMEM = SHMEM_COMPILERS.add(
Exemple #11
0
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""SHMEM compiler knowledgebase.

Keep a separate knowledge base for SHMEM compilers to simplify compiler
identification and because TAU doesn't require SHMEM for all configurations.
"""
from taucmdr.cf.compiler import Knowledgebase


SHMEM_COMPILERS = Knowledgebase('SHMEM', 'Compilers supporting Symmetric Hierarchical Memory',
                                CC=('SHMEM C', 'SHMEM_CC'),
                                CXX=('SHMEM C++', 'SHMEM_CXX'),
                                FC=('SHMEM Fortran', ('SHMEM_FC', 'SHMEM_F77', 'SHMEM_F90')))

OPENSHMEM = SHMEM_COMPILERS.add('OpenSHMEM',
                                CC='oshcc', CXX=('oshcxx', 'oshc++', 'oshCC'), FC='oshfort')

SOS = SHMEM_COMPILERS.add('SOS',
                          show_wrapper_flags=['-show'], 
                          CC='oshcc', CXX=('oshc++', 'oshCC'), FC='oshfort')

CRAY_SHMEM = SHMEM_COMPILERS.add('Cray', family_regex=r'-I.*cray', 
                                 version_flags=['-craype-verbose', '--version', '-E'],
                                 show_wrapper_flags=['-craype-verbose', '--version', '-E'],
                                 CC='cc', CXX='CC', FC='ftn')

SHMEM_CC = SHMEM_COMPILERS.roles['CC']
Exemple #12
0
#     be used to endorse or promote products derived from this software without
#     specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""CUDA compiler knowledgebase."""

from taucmdr.cf.compiler import Knowledgebase


CUDA_COMPILERS = Knowledgebase('CUDA', 'Compilers supporting CUDA',
                               CXX=('CUDA', 'CU'),
                               FC=('CUDA Fortran', 'CUF'))

NVIDIA = CUDA_COMPILERS.add('NVIDIA', CXX='nvcc') 

IBM = CUDA_COMPILERS.add('IBM', family_regex=r'^IBM XL', version_flags=['-qversion'],
                         FC='xlcuf')

CUDA_CXX = CUDA_COMPILERS.roles['CXX']
CUDA_FC = CUDA_COMPILERS.roles['FC']
Exemple #13
0
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""
Python Interpreter Knowledgebase (implemented using the compiler classes)

"""
from taucmdr.cf.compiler import Knowledgebase

PYTHON_INTERPRETERS = Knowledgebase(
    'python',
    'Compilers targeting different versions of Python',
    PY=('python', 'python')  # language: python, envars: python
)

PYTHON2 = PYTHON_INTERPRETERS.add('PY2_INTERPRETER',
                                  family_regex=r'^Python 2',
                                  version_flags=['--version'],
                                  PY=('python2', 'python'))

PYTHON3 = PYTHON_INTERPRETERS.add('PY3_INTERPRETER',
                                  family_regex=r'^Python 3',
                                  version_flags=['--version'],
                                  PY=('python3', 'python'))

PY = PYTHON_INTERPRETERS.roles['PY']
Exemple #14
0
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""Host CPU compiler knowledgebase.

These are the principal compilers used by the system and **must** be identified
to successfully configure and install TAU.
"""
from taucmdr.cf.compiler import Knowledgebase

HOST_COMPILERS = Knowledgebase('Host',
                               'Compilers targeting the host CPU',
                               CC=('C', 'CC'),
                               CXX=('C++', 'CXX'),
                               FC=('Fortran', ('FC', 'F77', 'F90')),
                               UPC=('Universal Parallel C', 'UPC'))

SYSTEM = HOST_COMPILERS.add('System',
                            CC='cc',
                            CXX=('c++', 'cxx', 'CC'),
                            FC=('ftn', 'f90', 'f77'),
                            UPC='upc')

GNU = HOST_COMPILERS.add('GNU',
                         family_regex=r'Free Software Foundation, Inc',
                         CC='gcc',
                         CXX='g++',
                         FC=('gfortran', 'g77'),
                         UPC='gupc')
Exemple #15
0
# (3) Neither the name of ParaTools, Inc. nor the names of its contributors may
#     be used to endorse or promote products derived from this software without
#     specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
"""CAF compiler knowledgebase.

We keep a separate knowledge base for CAF compilers to simplify compiler
identification and because TAU doesn't require CAF for all configurations.
"""
from taucmdr.cf.compiler import Knowledgebase

CAF_COMPILERS = Knowledgebase('CAF', 'Compilers supporting Coarray Fortran',
                              FC=('Coarray Fortran', ('FC', 'F77', 'F90')))

SYSTEM = CAF_COMPILERS.add('System', show_wrapper_flags=['-show'],
                           FC='caf')

CAF_FC = CAF_COMPILERS.roles['FC']

Exemple #16
0
 def _parse_tau_makefile(self, args):
     # Parsing a TAU Makefile is a really hairy operation, so let's lift the limits
     # pylint: disable=too-many-statements,too-many-locals
     makefile = args.forced_makefile
     if not util.path_accessible(makefile):
         self.parser.error("Invalid TAU makefile: %s" % makefile)
     tau_arch_name = os.path.basename(
         os.path.dirname(os.path.dirname(makefile)))
     matches = [
         arch for arch in TauMagic.all() if arch.name == tau_arch_name
     ]
     if len(matches) == 1:
         tau_arch = matches[0]
     elif not matches:
         raise ConfigurationError(
             "TAU Makefile '%s' targets an unrecognized TAU architecture: %s"
             % (makefile, tau_arch_name))
     else:
         for arch in matches:
             if arch.architecture == HOST_ARCH and arch.operating_system == HOST_OS:
                 tau_arch = arch
                 break
         else:
             parts = [
                 "TAU Makefile '%s' targets an ambiguous TAU architecture: %s"
                 % (makefile, tau_arch_name), "It could be any of these:"
             ]
             parts.extend([
                 "  - %s on %s" %
                 (arch.operating_system.name, arch.architecture.name)
                 for arch in matches
             ])
             raise ConfigurationError("\n".join(parts))
     self.logger.info(
         "Parsing TAU Makefile '%s' to populate command line arguments:",
         makefile)
     args.host_arch = tau_arch.architecture.name
     self.logger.info("  --host-arch='%s'", args.host_arch)
     args.host_os = tau_arch.operating_system.name
     self.logger.info("  --host-os='%s'", args.host_os)
     args.tau_source = os.path.abspath(
         os.path.join(os.path.dirname(makefile), '..', '..'))
     self.logger.info("  --taucmdr='%s'", args.tau_source)
     with open(makefile, 'r') as fin:
         compiler_parts = ("FULL_CC", "FULL_CXX", "TAU_F90")
         package_parts = {
             "BFDINCLUDE":
             ("binutils_source",
              lambda x: os.path.dirname(shlex.split(x)[0].lstrip("-I"))),
             "UNWIND_INC": ("libunwind_source",
                            lambda x: os.path.dirname(x.lstrip("-I"))),
             "PAPIDIR": ("papi_source", os.path.abspath),
             "PDTDIR": ("pdt_source", os.path.abspath),
             "SCOREPDIR": ("scorep_source", os.path.abspath)
         }
         tau_r = ''
         for line in fin:
             if line.startswith('#'):
                 continue
             try:
                 key, val = [x.strip() for x in line.split('=', 1)]
             except ValueError:
                 continue
             if key == 'TAU_R':
                 tau_r = val.split()[0]
             elif key in compiler_parts:
                 path = util.which(val.strip().split()[0].replace(
                     '$(TAU_R)', tau_r))
                 if not path:
                     self.logger.warning(
                         "Failed to parse %s in TAU Makefile '%s'", key,
                         makefile)
                     continue
                 matching_info = Knowledgebase.find_compiler(
                     os.path.basename(path))
                 if matching_info:
                     if len(matching_info) > 1:
                         self.logger.warning(
                             "Ambiguous compiler '%s' in TAU Makefile '%s'",
                             path, makefile)
                     comp = InstalledCompiler(path, matching_info[0])
                     attr = comp.info.role.keyword
                     setattr(args, attr, comp.absolute_path)
                     self.logger.info("  --%s='%s'",
                                      attr.lower().replace("_", "-"),
                                      comp.absolute_path)
                     while comp.wrapped:
                         comp = comp.wrapped
                         attr = comp.info.role.keyword
                         setattr(args, attr, comp.absolute_path)
                         self.logger.info("  --%s='%s'",
                                          attr.lower().replace("_", "-"),
                                          comp.absolute_path)
             elif key in package_parts:
                 attr, operator = package_parts[key]
                 path = val.strip()
                 if not path:
                     path = None
                 else:
                     path = operator(path)
                     if not os.path.exists(path):
                         self.logger.warning(
                             "'%s' referenced by TAU Makefile '%s' doesn't exist",
                             path, makefile)
                         continue
                 setattr(args, attr, path)
                 self.logger.info("  --%s='%s'",
                                  attr.replace("_source", ""), path)
Exemple #17
0
 def check_compiler(self, compiler_cmd, compiler_args):
     """Checks a compiler command its arguments for compatibility with this target configuration.
     
     Checks that the given compiler matches at least one, **but possibly more**, of the compilers 
     used in the target. Also performs any special checkes for invalid compiler arguments, 
     e.g. -mmic is only for native KNC.
     
     If the given compiler command and arguments are compatible with this target then information about
     matching compiler installations is returned as a list of n :any:`InstalledCompiler` instances.
     
     Args:
         compiler_cmd (str): The compiler command as passed by the user.
         compiler_args (list): Compiler command line arguments.
         
     Returns:
         list: Information about matching installed compilers as :any:`Compiler` instances.
         
     Raises:
         ConfigurationError: The compiler or command line arguments are incompatible with this target.
     """
     if '-mmic' in compiler_args and self['host_arch'] != str(INTEL_KNC):
         raise ConfigurationError(
             "Host architecture of target '%s' is '%s'"
             " but the '-mmic' compiler argument requires '%s'" %
             (self['name'], self['host_arch'], INTEL_KNC),
             "Select a different target",
             "Create a new target with host architecture '%s'" % INTEL_KNC)
     compiler_ctrl = Compiler.controller(self.storage)
     absolute_path = util.which(compiler_cmd)
     compiler_cmd = os.path.basename(compiler_cmd)
     found = []
     known_compilers = [comp for comp in self.compilers().itervalues()]
     for info in Knowledgebase.find_compiler(command=compiler_cmd):
         try:
             compiler_record = self.populate(info.role.keyword)
         except KeyError:
             # Target was not configured with a compiler in this role
             continue
         compiler_path = compiler_record['path']
         if (absolute_path and (compiler_path == absolute_path)
                 or (not absolute_path and
                     (os.path.basename(compiler_path) == compiler_cmd))):
             found.append(compiler_record)
         else:
             # Target was configured with a wrapper compiler so check if that wrapper wraps this compiler
             while 'wrapped' in compiler_record:
                 compiler_record = compiler_ctrl.one(
                     compiler_record['wrapped'])
                 known_compilers.append(compiler_record.installation())
                 compiler_path = compiler_record['path']
                 if (absolute_path and (compiler_path == absolute_path) or
                     (not absolute_path and
                      (os.path.basename(compiler_path) == compiler_cmd))):
                     found.append(compiler_record)
                     break
     if not found:
         parts = [
             "No compiler in target '%s' matches '%s'." %
             (self['name'], absolute_path or compiler_cmd),
             "The known compiler commands are:"
         ]
         parts.extend('  %s (%s)' %
                      (comp.absolute_path, comp.info.short_descr)
                      for comp in known_compilers)
         hints = (
             "Try one of the valid compiler commands",
             "Create and select a new target configuration that uses the '%s' compiler"
             % (absolute_path or compiler_cmd),
             "Check loaded modules and the PATH environment variable")
         raise ConfigurationError('\n'.join(parts), *hints)
     return found
Exemple #18
0
#
"""MPI compiler knowledgebase.

MPI compilers are a special case for several reasons including:
    1) No binary compatibility guarantee among MPI compilers.
    2) They're almost always wrappers, not actual compilers.
    3) They almost always depend on CPU compilers.
    
We keep a separate knowledge base for MPI compilers to simplify compiler
identification and because TAU doesn't require MPI for all configurations.
"""
from taucmdr.cf.compiler import Knowledgebase


MPI_COMPILERS = Knowledgebase('MPI', 'Compilers supporting the Message Passing Interface (MPI)',
                              CC=('MPI C', 'MPI_CC'),
                              CXX=('MPI C++', 'MPI_CXX'),
                              FC=('MPI Fortran', ('MPI_FC', 'MPI_F77', 'MPI_F90')))

SYSTEM = MPI_COMPILERS.add('System', show_wrapper_flags=['-show'],
                           CC='mpicc', 
                           CXX=('mpic++', 'mpicxx', 'mpiCC'), 
                           FC=('mpiftn', 'mpif90', 'mpif77', 'mpifort'))

INTEL = MPI_COMPILERS.add('Intel', show_wrapper_flags=['-show'],
                          CC='mpiicc', 
                          CXX='mpiicpc', 
                          FC='mpiifort')

IBM = MPI_COMPILERS.add('IBM', family_regex=r'^IBM XL',
                        version_flags=['-qversion'],
                        show_wrapper_flags=['-show'],
Exemple #19
0
 def _parse_tau_makefile(self, args):
     # Parsing a TAU Makefile is a really hairy operation, so let's lift the limits
     # pylint: disable=too-many-statements,too-many-locals
     makefile = args.forced_makefile
     if not util.path_accessible(makefile):
         self.parser.error("Invalid TAU makefile: %s" % makefile)
     tau_arch_name = os.path.basename(os.path.dirname(os.path.dirname(makefile)))
     matches = [arch for arch in TauMagic.all() if arch.name == tau_arch_name]
     if len(matches) == 1:
         tau_arch = matches[0]
     elif len(matches) == 0:
         raise ConfigurationError("TAU Makefile '%s' targets an unrecognized TAU architecture: %s" % 
                                  (makefile, tau_arch_name))
     else:
         for arch in matches:
             if arch.architecture == HOST_ARCH and arch.operating_system == HOST_OS:
                 tau_arch = arch
                 break
         else:
             parts = ["TAU Makefile '%s' targets an ambiguous TAU architecture: %s" % (makefile, tau_arch_name),
                      "It could be any of these:"]
             parts.extend(["  - %s on %s" % (arch.operating_system.name, arch.architecture.name) 
                           for arch in matches])
             raise ConfigurationError("\n".join(parts))
     self.logger.info("Parsing TAU Makefile '%s' to populate command line arguments:", makefile)
     args.host_arch = tau_arch.architecture.name
     self.logger.info("  --host-arch='%s'", args.host_arch)
     args.host_os = tau_arch.operating_system.name
     self.logger.info("  --host-os='%s'", args.host_os)
     args.tau_source = os.path.abspath(os.path.join(os.path.dirname(makefile), '..', '..'))
     self.logger.info("  --taucmdr='%s'", args.tau_source)
     with open(makefile, 'r') as fin:
         compiler_parts = ("FULL_CC", "FULL_CXX", "TAU_F90")
         package_parts = {"BFDINCLUDE": ("binutils_source", lambda x: os.path.dirname(x.lstrip("-I"))), 
                          "UNWIND_INC": ("libunwind_source", lambda x: os.path.dirname(x.lstrip("-I"))),
                          "PAPIDIR": ("papi_source", os.path.abspath),
                          "PDTDIR": ("pdt_source", os.path.abspath),
                          "SCOREPDIR": ("scorep_source", os.path.abspath)}
         tau_r = ''
         for line in fin:
             if line.startswith('#'):
                 continue
             try:
                 key, val = [x.strip() for x in line.split('=', 1)]
             except ValueError:
                 continue
             if key == 'TAU_R':
                 tau_r = val.split()[0]
             elif key in compiler_parts:
                 path = util.which(val.strip().split()[0].replace('$(TAU_R)', tau_r))
                 if not path:
                     self.logger.warning("Failed to parse %s in TAU Makefile '%s'", key, makefile)
                     continue
                 matching_info = Knowledgebase.find_compiler(os.path.basename(path))
                 if matching_info:
                     if len(matching_info) > 1:
                         self.logger.warning("Ambiguous compiler '%s' in TAU Makefile '%s'", path, makefile)
                     comp = InstalledCompiler(path, matching_info[0])
                     attr = comp.info.role.keyword
                     setattr(args, attr, comp.absolute_path)
                     self.logger.info("  --%s='%s'", attr.lower().replace("_", "-"), comp.absolute_path)
                     while comp.wrapped:
                         comp = comp.wrapped
                         attr = comp.info.role.keyword
                         setattr(args, attr, comp.absolute_path)
                         self.logger.info("  --%s='%s'", attr.lower().replace("_", "-"), comp.absolute_path)
             elif key in package_parts:
                 attr, operator = package_parts[key]
                 path = val.strip()
                 if not path:
                     path = None
                 else:
                     path = operator(path)
                     if not os.path.exists(path):
                         self.logger.warning("'%s' referenced by TAU Makefile '%s' doesn't exist", path, makefile)
                         continue
                 setattr(args, attr, path)
                 self.logger.info("  --%s='%s'", attr.replace("_source", ""), path)