Skip to content

Commit cac6705

Browse files
committed
move mkl_umath build system to meson
* removes cmake and setup.py from the project * vendors process_src_template.py from numpy and updates vendored conv_template.py * updates build scripts * updates meta.yaml * updates pyproject.toml * adds meson.build and meson.options
1 parent 52b0dcf commit cac6705

14 files changed

Lines changed: 328 additions & 331 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 147 deletions
This file was deleted.

_vendored/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
## Vendored files
22

3-
File `conv_template.py` is copied from NumPy's numpy/distutils folder, since
4-
`numpy.distutils` is absent from the installation layout starting with
5-
Python 3.12
3+
Files `conv_template.py` and `process_src_template.py` are copied from NumPy's numpy/numpy/_build_utils folder

_vendored/conv_template.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@
8282
__all__ = ['process_str', 'process_file']
8383

8484
import os
85-
import sys
8685
import re
86+
import sys
8787

8888
# names for replacement that are already global.
8989
global_names = {}
@@ -106,12 +106,12 @@ def parse_structure(astr, level):
106106
at zero. Returns an empty list if no loops found.
107107
108108
"""
109-
if level == 0 :
109+
if level == 0:
110110
loopbeg = "/**begin repeat"
111111
loopend = "/**end repeat**/"
112-
else :
113-
loopbeg = "/**begin repeat%d" % level
114-
loopend = "/**end repeat%d**/" % level
112+
else:
113+
loopbeg = f"/**begin repeat{level}"
114+
loopend = f"/**end repeat{level}**/"
115115

116116
ind = 0
117117
line = 0
@@ -124,9 +124,9 @@ def parse_structure(astr, level):
124124
start2 = astr.find("\n", start2)
125125
fini1 = astr.find(loopend, start2)
126126
fini2 = astr.find("\n", fini1)
127-
line += astr.count("\n", ind, start2+1)
128-
spanlist.append((start, start2+1, fini1, fini2+1, line))
129-
line += astr.count("\n", start2+1, fini2)
127+
line += astr.count("\n", ind, start2 + 1)
128+
spanlist.append((start, start2 + 1, fini1, fini2 + 1, line))
129+
line += astr.count("\n", start2 + 1, fini2)
130130
ind = fini2
131131
spanlist.sort()
132132
return spanlist
@@ -135,10 +135,13 @@ def parse_structure(astr, level):
135135
def paren_repl(obj):
136136
torep = obj.group(1)
137137
numrep = obj.group(2)
138-
return ','.join([torep]*int(numrep))
138+
return ','.join([torep] * int(numrep))
139+
139140

140141
parenrep = re.compile(r"\(([^)]*)\)\*(\d+)")
141142
plainrep = re.compile(r"([^*]+)\*(\d+)")
143+
144+
142145
def parse_values(astr):
143146
# replaces all occurrences of '(a,b,c)*4' in astr
144147
# with 'a,b,c,a,b,c,a,b,c,a,b,c'. Empty braces generate
@@ -155,7 +158,7 @@ def parse_values(astr):
155158
named_re = re.compile(r"#\s*(\w*)\s*=([^#]*)#")
156159
exclude_vars_re = re.compile(r"(\w*)=(\w*)")
157160
exclude_re = re.compile(":exclude:")
158-
def parse_loop_header(loophead) :
161+
def parse_loop_header(loophead):
159162
"""Find all named replacements in the header
160163
161164
Returns a list of dictionaries, one for each loop iteration,
@@ -179,14 +182,13 @@ def parse_loop_header(loophead) :
179182
name = rep[0]
180183
vals = parse_values(rep[1])
181184
size = len(vals)
182-
if nsub is None :
185+
if nsub is None:
183186
nsub = size
184-
elif nsub != size :
187+
elif nsub != size:
185188
msg = "Mismatch in number of values, %d != %d\n%s = %s"
186189
raise ValueError(msg % (nsub, size, name, vals))
187190
names.append((name, vals))
188191

189-
190192
# Find any exclude variables
191193
excludes = []
192194

@@ -200,30 +202,33 @@ def parse_loop_header(loophead) :
200202

201203
# generate list of dictionaries, one for each template iteration
202204
dlist = []
203-
if nsub is None :
205+
if nsub is None:
204206
raise ValueError("No substitution variables found")
205207
for i in range(nsub):
206208
tmp = {name: vals[i] for name, vals in names}
207209
dlist.append(tmp)
208210
return dlist
209211

212+
210213
replace_re = re.compile(r"@(\w+)@")
211-
def parse_string(astr, env, level, line) :
212-
lineno = "#line %d\n" % line
214+
215+
216+
def parse_string(astr, env, level, line):
217+
lineno = f"#line {line}\n"
213218

214219
# local function for string replacement, uses env
215220
def replace(match):
216221
name = match.group(1)
217-
try :
222+
try:
218223
val = env[name]
219224
except KeyError:
220-
msg = 'line %d: no definition of key "%s"'%(line, name)
225+
msg = f'line {line}: no definition of key "{name}"'
221226
raise ValueError(msg) from None
222227
return val
223228

224229
code = [lineno]
225230
struct = parse_structure(astr, level)
226-
if struct :
231+
if struct:
227232
# recurse over inner loops
228233
oldend = 0
229234
newlevel = level + 1
@@ -234,18 +239,18 @@ def replace(match):
234239
oldend = sub[3]
235240
newline = line + sub[4]
236241
code.append(replace_re.sub(replace, pref))
237-
try :
242+
try:
238243
envlist = parse_loop_header(head)
239244
except ValueError as e:
240-
msg = "line %d: %s" % (newline, e)
245+
msg = f"line {newline}: {e}"
241246
raise ValueError(msg)
242-
for newenv in envlist :
247+
for newenv in envlist:
243248
newenv.update(env)
244249
newcode = parse_string(text, newenv, newlevel, newline)
245250
code.extend(newcode)
246251
suff = astr[oldend:]
247252
code.append(replace_re.sub(replace, suff))
248-
else :
253+
else:
249254
# replace keys
250255
code.append(replace_re.sub(replace, astr))
251256
code.append('\n')
@@ -284,8 +289,8 @@ def process_file(source):
284289
try:
285290
code = process_str(''.join(lines))
286291
except ValueError as e:
287-
raise ValueError('In "%s" loop at %s' % (sourcefile, e)) from None
288-
return '#line 1 "%s"\n%s' % (sourcefile, code)
292+
raise ValueError(f'In "{sourcefile}" loop at {e}') from None
293+
return f'#line 1 "{sourcefile}"\n{code}'
289294

290295

291296
def unique_key(adict):
@@ -321,9 +326,10 @@ def main():
321326
try:
322327
writestr = process_str(allstr)
323328
except ValueError as e:
324-
raise ValueError("In %s loop at %s" % (file, e)) from None
329+
raise ValueError(f"In {file} loop at {e}") from None
325330

326331
outfile.write(writestr)
327332

333+
328334
if __name__ == "__main__":
329335
main()

_vendored/process_src_template.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import importlib.util
4+
import os
5+
6+
7+
def get_processor():
8+
# Convoluted because we can't import from numpy
9+
# (numpy is not yet built)
10+
conv_template_path = os.path.join(
11+
os.path.dirname(__file__),
12+
'conv_template.py'
13+
)
14+
spec = importlib.util.spec_from_file_location(
15+
'conv_template', conv_template_path
16+
)
17+
mod = importlib.util.module_from_spec(spec)
18+
spec.loader.exec_module(mod)
19+
return mod.process_file
20+
21+
22+
def process_and_write_file(fromfile, outfile):
23+
"""Process tempita templated file and write out the result.
24+
25+
The template file is expected to end in `.src`
26+
(e.g., `.c.src` or `.h.src`).
27+
Processing `npy_somefile.c.src` generates `npy_somefile.c`.
28+
29+
"""
30+
process_file = get_processor()
31+
content = process_file(fromfile)
32+
with open(outfile, 'w') as f:
33+
f.write(content)
34+
35+
36+
def main():
37+
parser = argparse.ArgumentParser()
38+
parser.add_argument(
39+
"infile",
40+
type=str,
41+
help="Path to the input file"
42+
)
43+
parser.add_argument(
44+
"-o",
45+
"--outfile",
46+
type=str,
47+
help="Path to the output file"
48+
)
49+
parser.add_argument(
50+
"-i",
51+
"--ignore",
52+
type=str,
53+
help="An ignored input - may be useful to add a "
54+
"dependency between custom targets",
55+
)
56+
args = parser.parse_args()
57+
58+
if not args.infile.endswith('.src'):
59+
raise ValueError(f"Unexpected extension: {args.infile}")
60+
61+
outfile_abs = os.path.join(os.getcwd(), args.outfile)
62+
process_and_write_file(args.infile, outfile_abs)
63+
64+
65+
if __name__ == "__main__":
66+
main()

0 commit comments

Comments
 (0)