2014-01-11 18:16:30 +05:30
#!/usr/bin/env python
2014-01-28 13:04:13 +05:30
# -*- coding: UTF-8 no BOM -*-
2014-01-11 18:16:30 +05:30
2014-01-15 00:33:41 +05:30
import os , sys , glob , string , subprocess , shlex
2014-01-11 18:16:30 +05:30
from damask import Environment
2014-01-28 13:04:13 +05:30
# compiles fortran code for Python
scriptID = ' $Id$ '
2014-01-12 00:43:02 +05:30
damaskEnv = Environment ( )
baseDir = damaskEnv . relPath ( ' installation/ ' )
codeDir = damaskEnv . relPath ( ' code/ ' )
2014-01-27 21:54:07 +05:30
keywords = [ ' IMKL_ROOT ' , ' ACML_ROOT ' , ' LAPACK_ROOT ' , ' FFTW_ROOT ' , ' F90 ' ]
2014-01-28 13:04:13 +05:30
options = { }
2014-01-12 00:43:02 +05:30
2014-01-28 13:04:13 +05:30
#--- getting options from damask.conf or, if not present, from envinronment -----------------------
2014-01-27 21:54:07 +05:30
for option in keywords :
2014-01-15 00:33:41 +05:30
try :
value = damaskEnv . options [ option ]
except :
value = os . getenv ( option )
if value is None : value = ' ' # env not set
options [ option ] = value
2014-01-12 00:43:02 +05:30
2014-01-28 13:04:13 +05:30
#--- overwrite default options with keyword=value pair from argument list to mimic make behavior --
2014-01-27 21:37:52 +05:30
for i , arg in enumerate ( sys . argv ) :
2014-01-27 21:54:07 +05:30
for option in keywords :
2014-01-27 21:37:52 +05:30
if arg . startswith ( option ) :
2014-01-28 03:36:39 +05:30
options [ option ] = sys . argv [ i ] [ len ( option ) + 1 : ]
2014-01-27 21:37:52 +05:30
2014-01-28 13:04:13 +05:30
#--- check for valid compiler and set options -----------------------------------------------------
2014-01-12 00:43:02 +05:30
compilers = [ ' ifort ' , ' gfortran ' ]
2014-01-15 00:33:41 +05:30
if options [ ' F90 ' ] not in compilers :
sys . exit ( ' compiler " F90 " (in installation/options or as Shell variable) has to be one out of: %s ' % ( ' , ' . join ( compilers ) ) )
2014-01-24 18:45:01 +05:30
2014-01-28 03:36:39 +05:30
compiler = {
' gfortran ' : ' --fcompiler=gnu95 --f90flags= " -fPIC -fno-range-check -xf95-cpp-input -std=f2008 -fall-intrinsics ' + \
2014-05-15 15:28:31 +05:30
' -fdefault-real-8 -fdefault-double-8 " ' ,
2014-01-28 03:36:39 +05:30
' ifort ' : ' --fcompiler=intelem --f90flags= " -fPIC -fpp -stand f08 -diag-disable 5268 -assume byterecl ' + \
2014-05-14 15:37:10 +05:30
' -real-size 64 -integer-size 32 -shared-intel " ' ,
2014-01-28 03:36:39 +05:30
} [ options [ ' F90 ' ] ]
2014-01-15 00:33:41 +05:30
2014-01-28 13:04:13 +05:30
#--- option not depending on compiler -------------------------------------------------------------
2014-01-30 01:36:57 +05:30
compileOptions = ' -DSpectral -DFLOAT=8 -DINT=4 -I %s /lib ' % damaskEnv . rootDir ( )
2014-01-27 19:40:49 +05:30
2014-01-28 13:04:13 +05:30
#--- this saves the path of libraries to core.so, hence it is known during runtime ----------------
2014-01-30 18:37:44 +05:30
if options [ ' F90 ' ] == ' gfortran ' :
2014-05-21 15:37:10 +05:30
LDFLAGS = ' -shared -Wl,-undefined,dynamic_lookup ' # solved error: Undefined symbols for architecture x86_64: "_PyArg_ParseTupleAndKeywords" as found on https://lists.macosforge.org/pipermail/macports-dev/2013-May/022735.html
2014-04-29 22:13:59 +05:30
else :
2014-05-21 15:37:10 +05:30
LDFLAGS = ' -openmp -Wl ' # some f2py versions/configurations compile with openMP, so linking against openMP is needed to prevent errors during loading of core module
2014-04-30 10:35:41 +05:30
#--- run path of for fftw during runtime ----------------------------------------------------------
LDFLAGS + = ' ,-rpath, %s /lib,-rpath, %s /lib64 ' % ( options [ ' FFTW_ROOT ' ] , options [ ' FFTW_ROOT ' ] )
2014-01-27 21:37:52 +05:30
2014-01-15 00:33:41 +05:30
# see http://cens.ioc.ee/pipermail/f2py-users/2003-December/000621.html
2014-01-29 17:50:56 +05:30
if options [ ' IMKL_ROOT ' ] :
if options [ ' F90 ' ] == ' gfortran ' :
arch = ' gf '
elif options [ ' F90 ' ] == ' ifort ' :
arch = ' intel '
2014-04-29 22:13:59 +05:30
lib_lapack = ' -L %s /lib/intel64 -lmkl_ %s _lp64 -lmkl_core -lmkl_sequential -lm ' \
2014-01-29 17:50:56 +05:30
% ( options [ ' IMKL_ROOT ' ] , arch )
2014-01-30 01:22:31 +05:30
LDFLAGS + = ' ,-rpath, %s /lib/intel64 ' % ( options [ ' IMKL_ROOT ' ] )
2014-01-15 00:33:41 +05:30
elif options [ ' ACML_ROOT ' ] != ' ' :
2014-01-27 19:40:49 +05:30
lib_lapack = ' -L %s / %s 64/lib -lacml ' % ( options [ ' ACML_ROOT ' ] , options [ ' F90 ' ] )
2014-01-30 01:22:31 +05:30
LDFLAGS + = ' ,-rpath, %s / %s 64/lib ' % ( options [ ' ACML_ROOT ' ] , options [ ' F90 ' ] )
2014-01-15 01:02:55 +05:30
elif options [ ' LAPACK_ROOT ' ] != ' ' :
2014-01-27 19:40:49 +05:30
lib_lapack = ' -L %s /lib -L %s /lib64 -llapack ' % ( options [ ' LAPACK_ROOT ' ] , options [ ' LAPACK_ROOT ' ] )
2014-01-30 01:22:31 +05:30
LDFLAGS + = ' ,-rpath, %s /lib,-rpath, %s /lib64 ' % ( options [ ' LAPACK_ROOT ' ] , options [ ' LAPACK_ROOT ' ] )
2014-01-27 21:37:52 +05:30
2014-01-28 13:04:13 +05:30
#--------------------------------------------------------------------------------------------------
2014-01-27 21:37:52 +05:30
# f2py does not (yet) support setting of special flags for the linker, hence they must be set via
2014-01-28 13:04:13 +05:30
# environment variable ----------------------------------------------------------------------------
2014-01-27 21:37:52 +05:30
my_env = os . environ
my_env [ " LDFLAGS " ] = LDFLAGS
2014-01-11 18:16:30 +05:30
2014-01-28 13:04:13 +05:30
#--- delete old file ------------------------------------------------------------------------------
2014-01-15 00:33:41 +05:30
try :
os . remove ( os . path . join ( damaskEnv . relPath ( ' lib/damask ' ) , ' core.so ' ) )
2014-01-28 13:04:13 +05:30
except OSError , e :
2014-01-15 00:33:41 +05:30
print ( " Error when deleting: %s - %s . " % ( e . filename , e . strerror ) )
# The following command is used to compile the fortran files and make the functions defined
# in damask.core.pyf available for python in the module core.so
# It uses the fortran wrapper f2py that is included in the numpy package to construct the
# module core.so out of the fortran code in the f90 files
# For the generation of the pyf file use the following lines:
###########################################################################
#'f2py -h damask.core.pyf' +\
#' --overwrite-signature --no-lower prec.f90 DAMASK_spectral_interface.f90 math.f90 mesh.f90,...'
###########################################################################
2014-01-28 13:04:13 +05:30
os . chdir ( codeDir )
2014-01-15 00:33:41 +05:30
cmd = ' f2py damask.core.pyf ' + \
2014-01-27 19:40:49 +05:30
' -c --no-lower %s ' % ( compiler ) + \
compileOptions + \
2014-01-15 00:33:41 +05:30
' prec.f90 ' + \
' DAMASK_spectral_interface.f90 ' + \
' IO.f90 ' + \
' libs.f90 ' + \
' numerics.f90 ' + \
' debug.f90 ' + \
' math.f90 ' + \
' FEsolving.f90 ' + \
' mesh.f90 ' + \
' core_quit.f90 ' + \
2014-01-27 19:40:49 +05:30
' -L %s /lib -lfftw3 ' % ( options [ ' FFTW_ROOT ' ] ) + \
2014-01-15 00:33:41 +05:30
' %s ' % lib_lapack
print ( ' Executing: ' + cmd )
try :
2014-01-27 19:40:49 +05:30
subprocess . call ( shlex . split ( cmd ) , env = my_env )
2014-01-15 00:33:41 +05:30
except subprocess . CalledProcessError :
print ( ' build failed ' )
except OSError :
print ( ' f2py not found ' )
2014-01-11 18:16:30 +05:30
2014-01-15 01:02:55 +05:30
try :
2014-01-16 03:47:32 +05:30
os . rename ( os . path . join ( codeDir , ' core.so ' ) , \
os . path . join ( damaskEnv . relPath ( ' lib/damask ' ) , ' core.so ' ) )
2014-01-15 01:02:55 +05:30
except :
pass
2014-01-11 18:16:30 +05:30
modules = glob . glob ( ' *.mod ' )
for module in modules :
print ' removing ' , module
os . remove ( module )
2014-01-28 13:04:13 +05:30
#--- check if compilation of core module was successful -------------------------------------------
2014-01-11 18:16:30 +05:30
try :
with open ( damaskEnv . relPath ( ' lib/damask/core.so ' ) ) as f : pass
except IOError as e :
print ' ********* \n * core.so not found, compilation of core modules was not successful \n ********* '