1#!/usr/bin/env python 2from __future__ import generators 3import user 4import config.base 5 6class Configure(config.base.Configure): 7 def __init__(self, framework): 8 config.base.Configure.__init__(self, framework) 9 self.headerPrefix = '' 10 self.substPrefix = '' 11 return 12 13 def __str1__(self): 14 desc = [] 15 if hasattr(self, 'scalartype'): 16 desc.append(' Scalar type: ' + self.scalartype) 17 if hasattr(self, 'precision'): 18 desc.append(' Precision: ' + self.precision) 19 return '\n'.join(desc)+'\n' 20 21 def setupHelp(self, help): 22 import nargs 23 help.addArgument('PETSc', '-with-precision=<single,double,__float128>', nargs.Arg(None, 'double', 'Specify numerical precision')) 24 help.addArgument('PETSc', '-with-scalar-type=<real or complex>', nargs.Arg(None, 'real', 'Specify real or complex numbers')) 25 return 26 27 def setupDependencies(self, framework): 28 config.base.Configure.setupDependencies(self, framework) 29 self.types = framework.require('config.types', self) 30 self.languages = framework.require('PETSc.options.languages', self) 31 self.compilers = framework.require('config.compilers', self) 32 self.libraries = framework.require('config.libraries',self) 33 self.mpi = framework.require('config.packages.MPI',self) 34 return 35 36 37 def configureScalarType(self): 38 '''Choose between real and complex numbers''' 39 self.scalartype = self.framework.argDB['with-scalar-type'].lower() 40 if self.scalartype == 'complex': 41 self.addDefine('USE_COMPLEX', '1') 42 if self.languages.clanguage == 'C' and not self.types.c99_complex: 43 raise RuntimeError('C Compiler provided doest not support C99 complex') 44 if self.languages.clanguage == 'Cxx' and not self.types.cxx_complex: 45 raise RuntimeError('Cxx compiler provided does not support std::complex') 46 elif not self.scalartype == 'real': 47 raise RuntimeError('--with-scalar-type must be real or complex') 48 self.addDefine('USE_SCALAR_'+self.scalartype.upper(), '1') 49 self.framework.logPrint('Scalar type is '+str(self.scalartype)) 50 # On apple isinf() and isnan() do not work when <complex> is included 51 self.pushLanguage(self.languages.clanguage) 52 if self.scalartype == 'complex' and self.languages.clanguage == 'Cxx': 53 if self.checkLink('#include <math.h>\n#include <complex>\n','double b = 2.0;int a = isnormal(b);\n'): 54 self.addDefine('HAVE_ISNORMAL',1) 55 if self.checkLink('#include <math.h>\n#include <complex>\n','double b = 2.0;int a = isnan(b);\n'): 56 self.addDefine('HAVE_ISNAN',1) 57 if self.checkLink('#include <math.h>\n#include <complex>\n','double b = 2.0;int a = isinf(b);\n'): 58 self.addDefine('HAVE_ISINF',1) 59 if self.checkLink('#include <math.h>\n#include <complex>\n','double b = 2.0;int a = _isnan(b);\n'): 60 self.addDefine('HAVE__ISNAN',1) 61 if self.checkLink('#include <math.h>\n#include <complex>\n','double b = 2.0;int a = _finite(b);\n'): 62 self.addDefine('HAVE__FINITE',1) 63 else: 64 if self.checkLink('#include <math.h>\n','double b = 2.0; int a = isnormal(b);\n'): 65 self.addDefine('HAVE_ISNORMAL',1) 66 if self.checkLink('#include <math.h>\n','double b = 2.0; int a = isnan(b);\n'): 67 self.addDefine('HAVE_ISNAN',1) 68 if self.checkLink('#include <math.h>\n','double b = 2.0; int a = isinf(b);\n'): 69 self.addDefine('HAVE_ISINF',1) 70 if self.checkLink('#include <math.h>\n','double b = 2.0;int a = _isnan(b);\n'): 71 self.addDefine('HAVE__ISNAN',1) 72 if self.checkLink('#include <math.h>\n','double b = 2.0;int a = _finite(b);\n'): 73 self.addDefine('HAVE__FINITE',1) 74 self.popLanguage() 75 return 76 77 def configurePrecision(self): 78 '''Set the default real number precision for PETSc objects''' 79 self.precision = self.framework.argDB['with-precision'].lower() 80 if self.precision == 'single': 81 self.addDefine('USE_REAL_SINGLE', '1') 82 self.addMakeMacro('PETSC_SCALAR_SIZE', '32') 83 elif self.precision == 'double': 84 self.addDefine('USE_REAL_DOUBLE', '1') 85 self.addMakeMacro('PETSC_SCALAR_SIZE', '64') 86 elif self.precision == '__float128': # supported by gcc 4.6 87 if self.libraries.add('quadmath','logq',prototype='#include <quadmath.h>',call='__float128 f; logq(f);'): 88 self.addDefine('USE_REAL___FLOAT128', '1') 89 self.addMakeMacro('PETSC_SCALAR_SIZE', '128') 90 else: 91 raise RuntimeError('quadmath support not found. --with-precision=__float128 works with gcc-4.6 and newer compilers.') 92 else: 93 raise RuntimeError('--with-precision must be single, double,__float128') 94 self.framework.logPrint('Precision is '+str(self.precision)) 95 return 96 97 def configure(self): 98 self.executeTest(self.configureScalarType) 99 self.executeTest(self.configurePrecision) 100 return 101