From 155071a2f2f45fcfd24338d034e213e30463c133 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Tue, 29 Mar 2016 10:16:35 -0500 Subject: [PATCH] Allow running CLI as python -m loopy --- bin/loopy | 256 +--------------------------------------------- loopy/__main__.py | 2 + loopy/cli.py | 252 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+), 254 deletions(-) create mode 100644 loopy/__main__.py create mode 100644 loopy/cli.py diff --git a/bin/loopy b/bin/loopy index b169c6296..84335bb21 100644 --- a/bin/loopy +++ b/bin/loopy @@ -1,257 +1,5 @@ #! /usr/bin/env python -from __future__ import print_function - -import sys - -import loopy as lp -import numpy as np - - -def to_python_literal(value): - try: - int(value) - except ValueError: - pass - else: - # It's an integer - return value - - try: - float(value) - except ValueError: - pass - else: - # It's a float - return repr(float(value)) - - if value.endswith("f"): - try: - float(value[:-1]) - except ValueError: - pass - else: - # It's a float - return repr(float(value[:-1])) - - return repr(value) - - -def defines_to_python_code(defines_str): - import re - define_re = re.compile(r"^\#define\s+([a-zA-Z0-9_]+)\s+(.*)$") - result = [] - for l in defines_str.split("\n"): - if not l.strip(): - continue - - match = define_re.match(l) - if match is None: - raise RuntimeError("#define not understood: '%s'" % l) - - result.append( - "%s = %s" % (match.group(1), to_python_literal(match.group(2)))) - - return "\n".join(result) - - -def main(): - from argparse import ArgumentParser - - parser = ArgumentParser(description="Stand-alone loopy frontend") - - parser.add_argument("infile", metavar="INPUT_FILE") - parser.add_argument("outfile", default="-", metavar="OUTPUT_FILE", - help="Defaults to stdout ('-').", nargs='?') - parser.add_argument("--lang", metavar="LANGUAGE", help="loopy|fortran") - parser.add_argument("--target", choices=( - "opencl", "ispc", "ispc-occa", "c", "c-fortran", "cuda"), - default="opencl") - parser.add_argument("--name") - parser.add_argument("--transform") - parser.add_argument("--edit-code", action="store_true") - parser.add_argument("--occa-defines") - parser.add_argument("--occa-add-dummy-arg", action="store_true") - parser.add_argument("--print-ir", action="store_true") - args = parser.parse_args() - - if args.target == "opencl": - from loopy.target.opencl import OpenCLTarget - target = OpenCLTarget() - elif args.target == "ispc": - from loopy.target.ispc import ISPCTarget - target = ISPCTarget() - elif args.target == "ispc-occa": - from loopy.target.ispc import ISPCTarget - target = ISPCTarget(occa_mode=True) - elif args.target == "c": - from loopy.target.c import CTarget - target = CTarget() - elif args.target == "c-fortran": - from loopy.target.c import CTarget - target = CTarget(fortran_abi=True) - elif args.target == "cuda": - from loopy.target.cuda import CudaTarget - target = CudaTarget() - else: - raise ValueError("unknown target: %s" % target) - - lp.set_default_target(target) - - lang = None - if args.infile == "-": - infile_content = sys.stdin.read() - else: - from os.path import splitext - _, ext = splitext(args.infile) - - lang = { - ".py": "loopy", - ".loopy": "loopy", - ".floopy": "fortran", - ".f90": "fortran", - ".fpp": "fortran", - ".f": "fortran", - ".f77": "fortran", - }.get(ext) - with open(args.infile, "r") as infile_fd: - infile_content = infile_fd.read() - - if args.lang is not None: - lang = args.lang - - if lang is None: - raise RuntimeError("unable to deduce input language " - "(wrong input file extension? --lang flag?)") - - if lang == "loopy": - # {{{ path wrangling - - from os.path import dirname, abspath - from os import getcwd - - infile_dirname = dirname(args.infile) - if infile_dirname: - infile_dirname = abspath(infile_dirname) - else: - infile_dirname = getcwd() - - sys.path.append(infile_dirname) - - # }}} - - data_dic = {} - data_dic["lp"] = lp - data_dic["np"] = np - - if args.occa_defines: - with open(args.occa_defines, "r") as defines_fd: - occa_define_code = defines_to_python_code(defines_fd.read()) - exec(compile(occa_define_code, args.occa_defines, "exec"), data_dic) - - with open(args.infile, "r") as infile_fd: - exec(compile(infile_content, args.infile, "exec"), data_dic) - - if args.transform: - with open(args.transform, "r") as xform_fd: - exec(compile(xform_fd.read(), - args.transform, "exec"), data_dic) - - try: - kernel = data_dic["lp_knl"] - except KeyError: - raise RuntimeError("loopy-lang requires 'lp_knl' " - "to be defined on exit") - - if args.name is not None: - kernel = kernel.copy(name=args.name) - - kernels = [kernel] - - elif lang in ["fortran", "floopy", "fpp"]: - pre_transform_code = None - if args.transform: - with open(args.transform, "r") as xform_fd: - pre_transform_code = xform_fd.read() - - if args.occa_defines: - if pre_transform_code is None: - pre_transform_code = "" - - with open(args.occa_defines, "r") as defines_fd: - pre_transform_code = ( - defines_to_python_code(defines_fd.read()) - + pre_transform_code) - - kernels = lp.parse_transformed_fortran( - infile_content, pre_transform_code=pre_transform_code, - filename=args.infile) - - if args.name is not None: - kernels = [kernel for kernel in kernels - if kernel.name == args.name] - - if not kernels: - raise RuntimeError("no kernels found (name specified: %s)" - % args.name) - - else: - raise RuntimeError("unknown language: '%s'" - % args.lang) - - if args.print_ir: - for kernel in kernels: - print(kernel, file=sys.stderr) - - if args.occa_add_dummy_arg: - new_kernels = [] - for kernel in kernels: - new_args = [ - lp.GlobalArg("occa_info", np.int32, shape=None) - ] + kernel.args - new_kernels.append(kernel.copy(args=new_args)) - - kernels = new_kernels - del new_kernels - - codes = [] - from loopy.codegen import generate_code - for kernel in kernels: - kernel = lp.preprocess_kernel(kernel) - code, impl_arg_info = generate_code(kernel) - codes.append(code) - - if args.outfile is not None: - outfile = args.outfile - else: - outfile = "-" - - code = "\n\n".join(codes) - - # {{{ edit code if requested - - import os - edit_kernel_env = os.environ.get("LOOPY_EDIT_KERNEL") - need_edit = args.edit_code - if not need_edit and edit_kernel_env is not None: - # Do not replace with "any()"--Py2.6/2.7 bug doesn't like - # comprehensions in functions with exec(). - - for k in kernels: - if edit_kernel_env.lower() in k.name.lower(): - need_edit = True - - if need_edit: - from pytools import invoke_editor - code = invoke_editor(code, filename="edit.cl") - - # }}} - - if outfile == "-": - sys.stdout.write(code) - else: - with open(outfile, "w") as outfile_fd: - outfile_fd.write(code) - if __name__ == "__main__": - main() + import loopy.cli + loopy.cli.main() diff --git a/loopy/__main__.py b/loopy/__main__.py new file mode 100644 index 000000000..a1b80dd72 --- /dev/null +++ b/loopy/__main__.py @@ -0,0 +1,2 @@ +import loopy.cli +loopy.cli.main() diff --git a/loopy/cli.py b/loopy/cli.py new file mode 100644 index 000000000..060340d59 --- /dev/null +++ b/loopy/cli.py @@ -0,0 +1,252 @@ +from __future__ import print_function + +import sys + +import loopy as lp +import numpy as np + + +def to_python_literal(value): + try: + int(value) + except ValueError: + pass + else: + # It's an integer + return value + + try: + float(value) + except ValueError: + pass + else: + # It's a float + return repr(float(value)) + + if value.endswith("f"): + try: + float(value[:-1]) + except ValueError: + pass + else: + # It's a float + return repr(float(value[:-1])) + + return repr(value) + + +def defines_to_python_code(defines_str): + import re + define_re = re.compile(r"^\#define\s+([a-zA-Z0-9_]+)\s+(.*)$") + result = [] + for l in defines_str.split("\n"): + if not l.strip(): + continue + + match = define_re.match(l) + if match is None: + raise RuntimeError("#define not understood: '%s'" % l) + + result.append( + "%s = %s" % (match.group(1), to_python_literal(match.group(2)))) + + return "\n".join(result) + + +def main(): + from argparse import ArgumentParser + + parser = ArgumentParser(description="Stand-alone loopy frontend") + + parser.add_argument("infile", metavar="INPUT_FILE") + parser.add_argument("outfile", default="-", metavar="OUTPUT_FILE", + help="Defaults to stdout ('-').", nargs='?') + parser.add_argument("--lang", metavar="LANGUAGE", help="loopy|fortran") + parser.add_argument("--target", choices=( + "opencl", "ispc", "ispc-occa", "c", "c-fortran", "cuda"), + default="opencl") + parser.add_argument("--name") + parser.add_argument("--transform") + parser.add_argument("--edit-code", action="store_true") + parser.add_argument("--occa-defines") + parser.add_argument("--occa-add-dummy-arg", action="store_true") + parser.add_argument("--print-ir", action="store_true") + args = parser.parse_args() + + if args.target == "opencl": + from loopy.target.opencl import OpenCLTarget + target = OpenCLTarget() + elif args.target == "ispc": + from loopy.target.ispc import ISPCTarget + target = ISPCTarget() + elif args.target == "ispc-occa": + from loopy.target.ispc import ISPCTarget + target = ISPCTarget(occa_mode=True) + elif args.target == "c": + from loopy.target.c import CTarget + target = CTarget() + elif args.target == "c-fortran": + from loopy.target.c import CTarget + target = CTarget(fortran_abi=True) + elif args.target == "cuda": + from loopy.target.cuda import CudaTarget + target = CudaTarget() + else: + raise ValueError("unknown target: %s" % target) + + lp.set_default_target(target) + + lang = None + if args.infile == "-": + infile_content = sys.stdin.read() + else: + from os.path import splitext + _, ext = splitext(args.infile) + + lang = { + ".py": "loopy", + ".loopy": "loopy", + ".floopy": "fortran", + ".f90": "fortran", + ".fpp": "fortran", + ".f": "fortran", + ".f77": "fortran", + }.get(ext) + with open(args.infile, "r") as infile_fd: + infile_content = infile_fd.read() + + if args.lang is not None: + lang = args.lang + + if lang is None: + raise RuntimeError("unable to deduce input language " + "(wrong input file extension? --lang flag?)") + + if lang == "loopy": + # {{{ path wrangling + + from os.path import dirname, abspath + from os import getcwd + + infile_dirname = dirname(args.infile) + if infile_dirname: + infile_dirname = abspath(infile_dirname) + else: + infile_dirname = getcwd() + + sys.path.append(infile_dirname) + + # }}} + + data_dic = {} + data_dic["lp"] = lp + data_dic["np"] = np + + if args.occa_defines: + with open(args.occa_defines, "r") as defines_fd: + occa_define_code = defines_to_python_code(defines_fd.read()) + exec(compile(occa_define_code, args.occa_defines, "exec"), data_dic) + + with open(args.infile, "r") as infile_fd: + exec(compile(infile_content, args.infile, "exec"), data_dic) + + if args.transform: + with open(args.transform, "r") as xform_fd: + exec(compile(xform_fd.read(), + args.transform, "exec"), data_dic) + + try: + kernel = data_dic["lp_knl"] + except KeyError: + raise RuntimeError("loopy-lang requires 'lp_knl' " + "to be defined on exit") + + if args.name is not None: + kernel = kernel.copy(name=args.name) + + kernels = [kernel] + + elif lang in ["fortran", "floopy", "fpp"]: + pre_transform_code = None + if args.transform: + with open(args.transform, "r") as xform_fd: + pre_transform_code = xform_fd.read() + + if args.occa_defines: + if pre_transform_code is None: + pre_transform_code = "" + + with open(args.occa_defines, "r") as defines_fd: + pre_transform_code = ( + defines_to_python_code(defines_fd.read()) + + pre_transform_code) + + kernels = lp.parse_transformed_fortran( + infile_content, pre_transform_code=pre_transform_code, + filename=args.infile) + + if args.name is not None: + kernels = [kernel for kernel in kernels + if kernel.name == args.name] + + if not kernels: + raise RuntimeError("no kernels found (name specified: %s)" + % args.name) + + else: + raise RuntimeError("unknown language: '%s'" + % args.lang) + + if args.print_ir: + for kernel in kernels: + print(kernel, file=sys.stderr) + + if args.occa_add_dummy_arg: + new_kernels = [] + for kernel in kernels: + new_args = [ + lp.GlobalArg("occa_info", np.int32, shape=None) + ] + kernel.args + new_kernels.append(kernel.copy(args=new_args)) + + kernels = new_kernels + del new_kernels + + codes = [] + from loopy.codegen import generate_code + for kernel in kernels: + kernel = lp.preprocess_kernel(kernel) + code, impl_arg_info = generate_code(kernel) + codes.append(code) + + if args.outfile is not None: + outfile = args.outfile + else: + outfile = "-" + + code = "\n\n".join(codes) + + # {{{ edit code if requested + + import os + edit_kernel_env = os.environ.get("LOOPY_EDIT_KERNEL") + need_edit = args.edit_code + if not need_edit and edit_kernel_env is not None: + # Do not replace with "any()"--Py2.6/2.7 bug doesn't like + # comprehensions in functions with exec(). + + for k in kernels: + if edit_kernel_env.lower() in k.name.lower(): + need_edit = True + + if need_edit: + from pytools import invoke_editor + code = invoke_editor(code, filename="edit.cl") + + # }}} + + if outfile == "-": + sys.stdout.write(code) + else: + with open(outfile, "w") as outfile_fd: + outfile_fd.write(code) -- GitLab