Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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])