| 986 |
slepc |
1 |
#!/usr/bin/env python
|
|
|
2 |
#!/bin/env python
|
|
|
3 |
#
|
| 1377 |
slepc |
4 |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| 1672 |
slepc |
5 |
# SLEPc - Scalable Library for Eigenvalue Problem Computations
|
|
|
6 |
# Copyright (c) 2002-2009, Universidad Politecnica de Valencia, Spain
|
| 1377 |
slepc |
7 |
#
|
| 1672 |
slepc |
8 |
# This file is part of SLEPc.
|
|
|
9 |
#
|
|
|
10 |
# SLEPc is free software: you can redistribute it and/or modify it under the
|
|
|
11 |
# terms of version 3 of the GNU Lesser General Public License as published by
|
|
|
12 |
# the Free Software Foundation.
|
|
|
13 |
#
|
|
|
14 |
# SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
15 |
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
16 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
|
|
17 |
# more details.
|
|
|
18 |
#
|
|
|
19 |
# You should have received a copy of the GNU Lesser General Public License
|
|
|
20 |
# along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
|
| 1377 |
slepc |
21 |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
22 |
#
|
| 986 |
slepc |
23 |
# Generates fortran stubs for PETSc using Sowings bfort program
|
|
|
24 |
#
|
|
|
25 |
import os
|
|
|
26 |
#
|
|
|
27 |
# Opens all generated files and fixes them; also generates list in makefile.src
|
|
|
28 |
#
|
|
|
29 |
def FixFile(filename):
|
|
|
30 |
import re
|
|
|
31 |
ff = open(filename)
|
|
|
32 |
data = ff.read()
|
|
|
33 |
ff.close()
|
|
|
34 |
|
|
|
35 |
# gotta be a better way to do this
|
|
|
36 |
data = re.subn('\nvoid ','\nvoid PETSC_STDCALL ',data)[0]
|
|
|
37 |
data = re.subn('\nPetscErrorCode ','\nvoid PETSC_STDCALL ',data)[0]
|
|
|
38 |
data = re.subn('Petsc([ToRm]*)Pointer\(int\)','Petsc\\1Pointer(void*)',data)[0]
|
|
|
39 |
data = re.subn('PetscToPointer\(a\) \(a\)','PetscToPointer(a) (*(long *)(a))',data)[0]
|
|
|
40 |
data = re.subn('PetscFromPointer\(a\) \(int\)\(a\)','PetscFromPointer(a) (long)(a)',data)[0]
|
|
|
41 |
data = re.subn('PetscToPointer\( \*\(int\*\)','PetscToPointer(',data)[0]
|
|
|
42 |
data = re.subn('MPI_Comm comm','MPI_Comm *comm',data)[0]
|
| 1531 |
slepc |
43 |
data = re.subn('\(MPI_Comm\)PetscToPointer\( \(comm\) \)','MPI_Comm_f2c(*(MPI_Fint*)(comm))',data)[0]
|
| 986 |
slepc |
44 |
data = re.subn('\(PetscInt\* \)PetscToPointer','',data)[0]
|
|
|
45 |
match = re.compile(r"""\b(PETSC)(_DLL|VEC_DLL|MAT_DLL|DM_DLL|KSP_DLL|SNES_DLL|TS_DLL|FORTRAN_DLL)(EXPORT)""")
|
|
|
46 |
data = match.sub(r'',data)
|
|
|
47 |
|
|
|
48 |
ff = open(filename, 'w')
|
|
|
49 |
ff.write('#include "petsc.h"\n#include "petscfix.h"\n'+data)
|
|
|
50 |
ff.close()
|
|
|
51 |
return
|
|
|
52 |
|
| 1531 |
slepc |
53 |
def FixDir(petscdir,dir):
|
|
|
54 |
mansec = 'unknown'
|
|
|
55 |
cnames = []
|
|
|
56 |
hnames = []
|
|
|
57 |
parentdir =os.path.abspath(os.path.join(dir,'..'))
|
| 986 |
slepc |
58 |
for f in os.listdir(dir):
|
| 1531 |
slepc |
59 |
ext = os.path.splitext(f)[1]
|
|
|
60 |
if ext == '.c':
|
| 986 |
slepc |
61 |
FixFile(os.path.join(dir, f))
|
| 1531 |
slepc |
62 |
cnames.append(f)
|
|
|
63 |
elif ext == '.h90':
|
|
|
64 |
hnames.append(f)
|
|
|
65 |
if (cnames != [] or hnames != []):
|
|
|
66 |
mfile=os.path.abspath(os.path.join(parentdir,'makefile'))
|
| 986 |
slepc |
67 |
try:
|
|
|
68 |
fd=open(mfile,'r')
|
|
|
69 |
except:
|
|
|
70 |
print 'Error! missing file:', mfile
|
|
|
71 |
return
|
|
|
72 |
inbuf = fd.read()
|
|
|
73 |
fd.close()
|
| 1531 |
slepc |
74 |
cppflags = ""
|
| 986 |
slepc |
75 |
libbase = ""
|
|
|
76 |
locdir = ""
|
|
|
77 |
for line in inbuf.splitlines():
|
| 1531 |
slepc |
78 |
if line.find('CPPFLAGS') >=0:
|
|
|
79 |
cppflags = line
|
| 986 |
slepc |
80 |
if line.find('LIBBASE') >=0:
|
|
|
81 |
libbase = line
|
|
|
82 |
elif line.find('LOCDIR') >=0:
|
|
|
83 |
locdir = line.rstrip() + 'ftn-auto/'
|
| 1531 |
slepc |
84 |
elif line.find('MANSEC') >=0:
|
|
|
85 |
mansec = line.split('=')[1].lower().strip()
|
| 986 |
slepc |
86 |
|
|
|
87 |
# now assemble the makefile
|
|
|
88 |
outbuf = '\n'
|
|
|
89 |
outbuf += "#requirespackage 'PETSC_HAVE_FORTRAN'\n"
|
|
|
90 |
outbuf += 'ALL: lib\n'
|
| 1531 |
slepc |
91 |
outbuf += cppflags + '\n'
|
| 986 |
slepc |
92 |
outbuf += 'CFLAGS =\n'
|
|
|
93 |
outbuf += 'FFLAGS =\n'
|
| 1531 |
slepc |
94 |
outbuf += 'SOURCEC = ' +' '.join(cnames)+ '\n'
|
|
|
95 |
outbuf += 'OBJSC = ' +' '.join(cnames).replace('.c','.o')+ '\n'
|
| 986 |
slepc |
96 |
outbuf += 'SOURCEF =\n'
|
| 1531 |
slepc |
97 |
outbuf += 'SOURCEH = ' +' '.join(hnames)+ '\n'
|
| 986 |
slepc |
98 |
outbuf += 'DIRS =\n'
|
| 1075 |
slepc |
99 |
outbuf += libbase + '\n'
|
| 986 |
slepc |
100 |
outbuf += locdir + '\n'
|
| 1523 |
slepc |
101 |
# outbuf += 'include ${PETSC_DIR}/conf/base\n'
|
|
|
102 |
# outbuf += 'include ${PETSC_DIR}/conf/test\n'
|
| 1531 |
slepc |
103 |
outbuf += 'include ${SLEPC_DIR}/conf/slepc_common \n'
|
| 986 |
slepc |
104 |
ff = open(os.path.join(dir, 'makefile'), 'w')
|
|
|
105 |
ff.write(outbuf)
|
|
|
106 |
ff.close()
|
|
|
107 |
|
|
|
108 |
# if dir is empty - remove it
|
|
|
109 |
if os.path.exists(dir) and os.path.isdir(dir) and os.listdir(dir) == []:
|
|
|
110 |
os.rmdir(dir)
|
| 1531 |
slepc |
111 |
|
|
|
112 |
# Now process f90module.f90 file - and update include/finclude/ftn-auto
|
|
|
113 |
modfile = os.path.join(parentdir,'f90module.f90')
|
|
|
114 |
if os.path.exists(modfile):
|
|
|
115 |
fd = open(modfile)
|
|
|
116 |
txt = fd.read()
|
|
|
117 |
fd.close()
|
|
|
118 |
|
|
|
119 |
if txt and mansec == 'unknown':
|
|
|
120 |
print 'makefile has missing MANSEC',parentdir
|
|
|
121 |
elif txt:
|
|
|
122 |
ftype = 'w'
|
| 1545 |
slepc |
123 |
f90inc = os.path.join(petscdir,'include','finclude','ftn-auto','slepc'+mansec+'.h90')
|
| 1531 |
slepc |
124 |
if os.path.exists(f90inc): ftype = 'a'
|
|
|
125 |
fd = open(f90inc,ftype)
|
|
|
126 |
fd.write(txt)
|
|
|
127 |
fd.close()
|
|
|
128 |
os.remove(modfile)
|
| 986 |
slepc |
129 |
return
|
|
|
130 |
|
|
|
131 |
def PrepFtnDir(dir):
|
|
|
132 |
if os.path.exists(dir) and not os.path.isdir(dir):
|
|
|
133 |
raise RuntimeError('Error - specified path is not a dir: ' + dir)
|
|
|
134 |
elif not os.path.exists(dir):
|
|
|
135 |
os.mkdir(dir)
|
|
|
136 |
else:
|
|
|
137 |
files = os.listdir(dir)
|
|
|
138 |
for file in files:
|
|
|
139 |
os.remove(os.path.join(dir,file))
|
|
|
140 |
return
|
|
|
141 |
|
|
|
142 |
def processDir(arg,dirname,names):
|
|
|
143 |
import commands
|
|
|
144 |
petscdir = arg[0]
|
|
|
145 |
bfort = arg[1]
|
|
|
146 |
newls = []
|
| 1531 |
slepc |
147 |
outdir = os.path.join(dirname,'ftn-auto')
|
|
|
148 |
|
|
|
149 |
# skip include/finclude/ftn-auto - as this is processed separately
|
|
|
150 |
if os.path.realpath(os.path.join(petscdir,'include','finclude','ftn-auto')) == os.path.realpath(outdir): return
|
|
|
151 |
|
| 986 |
slepc |
152 |
for l in names:
|
|
|
153 |
if os.path.splitext(l)[1] =='.c' or os.path.splitext(l)[1] == '.h':
|
|
|
154 |
newls.append(l)
|
|
|
155 |
if newls:
|
|
|
156 |
PrepFtnDir(outdir)
|
|
|
157 |
options = ['-dir '+outdir, '-mnative', '-ansi', '-nomsgs', '-noprofile', '-anyname', '-mapptr',
|
|
|
158 |
'-mpi', '-mpi2', '-ferr', '-ptrprefix Petsc', '-ptr64 PETSC_USE_POINTER_CONVERSION',
|
| 1531 |
slepc |
159 |
'-fcaps PETSC_HAVE_FORTRAN_CAPS', '-fuscore PETSC_HAVE_FORTRAN_UNDERSCORE','-f90mod_skip_header']
|
| 986 |
slepc |
160 |
(status,output) = commands.getstatusoutput('cd '+dirname+';'+bfort+' '+' '.join(options+newls))
|
|
|
161 |
if status:
|
|
|
162 |
raise RuntimeError('Error running bfort '+output)
|
| 1531 |
slepc |
163 |
FixDir(petscdir,outdir)
|
|
|
164 |
for name in ['.hg','SCCS', 'output', 'BitKeeper', 'examples', 'externalpackages', 'bilinear', 'ftn-auto','fortran','bin','maint','ftn-custom','config','f90-custom']:
|
| 986 |
slepc |
165 |
if name in names:
|
|
|
166 |
names.remove(name)
|
| 1531 |
slepc |
167 |
# check for configure generated PETSC_ARCHes
|
|
|
168 |
rmnames=[]
|
|
|
169 |
for name in names:
|
|
|
170 |
if os.path.isdir(os.path.join(name,'conf')):
|
|
|
171 |
rmnames.append(name)
|
|
|
172 |
for rmname in rmnames:
|
|
|
173 |
names.remove(rmname)
|
| 986 |
slepc |
174 |
return
|
|
|
175 |
|
|
|
176 |
def main(bfort):
|
|
|
177 |
petscdir = os.getcwd()
|
|
|
178 |
tmpdir = os.path
|
| 1531 |
slepc |
179 |
ftnautoinc = os.path.join(petscdir,'include','finclude','ftn-auto')
|
|
|
180 |
PrepFtnDir(ftnautoinc)
|
| 986 |
slepc |
181 |
os.path.walk(petscdir, processDir, [petscdir, bfort])
|
| 1531 |
slepc |
182 |
FixDir(petscdir,ftnautoinc)
|
| 986 |
slepc |
183 |
return
|
|
|
184 |
#
|
|
|
185 |
# The classes in this file can also be used in other python-programs by using 'import'
|
|
|
186 |
#
|
|
|
187 |
if __name__ == '__main__':
|
|
|
188 |
import sys
|
| 1335 |
slepc |
189 |
if len(sys.argv) < 2:
|
|
|
190 |
sys.exit('Must give the BFORT program as the first argument')
|
| 986 |
slepc |
191 |
main(sys.argv[1])
|