Skip to content

Commit 155071a

Browse files
committed
Allow running CLI as python -m loopy
1 parent 5aea25a commit 155071a

File tree

3 files changed

+256
-254
lines changed

3 files changed

+256
-254
lines changed

bin/loopy

Lines changed: 2 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -1,257 +1,5 @@
11
#! /usr/bin/env python
2-
from __future__ import print_function
3-
4-
import sys
5-
6-
import loopy as lp
7-
import numpy as np
8-
9-
10-
def to_python_literal(value):
11-
try:
12-
int(value)
13-
except ValueError:
14-
pass
15-
else:
16-
# It's an integer
17-
return value
18-
19-
try:
20-
float(value)
21-
except ValueError:
22-
pass
23-
else:
24-
# It's a float
25-
return repr(float(value))
26-
27-
if value.endswith("f"):
28-
try:
29-
float(value[:-1])
30-
except ValueError:
31-
pass
32-
else:
33-
# It's a float
34-
return repr(float(value[:-1]))
35-
36-
return repr(value)
37-
38-
39-
def defines_to_python_code(defines_str):
40-
import re
41-
define_re = re.compile(r"^\#define\s+([a-zA-Z0-9_]+)\s+(.*)$")
42-
result = []
43-
for l in defines_str.split("\n"):
44-
if not l.strip():
45-
continue
46-
47-
match = define_re.match(l)
48-
if match is None:
49-
raise RuntimeError("#define not understood: '%s'" % l)
50-
51-
result.append(
52-
"%s = %s" % (match.group(1), to_python_literal(match.group(2))))
53-
54-
return "\n".join(result)
55-
56-
57-
def main():
58-
from argparse import ArgumentParser
59-
60-
parser = ArgumentParser(description="Stand-alone loopy frontend")
61-
62-
parser.add_argument("infile", metavar="INPUT_FILE")
63-
parser.add_argument("outfile", default="-", metavar="OUTPUT_FILE",
64-
help="Defaults to stdout ('-').", nargs='?')
65-
parser.add_argument("--lang", metavar="LANGUAGE", help="loopy|fortran")
66-
parser.add_argument("--target", choices=(
67-
"opencl", "ispc", "ispc-occa", "c", "c-fortran", "cuda"),
68-
default="opencl")
69-
parser.add_argument("--name")
70-
parser.add_argument("--transform")
71-
parser.add_argument("--edit-code", action="store_true")
72-
parser.add_argument("--occa-defines")
73-
parser.add_argument("--occa-add-dummy-arg", action="store_true")
74-
parser.add_argument("--print-ir", action="store_true")
75-
args = parser.parse_args()
76-
77-
if args.target == "opencl":
78-
from loopy.target.opencl import OpenCLTarget
79-
target = OpenCLTarget()
80-
elif args.target == "ispc":
81-
from loopy.target.ispc import ISPCTarget
82-
target = ISPCTarget()
83-
elif args.target == "ispc-occa":
84-
from loopy.target.ispc import ISPCTarget
85-
target = ISPCTarget(occa_mode=True)
86-
elif args.target == "c":
87-
from loopy.target.c import CTarget
88-
target = CTarget()
89-
elif args.target == "c-fortran":
90-
from loopy.target.c import CTarget
91-
target = CTarget(fortran_abi=True)
92-
elif args.target == "cuda":
93-
from loopy.target.cuda import CudaTarget
94-
target = CudaTarget()
95-
else:
96-
raise ValueError("unknown target: %s" % target)
97-
98-
lp.set_default_target(target)
99-
100-
lang = None
101-
if args.infile == "-":
102-
infile_content = sys.stdin.read()
103-
else:
104-
from os.path import splitext
105-
_, ext = splitext(args.infile)
106-
107-
lang = {
108-
".py": "loopy",
109-
".loopy": "loopy",
110-
".floopy": "fortran",
111-
".f90": "fortran",
112-
".fpp": "fortran",
113-
".f": "fortran",
114-
".f77": "fortran",
115-
}.get(ext)
116-
with open(args.infile, "r") as infile_fd:
117-
infile_content = infile_fd.read()
118-
119-
if args.lang is not None:
120-
lang = args.lang
121-
122-
if lang is None:
123-
raise RuntimeError("unable to deduce input language "
124-
"(wrong input file extension? --lang flag?)")
125-
126-
if lang == "loopy":
127-
# {{{ path wrangling
128-
129-
from os.path import dirname, abspath
130-
from os import getcwd
131-
132-
infile_dirname = dirname(args.infile)
133-
if infile_dirname:
134-
infile_dirname = abspath(infile_dirname)
135-
else:
136-
infile_dirname = getcwd()
137-
138-
sys.path.append(infile_dirname)
139-
140-
# }}}
141-
142-
data_dic = {}
143-
data_dic["lp"] = lp
144-
data_dic["np"] = np
145-
146-
if args.occa_defines:
147-
with open(args.occa_defines, "r") as defines_fd:
148-
occa_define_code = defines_to_python_code(defines_fd.read())
149-
exec(compile(occa_define_code, args.occa_defines, "exec"), data_dic)
150-
151-
with open(args.infile, "r") as infile_fd:
152-
exec(compile(infile_content, args.infile, "exec"), data_dic)
153-
154-
if args.transform:
155-
with open(args.transform, "r") as xform_fd:
156-
exec(compile(xform_fd.read(),
157-
args.transform, "exec"), data_dic)
158-
159-
try:
160-
kernel = data_dic["lp_knl"]
161-
except KeyError:
162-
raise RuntimeError("loopy-lang requires 'lp_knl' "
163-
"to be defined on exit")
164-
165-
if args.name is not None:
166-
kernel = kernel.copy(name=args.name)
167-
168-
kernels = [kernel]
169-
170-
elif lang in ["fortran", "floopy", "fpp"]:
171-
pre_transform_code = None
172-
if args.transform:
173-
with open(args.transform, "r") as xform_fd:
174-
pre_transform_code = xform_fd.read()
175-
176-
if args.occa_defines:
177-
if pre_transform_code is None:
178-
pre_transform_code = ""
179-
180-
with open(args.occa_defines, "r") as defines_fd:
181-
pre_transform_code = (
182-
defines_to_python_code(defines_fd.read())
183-
+ pre_transform_code)
184-
185-
kernels = lp.parse_transformed_fortran(
186-
infile_content, pre_transform_code=pre_transform_code,
187-
filename=args.infile)
188-
189-
if args.name is not None:
190-
kernels = [kernel for kernel in kernels
191-
if kernel.name == args.name]
192-
193-
if not kernels:
194-
raise RuntimeError("no kernels found (name specified: %s)"
195-
% args.name)
196-
197-
else:
198-
raise RuntimeError("unknown language: '%s'"
199-
% args.lang)
200-
201-
if args.print_ir:
202-
for kernel in kernels:
203-
print(kernel, file=sys.stderr)
204-
205-
if args.occa_add_dummy_arg:
206-
new_kernels = []
207-
for kernel in kernels:
208-
new_args = [
209-
lp.GlobalArg("occa_info", np.int32, shape=None)
210-
] + kernel.args
211-
new_kernels.append(kernel.copy(args=new_args))
212-
213-
kernels = new_kernels
214-
del new_kernels
215-
216-
codes = []
217-
from loopy.codegen import generate_code
218-
for kernel in kernels:
219-
kernel = lp.preprocess_kernel(kernel)
220-
code, impl_arg_info = generate_code(kernel)
221-
codes.append(code)
222-
223-
if args.outfile is not None:
224-
outfile = args.outfile
225-
else:
226-
outfile = "-"
227-
228-
code = "\n\n".join(codes)
229-
230-
# {{{ edit code if requested
231-
232-
import os
233-
edit_kernel_env = os.environ.get("LOOPY_EDIT_KERNEL")
234-
need_edit = args.edit_code
235-
if not need_edit and edit_kernel_env is not None:
236-
# Do not replace with "any()"--Py2.6/2.7 bug doesn't like
237-
# comprehensions in functions with exec().
238-
239-
for k in kernels:
240-
if edit_kernel_env.lower() in k.name.lower():
241-
need_edit = True
242-
243-
if need_edit:
244-
from pytools import invoke_editor
245-
code = invoke_editor(code, filename="edit.cl")
246-
247-
# }}}
248-
249-
if outfile == "-":
250-
sys.stdout.write(code)
251-
else:
252-
with open(outfile, "w") as outfile_fd:
253-
outfile_fd.write(code)
254-
2552

2563
if __name__ == "__main__":
257-
main()
4+
import loopy.cli
5+
loopy.cli.main()

loopy/__main__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import loopy.cli
2+
loopy.cli.main()

0 commit comments

Comments
 (0)