Subversion Repositories slepc-dev

Rev

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
#  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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])