Changed architecture class and added class Target
This commit is contained in:
parent
38508c5a3f
commit
7ab921ff02
1 changed files with 85 additions and 56 deletions
|
@ -23,11 +23,16 @@
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import os
|
import os
|
||||||
|
import imp
|
||||||
import platform as py_platform
|
import platform as py_platform
|
||||||
|
import inspect
|
||||||
|
|
||||||
from llnl.util.lang import memoized
|
from llnl.util.lang import memoized, list_modules
|
||||||
|
from llnl.util.filesystem import join_path
|
||||||
|
import llnl.util.tty as tty
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
|
from spack.util.naming import mod_to_class
|
||||||
import spack.error as serr
|
import spack.error as serr
|
||||||
from spack.version import Version
|
from spack.version import Version
|
||||||
from external import yaml
|
from external import yaml
|
||||||
|
@ -42,41 +47,55 @@ def __init__(self):
|
||||||
super(NoSysTypeError, self).__init__("Could not determine sys_type for this machine.")
|
super(NoSysTypeError, self).__init__("Could not determine sys_type for this machine.")
|
||||||
|
|
||||||
|
|
||||||
class Architecture(object):
|
class Target(object):
|
||||||
""" Architecture class that contains a dictionary of architecture name and compiler search strategy methods.
|
""" This is the processor type e.g. cray-ivybridge """
|
||||||
The idea is to create an object that Spack can interact with and know how to search for the compiler
|
# Front end or back end target. Target needs to know which one this is
|
||||||
If it is on a Cray architecture it should look in modules. If it is anything else search $PATH.
|
# Should autodetect from the machine
|
||||||
"""
|
# features of a target
|
||||||
|
# - a module name
|
||||||
|
# -a compiler finding strategy
|
||||||
|
# -a name
|
||||||
|
# architecture classes handling the aliasing for front-end, back-end and default
|
||||||
|
|
||||||
def add_compiler_strategy(self, front,back):
|
def __init__(self,name, module_name=None):
|
||||||
names = []
|
self.name = name # case of cray "ivybridge but if it's x86_64
|
||||||
names.append(front)
|
self.module_name = module_name # craype-ivybridge
|
||||||
names.append(back)
|
|
||||||
d = {}
|
def compiler_strategy(self):
|
||||||
for n in names:
|
if self.module_name: # If there is a module_name given then use MODULES
|
||||||
if n:
|
return "MODULES"
|
||||||
if 'cray' in n.lower():
|
|
||||||
d[n] = "MODULES"
|
|
||||||
elif 'linux' in n.lower():
|
|
||||||
d[n] = "PATH"
|
|
||||||
else:
|
else:
|
||||||
d[n] = 'No Strategy'
|
return "PATH"
|
||||||
return d
|
|
||||||
|
|
||||||
def __init__(self, front=None, back=None):
|
class Architecture(object):
|
||||||
""" Constructor for the architecture class. It will create a list from the given arguments and iterate
|
""" Abstract class that each type of Architecture will subclass. Will return a instance of it once it
|
||||||
through that list. It will then create a dictionary of {arch_name : strategy}
|
is returned
|
||||||
Takes in two parameters:
|
|
||||||
|
|
||||||
front = None defaults to None. Should be the front-end architecture of the machine
|
|
||||||
back = None defaults to None. Should be the back-end architecture of the machine
|
|
||||||
|
|
||||||
If no arguments are given it will return an empty dictionary
|
|
||||||
Uses the _add_compiler_strategy(front, back) to create the dictionary
|
|
||||||
"""
|
"""
|
||||||
self.front = front
|
|
||||||
self.back = back
|
priority = None # Subclass needs to set this number. This controls order in which arch is detected.
|
||||||
self.arch_dict = self.add_compiler_strategy(front, back)
|
front = None
|
||||||
|
back = None
|
||||||
|
default_front = None # The default front end target. On cray sandybridge
|
||||||
|
default_back = None # The default back end target. On cray ivybridge
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self.targets = {}
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def add_target(self, name, target):
|
||||||
|
self.targets[name] = target
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def detect(self):
|
||||||
|
""" Subclass is responsible for implementing this method.
|
||||||
|
Returns True if the architecture detects if it is the current architecture
|
||||||
|
and False if it's not.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
def get_sys_type_from_spack_globals():
|
def get_sys_type_from_spack_globals():
|
||||||
|
@ -84,9 +103,9 @@ def get_sys_type_from_spack_globals():
|
||||||
if not hasattr(spack, "sys_type"):
|
if not hasattr(spack, "sys_type"):
|
||||||
return None
|
return None
|
||||||
elif hasattr(spack.sys_type, "__call__"):
|
elif hasattr(spack.sys_type, "__call__"):
|
||||||
return Architecture(spack.sys_type()) #If in __init__.py there is a sys_type() then call that
|
return spack.sys_type() #If in __init__.py there is a sys_type() then call that
|
||||||
else:
|
else:
|
||||||
return Architecture(spack.sys_type) # Else use the attributed which defaults to None
|
return spack.sys_type # Else use the attributed which defaults to None
|
||||||
|
|
||||||
|
|
||||||
# This is livermore dependent. Hard coded for livermore
|
# This is livermore dependent. Hard coded for livermore
|
||||||
|
@ -102,15 +121,19 @@ def get_mac_sys_type():
|
||||||
mac_ver = py_platform.mac_ver()[0]
|
mac_ver = py_platform.mac_ver()[0]
|
||||||
if not mac_ver:
|
if not mac_ver:
|
||||||
return None
|
return None
|
||||||
return Architecture("macosx_%s_%s" % (Version(mac_ver).up_to(2), py_platform.machine()))
|
return "macosx_%s_%s" % (Version(mac_ver).up_to(2), py_platform.machine())
|
||||||
|
|
||||||
|
|
||||||
def get_sys_type_from_uname():
|
def get_sys_type_from_uname():
|
||||||
""" Returns a sys_type from the uname argument
|
""" Returns a sys_type from the uname argument
|
||||||
Front-end config
|
Front-end config
|
||||||
"""
|
"""
|
||||||
return Architecture(os.uname()[0])
|
try:
|
||||||
|
arch_proc = subprocess.Popen(['uname', '-i'], stdout = subprocess.PIPE)
|
||||||
|
arch, _ = arch_proc.communicate()
|
||||||
|
return arch.strip()
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_sys_type_from_config_file():
|
def get_sys_type_from_config_file():
|
||||||
""" Should read in a sys_type from the config yaml file. This should be the first thing looked at since
|
""" Should read in a sys_type from the config yaml file. This should be the first thing looked at since
|
||||||
|
@ -131,6 +154,24 @@ def get_sys_type_from_config_file():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@memoized
|
||||||
|
def all_architectures():
|
||||||
|
modules = []
|
||||||
|
for name in list_modules(spack.arch_path):
|
||||||
|
mod_name = 'spack.architectures.' + name
|
||||||
|
path = join_path(spack.arch_path, name) + ".py"
|
||||||
|
mod = imp.load_source(mod_name, path)
|
||||||
|
class_name = mod_to_class(name)
|
||||||
|
if not hasattr(mod, class_name):
|
||||||
|
tty.die('No class %s defined in %s' % (class_name, mod_name))
|
||||||
|
cls = getattr(mod, class_name)
|
||||||
|
if not inspect.isclass(cls):
|
||||||
|
tty.die('%s.%s is not a class' % (mod_name, class_name))
|
||||||
|
|
||||||
|
modules.append(cls)
|
||||||
|
|
||||||
|
return modules
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
def sys_type():
|
def sys_type():
|
||||||
"""Priority of gathering sys-type.
|
"""Priority of gathering sys-type.
|
||||||
|
@ -143,22 +184,10 @@ def sys_type():
|
||||||
arch name
|
arch name
|
||||||
"""
|
"""
|
||||||
# Try to create an architecture object using the config file FIRST
|
# Try to create an architecture object using the config file FIRST
|
||||||
functions = [get_sys_type_from_config_file,
|
architecture_list = all_architectures()
|
||||||
get_sys_type_from_uname,
|
architecture_list.sort(key = lambda a: a.priority)
|
||||||
get_sys_type_from_spack_globals,
|
|
||||||
get_mac_sys_type]
|
|
||||||
|
|
||||||
sys_type = None
|
for arch in architecture_list:
|
||||||
for func in functions:
|
if arch.detect():
|
||||||
sys_type = func()
|
return arch()
|
||||||
if sys_type:
|
|
||||||
break
|
|
||||||
|
|
||||||
if sys_type is None:
|
|
||||||
return Architecture("unknown_arch")
|
|
||||||
|
|
||||||
if not isinstance(sys_type, Architecture):
|
|
||||||
raise InvalidSysTypeError(sys_type)
|
|
||||||
|
|
||||||
return sys_type
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue