xref: /petsc/config/BuildSystem/config/packages/f2cblaslapack.py (revision 7b5fd022a6ba26727040df7457b27566b4c6742d)
1import config.package
2
3class Configure(config.package.Package):
4  def __init__(self, framework):
5    config.package.Package.__init__(self, framework)
6    self.download               = ['https://web.cels.anl.gov/projects/petsc/download/externalpackages/f2cblaslapack-3.8.0.q2.tar.gz']
7    self.downloadonWindows      = 1
8    self.skippackagewithoptions = 1
9    self.brokengnu23            = 1
10
11  def setupDependencies(self, framework):
12    config.package.Package.setupDependencies(self, framework)
13    self.blis = framework.require('config.packages.BLIS', self)
14    self.blis.complex_return = 'intel' # f2cblaslapack puts complex return values into the arguments, like Intel Fortran compilers, and blis needs to know this
15    self.scalartypes = framework.require('PETSc.options.scalarTypes', self)
16    self.odeps = [self.blis]
17    return
18
19  def setupHelp(self, help):
20    config.package.GNUPackage.setupHelp(self,help)
21    import nargs
22    help.addArgument('F2CBLASLAPACK', '-with-f2cblaslapack-float128-bindings', nargs.ArgBool(None, 0, 'Build BLAS/LAPACK with __float128 bindings'))
23    help.addArgument('F2CBLASLAPACK', '-with-f2cblaslapack-fp16-bindings', nargs.ArgBool(None, 0, 'Build BLAS/LAPACK with __fp16 bindings'))
24
25  def configureLibrary(self):
26    if self.argDB['with-64-bit-blas-indices']:
27      raise RuntimeError('f2cblaslapack does not support -with-64-bit-blas-indices')
28    if hasattr(self.argDB,'known-64-bit-blas-indices') and self.argDB['known-64-bit-blas-indices']:
29      raise RuntimeError('f2cblaslapack does not support -known-64-bit-blas-indices')
30    config.package.Package.configureLibrary(self)
31
32  def Install(self):
33    import os
34
35    if self.defaultPrecision == '__float128': make_target = 'blas_qlib lapack_qlib'
36    elif self.defaultPrecision == '__fp16': make_target   = 'blas_hlib lapack_hlib'
37    elif self.blis.found: make_target = 'blasaux_lib lapack_lib'
38    else: make_target = 'blas_lib lapack_lib'
39
40    if self.argDB['with-f2cblaslapack-float128-bindings'] and self.defaultPrecision != '__fp128':
41      if not self.scalartypes.have__float128:
42        raise RuntimeError('No __float128 support provided by the compiler, cannot use --with-f2cblaslapack-float128-bindings')
43      if self.defaultPrecision == '__fp16':
44        make_target = 'blas_qhlib lapack_qhlib'
45      else:
46        make_target = 'blas_qlib lapack_qlib'
47    if self.argDB['with-f2cblaslapack-fp16-bindings'] and self.defaultPrecision != '__fp16':
48      if not self.scalartypes.have__fp16:
49        raise RuntimeError('No __fp16 support provided by the compiler, cannot use --with-f2cblaslapack-fp16-bindings')
50      if self.defaultPrecision == '__float128' or self.argDB['with-f2cblaslapack-float128-bindings']:
51        make_target = 'blas_qhlib lapack_qhlib'
52      else:
53        make_target = 'blas_hlib lapack_hlib'
54
55    libdir = self.libDir
56    confdir = self.confDir
57
58    with open(os.path.join(self.packageDir,'tmpmakefile'),'w') as g:
59      with open(os.path.join(self.packageDir,'makefile'),'r') as f:
60        for line in f:
61          if line.startswith('CC  '):
62            cc = self.compilers.CC
63            line = 'CC = '+cc+'\n'
64          if line.startswith('COPTFLAGS '):
65            self.pushLanguage('C')
66            line = 'COPTFLAGS  = '+self.updatePackageCFlags(self.getCompilerFlags())+'\n'
67            self.popLanguage()
68          if line.startswith('CNOOPT'):
69            self.pushLanguage('C')
70            noopt = self.checkNoOptFlag()
71            line = 'CNOOPT = '+noopt+ ' '+self.getSharedFlag(self.getCompilerFlags())+' '+self.getPointerSizeFlag(self.getCompilerFlags())+' '+self.getWindowsNonOptFlags(self.getCompilerFlags())+'\n'
72            self.popLanguage()
73          if line.startswith('AR  '):
74            line = 'AR      = '+self.setCompilers.AR+'\n'
75          if line.startswith('AR_FLAGS  '):
76            line = 'AR_FLAGS      = '+self.setCompilers.AR_FLAGS+'\n'
77          if line.startswith('LIB_SUFFIX '):
78            line = 'LIB_SUFFIX = '+self.setCompilers.AR_LIB_SUFFIX+'\n'
79          if line.startswith('RANLIB  '):
80            line = 'RANLIB = '+self.setCompilers.RANLIB+'\n'
81          if line.startswith('RM  '):
82            line = 'RM = '+self.programs.RM+'\nMAKE = '+self.make.make+'\n'
83          if line.startswith('include'):
84            line = '\n'
85          if line.find("-no-prec-div") >= 0:
86             raise RuntimeError('Some versions of the Intel compiler generate incorrect code on f2cblaslapack with the option -no-prec-div\nRun configure without this option')
87          g.write(line)
88        otherlibs = '''
89blas_hlib:\n\
90\t-@cd blas;   $(MAKE) hlib $(MAKE_OPTIONS_BLAS)\n\
91\t-@$(RANLIB) $(BLAS_LIB_NAME)\n\
92lapack_hlib:\n\
93\t-@cd lapack; $(MAKE) hlib $(MAKE_OPTIONS_LAPACK)\n\
94\t-@$(RANLIB) $(LAPACK_LIB_NAME)\n\
95blas_qlib:\n\
96\t-@cd blas;   $(MAKE) qlib $(MAKE_OPTIONS_BLAS)\n\
97\t-@$(RANLIB) $(BLAS_LIB_NAME)\n\
98lapack_qlib:\n\
99\t-@cd lapack; $(MAKE) qlib $(MAKE_OPTIONS_LAPACK)\n\
100\t-@$(RANLIB) $(LAPACK_LIB_NAME)\n\
101blas_qhlib:\n\
102\t-@cd blas;   $(MAKE) qhlib $(MAKE_OPTIONS_BLAS)\n\
103\t-@$(RANLIB) $(BLAS_LIB_NAME)\n\
104lapack_qhlib:\n\
105\t-@cd lapack; $(MAKE) qhlib $(MAKE_OPTIONS_LAPACK)\n\
106\t-@$(RANLIB) $(LAPACK_LIB_NAME)\n'''
107      g.write(otherlibs)
108
109    if not self.installNeeded('tmpmakefile'): return self.installDir
110
111    try:
112      self.logPrintBox('Compiling F2CBLASLAPACK; this may take several minutes')
113      output1,err1,ret  = config.package.Package.executeShellCommandSeq([
114        self.make.make_jnp_list + ['-f', 'tmpmakefile', 'cleanblaslapck', 'cleanlib'],
115        self.make.make_jnp_list + ['-f', 'tmpmakefile'] + make_target.split(),
116        ], cwd=self.packageDir, timeout=2500, log = self.log)
117    except RuntimeError as e:
118      self.logPrint('Error running make on '+self.packageDir+': '+str(e))
119      raise RuntimeError('Error running make on '+self.packageDir)
120    try:
121      self.logPrintBox('Installing F2CBLASLAPACK; this may take several minutes')
122      output2,err2,ret  = config.package.Package.executeShellCommandSeq([
123        ['mkdir', '-p', libdir],
124        ['cp', '-f', 'libf2clapack.' + self.setCompilers.AR_LIB_SUFFIX, 'libf2cblas.' + self.setCompilers.AR_LIB_SUFFIX, libdir],
125        ], cwd=self.packageDir, timeout=60, log = self.log)
126    except RuntimeError as e:
127      self.logPrint('Error moving '+self.packageDir+' libraries: '+str(e))
128      raise RuntimeError('Error moving '+self.packageDir+' libraries')
129    self.postInstall(output1+err1+output2+err2,'tmpmakefile')
130    return self.installDir
131