forked from scipy/scipy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_cython_signature_generator.py
198 lines (181 loc) · 11.8 KB
/
_cython_signature_generator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
"""
A script that uses f2py to generate the signature files used to make
the Cython BLAS and LAPACK wrappers from the fortran source code for
LAPACK and the reference BLAS.
To generate the BLAS wrapper signatures call:
python _cython_signature_generator.py blas <blas_directory> <out_file>
To generate the LAPACK wrapper signatures call:
python _cython_signature_generator.py lapack <lapack_src_directory> <out_file>
This script expects to be run on the source directory for
the oldest supported version of LAPACK (currently 3.4.0).
"""
import glob
import os
from numpy.f2py import crackfortran
sig_types = {'integer': 'int',
'complex': 'c',
'double precision': 'd',
'real': 's',
'complex*16': 'z',
'double complex': 'z',
'character': 'char',
'logical': 'bint'}
def get_type(info, arg):
argtype = sig_types[info['vars'][arg]['typespec']]
if argtype == 'c' and info['vars'][arg].get('kindselector') is not None:
argtype = 'z'
return argtype
def make_signature(filename):
info = crackfortran.crackfortran(filename)[0]
name = info['name']
if info['block'] == 'subroutine':
return_type = 'void'
else:
return_type = get_type(info, name)
arglist = [' *'.join([get_type(info, arg), arg]) for arg in info['args']]
args = ', '.join(arglist)
# Eliminate strange variable naming that replaces rank with rank_bn.
args = args.replace('rank_bn', 'rank')
return '{0} {1}({2})\n'.format(return_type, name, args)
def get_sig_name(line):
return line.split('(')[0].split(' ')[-1]
def sigs_from_dir(directory, outfile, manual_wrappers=None, exclusions=None):
if directory[-1] in ['/', '\\']:
directory = directory[:-1]
files = sorted(glob.glob(directory + '/*.f*'))
if exclusions is None:
exclusions = []
if manual_wrappers is not None:
exclusions += [get_sig_name(l) for l in manual_wrappers.split('\n')]
signatures = []
for filename in files:
name = os.path.splitext(os.path.basename(filename))[0]
if name in exclusions:
continue
signatures.append(make_signature(filename))
if manual_wrappers is not None:
signatures += [l + '\n' for l in manual_wrappers.split('\n')]
signatures.sort(key=get_sig_name)
comment = ["# This file was generated by _cython_signature_generator.py.\n",
"# Do not edit this file directly.\n\n"]
with open(outfile, 'w') as f:
f.writelines(comment)
f.writelines(signatures)
# slamch and dlamch are not in the lapack src directory, but,since they
# already have Python wrappers, we'll wrap them as well.
# The other manual signatures are used because the signature generating
# functions don't work when function pointer arguments are used.
lapack_manual_wrappers = '''void cgees(char *jobvs, char *sort, cselect1 *select, int *n, c *a, int *lda, int *sdim, c *w, c *vs, int *ldvs, c *work, int *lwork, s *rwork, bint *bwork, int *info)
void cgeesx(char *jobvs, char *sort, cselect1 *select, char *sense, int *n, c *a, int *lda, int *sdim, c *w, c *vs, int *ldvs, s *rconde, s *rcondv, c *work, int *lwork, s *rwork, bint *bwork, int *info)
void cgges(char *jobvsl, char *jobvsr, char *sort, cselect2 *selctg, int *n, c *a, int *lda, c *b, int *ldb, int *sdim, c *alpha, c *beta, c *vsl, int *ldvsl, c *vsr, int *ldvsr, c *work, int *lwork, s *rwork, bint *bwork, int *info)
void cggesx(char *jobvsl, char *jobvsr, char *sort, cselect2 *selctg, char *sense, int *n, c *a, int *lda, c *b, int *ldb, int *sdim, c *alpha, c *beta, c *vsl, int *ldvsl, c *vsr, int *ldvsr, s *rconde, s *rcondv, c *work, int *lwork, s *rwork, int *iwork, int *liwork, bint *bwork, int *info)
void dgees(char *jobvs, char *sort, dselect2 *select, int *n, d *a, int *lda, int *sdim, d *wr, d *wi, d *vs, int *ldvs, d *work, int *lwork, bint *bwork, int *info)
void dgeesx(char *jobvs, char *sort, dselect2 *select, char *sense, int *n, d *a, int *lda, int *sdim, d *wr, d *wi, d *vs, int *ldvs, d *rconde, d *rcondv, d *work, int *lwork, int *iwork, int *liwork, bint *bwork, int *info)
void dgges(char *jobvsl, char *jobvsr, char *sort, dselect3 *selctg, int *n, d *a, int *lda, d *b, int *ldb, int *sdim, d *alphar, d *alphai, d *beta, d *vsl, int *ldvsl, d *vsr, int *ldvsr, d *work, int *lwork, bint *bwork, int *info)
void dggesx(char *jobvsl, char *jobvsr, char *sort, dselect3 *selctg, char *sense, int *n, d *a, int *lda, d *b, int *ldb, int *sdim, d *alphar, d *alphai, d *beta, d *vsl, int *ldvsl, d *vsr, int *ldvsr, d *rconde, d *rcondv, d *work, int *lwork, int *iwork, int *liwork, bint *bwork, int *info)
d dlamch(char *cmach)
void ilaver(int *vers_major, int *vers_minor, int *vers_patch)
void sgees(char *jobvs, char *sort, sselect2 *select, int *n, s *a, int *lda, int *sdim, s *wr, s *wi, s *vs, int *ldvs, s *work, int *lwork, bint *bwork, int *info)
void sgeesx(char *jobvs, char *sort, sselect2 *select, char *sense, int *n, s *a, int *lda, int *sdim, s *wr, s *wi, s *vs, int *ldvs, s *rconde, s *rcondv, s *work, int *lwork, int *iwork, int *liwork, bint *bwork, int *info)
void sgges(char *jobvsl, char *jobvsr, char *sort, sselect3 *selctg, int *n, s *a, int *lda, s *b, int *ldb, int *sdim, s *alphar, s *alphai, s *beta, s *vsl, int *ldvsl, s *vsr, int *ldvsr, s *work, int *lwork, bint *bwork, int *info)
void sggesx(char *jobvsl, char *jobvsr, char *sort, sselect3 *selctg, char *sense, int *n, s *a, int *lda, s *b, int *ldb, int *sdim, s *alphar, s *alphai, s *beta, s *vsl, int *ldvsl, s *vsr, int *ldvsr, s *rconde, s *rcondv, s *work, int *lwork, int *iwork, int *liwork, bint *bwork, int *info)
s slamch(char *cmach)
void zgees(char *jobvs, char *sort, zselect1 *select, int *n, z *a, int *lda, int *sdim, z *w, z *vs, int *ldvs, z *work, int *lwork, d *rwork, bint *bwork, int *info)
void zgeesx(char *jobvs, char *sort, zselect1 *select, char *sense, int *n, z *a, int *lda, int *sdim, z *w, z *vs, int *ldvs, d *rconde, d *rcondv, z *work, int *lwork, d *rwork, bint *bwork, int *info)
void zgges(char *jobvsl, char *jobvsr, char *sort, zselect2 *selctg, int *n, z *a, int *lda, z *b, int *ldb, int *sdim, z *alpha, z *beta, z *vsl, int *ldvsl, z *vsr, int *ldvsr, z *work, int *lwork, d *rwork, bint *bwork, int *info)
void zggesx(char *jobvsl, char *jobvsr, char *sort, zselect2 *selctg, char *sense, int *n, z *a, int *lda, z *b, int *ldb, int *sdim, z *alpha, z *beta, z *vsl, int *ldvsl, z *vsr, int *ldvsr, d *rconde, d *rcondv, z *work, int *lwork, d *rwork, int *iwork, int *liwork, bint *bwork, int *info)'''
if __name__ == '__main__':
from sys import argv
libname, src_dir, outfile = argv[1:]
# Exclude scabs and sisnan since they aren't currently included
# in the scipy-specific ABI wrappers.
if libname.lower() == 'blas':
sigs_from_dir(src_dir, outfile, exclusions=['scabs1', 'xerbla'])
elif libname.lower() == 'lapack':
# Exclude all routines that do not have consistent interfaces from
# LAPACK 3.4.0 through 3.6.0.
# Also exclude routines with string arguments to avoid
# compatibility woes with different standards for string arguments.
exclusions = [
# Not included because people should be using the
# C standard library function instead.
# sisnan is also not currently included in the
# ABI wrappers.
'sisnan', 'dlaisnan', 'slaisnan',
# Exclude slaneg because it isn't currently included
# in the ABI wrappers
'slaneg',
# Excluded because they require Fortran string arguments.
'ilaenv', 'iparmq', 'lsamen', 'xerbla',
# Exclude XBLAS routines since they aren't included
# by default.
'cgesvxx', 'dgesvxx', 'sgesvxx', 'zgesvxx',
'cgerfsx', 'dgerfsx', 'sgerfsx', 'zgerfsx',
'cla_gerfsx_extended', 'dla_gerfsx_extended',
'sla_gerfsx_extended', 'zla_gerfsx_extended',
'cla_geamv', 'dla_geamv', 'sla_geamv', 'zla_geamv',
'dla_gercond', 'sla_gercond',
'cla_gercond_c', 'zla_gercond_c',
'cla_gercond_x', 'zla_gercond_x',
'cla_gerpvgrw', 'dla_gerpvgrw',
'sla_gerpvgrw', 'zla_gerpvgrw',
'csysvxx', 'dsysvxx', 'ssysvxx', 'zsysvxx',
'csyrfsx', 'dsyrfsx', 'ssyrfsx', 'zsyrfsx',
'cla_syrfsx_extended', 'dla_syrfsx_extended',
'sla_syrfsx_extended', 'zla_syrfsx_extended',
'cla_syamv', 'dla_syamv', 'sla_syamv', 'zla_syamv',
'dla_syrcond', 'sla_syrcond',
'cla_syrcond_c', 'zla_syrcond_c',
'cla_syrcond_x', 'zla_syrcond_x',
'cla_syrpvgrw', 'dla_syrpvgrw',
'sla_syrpvgrw', 'zla_syrpvgrw',
'cposvxx', 'dposvxx', 'sposvxx', 'zposvxx',
'cporfsx', 'dporfsx', 'sporfsx', 'zporfsx',
'cla_porfsx_extended', 'dla_porfsx_extended',
'sla_porfsx_extended', 'zla_porfsx_extended',
'dla_porcond', 'sla_porcond',
'cla_porcond_c', 'zla_porcond_c',
'cla_porcond_x', 'zla_porcond_x',
'cla_porpvgrw', 'dla_porpvgrw',
'sla_porpvgrw', 'zla_porpvgrw',
'cgbsvxx', 'dgbsvxx', 'sgbsvxx', 'zgbsvxx',
'cgbrfsx', 'dgbrfsx', 'sgbrfsx', 'zgbrfsx',
'cla_gbrfsx_extended', 'dla_gbrfsx_extended',
'sla_gbrfsx_extended', 'zla_gbrfsx_extended',
'cla_gbamv', 'dla_gbamv', 'sla_gbamv', 'zla_gbamv',
'dla_gbrcond', 'sla_gbrcond',
'cla_gbrcond_c', 'zla_gbrcond_c',
'cla_gbrcond_x', 'zla_gbrcond_x',
'cla_gbrpvgrw', 'dla_gbrpvgrw',
'sla_gbrpvgrw', 'zla_gbrpvgrw',
'chesvxx', 'zhesvxx',
'cherfsx', 'zherfsx',
'cla_herfsx_extended', 'zla_herfsx_extended',
'cla_heamv', 'zla_heamv',
'cla_hercond_c', 'zla_hercond_c',
'cla_hercond_x', 'zla_hercond_x',
'cla_herpvgrw', 'zla_herpvgrw',
'sla_lin_berr', 'cla_lin_berr',
'dla_lin_berr', 'zla_lin_berr',
'clarscl2', 'dlarscl2', 'slarscl2', 'zlarscl2',
'clascl2', 'dlascl2', 'slascl2', 'zlascl2',
'cla_wwaddw', 'dla_wwaddw', 'sla_wwaddw', 'zla_wwaddw',
# Removed between 3.3.1 and 3.4.0.
'cla_rpvgrw', 'dla_rpvgrw', 'sla_rpvgrw', 'zla_rpvgrw',
# Signatures changed between 3.4.0 and 3.4.1.
'dlasq5', 'slasq5',
# Routines deprecated in LAPACK 3.6.0
'cgegs', 'cgegv', 'cgelsx',
'cgeqpf', 'cggsvd', 'cggsvp',
'clahrd', 'clatzm', 'ctzrqf',
'dgegs', 'dgegv', 'dgelsx',
'dgeqpf', 'dggsvd', 'dggsvp',
'dlahrd', 'dlatzm', 'dtzrqf',
'sgegs', 'sgegv', 'sgelsx',
'sgeqpf', 'sggsvd', 'sggsvp',
'slahrd', 'slatzm', 'stzrqf',
'zgegs', 'zgegv', 'zgelsx',
'zgeqpf', 'zggsvd', 'zggsvp',
'zlahrd', 'zlatzm', 'ztzrqf']
sigs_from_dir(src_dir, outfile, manual_wrappers=lapack_manual_wrappers,
exclusions=exclusions)