274 lines
12 KiB
Python
Executable File
274 lines
12 KiB
Python
Executable File
#!/usr/bin/env python
|
|
import os,re,sys,string,subprocess,shutil
|
|
|
|
from optparse import OptionParser, Option
|
|
|
|
# -----------------------------
|
|
class extendableOption(Option):
|
|
# -----------------------------
|
|
# used for definition of new option parser action 'extend', which enables to take multiple option arguments
|
|
# taken from online tutorial http://docs.python.org/library/optparse.html
|
|
|
|
ACTIONS = Option.ACTIONS + ("extend",)
|
|
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
|
|
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
|
|
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
|
|
|
|
def take_action(self, action, dest, opt, value, values, parser):
|
|
if action == "extend":
|
|
lvalue = value.split(",")
|
|
values.ensure_value(dest, []).extend(lvalue)
|
|
else:
|
|
Option.take_action(self, action, dest, opt, value, values, parser)
|
|
|
|
|
|
|
|
########################################################
|
|
# MAIN
|
|
########################################################
|
|
|
|
parser = OptionParser(option_class=extendableOption, usage='%prog options', description = """
|
|
Configures the compilation and installation of DAMASK
|
|
|
|
""" + string.replace('$Id$','\n','\\n')
|
|
)
|
|
|
|
#--- determine default compiler ----------------------------------------------------------------------
|
|
compiler = os.getenv('F90')
|
|
if compiler == None: compiler ={True:'ifort',False:'gfortran'}[\
|
|
subprocess.call(['which', 'ifort'],\
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0]
|
|
|
|
#--- default option values --------------------------------------------------------------------------
|
|
BLAS_order = ['IMKL','ACML','LAPACK']
|
|
|
|
defaults={'DAMASK_BIN':'depending on access rights',
|
|
'F90':compiler,
|
|
'FFTW_ROOT':'/usr/local',
|
|
'MSC_ROOT' :'/msc',
|
|
'HDF5_ROOT':'/usr/local',
|
|
'DAMASK_NUM_THREADS':4,
|
|
'blasType':'LAPACK',
|
|
'blasRoot':{'LAPACK':'/usr',
|
|
'ACML' :'/opt/acml5.3.1',
|
|
'IMKL' :{True:os.getenv('MKLROOT'), False:'/opt/intel/composerxe/mkl'}\
|
|
[os.getenv('MKLROOT') != None]},
|
|
'spectralOptions':{}}
|
|
|
|
|
|
|
|
#--- if local config file exists, read, otherwise assume global config file ------------------------
|
|
if os.path.isfile(os.path.join(os.getenv('HOME'),'.damask/damask.conf')):
|
|
configFile = os.path.join(os.getenv('HOME'),'.damask/damask.conf')
|
|
else:
|
|
configFile = '/etc/damask.conf'
|
|
|
|
#--- set default values according to read in values ------------------------------------------------
|
|
try:
|
|
with open(configFile,'r') as f:
|
|
print('\n-----\n reading default values from %s\n-----'%configFile)
|
|
for line in f:
|
|
[key,value] = (re.split('[= ]',line)+[None,None])[:2]
|
|
value = value.rstrip()
|
|
|
|
if (not line.strip() or key.startswith('#')):
|
|
pass
|
|
if key == 'DAMASK_NUM_THREADS':
|
|
defaults['DAMASK_NUM_THREADS'] = int(value)
|
|
if key == 'DAMASK_BIN':
|
|
defaults['DAMASK_BIN'] = value
|
|
for theKey in ['F90','FFTW_ROOT','HDF5_ROOT','MSC_ROOT','spectralOptions']:
|
|
if key == theKey:
|
|
defaults[key] = value
|
|
for theKey in reversed(BLAS_order):
|
|
if key == theKey+'_ROOT' and (value != None or value != ''):
|
|
defaults['blasType'] = theKey
|
|
defaults['blasRoot'][theKey] = value
|
|
except IOError:
|
|
pass
|
|
|
|
parser.add_option('--prefix', dest='prefix', type='string', metavar='string',
|
|
help='location of (links to) DAMASK executables [%default]')
|
|
parser.add_option('--with-FC','--with-fc',
|
|
dest='compiler', type='string', metavar='string',
|
|
help='F90 compiler [%default]')
|
|
parser.add_option('--with-FFTW-dir','--with-fftw-dir',
|
|
dest='fftwRoot', type='string', metavar='string',
|
|
help='root directory of FFTW [%default]')
|
|
parser.add_option('--with-MSC-dir','--with-msc-dir',
|
|
dest='mscRoot', type='string', metavar='string',
|
|
help='root directory of MSC.Marc/Mentat [%default]')
|
|
parser.add_option('--with-HDF5-dir','--with-hdf5-dir',
|
|
dest='hdf5Root', type='string', metavar='string',
|
|
help='root directory of HDF5 [%default]')
|
|
parser.add_option('--with-OMP-threads','--with-omp-threads',
|
|
dest='threads', type='int', metavar='int',
|
|
help='number of openMP threads [%default]')
|
|
parser.add_option('--with-BLAS-type','--with-blas-type',
|
|
dest='blasType', type='string', metavar='string',
|
|
help='type of BLAS/LAPACK library [%default]')
|
|
parser.add_option('--with-BLAS-dir','--with-blas-dir',
|
|
dest='blasRoot', type='string', metavar='string',
|
|
help='root directory of BLAS/LAPACK library [%default]')
|
|
parser.add_option('--with-spectral-options', dest='spectraloptions', type='string', action='extend', metavar='<string LIST>',
|
|
help='options for compilation of spectral solver')
|
|
|
|
parser.set_defaults(prefix = defaults['DAMASK_BIN'])
|
|
parser.set_defaults(compiler = defaults['F90'])
|
|
parser.set_defaults(fftwRoot = defaults['FFTW_ROOT'])
|
|
parser.set_defaults(mscRoot = defaults['MSC_ROOT'])
|
|
parser.set_defaults(hdf5Root = defaults['HDF5_ROOT'])
|
|
parser.set_defaults(threads = defaults['DAMASK_NUM_THREADS'])
|
|
parser.set_defaults(blasType = defaults['blasType'])
|
|
|
|
#--- set default for blasRoot depending on current option (or default) for blasType --------------------
|
|
blasType = defaults['blasType'].upper()
|
|
for i, arg in enumerate(sys.argv):
|
|
if arg.startswith('--with-blas-type'):
|
|
if arg.endswith('--with-blas-type'):
|
|
blasType = sys.argv[i+1].upper()
|
|
else:
|
|
blasType = sys.argv[i][17:].upper()
|
|
if blasType not in BLAS_order:
|
|
blasType='LAPACK'
|
|
|
|
parser.set_defaults(blasRoot = [defaults['blasRoot'][blasType]][0])
|
|
parser.set_defaults(spectraloptions = [])
|
|
|
|
(options,filenames) = parser.parse_args()
|
|
|
|
#--- consistency checks --------------------------------------------------------------------------------
|
|
options.compiler=options.compiler.lower()
|
|
options.blasType=options.blasType.upper()
|
|
options.fftwRoot=options.fftwRoot.rstrip('/')
|
|
options.mscRoot =options.mscRoot.rstrip('/')
|
|
options.hdf5Root=options.hdf5Root.rstrip('/')
|
|
options.blasRoot=options.blasRoot.rstrip('/')
|
|
|
|
if options.compiler not in ['ifort','gfortran']:
|
|
print('Error: Unknown compiler option: %s'%options.compiler)
|
|
sys.exit(1)
|
|
|
|
if not subprocess.call(['which', options.compiler],stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
|
|
print('Compiler Warning: executable %s not found!'%options.compiler)
|
|
|
|
fftwLocations =[os.path.join(options.fftwRoot,'lib'),os.path.join(options.fftwRoot,'lib64')]
|
|
for lib in ['libfftw3.so','libfftw3.a',
|
|
'libfftw3_threads.so','libfftw3_threads.a']:
|
|
if (not os.path.isfile(os.path.join(fftwLocations[0],lib))) and \
|
|
(not os.path.isfile(os.path.join(fftwLocations[1],lib))):
|
|
print('FFTW Warning: %s not found in %s or %s!'%(lib,fftwLocations[0],fftwLocations[1]))
|
|
|
|
if not os.path.isdir(options.mscRoot):
|
|
print('MSC.Marc/Mentat Warning: Root directory %s not found!'%options.mscRoot)
|
|
|
|
if options.blasType == 'LAPACK':
|
|
lapackLocations =[os.path.join(options.blasRoot,'lib'),os.path.join(options.blasRoot,'lib64')]
|
|
for lib in ['liblapack.so','liblapack.a']:
|
|
if (not os.path.isfile(os.path.join(lapackLocations[0],lib))) and \
|
|
(not os.path.isfile(os.path.join(lapackLocations[1],lib))):
|
|
print('LAPACK Warning: %s not found in %s or %s!'%(lib,lapackLocations[0],lapackLocations[1]))
|
|
elif options.blasType == 'ACML':
|
|
blasLocationSerial=os.path.join(options.blasRoot,'%s64/lib'%options.compiler)
|
|
for lib in ['libacml.so','libacml.a']:
|
|
if not os.path.isfile(os.path.join(blasLocationSerial,lib)):
|
|
print('ACML Warning: %s not found in %s!'%(lib,blasLocationSerial))
|
|
blasLocationParallel=os.path.join(options.blasRoot,'%s64_mp/lib'%options.compiler)
|
|
for lib in ['libacml_mp.so','libacml_mp.a']:
|
|
if not os.path.isfile(os.path.join(blasLocationParallel,lib)):
|
|
print('ACML Warning: %s not found in %s!'%(lib,blasLocationParallel))
|
|
elif options.blasType == 'IMKL':
|
|
blasLocation=os.path.join(options.blasRoot,'lib/intel64')
|
|
for lib in ['libmkl_core.so','libmkl_core.a',
|
|
'libmkl_sequential.so','libmkl_sequential.a',
|
|
'libmkl_intel_thread.so','libmkl_intel_thread.a',
|
|
'libmkl_intel_lp64.so','libmkl_intel_lp64.a',
|
|
'libmkl_gnu_thread.so','libmkl_gnu_thread.a',
|
|
'libmkl_gf_lp64.so','libmkl_gf_lp64.a',
|
|
]:
|
|
if not os.path.isfile(os.path.join(blasLocation,lib)):
|
|
print('IMKL Warning: %s not found in %s!'%(lib,blasLocation))
|
|
else:
|
|
print('Error: Unknown BLAS/LAPACK library: %s'%options.blasType)
|
|
sys.exit(1)
|
|
|
|
#--- read config file if present to keep comments and order ---------------------------------------
|
|
output = []
|
|
try:
|
|
with open(configFile,'r') as f:
|
|
for line in f:
|
|
items = re.split('[= ]',line)
|
|
|
|
if (not line.strip() or items[0].startswith('#')):
|
|
pass
|
|
if items[0] == 'DAMASK_BIN':
|
|
line = '%s=%s\n'%(items[0],options.prefix)
|
|
options.prefix ='depending on access rights'
|
|
if items[0] == 'F90':
|
|
line = '%s=%s\n'%(items[0],options.compiler)
|
|
options.compiler =''
|
|
if items[0] == 'FFTW_ROOT':
|
|
line = '%s=%s\n'%(items[0],options.fftwRoot)
|
|
options.fftwRoot =''
|
|
if items[0] == 'MSC_ROOT':
|
|
line = '%s=%s\n'%(items[0],options.mscRoot)
|
|
options.mscRoot =''
|
|
if items[0] == 'HDF5_ROOT':
|
|
line = '%s=%s\n'%(items[0],options.hdf5Root)
|
|
options.hdf5Root =''
|
|
if items[0] == 'DAMASK_NUM_THREADS':
|
|
line = '%s=%s\n'%(items[0],options.threads)
|
|
options.threads =''
|
|
for blasType in defaults['blasRoot'].keys():
|
|
if items[0] == '%s_ROOT'%blasType and items[0] == '%s_ROOT'%options.blasType:
|
|
line = '%s=%s\n'%(items[0],options.blasRoot)
|
|
options.blasType=''
|
|
elif items[0] == '#%s_ROOT'%blasType and items[0] == '#%s_ROOT'%options.blasType:
|
|
line = '%s=%s\n'%(items[0][1:],options.blasRoot)
|
|
options.blasType=''
|
|
elif items[0] == '%s_ROOT'%blasType: line = '#'+line
|
|
for spectralOption in options.spectraloptions:
|
|
[key,value] = re.split('[= ]',spectralOption)[0:2]
|
|
if key == items[0]:
|
|
line = '%s=%s\n'%(items[0],value)
|
|
options.spectraloptions.remove(spectralOption)
|
|
output.append(line)
|
|
except IOError:
|
|
pass
|
|
|
|
#--- write remaining options --------------------------------------------------------------------------
|
|
for opt, value in options.__dict__.items():
|
|
if opt == 'prefix' and value !='depending on access rights':
|
|
output.append('DAMASK_BIN=%s\n'%value)
|
|
if opt == 'compiler' and value !='':
|
|
output.append('F90=%s\n'%value)
|
|
if opt == 'fftwRoot' and value !='':
|
|
output.append('FFTW_ROOT=%s\n'%value)
|
|
if opt == 'mscRoot' and value !='':
|
|
output.append('MSC_ROOT=%s\n'%value)
|
|
if opt == 'hdf5Root' and value !='':
|
|
output.append('HDF5_ROOT=%s\n'%value)
|
|
if opt == 'threads' and value !='':
|
|
output.append('DAMASK_NUM_THREADS=%s\n'%value)
|
|
if opt == 'blasType' and value !='':
|
|
output.append('%s_ROOT=%s\n'%(options.blasType,options.blasRoot))
|
|
|
|
for spectralOption in options.spectraloptions:
|
|
output.append(spectralOption+'\n')
|
|
|
|
#--- decide where do save the data -------------------------------------------------------------------
|
|
if os.access('/etc/', os.W_OK): # super user (no home)
|
|
configDir = '/etc'
|
|
else: # normal user
|
|
configDir = os.path.join(os.getenv('HOME'),'.damask')
|
|
configFileNew = os.path.join(configDir,'damask.conf')
|
|
|
|
if not os.path.isdir(configDir):
|
|
os.mkdir(configDir)
|
|
|
|
print('\n-----\n writing values to %s\n-----'%configFileNew)
|
|
with open(configFileNew,'w') as f:
|
|
for line in output:
|
|
print(line.rstrip('\n'))
|
|
f.write(line)
|