| 986 |
slepc |
1 |
#!/usr/bin/env python
|
|
|
2 |
#!/bin/env python
|
|
|
3 |
#
|
| 1377 |
slepc |
4 |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
5 |
# SLEPc - Scalable Library for Eigenvalue Problem Computations
|
|
|
6 |
# Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
|
|
|
7 |
#
|
|
|
8 |
# This file is part of SLEPc. See the README file for conditions of use
|
|
|
9 |
# and additional information.
|
|
|
10 |
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
11 |
#
|
| 986 |
slepc |
12 |
# Generates fortran stubs for PETSc using Sowings bfort program
|
|
|
13 |
#
|
|
|
14 |
import os
|
|
|
15 |
#
|
|
|
16 |
# Opens all generated files and fixes them; also generates list in makefile.src
|
|
|
17 |
#
|
|
|
18 |
def FixFile(filename):
|
|
|
19 |
import re
|
|
|
20 |
ff = open(filename)
|
|
|
21 |
data = ff.read()
|
|
|
22 |
ff.close()
|
|
|
23 |
|
|
|
24 |
# gotta be a better way to do this
|
|
|
25 |
data = re.subn('\nvoid ','\nvoid PETSC_STDCALL ',data)[0]
|
|
|
26 |
data = re.subn('\nPetscErrorCode ','\nvoid PETSC_STDCALL ',data)[0]
|
|
|
27 |
data = re.subn('Petsc([ToRm]*)Pointer\(int\)','Petsc\\1Pointer(void*)',data)[0]
|
|
|
28 |
data = re.subn('PetscToPointer\(a\) \(a\)','PetscToPointer(a) (*(long *)(a))',data)[0]
|
|
|
29 |
data = re.subn('PetscFromPointer\(a\) \(int\)\(a\)','PetscFromPointer(a) (long)(a)',data)[0]
|
|
|
30 |
data = re.subn('PetscToPointer\( \*\(int\*\)','PetscToPointer(',data)[0]
|
|
|
31 |
data = re.subn('MPI_Comm comm','MPI_Comm *comm',data)[0]
|
|
|
32 |
data = re.subn('\(MPI_Comm\)PetscToPointer\( \(comm\) \)','(MPI_Comm)MPI_Comm_f2c(*(MPI_Fint*)(comm))',data)[0]
|
|
|
33 |
data = re.subn('\(PetscInt\* \)PetscToPointer','',data)[0]
|
|
|
34 |
match = re.compile(r"""\b(PETSC)(_DLL|VEC_DLL|MAT_DLL|DM_DLL|KSP_DLL|SNES_DLL|TS_DLL|FORTRAN_DLL)(EXPORT)""")
|
|
|
35 |
data = match.sub(r'',data)
|
|
|
36 |
|
|
|
37 |
ff = open(filename, 'w')
|
|
|
38 |
ff.write('#include "petsc.h"\n#include "petscfix.h"\n'+data)
|
|
|
39 |
ff.close()
|
|
|
40 |
return
|
|
|
41 |
|
|
|
42 |
def FixDir(dir):
|
|
|
43 |
names = []
|
|
|
44 |
for f in os.listdir(dir):
|
|
|
45 |
if os.path.splitext(f)[1] == '.c':
|
|
|
46 |
FixFile(os.path.join(dir, f))
|
|
|
47 |
names.append(f)
|
|
|
48 |
if not names == []:
|
|
|
49 |
mfile=os.path.abspath(os.path.join(dir,'..','makefile'))
|
|
|
50 |
try:
|
|
|
51 |
fd=open(mfile,'r')
|
|
|
52 |
except:
|
|
|
53 |
print 'Error! missing file:', mfile
|
|
|
54 |
return
|
|
|
55 |
inbuf = fd.read()
|
|
|
56 |
fd.close()
|
|
|
57 |
libbase = ""
|
|
|
58 |
locdir = ""
|
|
|
59 |
for line in inbuf.splitlines():
|
|
|
60 |
if line.find('LIBBASE') >=0:
|
|
|
61 |
libbase = line
|
|
|
62 |
elif line.find('LOCDIR') >=0:
|
|
|
63 |
locdir = line.rstrip() + 'ftn-auto/'
|
|
|
64 |
|
|
|
65 |
# now assemble the makefile
|
|
|
66 |
outbuf = '\n'
|
|
|
67 |
outbuf += "#requirespackage 'PETSC_HAVE_FORTRAN'\n"
|
|
|
68 |
outbuf += 'ALL: lib\n'
|
|
|
69 |
outbuf += 'CFLAGS =\n'
|
|
|
70 |
outbuf += 'FFLAGS =\n'
|
|
|
71 |
outbuf += 'SOURCEC = ' +' '.join(names)+ '\n'
|
|
|
72 |
outbuf += 'OBJSC = ' +' '.join(names).replace('.c','.o')+ '\n'
|
|
|
73 |
outbuf += 'SOURCEF =\n'
|
|
|
74 |
outbuf += 'SOURCEH =\n'
|
|
|
75 |
outbuf += 'DIRS =\n'
|
| 1075 |
slepc |
76 |
outbuf += libbase + '\n'
|
| 986 |
slepc |
77 |
outbuf += locdir + '\n'
|
|
|
78 |
# outbuf += 'include ${PETSC_DIR}/bmake/common/base\n'
|
|
|
79 |
# outbuf += 'include ${PETSC_DIR}/bmake/common/test\n'
|
|
|
80 |
outbuf += 'include ${SLEPC_DIR}/bmake/slepc_common \n'
|
|
|
81 |
ff = open(os.path.join(dir, 'makefile'), 'w')
|
|
|
82 |
ff.write(outbuf)
|
|
|
83 |
ff.close()
|
|
|
84 |
|
|
|
85 |
# if dir is empty - remove it
|
|
|
86 |
if os.path.exists(dir) and os.path.isdir(dir) and os.listdir(dir) == []:
|
|
|
87 |
os.rmdir(dir)
|
|
|
88 |
return
|
|
|
89 |
|
|
|
90 |
def PrepFtnDir(dir):
|
|
|
91 |
if os.path.exists(dir) and not os.path.isdir(dir):
|
|
|
92 |
raise RuntimeError('Error - specified path is not a dir: ' + dir)
|
|
|
93 |
elif not os.path.exists(dir):
|
|
|
94 |
os.mkdir(dir)
|
|
|
95 |
else:
|
|
|
96 |
files = os.listdir(dir)
|
|
|
97 |
for file in files:
|
|
|
98 |
os.remove(os.path.join(dir,file))
|
|
|
99 |
return
|
|
|
100 |
|
|
|
101 |
def processDir(arg,dirname,names):
|
|
|
102 |
import commands
|
|
|
103 |
petscdir = arg[0]
|
|
|
104 |
bfort = arg[1]
|
|
|
105 |
newls = []
|
|
|
106 |
for l in names:
|
|
|
107 |
if os.path.splitext(l)[1] =='.c' or os.path.splitext(l)[1] == '.h':
|
|
|
108 |
newls.append(l)
|
|
|
109 |
if newls:
|
|
|
110 |
outdir = os.path.join(dirname,'ftn-auto')
|
|
|
111 |
PrepFtnDir(outdir)
|
|
|
112 |
options = ['-dir '+outdir, '-mnative', '-ansi', '-nomsgs', '-noprofile', '-anyname', '-mapptr',
|
|
|
113 |
'-mpi', '-mpi2', '-ferr', '-ptrprefix Petsc', '-ptr64 PETSC_USE_POINTER_CONVERSION',
|
|
|
114 |
'-fcaps PETSC_HAVE_FORTRAN_CAPS', '-fuscore PETSC_HAVE_FORTRAN_UNDERSCORE']
|
|
|
115 |
(status,output) = commands.getstatusoutput('cd '+dirname+';'+bfort+' '+' '.join(options+newls))
|
|
|
116 |
if status:
|
|
|
117 |
raise RuntimeError('Error running bfort '+output)
|
|
|
118 |
FixDir(outdir)
|
| 1183 |
slepc |
119 |
for name in ['CVS', 'SCCS', 'output', 'BitKeeper', 'examples', 'externalpackages', 'bilinear', 'ftn-auto','fortran']:
|
| 986 |
slepc |
120 |
if name in names:
|
|
|
121 |
names.remove(name)
|
|
|
122 |
return
|
|
|
123 |
|
|
|
124 |
def main(bfort):
|
|
|
125 |
petscdir = os.getcwd()
|
|
|
126 |
tmpdir = os.path
|
|
|
127 |
os.path.walk(petscdir, processDir, [petscdir, bfort])
|
|
|
128 |
return
|
|
|
129 |
#
|
|
|
130 |
# The classes in this file can also be used in other python-programs by using 'import'
|
|
|
131 |
#
|
|
|
132 |
if __name__ == '__main__':
|
|
|
133 |
import sys
|
| 1335 |
slepc |
134 |
if len(sys.argv) < 2:
|
|
|
135 |
sys.exit('Must give the BFORT program as the first argument')
|
| 986 |
slepc |
136 |
main(sys.argv[1])
|