diff --git a/.gitignore b/.gitignore index 526b84547d94d36966bca36346ec378e335ce3db..1202eabefaef53bca0ec6069fd3fc9718a06c4b9 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ visitlog.py dist *.egg* MANIFEST +*.patch *.LOCAL.[0-9]* *.REMOTE.[0-9]* *.BASE.[0-9]* @@ -47,10 +48,3 @@ setuptools-*.tar.gz core src/wrapper/gen-* .dirty-git-ok -wrapped-functions.h -_isl_cffi.c -_isl.py -name_list.py -islpy_cffi_build.py - -.cache diff --git a/MANIFEST.in b/MANIFEST.in index 7f39856ea32880aee1e3a49e5c839b67718cb537..190d35e09e1e5dc9f5b12cd6ef1219a4cc81dd79 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -19,7 +19,6 @@ include src/wrapper/*.hpp include src/wrapper/*.cpp include gen_wrap.py -include py_codegen.py include test/*.py include examples/*.py diff --git a/README.rst b/README.rst index 6d3c34b61e64733ef39e00f415f0f68a0a35e8f1..28065c1b301c3d21f68baff8e62ac3539fe4ff1a 100644 --- a/README.rst +++ b/README.rst @@ -32,5 +32,5 @@ bounds on piecewise step-polynomials. Islpy comes with comprehensive `documentation `_. -*Requirements:* islpy needs a C compiler to build. GMP, which used to be +*Requirements:* islpy needs a C++ compiler to build. GMP, which used to be a dependency, is no longer required. diff --git a/add-missing-isl_term_cow-in-isl_poly_foreach_term.patch b/add-missing-isl_term_cow-in-isl_poly_foreach_term.patch deleted file mode 100644 index 6c36d5fec0fe1ddc71c338b2f008e8d3d7db9c4d..0000000000000000000000000000000000000000 --- a/add-missing-isl_term_cow-in-isl_poly_foreach_term.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/isl_polynomial.c b/isl_polynomial.c -index 13333d54..15bf1e2c 100644 ---- a/isl_polynomial.c -+++ b/isl_polynomial.c -@@ -4142,6 +4142,7 @@ __isl_give isl_term *isl_poly_foreach_term(__isl_keep isl_poly *poly, - if (!term) - goto error; - } -+ term = isl_term_cow(term); - term->pow[poly->var] = 0; - - return term; diff --git a/aksetup_helper.py b/aksetup_helper.py index f90d085284f00e6a6cd2a44e6b9bd63a857485f3..e8b4814e9bb61ebc434746fb9e2749e5edbea9f3 100644 --- a/aksetup_helper.py +++ b/aksetup_helper.py @@ -162,10 +162,12 @@ def hack_distutils(debug=False, fast_link=True, what_opt=3): from distutils import sysconfig cvars = sysconfig.get_config_vars() - cflags = cvars.get('OPT') + + bad_prefixes = ['-g', '-O', '-Wstrict-prototypes', '-DNDEBUG'] + + cflags = cvars.get("OPT") if cflags: - cflags = remove_prefixes(cflags.split(), - ['-g', '-O', '-Wstrict-prototypes', '-DNDEBUG']) + cflags = remove_prefixes(cflags.split(), bad_prefixes) if debug: cflags.append("-g") else: @@ -175,11 +177,17 @@ def hack_distutils(debug=False, fast_link=True, what_opt=3): cflags.append("-O%s" % what_opt) cflags.append("-DNDEBUG") - cvars['OPT'] = str.join(' ', cflags) - if "BASECFLAGS" in cvars: - cvars["CFLAGS"] = cvars["BASECFLAGS"] + " " + cvars["OPT"] - else: - assert "CFLAGS" in cvars + cvars["OPT"] = str.join(' ', cflags) + + cflags = cvars.get("CONFIGURE_CFLAGS") + if cflags: + cflags = remove_prefixes(cflags.split(), bad_prefixes) + cvars["CONFIGURE_CFLAGS"] = str.join(' ', cflags) + + if "BASECFLAGS" in cvars: + cvars["CFLAGS"] = cvars["BASECFLAGS"] + " " + cvars.get("OPT", "") + else: + assert "CFLAGS" in cvars if fast_link: for varname in ["LDSHARED", "BLDSHARED"]: diff --git a/build-with-barvinok.sh b/build-with-barvinok.sh index f9d548b87e717b34b3203a5f5a7a671bddc913a9..a28386ba932d4f2f421294779c190ad4961c85af 100755 --- a/build-with-barvinok.sh +++ b/build-with-barvinok.sh @@ -29,7 +29,7 @@ if true; then cd "$BUILD_DIR" rm -Rf barvinok - git clone git://repo.or.cz/barvinok.git + git clone https://github.com/inducer/barvinok.git cd barvinok git checkout $BARVINOK_GIT_REV diff --git a/configure.py b/configure.py index 63edd4b997e7a83f6d182359cbafe5078b126a60..afe32be6ede21b4c009042ac27a5e9dd57a27cb6 100755 --- a/configure.py +++ b/configure.py @@ -1,6 +1,4 @@ #! /usr/bin/env python -from __future__ import absolute_import - from aksetup_helper import configure_frontend configure_frontend() diff --git a/doc/conf.py b/doc/conf.py index fe3c96e7a2ddbe7a8ad03f18fc28e0f01f3faef0..b66f0f2aba937a12241e84820aa77d62dacfd34c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -133,7 +133,7 @@ html_sidebars = { # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/doc/ref_containers.rst b/doc/ref_containers.rst index 71dbef9efa728a5b812cf913b39abf981e994bf0..40bc43c5a85bfc10322d7e04bea53c84b4dd28db 100644 --- a/doc/ref_containers.rst +++ b/doc/ref_containers.rst @@ -33,9 +33,6 @@ Lists .. autoclass:: UnionPwAffList :members: -.. autoclass:: BandList - :members: - .. autoclass:: AstExprList :members: diff --git a/doc/ref_schedule.rst b/doc/ref_schedule.rst index e38e5bad0bfdbd2e523d916cf17357646ee13265..c9a93d835029269545fd579a90f40a86ebfa1980 100644 --- a/doc/ref_schedule.rst +++ b/doc/ref_schedule.rst @@ -3,12 +3,6 @@ Reference: Scheduling .. currentmodule:: islpy -Band ----- - -.. autoclass:: Band - :members: - Schedule -------- diff --git a/gen_wrap.py b/gen_wrap.py index f000e8783a70ca8725fabb32bfc7faf1d3235045..ab3193106fdd8693745d410b627ebc4d81938e33 100644 --- a/gen_wrap.py +++ b/gen_wrap.py @@ -1,6 +1,4 @@ -from __future__ import print_function - -__copyright__ = "Copyright (C) 2011-15 Andreas Kloeckner" +__copyright__ = "Copyright (C) 2011-20 Andreas Kloeckner" __license__ = """ Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,10 +22,8 @@ THE SOFTWARE. import re import sys -from py_codegen import PythonCodeGenerator, Indentation -from distutils.sysconfig import get_config_var -from os.path import join import os +from os.path import join SEM_TAKE = "take" SEM_GIVE = "give" @@ -55,24 +51,56 @@ def for lambda try """.split() +class Retry(RuntimeError): + pass + + +class BadArg(ValueError): + pass + + +class Undocumented(ValueError): + pass + + +class SignatureNotSupported(ValueError): + pass + + +def to_py_class(cls): + if cls.startswith("isl_"): + cls = cls[4:] + + if cls == "ctx": + return "Context" + + upper_next = True + result = "" + + for c in cls: + if c == "_": + upper_next = True + else: + if upper_next: + result += c.upper() + upper_next = False + else: + result += c + + result = result.replace("Qpoly", "QPoly") + + return result + + # {{{ data model class Argument: - def __init__(self, name, semantics, decl_words, base_type, ptr): + def __init__(self, name, semantics, base_type, ptr): self.name = name self.semantics = semantics - assert isinstance(decl_words, list) - self.decl_words = decl_words self.base_type = base_type self.ptr = ptr - def c_declarator(self): - return "{decl_words} {type} {ptr}{name}".format( - decl_words=" ".join(self.decl_words), - type=self.base_type, - ptr=self.ptr, - name=self.name) - class CallbackArgument: def __init__(self, name, @@ -85,24 +113,16 @@ class CallbackArgument: self.return_ptr = return_ptr self.args = args - def c_declarator(self): - return "{decl_words} {type} {ptr}(*{name})({args})".format( - decl_words=" ".join(self.return_decl_words), - type=self.return_base_type, - ptr=self.return_ptr, - name=self.name, - args=", ".join(arg.c_declarator() for arg in self.args)) - class Method: def __init__(self, cls, name, c_name, - return_semantics, return_decl_words, return_base_type, return_ptr, + return_semantics, return_base_type, return_ptr, args, is_exported, is_constructor): self.cls = cls self.name = name + assert name self.c_name = c_name self.return_semantics = return_semantics - self.return_decl_words = return_decl_words self.return_base_type = return_base_type self.return_ptr = return_ptr self.args = args @@ -133,210 +153,103 @@ class Method: # }}} -CLASSES = [ - # /!\ Order matters, class names that are prefixes of others should go last. - - "ctx", - - # lists - "id_list", "val_list", - "basic_set_list", "basic_map_list", "set_list", "map_list", - "union_set_list", - "constraint_list", - "aff_list", "pw_aff_list", "pw_multi_aff_list", - "ast_expr_list", "ast_node_list", - "pw_qpolynomial_list", - "pw_qpolynomial_fold_list", - "union_pw_aff_list", - "union_pw_multi_aff_list", - "union_map_list", - - # maps - "id_to_ast_expr", - - # others - "printer", "val", "multi_val", "vec", "mat", "fixed_box", - "aff", "pw_aff", "union_pw_aff", - "multi_aff", "multi_pw_aff", "pw_multi_aff", "union_pw_multi_aff", - "multi_union_pw_aff", - - "id", "multi_id", - "constraint", "space", "local_space", - - "basic_set", "basic_map", - "set", "map", - "union_map", "union_set", - "point", "vertex", "cell", "vertices", - "stride_info", - - "qpolynomial_fold", "pw_qpolynomial_fold", - "union_pw_qpolynomial_fold", - "union_pw_qpolynomial", - "qpolynomial", "pw_qpolynomial", - "term", - - "band", "schedule_constraints", "schedule_node", "schedule", - - "access_info", "flow", "restriction", - "union_access_info", "union_flow", - - "ast_expr", "ast_node", "ast_print_options", - "ast_build", +# {{{ PART_TO_CLASSES + +PART_TO_CLASSES = { + # If you change this, change: + # - src/wrapper/wrap_isl.hpp to add WRAP_CLASS(...) + # - src/wrapper/wrap_isl_partN.hpp to add MAKE_WRAP(...) + # - doc/reference.rst + + "part1": [ + # lists + "id_list", "val_list", + "basic_set_list", "basic_map_list", "set_list", "map_list", + "union_set_list", + "constraint_list", + "aff_list", "pw_aff_list", "pw_multi_aff_list", + "ast_expr_list", "ast_node_list", + "pw_qpolynomial_list", + "pw_qpolynomial_fold_list", + "union_pw_aff_list", + "union_pw_multi_aff_list", + "union_map_list", + + # maps + "id_to_ast_expr", + + # others + "ctx", + "printer", "val", "multi_val", "vec", "mat", "fixed_box", + "aff", "pw_aff", "union_pw_aff", + "multi_aff", "multi_pw_aff", "pw_multi_aff", "union_pw_multi_aff", + "multi_union_pw_aff", + + "id", "multi_id", + + "constraint", "space", "local_space", + ], + + "part2": [ + "basic_set", "basic_map", + "set", "map", + "union_map", "union_set", + "point", "vertex", "cell", "vertices", + "stride_info", + ], + + "part3": [ + "qpolynomial", "pw_qpolynomial", + "qpolynomial_fold", "pw_qpolynomial_fold", + "union_pw_qpolynomial_fold", + "union_pw_qpolynomial", + "term", + + "schedule", "schedule_constraints", + "schedule_node", + + "access_info", "flow", "restriction", + "union_access_info", "union_flow", + + "ast_expr", "ast_node", "ast_print_options", + "ast_build", ] + } +CLASSES = [] +for cls_list in PART_TO_CLASSES.values(): + CLASSES.extend(cls_list) + +CLASS_MAP = { + "equality": "constraint", + "inequality": "constraint", + "options": "ctx", + } -UNTYPEDEFD_CLASSES = ["options"] - +# }}} -IMPLICIT_CONVERSIONS = { - "isl_set": [("isl_basic_set", "from_basic_set")], - "isl_map": [("isl_basic_map", "from_basic_map")], - "isl_union_set": [("isl_set", "from_set")], - "isl_union_map": [("isl_map", "from_map")], - "isl_local_space": [("isl_space", "from_space")], - "isl_pw_aff": [("isl_aff", "from_aff")], - } +# {{{ enums ENUMS = { # ctx.h - "isl_error": """ - isl_error_none, - isl_error_abort, - isl_error_alloc, - isl_error_unknown, - isl_error_internal, - isl_error_invalid, - isl_error_quota, - isl_error_unsupported, - """, - "isl_stat": """ - isl_stat_error, - isl_stat_ok, - """, - "isl_bool": """ - isl_bool_error, - isl_bool_false, - isl_bool_true, - """, + "isl_error", + "isl_stat", + "isl_bool", + # space.h - "isl_dim_type": """ - isl_dim_cst, - isl_dim_param, - isl_dim_in, - isl_dim_out, - isl_dim_set, - isl_dim_div, - isl_dim_all, - """, + "isl_dim_type", # schedule_type.h - "isl_schedule_node_type": """ - isl_schedule_node_error, - isl_schedule_node_band, - isl_schedule_node_context, - isl_schedule_node_domain, - isl_schedule_node_expansion, - isl_schedule_node_extension, - isl_schedule_node_filter, - isl_schedule_node_leaf, - isl_schedule_node_guard, - isl_schedule_node_mark, - isl_schedule_node_sequence, - isl_schedule_node_set, - """, + "isl_schedule_node_type", # ast_type.h - "isl_ast_expr_op_type": """ - isl_ast_op_error, - isl_ast_op_and, - isl_ast_op_and_then, - isl_ast_op_or, - isl_ast_op_or_else, - isl_ast_op_max, - isl_ast_op_min, - isl_ast_op_minus, - isl_ast_op_add, - isl_ast_op_sub, - isl_ast_op_mul, - isl_ast_op_div, - isl_ast_op_fdiv_q, - isl_ast_op_pdiv_q, - isl_ast_op_pdiv_r, - isl_ast_op_zdiv_r, - isl_ast_op_cond, - isl_ast_op_select, - isl_ast_op_eq, - isl_ast_op_le, - isl_ast_op_lt, - isl_ast_op_ge, - isl_ast_op_gt, - isl_ast_op_call, - isl_ast_op_access, - isl_ast_op_member, - isl_ast_op_address_of, - """, - "isl_ast_expr_type": """ - isl_ast_expr_error, - isl_ast_expr_op, - isl_ast_expr_id, - isl_ast_expr_int, - """, - "isl_ast_node_type": """ - isl_ast_node_error, - isl_ast_node_for, - isl_ast_node_if, - isl_ast_node_block, - isl_ast_node_mark, - isl_ast_node_user, - """, - "isl_ast_loop_type": """ - isl_ast_loop_error, - isl_ast_loop_default, - isl_ast_loop_atomic, - isl_ast_loop_unroll, - isl_ast_loop_separate, - """, + "isl_ast_expr_op_type", + "isl_ast_expr_type", + "isl_ast_node_type", + "isl_ast_loop_type", # polynomial_type.h - "isl_fold": """ - isl_fold_min, - isl_fold_max, - isl_fold_list, - """, - - # printer.h - "isl_format": """ - ISL_FORMAT_ISL, - ISL_FORMAT_POLYLIB, - ISL_FORMAT_POLYLIB_CONSTRAINTS, - ISL_FORMAT_OMEGA, - ISL_FORMAT_C, - ISL_FORMAT_LATEX, - ISL_FORMAT_EXT_POLYLIB, - """, - - "isl_yaml_style": """ - ISL_YAML_STYLE_BLOCK, - ISL_YAML_STYLE_FLOW, - """, - - # options.h - - "isl_bound": """ - ISL_BOUND_BERNSTEIN, - ISL_BOUND_RANGE, - """, - - "isl_on_error": """ - ISL_ON_ERROR_WARN, - ISL_ON_ERROR_CONTINUE, - ISL_ON_ERROR_ABORT, - """, - - "isl_schedule_algorithm": """ - ISL_SCHEDULE_ALGORITHM_ISL, - ISL_SCHEDULE_ALGORITHM_FEAUTRIER, - """, + "isl_fold", } TYPEDEFD_ENUMS = ["isl_stat", "isl_bool"] @@ -345,211 +258,13 @@ MACRO_ENUMS = [ "isl_bound", "isl_on_error", "isl_schedule_algorithm", ] -HEADER_PREAMBLE = """ -// flow.h -typedef int isl_size; -typedef int (*isl_access_level_before)(void *first, void *second); -typedef isl_restriction *(*isl_access_restrict)( - isl_map *source_map, isl_set *sink, - void *source_user, void *user); - -""" - -PY_PREAMBLE = """ -from __future__ import print_function - -import six -import sys -import logging -import threading -import operator as _operator - -# isl has parameters called type which end up shadowing the built-in function. -_type = type - - -_PY3 = sys.version_info >= (3,) - -is_win = sys.platform.startswith('win32') - -from islpy._isl_cffi import ffi - -if is_win: - lib = ffi.dlopen('{win_pyd}') -else: - lib = ffi.dlopen(None) - -from cffi import FFI -libc_ffi = FFI() - -cdef_string = ''' - char *strdup(const char *s); - void free(void *ptr); - ''' - -if is_win: - cdef_string = cdef_string.replace('strdup', '_strdup') - -libc_ffi.cdef(cdef_string) - -if is_win and sys.version_info >= (3,5): - libc = libc_ffi.dlopen('ucrtbase') -else: - libc = libc_ffi.dlopen(None) - - -class Error(Exception): - pass - - -class IslTypeError(Error, TypeError): - pass - -_context_use_map = {{}} - - -def _get_last_error_str(ctx_data): - code = lib.isl_ctx_last_error(ctx_data) - for name in dir(error): - if name.startswith("_"): - continue - if getattr(error, name) == code: - return "isl_error_"+name - - return "(unknown error)" - - -class _ISLObjectBase(object): - def __init__(self, _data, context): - self._setup(_data, context) - - def _setup(self, data, context): - assert not hasattr(self, "data") - assert isinstance(data, ffi.CData) - self.data = data - self.context = context - - def _reset(self, data): - assert self.data is not None - assert isinstance(data, ffi.CData) - - self.data = data - - def _release(self): - if self.data is None: - raise Error("cannot release already-released object") - data = self.data - self.data = None - return data - - def get_ctx(self): - return self.context - - def __eq__(self, other): - return (type(self) == type(other) and self.data == other.data) - - def __ne__(self, other): - return not self.__eq__(other) - - -class Context(object): - def __init__(self, _data=None): - if _data is None: - new_ctx = Context.alloc() - _data = new_ctx.data - new_ctx._release() - self.data = _data - - def get_ctx(self): - return self - - def _release(self): - self.data = None - - def _reset(self, data): - self.data = data - - def __del__(self): - if self.data is not None: - lib.isl_ctx_free(self.data) - - def __eq__(self, other): - return self.data == other.data - - -class _EnumBase(object): - @classmethod - def find_value(cls, v): - for name in dir(cls): - if getattr(cls, name) == v: - return name - - raise ValueError("Value '%s' not found in enum" % v) - - -class _ManagedCString(object): - def __init__(self, cdata): - if is_win: - self.data = libc._strdup(cdata) - else: - self.data = libc.strdup(cdata) - if self.data == libc_ffi.NULL: - raise Error("strdup() failed") - - def release(self): - if self.data is None: - raise Error("cannot release already-released object") - - data = self.data - self.data = None - return data - - def __del__(self): - libc.free(self.data) - - -if _PY3: - class DelayedKeyboardInterrupt(object): - def __enter__(self): - self.previous_switch_interval = sys.getswitchinterval() - sys.setswitchinterval(10000000) - - def __exit__(self, type, value, traceback): - sys.setswitchinterval(self.previous_switch_interval) -else: - class DelayedKeyboardInterrupt(object): - def __enter__(self): - self.previous_check_interval = sys.getcheckinterval() - sys.setcheckinterval(100000000) - - def __exit__(self, type, value, traceback): - sys.setcheckinterval(self.previous_check_interval) - -""" +# }}} SAFE_TYPES = list(ENUMS) + ["int", "unsigned", "uint32_t", "size_t", "double", "long", "unsigned long", "isl_size"] SAFE_IN_TYPES = SAFE_TYPES + ["const char *", "char *"] - -SPECIAL_CLASS_NAME_MAP = { - "ctx": "Context" - } - - -def isl_class_to_py_class(cls_name): - if cls_name.startswith("isl_"): - cls_name = cls_name[4:] - - try: - return SPECIAL_CLASS_NAME_MAP[cls_name] - except KeyError: - result = cls_name.title().replace("_", "") - result = result.replace("Qpoly", "QPoly") - return result - - -# {{{ parser +# {{{ parser helpers DECL_RE = re.compile(r""" (?:__isl_overload\s*)? @@ -568,12 +283,7 @@ FUNC_PTR_RE = re.compile(r""" \) """, re.VERBOSE) -STRUCT_DECL_RE = re.compile( - r"(__isl_export\s+)?" - r"struct\s+" - r"(__isl_export\s+)?" - r"(__isl_subclass\([a-z_ ]+\)\s+)?" - r"([a-z_A-Z0-9]+)\s*;") +STRUCT_DECL_RE = re.compile(r"(__isl_export\s+)?struct\s+([a-z_A-Z0-9]+)\s*;") ARG_RE = re.compile(r"^((?:\w+)\s+)+(\**)\s*(\w+)$") INLINE_SEMICOLON_RE = re.compile(r"\;[ \t]*(?=\w)") SUBCLASS_RE = re.compile( @@ -619,22 +329,6 @@ def split_at_unparenthesized_commas(s): yield s[last_start:i] -class BadArg(ValueError): - pass - - -class Retry(ValueError): - pass - - -class Undocumented(ValueError): - pass - - -class SignatureNotSupported(ValueError): - pass - - def parse_arg(arg): if "(*" in arg: arg_match = FUNC_PTR_RE.match(arg) @@ -660,24 +354,16 @@ def parse_arg(arg): words = arg.split() semantics, words = filter_semantics(words) - decl_words = [] - if words[0] in ["struct", "enum"]: - decl_words.append(words.pop(0)) + words = [w for w in words if w not in ["struct", "enum"]] rebuilt_arg = " ".join(words) arg_match = ARG_RE.match(rebuilt_arg) - base_type = arg_match.group(1).strip() - - if base_type == "isl_args": - raise BadArg("isl_args not supported") - assert arg_match is not None, rebuilt_arg return Argument( name=arg_match.group(3), semantics=semantics, - decl_words=decl_words, - base_type=base_type, + base_type=arg_match.group(1).strip(), ptr=arg_match.group(2).strip()) @@ -719,6 +405,10 @@ def preprocess_with_macros(macro_header_contents, code): return sio_output.getvalue() +# }}} + + +# {{{ FunctionData (includes parser) class FunctionData: def __init__(self, include_dirs): @@ -726,9 +416,6 @@ class FunctionData: self.include_dirs = include_dirs self.seen_c_names = set() - # used in setup.py - self.headers = [] - def get_header_contents(self, fname): from os.path import join success = False @@ -779,9 +466,6 @@ class FunctionData: try: with open(prepro_fname, "rt") as inf: return inf.read() - except IOError: - # Python 2 - pass except OSError: pass @@ -798,9 +482,9 @@ class FunctionData: return prepro_header - def read_header(self, fname): - self.headers.append(fname) + # {{{ read_header + def read_header(self, fname): lines = self.get_preprocessed_header(fname).split("\n") # heed continuations, split at semicolons @@ -874,6 +558,10 @@ class FunctionData: if not STRUCT_DECL_RE.search(decl): self.parse_decl(decl) + # }}} + + # {{{ parse_decl + def parse_decl(self, decl): decl_match = DECL_RE.match(decl) if decl_match is None: @@ -921,12 +609,13 @@ class FunctionData: assert c_name.startswith("isl_"), c_name name = c_name[4:] - found_class = False - for cls in CLASSES: - if name.startswith(cls): - found_class = True - name = name[len(cls)+1:] - break + # find longest class name match + class_name = None + for it_cls_name in CLASSES: + if (name.startswith(it_cls_name) + and (class_name is None + or len(class_name) < len(it_cls_name))): + class_name = it_cls_name # Don't be tempted to chop off "_val"--the "_val" versions of # some methods are incompatible with the isl_int ones. @@ -938,36 +627,35 @@ class FunctionData: # To avoid breaking user code in non-obvious ways, the new # names are carried over to the Python level. - if not found_class: + if class_name is not None: + name = name[len(class_name)+1:] + else: if name.startswith("bool_"): return if name.startswith("options_"): - found_class = True - cls = "ctx" + class_name = "ctx" name = name[len("options_"):] elif name.startswith("equality_") or name.startswith("inequality_"): - found_class = True - cls = "constraint" + class_name = "constraint" elif name == "ast_op_type_set_print_name": - found_class = True - cls = "printer" + class_name = "printer" name = "ast_op_type_set_print_name" - if name.startswith("2"): - name = "two_"+name[1:] + assert class_name is not None - assert found_class, name + if name in ["free", "cow"]: + return try: args = [parse_arg(arg) for arg in args] except BadArg: - print("SKIP: %s %s" % (cls, name)) + print("SKIP: %s %s" % (class_name, name)) return if name in PYTHON_RESERVED_WORDS: name = name + "_" - if cls == "options": + if class_name == "options": assert name.startswith("set_") or name.startswith("get_"), (name, c_name) name = name[:4]+"option_"+name[4:] @@ -982,363 +670,227 @@ class FunctionData: words.remove("__isl_constructor") return_semantics, words = filter_semantics(words) - return_decl_words = [] - if words[0] in ["struct", "enum"]: - return_decl_words.append(words.pop(0)) + words = [w for w in words if w not in ["struct", "enum"]] return_base_type = " ".join(words) - cls_meth_list = self.classes_to_methods.setdefault(cls, []) + cls_meth_list = self.classes_to_methods.setdefault(class_name, []) if c_name in self.seen_c_names: return cls_meth_list.append(Method( - cls, name, c_name, - return_semantics, return_decl_words, return_base_type, return_ptr, + class_name, name, c_name, + return_semantics, return_base_type, return_ptr, args, is_exported=is_exported, is_constructor=is_constructor)) self.seen_c_names.add(c_name) -# }}} - - -# {{{ header writer - -def write_enums_to_header(header_f): - for enum_name, value_str in ENUMS.items(): - values = [v.strip() for v in value_str.split(",") if v.strip()] - - if enum_name not in MACRO_ENUMS: - if enum_name in TYPEDEFD_ENUMS: - pattern = "typedef enum {{ {values}, ... }} {name};\n" - else: - pattern = "enum {name} {{ {values}, ... }};\n" - - header_f.write( - pattern.format( - name=enum_name, - values=", ".join(values))) - else: - for v in values: - header_f.write("static const int {name};".format(name=v)) - - -def write_classes_to_header(header_f): - for cls_name in CLASSES: - header_f.write("struct isl_{name};\n".format(name=cls_name)) - if cls_name not in UNTYPEDEFD_CLASSES: - header_f.write( - "typedef struct isl_{name} isl_{name};\n" - .format(name=cls_name)) - - -def write_method_header(header_f, method): - header_f.write( - "{return_decl_words} {ret_type} {ret_ptr}{name}({args});\n" - .format( - return_decl_words=" ".join(method.return_decl_words), - ret_type=method.return_base_type, - ret_ptr=method.return_ptr, - name=method.c_name, - args=", ".join(arg.c_declarator() for arg in method.args))) + # }}} # }}} -# {{{ python wrapper writer - -def write_enums_to_wrapper(wrapper_f): - gen = PythonCodeGenerator() - - gen("") - gen("# {{{ enums") - gen("") - for enum_name, value_str in ENUMS.items(): - values = [v.strip() for v in value_str.split(",") if v.strip()] - - assert enum_name.startswith("isl_") - name = enum_name[4:] - - if name == "bool": - continue - - from os.path import commonprefix - common_len = len(commonprefix(values)) - - gen("class {name}(_EnumBase):".format(name=name)) - with Indentation(gen): - for val in values: - py_name = val[common_len:] - if py_name in PYTHON_RESERVED_WORDS: - py_name += "_" - gen( - "{py_name} = lib.{val}" - .format( - val=val, - py_name=py_name, - )) - - gen("") - - gen("# }}}") - gen("") - wrapper_f.write(gen.get()) - - -def write_classes_to_wrapper(wrapper_f): - gen = PythonCodeGenerator() - - gen("# {{{ declare classes") - gen("") - for cls_name in CLASSES: - if cls_name == "ctx": - continue - py_cls = isl_class_to_py_class(cls_name) - gen("class {cls}(_ISLObjectBase):".format(cls=py_cls)) - with Indentation(gen): - gen("_base_name = "+repr(cls_name)) - gen("") - - if cls_name == "ctx": - gen(""" - def __del__(self): - if self.data is not None: - self._release() - """) - gen("") +# {{{ get_callback - else: - gen(""" - def __del__(self): - if self.data is not None: - lib.isl_{cls}_free(self.data) - """ - .format(cls=cls_name)) - gen("") - - if cls_name not in NON_COPYABLE: - gen(""" - def _copy(self): - assert self.data is not None - - data = lib.isl_{cls}_copy(self.data) - if data == ffi.NULL: - raise Error("failed to copy instance of {py_cls}") - - return {py_cls}(_data=data, context=self.get_ctx()) - """ - .format(cls=cls_name, py_cls=py_cls)) - - gen("") - - gen("") - gen("# }}}") - gen("") - gen("") - - wrapper_f.write(gen.get()) - - -def gen_conversions(gen, tgt_cls, name): - conversions = IMPLICIT_CONVERSIONS.get(tgt_cls, []) - for src_cls, conversion_method in conversions: - gen_conversions(gen, src_cls, name) - - gen(""" - if isinstance({name}, {py_src_cls}): - {name} = {py_cls}.{conversion_method}({name}) - """ - .format( - name=name, - py_src_cls=isl_class_to_py_class(src_cls), - py_cls=isl_class_to_py_class(tgt_cls), - conversion_method=conversion_method)) - - -def gen_callback_wrapper(gen, cb, func_name, has_userptr): +def get_callback(cb_name, cb): + pre_call = [] passed_args = [] - input_args = [] - - if has_userptr: - assert cb.args[-1].name == "user" + post_call = [] - pre_call = PythonCodeGenerator() - post_call = PythonCodeGenerator() + assert cb.args[-1].name == "user" for arg in cb.args[:-1]: - if arg.base_type.startswith("isl_") and arg.ptr == "*": - input_args.append(arg.name) - passed_args.append("_py_%s" % arg.name) + if arg.base_type.startswith("isl_"): + if arg.ptr != "*": + raise SignatureNotSupported("unsupported callback arg: %s %s" % ( + arg.base_type, arg.ptr)) + arg_cls = arg.base_type[4:] - pre_call( - "_py_{name} = {py_cls}(_data={name}, context=_ctx)" - .format( - name=arg.name, - py_cls=isl_class_to_py_class(arg.base_type))) + passed_args.append("arg_%s" % arg.name) + + pre_call.append(""" + %(arg_cls)s *wrapped_arg_%(name)s(new %(arg_cls)s(c_arg_%(name)s)); + py::object arg_%(name)s( + handle_from_new_ptr(wrapped_arg_%(name)s)); + """ % dict( + arg_cls=arg_cls, + name=arg.name, + )) if arg.semantics is SEM_TAKE: # We (the callback) are supposed to free the object, so - # just keep it attached to its wrapper until GC gets - # rid of it. + # just let the unique_ptr get rid of it. pass elif arg.semantics is SEM_KEEP: - # The caller wants to keep this object, so we'll stop managing - # it. - post_call("_py_{name}._release()".format(name=arg.name)) + # The caller wants to keep this object, so we simply tell our + # wrapper to stop managing it after the call completes. + post_call.append(""" + wrapped_arg_%(name)s->invalidate(); + """ % {"name": arg.name}) else: - raise SignatureNotSupported( - "callback arg semantics not understood: %s" % arg.semantics) + raise SignatureNotSupported("unsupported callback arg semantics") else: raise SignatureNotSupported("unsupported callback arg: %s %s" % ( arg.base_type, arg.ptr)) - if has_userptr: - input_args.append("user") - - if cb.return_base_type in SAFE_IN_TYPES and cb.return_ptr == "": - failure_return = "lib.isl_stat_error" - - post_call(""" - if _result is None: - _result = lib.isl_stat_ok - """) + if cb.return_base_type in SAFE_IN_TYPES and not cb.return_ptr: + ret_type = "%s %s" % (cb.return_base_type, cb.return_ptr) + if cb.return_base_type == "isl_stat": + post_call.append(""" + if (retval.ptr() == Py_None) + { + return isl_stat_ok; + } + """) + else: + post_call.append(""" + if (retval.ptr() == Py_None) + { + throw isl::error("callback returned None"); + } + """) + post_call.append(""" + else + return py::cast<%(ret_type)s>(retval); + """ % { + "ret_type": ret_type, + } + ) + if cb.return_base_type == "isl_bool": + error_return = "isl_bool_error" + else: + error_return = "isl_stat_error" elif cb.return_base_type.startswith("isl_") and cb.return_ptr == "*": - failure_return = "ffi.NULL" - - ret_py_cls = isl_class_to_py_class(cb.return_base_type) - if cb.return_semantics is None: raise SignatureNotSupported("callback return with unspecified semantics") elif cb.return_semantics is not SEM_GIVE: raise SignatureNotSupported("callback return with non-GIVE semantics") - post_call(""" - if _result is None: - _result = ffi.NULL - elif not isinstance(_result, {py_cls}): - raise IslTypeError("return value is not a {py_cls}") - else: - _result = _result._release() - """ - .format(py_cls=ret_py_cls)) + ret_type = "%s %s" % (cb.return_base_type, cb.return_ptr) + post_call.append(""" + if (retval.ptr() == Py_None) + { + return nullptr; + } + else + { + isl::%(ret_type_name)s *wrapper_retval = + py::cast(retval); + isl_%(ret_type_name)s *unwrapped_retval = + wrapper_retval->m_data; + wrapper_retval->invalidate(); + return unwrapped_retval; + } + """ % { + "ret_type_name": cb.return_base_type[4:], + } + ) + error_return = "nullptr" else: - raise SignatureNotSupported("unsupported callback signature") - - gen( - "def {func_name}({input_args}):" - .format( - func_name=func_name, - input_args=", ".join(input_args))) - - with Indentation(gen): - gen("try:") - with Indentation(gen): - gen.extend(pre_call) - gen( - "_result = {name}({passed_args})" - .format(name=cb.name, passed_args=", ".join(passed_args))) - - gen.extend(post_call) - - gen("return _result") - - gen(""" - except Exception as e: - import sys - sys.stderr.write("[WARNING] An exception occurred " - "in a callback function." - "This exception was ignored.\\n") - sys.stderr.flush() - import traceback - traceback.print_exc() - - return {failure_return} - """.format(failure_return=failure_return)) - - gen("") - - -def write_method_wrapper(gen, cls_name, meth): - pre_call = PythonCodeGenerator() - - # There are two post-call phases, "safety", and "check". The "safety" - # phase's job is to package up all the data returned by the function - # called. No exceptions may be raised before safety ends. - # - # Next, the "check" phase will perform error checking and may raise exceptions. - safety = PythonCodeGenerator() - check = PythonCodeGenerator() + raise SignatureNotSupported("non-int callback") + + return """ + static %(ret_type)s %(cb_name)s(%(input_args)s) + { + py::object py_cb = py::reinterpret_borrow( + (PyObject *) c_arg_user); + try + { + %(pre_call)s + py::object retval = py_cb(%(passed_args)s); + %(post_call)s + } + catch (py::error_already_set &err) + { + std::cout << "[islpy warning] A Python exception occurred in " + "a call back function, ignoring:" << std::endl; + PyErr_Print(); + return %(error_return)s; + } + catch (std::exception &e) + { + std::cerr << "[islpy] An exception occurred in " + "a Python callback query:" << std::endl + << e.what() << std::endl; + std::cout << "[islpy] Aborting now." << std::endl; + return %(error_return)s; + } + } + """ % dict( + ret_type=ret_type, + cb_name=cb_name, + input_args=( + ", ".join("%s %sc_arg_%s" % (arg.base_type, arg.ptr, arg.name) + for arg in cb.args)), + pre_call="\n".join(pre_call), + passed_args=", ".join(passed_args), + post_call="\n".join(post_call), + error_return=error_return, + ) + +# }}} + + +# {{{ wrapper generator + +def write_wrapper(outf, meth): + body = [] + checks = [] docs = [] passed_args = [] input_args = [] - doc_args = [] - ret_vals = [] - ret_descrs = [] + post_call = [] + extra_ret_vals = [] + extra_ret_descrs = [] + preamble = [] - def emit_context_check(arg_idx, arg_name): - if arg_idx == 0: - pre_call("_ctx = {arg_name}.get_ctx()".format(arg_name=arg_name)) - else: - pre_call(""" - if _ctx != {arg_name}.get_ctx(): - raise Error("mismatched context in {arg_name}") - """.format(arg_name=arg_name)) + arg_names = [] arg_idx = 0 while arg_idx < len(meth.args): arg = meth.args[arg_idx] + arg_names.append(arg.name) if isinstance(arg, CallbackArgument): has_userptr = ( arg_idx + 1 < len(meth.args) - and meth.args[arg_idx+1].name == "user") - if has_userptr: + and meth.args[arg_idx+1].name.endswith("user")) + if not has_userptr: + raise SignatureNotSupported( + "callback signature without user pointer") + else: arg_idx += 1 - cb_wrapper_name = "_cb_wrapper_"+arg.name + if meth.args[arg_idx].name != "user": + raise SignatureNotSupported("unexpected callback signature") - gen_callback_wrapper(pre_call, arg, cb_wrapper_name, has_userptr) - - pre_call( - '_cb_{name} = ffi.callback("{cb_decl}")({cb_wrapper_name})' - .format( - name=arg.name, cb_decl=arg.c_declarator(), - cb_wrapper_name=cb_wrapper_name - )) + cb_name = "cb_%s_%s_%s" % (meth.cls, meth.name, arg.name) if (meth.cls in ["ast_build", "ast_print_options"] and meth.name.startswith("set_")): - # These callbacks need to outlive the set call. - # Store them on the instance. - ret_vals.append("_cb_"+arg.name) - ret_descrs.append(":class:`ffi_callback_handle`") - - input_args.append(arg.name) - - passed_args.append("_cb_"+arg.name) - if has_userptr: - passed_args.append("ffi.NULL") - - docs.append(":param %s: callback(%s) -> %s" - % ( - arg.name, - ", ".join( - sub_arg.name - for sub_arg in arg.args - if sub_arg.name != "user"), - arg.return_base_type - )) + extra_ret_vals.append("py_%s" % arg.name) + extra_ret_descrs.append("(opaque handle to " + "manage callback lifetime)") - elif arg.base_type in SAFE_IN_TYPES and not arg.ptr: - passed_args.append(arg.name) - input_args.append(arg.name) - doc_args.append(arg.name) + input_args.append("py::object py_%s" % arg.name) + passed_args.append(cb_name) + passed_args.append("py_%s.ptr()" % arg.name) + + preamble.append(get_callback(cb_name, arg)) - pre_call("# no argument processing for {0}".format(arg.name)) + docs.append(":param %s: callback(%s)" + % (arg.name, ", ".join( + sub_arg.name + for sub_arg in arg.args + if sub_arg.name != "user"))) + + elif arg.base_type in SAFE_IN_TYPES and not arg.ptr: + passed_args.append("arg_"+arg.name) + input_args.append("%s arg_%s" % (arg.base_type, arg.name)) doc_cls = arg.base_type if doc_cls.startswith("isl_"): @@ -1347,131 +899,148 @@ def write_method_wrapper(gen, cls_name, meth): docs.append(":param %s: :class:`%s`" % (arg.name, doc_cls)) elif arg.base_type in ["char", "const char"] and arg.ptr == "*": - c_name = "_cstr_"+arg.name - - pre_call('{c_name} = ffi.new("char[]", {arg_name}.encode())' - .format(c_name=c_name, arg_name=arg.name)) - - if arg.semantics is SEM_TAKE: - pre_call( - "{c_name} = _ManagedCString({c_name})" - .format(c_name=c_name)) - passed_args.append(c_name + "._release()") + if arg.semantics is SEM_KEEP: + passed_args.append("strdup(%s)" % arg.name) else: - passed_args.append(c_name) - input_args.append(arg.name) + passed_args.append(arg.name) + input_args.append("%s *%s" % (arg.base_type, arg.name)) docs.append(":param %s: string" % arg.name) - elif (arg.base_type == "isl_bool" or arg.base_type == "int") and arg.ptr == "*": + elif arg.base_type in ["int", "isl_bool"] and arg.ptr == "*": if arg.name in ["exact", "tight"]: - c_name = "c{base_type}_".format(base_type=arg.base_type) + arg.name - pre_call('{c_name} = ffi.new("{base_type}[1]")' - .format(c_name=c_name, base_type=arg.base_type)) - - passed_args.append(c_name) + body.append("%s arg_%s;" % (arg.base_type, arg.name)) + passed_args.append("&arg_%s" % arg.name) if arg.base_type == "isl_bool": - ret_vals.append("({c_name}[0] == lib.isl_bool_true)" - .format(c_name=c_name)) - ret_descrs.append("%s (bool)" % arg.name) - check('if {c_name}[0] == lib.isl_bool_error:'.format(c_name=c_name)) - with Indentation(check): - check('raise Error("call to \\"{0}\\" failed: %s" ' - '% _get_last_error_str(_ctx.data))'.format(meth.c_name)) + extra_ret_vals.append("(bool) arg_%s" % arg.name) else: - ret_vals.append("{c_name}[0]".format(c_name=c_name)) - ret_descrs.append("%s (integer)" % arg.name) + extra_ret_vals.append("arg_%s" % arg.name) + extra_ret_descrs.append("%s (%s)" % ( + arg.name, to_py_class(arg.base_type))) + arg_names.pop() else: - raise SignatureNotSupported("{base_type} *".format(base_type=arg.base_type)) + raise SignatureNotSupported("int *") elif arg.base_type == "isl_val" and arg.ptr == "*" and arg_idx > 0: # {{{ val input argument - val_name = "_val_" + arg.name - fmt_args = dict( - arg0_name=meth.args[0].name, + arg_descr = ":param %s: :class:`Val`" % arg.name + input_args.append("py::object py_%s" % arg.name) + checks.append(""" + std::unique_ptr unique_arg_%(name)s; + isl_ctx *ctx_for_%(name)s = + %(first_arg_base_type)s_get_ctx(arg_%(first_arg)s.m_data); + + try + { + val *arg_%(name)s = py::cast(py_%(name)s); + isl_val *tmp_ptr = isl_val_copy(arg_%(name)s->m_data); + if (!tmp_ptr) + throw isl::error("failed to copy arg %(name)s"); + unique_arg_%(name)s = std::unique_ptr(new val(tmp_ptr)); + } + catch (py::cast_error &err) + { + // fall through to next case + } + + try + { + if (!unique_arg_%(name)s.get()) + { + isl_val *tmp_ptr = isl_val_int_from_si(ctx_for_%(name)s, + py::cast(py_%(name)s)); + if (!tmp_ptr) + throw isl::error("failed to create arg " + "%(name)s from integer"); + unique_arg_%(name)s = std::unique_ptr(new val(tmp_ptr)); + } + } + catch (py::cast_error &err) + { + throw isl::error("unrecognized argument for %(name)s"); + } + """ % dict( name=arg.name, - val_name=val_name) - - pre_call("if isinstance({name}, Val):".format(**fmt_args)) - - with Indentation(pre_call): - emit_context_check(arg_idx, arg.name) - pre_call("{val_name} = {name}._copy()".format(**fmt_args)) - - pre_call(""" - else: - try: - {name} = _operator.index({name}) - except TypeError: - raise IslTypeError("{name} is a %s and cannot " - "be cast to a Val" % _type({name})) - - _cdata_{name} = lib.isl_val_int_from_si( - {arg0_name}.get_ctx().data, {name}) - - if _cdata_{name} == ffi.NULL: - raise Error("isl_val_int_from_si failed") + first_arg_base_type=meth.args[0].base_type, + first_arg=meth.args[0].name, + )) - {val_name} = Val(_data=_cdata_{name}, context=_ctx) - """ - .format(**fmt_args)) + if arg.semantics is None and arg.base_type != "isl_ctx": + raise Undocumented(meth) if arg.semantics is SEM_TAKE: - passed_args.append(val_name + "._release()") - else: - passed_args.append(val_name + ".data") - input_args.append(arg.name) + post_call.append("unique_arg_%s.release();" % arg.name) - docs.append(":param %s: :class:`Val`" % arg.name) + passed_args.append("unique_arg_%s->m_data" % arg.name) + docs.append(arg_descr) # }}} elif arg.base_type.startswith("isl_") and arg.ptr == "*": # {{{ isl types input arguments - gen_conversions(pre_call, arg.base_type, arg.name) - - arg_py_cls = isl_class_to_py_class(arg.base_type) - pre_call(""" - if not isinstance({name}, {py_cls}): - raise IslTypeError("{name} is not a {py_cls}") - """ - .format(name=arg.name, py_cls=arg_py_cls)) - - emit_context_check(arg_idx, arg.name) - arg_cls = arg.base_type[4:] - arg_descr = ":param %s: :class:`%s`" % ( - arg.name, isl_class_to_py_class(arg_cls)) - - if arg.semantics is None and arg.base_type != "isl_ctx": - raise Undocumented(meth) - - copyable = arg_cls not in NON_COPYABLE - if arg.semantics is SEM_TAKE: - if copyable: - copy_name = "_copy_"+arg.name - pre_call('{copy_name} = {name}._copy()' - .format(copy_name=copy_name, name=arg.name)) + arg_descr = ":param %s: :class:`%s`" % (arg.name, to_py_class(arg_cls)) + + if arg_idx == 0 and meth.is_mutator: + arg_descr += " (mutated in-place)" + input_args.append("py::object py_%s" % arg.name) + checks.append(""" + isl::%(cls)s &arg_%(name)s( + py::cast(py_%(name)s)); + if (!arg_%(name)s.is_valid()) + throw isl::error( + "passed invalid arg to isl_%(meth)s for %(name)s"); + """ % dict( + name=arg.name, + meth="%s_%s" % (meth.cls, meth.name), + cls=arg_cls)) + passed_args.append("arg_%s.m_data" % arg.name) + post_call.append("arg_%s.invalidate();" % arg.name) + arg_descr += " (mutated in-place)" - passed_args.append(copy_name+"._release()") + else: + if arg.semantics is None and arg.base_type != "isl_ctx": + raise Undocumented(meth) + + checks.append(""" + if (!arg_%(name)s.is_valid()) + throw isl::error( + "passed invalid arg to isl_%(meth)s for %(name)s"); + """ % dict(name=arg.name, meth="%s_%s" % (meth.cls, meth.name))) + + if arg.semantics is SEM_TAKE: + if arg_cls not in NON_COPYABLE: + input_args.append( + "%s const &%s" % (arg_cls, "arg_"+arg.name)) + checks.append(""" + std::unique_ptr<%(cls)s> auto_arg_%(name)s; + { + isl_%(cls)s *tmp_ptr = + isl_%(cls)s_copy(arg_%(name)s.m_data); + if (!tmp_ptr) + throw isl::error("failed to copy arg " + "%(name)s on entry to %(meth)s"); + auto_arg_%(name)s = std::unique_ptr<%(cls)s>( + new %(cls)s(tmp_ptr)); + } + """ % dict( + name=arg.name, + meth="%s_%s" % (meth.cls, meth.name), + cls=arg_cls)) + + post_call.append("auto_arg_%s.release();" % arg.name) + passed_args.append("auto_arg_%s->m_data" % arg.name) - else: - if not (arg_idx == 0 and meth.is_mutator): - passed_args.append(arg.name+"._release()") - arg_descr += " (mutated in-place)" else: - passed_args.append(arg.name+".data") + input_args.append("%s &%s" % (arg_cls, "arg_"+arg.name)) + post_call.append("arg_%s.invalidate();" % arg.name) + passed_args.append("arg_%s.m_data" % arg.name) arg_descr += " (:ref:`becomes invalid `)" - - elif arg.semantics is SEM_KEEP or arg.semantics is None: - passed_args.append("%s.data" % arg.name) - - else: - raise RuntimeError("unexpected semantics: %s" % arg.semantics) - - input_args.append(arg.name) + else: + passed_args.append("arg_%s.m_data" % arg.name) + input_args.append("%s const &%s" % (arg_cls, "arg_"+arg.name)) docs.append(arg_descr) @@ -1483,149 +1052,247 @@ def write_method_wrapper(gen, cls_name, meth): if arg.semantics is not SEM_GIVE: raise SignatureNotSupported("non-give secondary ptr return value") - pre_call( - '_retptr_{name} = ffi.new("{cls} **")' - .format(name=arg.name, cls=arg.base_type)) + ret_cls = arg.base_type[4:] - passed_args.append("_retptr_{name}".format(name=arg.name)) + arg_names.pop() + body.append("%s *ret_%s;" % (arg.base_type, arg.name)) + passed_args.append("&ret_%s" % arg.name) - py_cls = isl_class_to_py_class(arg.base_type) - safety(""" - if _retptr_{name} == ffi.NULL: - _ret_{name} = None - else: - _ret_{name} = {py_cls}(_data=_retptr_{name}[0], context=_ctx) - """ - .format(name=arg.name, cls=arg.base_type, py_cls=py_cls)) + post_call.append(""" + py::object py_ret_%(name)s; + if (ret_%(name)s) + { + py_ret_%(name)s = handle_from_new_ptr( + new %(ret_cls)s(ret_%(name)s)); + } + """ % dict(name=arg.name, ret_cls=ret_cls)) - ret_vals.append("_ret_" + arg.name) - ret_descrs.append("%s (:class:`%s`)" % (arg.name, py_cls)) + extra_ret_vals.append("py_ret_%s" % arg.name) + extra_ret_descrs.append( + "%s (:class:`%s`)" % (arg.name, to_py_class(ret_cls))) # }}} + elif arg.base_type == "FILE" and arg.ptr == "*": + if sys.version_info >= (3,): + raise SignatureNotSupported( + "arg type %s %s" % (arg.base_type, arg.ptr)) + + passed_args.append("PyFile_AsFile(arg_%s.ptr())" % arg.name) + input_args.append("py::object %s" % ("arg_"+arg.name)) + docs.append(":param %s: :class:`file`-like " + "(NOTE: This will cease to be supported in Python 3.)" + % arg.name) + elif (arg.base_type == "void" and arg.ptr == "*" and arg.name == "user"): - - passed_args.append("ffi.NULL") - input_args.append(arg.name) - - pre_call(""" - if {name} is not None: - raise Error("passing non-None arguments for '{name}' " - "is not yet supported") - """ - .format(name=arg.name)) - - docs.append(":param %s: None" % arg.name) + body.append("Py_INCREF(arg_%s.ptr());" % arg.name) + passed_args.append("arg_%s.ptr()" % arg.name) + input_args.append("py::object %s" % ("arg_"+arg.name)) + post_call.append(""" + isl_%s_set_free_user(result, my_decref); + """ % meth.cls) + docs.append(":param %s: a user-specified Python object" % arg.name) else: raise SignatureNotSupported("arg type %s %s" % (arg.base_type, arg.ptr)) arg_idx += 1 - pre_call("") + + processed_return_type = "%s %s" % (meth.return_base_type, meth.return_ptr) + + if meth.return_base_type == "void" and not meth.return_ptr: + result_capture = "" + else: + result_capture = "%s %sresult = " % (meth.return_base_type, meth.return_ptr) + + body = checks + body + + body.append("%s%s(%s);" % ( + result_capture, meth.c_name, ", ".join(passed_args))) + + body += post_call # {{{ return value processing - if meth.return_base_type == "isl_stat" and not meth.return_ptr: - check("if _result == lib.isl_stat_error:") - with Indentation(check): - check('raise Error("call to \\"{0}\\" failed: %s" ' - '% _get_last_error_str(_ctx.data))'.format(meth.c_name)) + if meth.return_base_type == "int" and not meth.return_ptr: + # {{{ integer return + + if meth.name.startswith("is_") or meth.name.startswith("has_"): + processed_return_type = "bool" + + ret_descr = processed_return_type + + if extra_ret_vals: + if len(extra_ret_vals) == 1: + processed_return_type = "py::object" + body.append("return py::object(result, %s);" % extra_ret_vals[0]) + ret_descr = extra_ret_descrs[0] + else: + processed_return_type = "py::object" + body.append("return py::make_tuple(result, %s);" + % ", ".join(extra_ret_vals)) + ret_descr = "tuple: (%s)" % (", ".join(extra_ret_descrs)) + else: + body.append("return result;") + + # }}} + + elif meth.return_base_type == "isl_stat" and not meth.return_ptr: + # {{{ error code + + body.append(""" + if (result == isl_stat_error) + { + throw isl::error("call to isl_%(cls)s_%(name)s failed"); + }""" % {"cls": meth.cls, "name": meth.name}) + + assert not (meth.name.startswith("is_") or meth.name.startswith("has_")) + + ret_descr = processed_return_type + + if extra_ret_vals: + if len(extra_ret_vals) == 1: + processed_return_type = "py::object" + body.append("return py::object(%s);" % extra_ret_vals[0]) + ret_descr = extra_ret_descrs[0] + else: + processed_return_type = "py::object" + body.append("return py::make_tuple(%s);" % ", ".join(extra_ret_vals)) + ret_descr = "tuple: (%s)" % (", ".join(extra_ret_descrs)) + else: + body.append("return result;") + + # }}} elif meth.return_base_type == "isl_bool" and not meth.return_ptr: - check("if _result == lib.isl_bool_error:") - with Indentation(check): - check('raise Error("call to \\"{0}\\" failed: %s" ' - '% _get_last_error_str(_ctx.data))'.format(meth.c_name)) + # {{{ bool + + body.append(""" + if (result == isl_bool_error) + { + throw isl::error("call to isl_%(cls)s_%(name)s failed"); + }""" % {"cls": meth.cls, "name": meth.name}) + + processed_return_type = "bool" + ret_descr = "bool" + + if extra_ret_vals: + if len(extra_ret_vals) == 1: + processed_return_type = "py::object" + body.append("return py::object(%s);" % extra_ret_vals[0]) + ret_descr = extra_ret_descrs[0] + else: + processed_return_type = "py::object" + body.append("return py::make_tuple(%s);" % ", ".join(extra_ret_vals)) + ret_descr = "tuple: (%s)" % (", ".join(extra_ret_descrs)) + else: + body.append("return result;") - ret_vals.insert(0, "_result == lib.isl_bool_true") - ret_descrs.insert(0, "bool") + # }}} elif meth.return_base_type in SAFE_TYPES and not meth.return_ptr: - ret_vals.insert(0, "_result") - ret_descrs.insert(0, meth.return_base_type) + # {{{ enums etc - elif (meth.return_base_type.startswith("isl_") - and meth.return_semantics is SEM_NULL): - assert not meth.is_mutator + if extra_ret_vals: + raise NotImplementedError("extra ret val with safe type") + + body.append("return result;") + ret_descr = processed_return_type + + # }}} + + elif meth.return_base_type.startswith("isl_"): + assert meth.return_ptr == "*", meth - elif meth.return_base_type.startswith("isl_") and meth.return_ptr == "*": ret_cls = meth.return_base_type[4:] if meth.is_mutator: - if ret_vals: + if extra_ret_vals: meth.mutator_veto = True raise Retry() - safety("%s._reset(_result)" % meth.args[0].name) + processed_return_type = "py::object" + body.append("arg_%s.take_possession_of(result);" % meth.args[0].name) + body.append("return py_%s;" % meth.args[0].name) - ret_vals.insert(0, meth.args[0].name) - ret_descrs.insert(0, - ":class:`%s` (self)" % isl_class_to_py_class(ret_cls)) + ret_descr = ":class:`%s` (self)" % to_py_class(ret_cls) else: + processed_return_type = "py::object" + isl_obj_ret_val = \ + "handle_from_new_ptr(uptr_result.release())" + + if extra_ret_vals: + isl_obj_ret_val = "py::make_tuple(%s, %s)" % ( + isl_obj_ret_val, ", ".join(extra_ret_vals)) + ret_descr = "tuple: (:class:`%s`, %s)" % ( + to_py_class(ret_cls), ", ".join(extra_ret_descrs)) + else: + ret_descr = ":class:`%s`" % to_py_class(ret_cls) + if meth.return_semantics is None and ret_cls != "ctx": raise Undocumented(meth) if meth.return_semantics is not SEM_GIVE and ret_cls != "ctx": raise SignatureNotSupported("non-give return") - py_ret_cls = isl_class_to_py_class(ret_cls) - if ret_cls == "ctx": - safety( - "_result = None if " - "(_result == ffi.NULL or _result is None) " - "else {0}(_data=_result)" - .format(py_ret_cls)) - else: - safety( - "_result = None if " - "(_result == ffi.NULL or _result is None) " - "else {0}(_data=_result, context=_ctx)" - .format(py_ret_cls)) - - check(""" - if _result is None: - raise Error("call to {c_method} failed: %s" - % _get_last_error_str(_ctx.data)) - """ - .format(c_method=meth.c_name)) - - ret_vals.insert(0, "_result") - ret_descrs.insert(0, ":class:`%s`" % py_ret_cls) + body.append(""" + if (result) + { + std::unique_ptr + uptr_result(new %(ret_cls)s(result)); + return %(ret_val)s; + } + else + { + throw isl::error("call to isl_%(cls)s_%(name)s failed"); + } + """ % { + "ret_cls": ret_cls, + "ret_val": isl_obj_ret_val, + "cls": meth.cls, + "name": meth.name, + }) elif meth.return_base_type in ["const char", "char"] and meth.return_ptr == "*": - safety(""" - if _result != ffi.NULL: - _str_ret = ffi.string(_result) - else: - _str_ret = None + if extra_ret_vals: + raise NotImplementedError("extra ret val with string") + + processed_return_type = "py::object" + body.append(""" + if (result) + return py::cast(std::string(result)); + else + return py::none(); """) - if meth.return_semantics is SEM_GIVE: - safety("libc.free(_result)") - - check(""" - if _PY3 and _str_ret is not None: - _str_ret = _str_ret.decode() - """) - - ret_vals.insert(0, "_str_ret") + body.append("free(result);") - ret_descrs.insert(0, "string") + ret_descr = "string" elif (meth.return_base_type == "void" and meth.return_ptr == "*" and meth.name == "get_user"): - raise SignatureNotSupported("get_user") - # body.append(""" - # return py::object(py::handle<>(py::borrowed((PyObject *) _result))); - # """) - # ret_descr = "a user-specified python object" + body.append(""" + return py::reinterpret_borrow((PyObject *) result); + """) + ret_descr = "a user-specified python object" + processed_return_type = "py::object" elif meth.return_base_type == "void" and not meth.return_ptr: - pass + if extra_ret_vals: + processed_return_type = "py::object" + if len(extra_ret_vals) == 1: + body.append("return %s;" % extra_ret_vals[0]) + ret_descr = extra_ret_descrs[0] + else: + body.append("return py::make_tuple(%s);" + % ", ".join(extra_ret_vals)) + ret_descr = "tuple: " + ", ".join(extra_ret_descrs) + else: + ret_descr = "None" else: raise SignatureNotSupported("ret type: %s %s in %s" % ( @@ -1633,90 +1300,104 @@ def write_method_wrapper(gen, cls_name, meth): # }}} - assert len(ret_vals) == len(ret_descrs) - - check("") - if len(ret_vals) == 0: - ret_descr = "(nothing)" - - elif len(ret_vals) == 1: - check("return " + ret_vals[0]) - ret_descr = ret_descrs[0] - - else: - check("return " + ", ".join(ret_vals)) - ret_descr = "(%s)" % ", ".join(ret_descrs) + outf.write(""" + %s + %s %s_%s(%s) + { + %s + } + """ % ( + "\n".join(preamble), + processed_return_type, meth.cls, meth.name, + ", ".join(input_args), + "\n".join(body))) - docs = (["%s(%s)" % (meth.name, ", ".join(input_args)), ""] + docs = (["%s(%s)" % (meth.name, ", ".join(arg_names)), ""] + docs + [":return: %s" % ret_descr]) - gen("def {name}({input_args}):" - .format(name=meth.name, input_args=", ".join(input_args))) - gen.indent() - gen(repr("\n".join(docs))) - gen("") - gen.extend(pre_call) - gen("") - - gen("try:") - with Indentation(gen): - gen("_result = None") - gen("with DelayedKeyboardInterrupt():") - with Indentation(gen): - gen( - "_result = lib.{c_name}({args})" - .format(c_name=meth.c_name, args=", ".join(passed_args))) - - gen("finally:") - with Indentation(gen): - if not (meth.return_base_type == "void" and not meth.return_ptr): - gen(r""" - if _result is None: - # This should never happen. - sys.stderr.write("*** islpy was interrupted while collecting " - "a result. " - "System state is inconsistent as a result, will print " - "traceback and abort.\n") - sys.stderr.flush() - import traceback - traceback.print_stack() - import os - os._exit(-1) - """) + return arg_names, "\n".join(docs) + +# }}} - gen.extend(safety) - gen("pass") - gen.extend(check) - gen.dedent() - gen("") +# {{{ exposer generator - method_val = meth.name +def write_exposer(outf, meth, arg_names, doc_str): + func_name = "isl::%s_%s" % (meth.cls, meth.name) py_name = meth.name - if meth.is_static: - method_val = "staticmethod(%s)" % method_val - if py_name == "size" and len(meth.args) == 1: + nonself_arg_names = arg_names + if not meth.is_static: + nonself_arg_names = nonself_arg_names[1:] + args_str = ", ".join('py::arg("%s")' % arg_name + for arg_name in nonself_arg_names) + if args_str: + args_str = ", %s" % args_str + + if meth.name == "size" and len(meth.args) == 1: py_name = "__len__" - gen("{py_cls}.{py_name} = {method_val}" - .format( - py_cls=isl_class_to_py_class(meth.cls), - py_name=py_name, - method_val=method_val)) - gen("") + if meth.name == "get_hash" and len(meth.args) == 1: + py_name = "__hash__" + + extra_py_names = [] - if meth.is_static: - gen("{py_cls}._{name}_is_static = True" - .format( - py_cls=isl_class_to_py_class(meth.cls), - name=py_name)) - gen("") + #if meth.is_static: + # doc_str = "(static method)\n" + doc_str + + doc_str_arg = ", \"%s\"" % doc_str.replace("\n", "\\n") + + wrap_class = CLASS_MAP.get(meth.cls, meth.cls) + + for exp_py_name in [py_name]+extra_py_names: + outf.write("wrap_%s.def%s(\"%s\", %s%s);\n" % ( + wrap_class, "_static" if meth.is_static else "", + exp_py_name, func_name, args_str+doc_str_arg)) # }}} +def write_wrappers(expf, wrapf, methods): + undoc = [] + + for meth in methods: + #print "TRY_WRAP:", meth + if meth.name.endswith("_si") or meth.name.endswith("_ui"): + val_versions = [ + meth2 + for meth2 in methods + if meth2.cls == meth.cls + and ( + meth2.name == meth.name[:-3] + or meth2.name == meth.name[:-3] + "_val" + ) + ] + + if val_versions: + # no need to expose C integer versions of things + print("SKIP (val version available): %s -> %s" + % (meth, ", ".join(str(s) for s in val_versions))) + continue + + try: + arg_names, doc_str = write_wrapper(wrapf, meth) + write_exposer(expf, meth, arg_names, doc_str) + except Undocumented: + undoc.append(str(meth)) + except Retry: + arg_names, doc_str = write_wrapper(wrapf, meth) + write_exposer(expf, meth, arg_names, doc_str) + except SignatureNotSupported: + _, e, _ = sys.exc_info() + print("SKIP (sig not supported: %s): %s" % (e, meth)) + else: + #print "WRAPPED:", meth + pass + + print("SKIP (%d undocumented methods): %s" % (len(undoc), ", ".join(undoc))) + + ADD_VERSIONS = { "union_pw_aff": 15, "multi_union_pw_aff": 15, @@ -1728,7 +1409,6 @@ ADD_VERSIONS = { def gen_wrapper(include_dirs, include_barvinok=False, isl_version=None): fdata = FunctionData(["."] + include_dirs) - fdata.read_header("isl/ctx.h") fdata.read_header("isl/id.h") fdata.read_header("isl/space.h") fdata.read_header("isl/set.h") @@ -1758,123 +1438,24 @@ def gen_wrapper(include_dirs, include_barvinok=False, isl_version=None): if include_barvinok: fdata.read_header("barvinok/isl.h") - undoc = [] + for part, classes in PART_TO_CLASSES.items(): + expf = open("src/wrapper/gen-expose-%s.inc" % part, "wt") + wrapf = open("src/wrapper/gen-wrap-%s.inc" % part, "wt") - with open("wrapped-functions.h", "wt") as header_f: - with open("islpy/_isl.py", "wt") as wrapper_f: - header_f.write( - "// AUTOMATICALLY GENERATED by gen_wrap.py -- do not edit\n\n") - write_enums_to_header(header_f) - write_classes_to_header(header_f) - header_f.write(HEADER_PREAMBLE) - - wrapper_f.write( - "# AUTOMATICALLY GENERATED by gen_wrap.py -- do not edit\n") - win_ext_suffix = get_config_var('EXT_SUFFIX') - if win_ext_suffix is None: - win_ext_suffix = ".pyd" - win_pyd = "_isl_cffi{}".format(win_ext_suffix) - wrapper_f.write(PY_PREAMBLE.format(win_pyd=win_pyd)) - write_enums_to_wrapper(wrapper_f) - write_classes_to_wrapper(wrapper_f) - - wrapper_gen = PythonCodeGenerator() - wrapper_gen("# {{{ wrappers") - wrapper_gen("") - wrapper_gen("def _add_methods():") - - with Indentation(wrapper_gen): - for cls_name in CLASSES: - if not ( - isl_version is None - or ADD_VERSIONS.get(cls_name) is None - or ADD_VERSIONS.get(cls_name) <= isl_version): - continue - - methods = [ - meth - for meth in fdata.classes_to_methods.get(cls_name, [])] - - wrapper_gen("# {{{ " + cls_name) - wrapper_gen("") - - for meth in methods: - if meth.name.endswith("get_ctx"): - continue - - if meth.name.endswith("_si") or meth.name.endswith("_ui"): - val_versions = [ - meth2 - for meth2 in methods - if meth2.cls == meth.cls - and ( - meth2.name == meth.name[:-3] - or meth2.name == meth.name[:-3] + "_val" - ) - ] - - if val_versions: - # no need to expose C integer versions of things - # print("SKIP (val version available): %s -> %s" - # % (meth, ", ".join(str(s) - # for s in val_versions))) - continue - - write_method_header(header_f, meth) - - if meth.name in ["free", "set_free_user"]: - continue - - try: - write_method_wrapper(wrapper_gen, cls_name, meth) - except Retry: - write_method_wrapper(wrapper_gen, cls_name, meth) - except Undocumented: - undoc.append(str(meth)) - except SignatureNotSupported: - _, e, _ = sys.exc_info() - print("SKIP (sig not supported: %s): %s" % (e, meth)) - else: - #print "WRAPPED:", meth - pass - - wrapper_gen("# }}}") - wrapper_gen("") - - wrapper_gen("") - wrapper_gen("# }}}") - wrapper_gen("") - wrapper_gen("_add_methods()") - - wrapper_f.write("\n" + wrapper_gen.get()) - wrapper_f.write("\n\n# vim: fdm=marker\n") - - with open("name_list.py", "wt") as clist_f: - py_classes = [] - - for cls_name in CLASSES: - py_cls = isl_class_to_py_class(cls_name) - py_classes.append(py_cls) - clist_f.write("{py_cls} = _isl.{py_cls}\n".format(py_cls=py_cls)) - clist_f.write("\n") - - for enum_name in ENUMS: - py_name = enum_name[4:] - - if py_name == "bool": - continue - - clist_f.write( - "{py_name} = _isl.{py_name}\n" - .format(py_name=py_name) - ) - clist_f.write("\n") + classes = [ + cls + for cls in classes + if isl_version is None + or ADD_VERSIONS.get(cls) is None + or ADD_VERSIONS.get(cls) <= isl_version] - clist_f.write("ALL_CLASSES = [{0}]\n".format(", ".join(py_classes))) - - print("SKIP (%d undocumented methods): %s" % (len(undoc), ", ".join(undoc))) + write_wrappers(expf, wrapf, [ + meth + for cls in classes + for meth in fdata.classes_to_methods.get(cls, [])]) - return fdata.headers + expf.close() + wrapf.close() if __name__ == "__main__": diff --git a/isl b/isl index 86d64c07cfbb41cee88e2f778b77d043bad5c2ed..13b9178b9b370164d0dbea232dbbe0112a27b6ae 160000 --- a/isl +++ b/isl @@ -1 +1 @@ -Subproject commit 86d64c07cfbb41cee88e2f778b77d043bad5c2ed +Subproject commit 13b9178b9b370164d0dbea232dbbe0112a27b6ae diff --git a/islpy/__init__.py b/islpy/__init__.py index 4d1e22b42a2460bf081bad5ef61e836db4f90108..3c2a5db012305fd3561ff676da42ef873ef3b951 100644 --- a/islpy/__init__.py +++ b/islpy/__init__.py @@ -1,6 +1,4 @@ -from __future__ import division, absolute_import - -__copyright__ = "Copyright (C) 2011-15 Andreas Kloeckner" +__copyright__ = "Copyright (C) 2011-20 Andreas Kloeckner" __license__ = """ Permission is hereby granted, free of charge, to any person obtaining a copy @@ -30,7 +28,7 @@ from six.moves import range Error = _isl.Error -# {{{ generated by gen_wrap as name_list.py +# {{{ name imports Context = _isl.Context IdList = _isl.IdList @@ -82,7 +80,6 @@ UnionPwQPolynomial = _isl.UnionPwQPolynomial QPolynomial = _isl.QPolynomial PwQPolynomial = _isl.PwQPolynomial Term = _isl.Term -Band = _isl.Band ScheduleConstraints = _isl.ScheduleConstraints ScheduleNode = _isl.ScheduleNode Schedule = _isl.Schedule @@ -111,6 +108,9 @@ bound = _isl.bound on_error = _isl.on_error schedule_algorithm = _isl.schedule_algorithm +# backward compatibility +ast_op_type = _isl.ast_expr_op_type + ALL_CLASSES = [Context, IdList, ValList, BasicSetList, BasicMapList, SetList, MapList, UnionSetList, ConstraintList, AffList, PwAffList, AstExprList, AstNodeList, IdToAstExpr, Printer, Val, MultiVal, Vec, Mat, Aff, PwAff, @@ -119,7 +119,7 @@ ALL_CLASSES = [Context, IdList, ValList, BasicSetList, BasicMapList, SetList, BasicSet, BasicMap, Set, Map, UnionMap, UnionSet, Point, Vertex, Cell, Vertices, StrideInfo, QPolynomialFold, PwQPolynomialFold, UnionPwQPolynomialFold, UnionPwQPolynomial, QPolynomial, PwQPolynomial, - Term, Band, ScheduleConstraints, ScheduleNode, Schedule, AccessInfo, + Term, ScheduleConstraints, ScheduleNode, Schedule, AccessInfo, Flow, Restriction, UnionAccessInfo, UnionFlow, AstExpr, AstNode, AstPrintOptions, AstBuild] @@ -129,84 +129,88 @@ ALL_CLASSES = [Context, IdList, ValList, BasicSetList, BasicMapList, SetList, _CHECK_DIM_TYPES = [ dim_type.in_, dim_type.param, dim_type.set] +ALL_CLASSES = tuple(getattr(_isl, cls) for cls in dir(_isl) if cls[0].isupper()) EXPR_CLASSES = tuple(cls for cls in ALL_CLASSES if "Aff" in cls.__name__ or "Polynomial" in cls.__name__) +DEFAULT_CONTEXT = Context() -def _get_default_ctx(): + +def _get_default_context(): + """A callable to get the default context for the benefit of Python's + ``__reduce__`` protocol. + """ return DEFAULT_CONTEXT -def _get_a_ctx(): - return Context.alloc() +def _read_from_str_wrapper(cls, context, s): + """A callable to reconstitute instances from strings for the benefit + of Python's ``__reduce__`` protocol. + """ + return cls.read_from_str(context, s) def _add_functionality(): + import islpy._isl as _isl # noqa + # {{{ Context def context_reduce(self): - if self.data == DEFAULT_CONTEXT.data: - return (_get_default_ctx, ()) + if self._wraps_same_instance_as(DEFAULT_CONTEXT): + return (_get_default_context, ()) else: - return (_get_a_ctx, ()) + return (Context, ()) + + def context_eq(self, other): + return isinstance(other, Context) and self._wraps_same_instance_as(other) + + def context_ne(self, other): + return not self.__eq__(other) Context.__reduce__ = context_reduce + Context.__eq__ = context_eq + Context.__ne__ = context_ne # }}} # {{{ generic initialization, pickling - def obj_init(self, s=None, context=None, _data=None): + def obj_new(cls, s=None, context=None): """Construct a new object from :class:`str` s. :arg context: a :class:`islpy.Context` to use. If not supplied, use a global default context. """ + if not isinstance(s, str): + return cls._prev_new(cls) - if _data is not None: - if s is not None: - raise TypeError("may not pass _data and string at the same time") - - assert context is not None - _isl._ISLObjectBase.__init__(self, _data, context=context) - else: - if s is None: - raise TypeError("'s' argument not supplied") + if context is None: + context = DEFAULT_CONTEXT - if context is None: - context = DEFAULT_CONTEXT + result = cls.read_from_str(context, s) + return result - try: - new_me = self.read_from_str(context, s) - except Exception: - # Turns out __del__ is called even if the constructor fails with an - # exception. This is creates a semi-valid state that's just good - # enough to get us past the __del__ method. - self.data = None - raise - else: - self._setup(new_me._release(), context) + def obj_bogus_init(self, s, context=None): + if not isinstance(s, str) and self._prev_init is not None: + self._prev_init(s) - def generic_getstate(self): + def generic_reduce(self): ctx = self.get_ctx() prn = Printer.to_str(ctx) - getattr(prn, "print_"+self._base_name)(self) - return (ctx, prn.get_str()) - - def generic_setstate(self, data): - ctx, new_str = data - new_inst = self.read_from_str(ctx, new_str) - self._setup(new_inst._release(), ctx) + prn = getattr(prn, "print_"+self._base_name)(self) + return (_read_from_str_wrapper, (type(self), ctx, prn.get_str())) for cls in ALL_CLASSES: if hasattr(cls, "read_from_str"): - cls.__init__ = obj_init - cls.__getstate__ = generic_getstate - cls.__setstate__ = generic_setstate + cls._prev_new = cls.__new__ + cls.__new__ = obj_new + cls._prev_init = getattr(cls, "__init__", None) + cls.__init__ = obj_bogus_init + cls.__reduce__ = generic_reduce # }}} - # {{{ str, repr, hash + # {{{ printing def generic_str(self): prn = Printer.to_str(self.get_ctx()) @@ -455,25 +459,21 @@ def _add_functionality(): # {{{ Id - def id_init(self, name=None, user=None, context=None, _data=None): - if _data is not None: - if name is not None: - raise TypeError("may not pass _data and name at the same time") - - _isl._ISLObjectBase.__init__(self, _data, context) - return - - if name is None: - raise TypeError("'name' argument not supplied") - + def id_new(cls, name, user=None, context=None): if context is None: context = DEFAULT_CONTEXT - new_me = self.alloc(context, name, user) - self._setup(new_me._release(), context) + result = cls.alloc(context, name, user) + result._made_from_python = True + return result - Id.__init__ = id_init - #Id.user = property(Id.get_user) # FIXME: reenable + def id_bogus_init(self, name, user=None, context=None): + assert self._made_from_python + del self._made_from_python + + Id.__new__ = staticmethod(id_new) + Id.__init__ = id_bogus_init + Id.user = property(Id.get_user) Id.name = property(Id.get_name) # }}} @@ -709,10 +709,7 @@ def _add_functionality(): def expr_like_add(self, other): if not isinstance(other, ARITH_CLASSES): - try: - other = _number_to_expr_like(self, other) - except _isl.IslTypeError: - return NotImplemented + other = _number_to_expr_like(self, other) try: return self.add(other) @@ -721,10 +718,7 @@ def _add_functionality(): def expr_like_sub(self, other): if not isinstance(other, ARITH_CLASSES): - try: - other = _number_to_expr_like(self, other) - except _isl.IslTypeError: - return NotImplemented + other = _number_to_expr_like(self, other) try: return self.sub(other) @@ -733,19 +727,13 @@ def _add_functionality(): def expr_like_rsub(self, other): if not isinstance(other, ARITH_CLASSES): - try: - other = _number_to_expr_like(self, other) - except _isl.IslTypeError: - return NotImplemented + other = _number_to_expr_like(self, other) return -self + other def expr_like_mul(self, other): if not isinstance(other, ARITH_CLASSES): - try: - other = _number_to_expr_like(self, other) - except _isl.IslTypeError: - return NotImplemented + other = _number_to_expr_like(self, other) try: return self.mul(other) @@ -775,28 +763,23 @@ def _add_functionality(): # {{{ Val - def val_init(self, src=None, context=None, _data=None): - if _data is not None: - if src is not None: - raise TypeError("may not pass _data and src at the same time") - - _isl._ISLObjectBase.__init__(self, _data, context) - return - - if src is None: - raise TypeError("'src' argument not supplied") - + def val_new(cls, src, context=None): if context is None: context = DEFAULT_CONTEXT if isinstance(src, six.string_types): - new_me = Val.read_from_str(context, src) + result = cls.read_from_str(context, src) elif isinstance(src, six.integer_types): - new_me = Val.int_from_si(context, src) + result = cls.int_from_si(context, src) else: raise TypeError("'src' must be int or string") - self._setup(new_me._release(), context) + result._made_from_python = True + return result + + def val_bogus_init(self, src, context=None): + assert self._made_from_python + del self._made_from_python def val_rsub(self, other): return -self + other @@ -817,7 +800,8 @@ def _add_functionality(): else: return int(self.to_str()) - Val.__init__ = val_init + Val.__new__ = staticmethod(val_new) + Val.__init__ = val_bogus_init Val.__add__ = Val.add Val.__radd__ = Val.add Val.__sub__ = Val.sub @@ -865,9 +849,11 @@ def _add_functionality(): def wrapper(basic_instance, *args, **kwargs): try: return basic_method(basic_instance, *args, **kwargs) - except _isl.IslTypeError: - special_instance = upcast(basic_instance) - return special_method(special_instance, *args, **kwargs) + except TypeError: + pass + + special_instance = upcast(basic_instance) + return special_method(special_instance, *args, **kwargs) return wrapper @@ -883,7 +869,10 @@ def _add_functionality(): if not callable(method): return False - if hasattr(class_, "_%s_is_static" % method_name): + # Here we're desperately trying to filter out static methods, + # based on what seems to be a common feature. + if any("builtin_function_or_method" in meth_superclass.__name__ + for meth_superclass in type(method).__mro__): return False return True @@ -1067,9 +1056,6 @@ def _add_functionality(): _add_functionality() -DEFAULT_CONTEXT = Context() - - def _back_to_basic(new_obj, old_obj): # Work around set_dim_id not being available for Basic{Set,Map} if isinstance(old_obj, BasicSet) and isinstance(new_obj, Set): diff --git a/islpy/version.py b/islpy/version.py index 5cea8857d9550183c2caabd0948032faac48e0ae..82ea6fb128de4adc8cddd1928ee3eb063bd70aa0 100644 --- a/islpy/version.py +++ b/islpy/version.py @@ -1,2 +1,2 @@ -VERSION = (2020, 1) +VERSION = (2020, 2) VERSION_TEXT = ".".join(str(i) for i in VERSION) diff --git a/preproc-headers/57dee46405fb01516cd1a9e39519649e3282b5a90f62b02f66bbfc88c555a4a7 b/preproc-headers/57dee46405fb01516cd1a9e39519649e3282b5a90f62b02f66bbfc88c555a4a7 deleted file mode 100644 index 5a2e2fc94735136c8ed6927589791a46335f009e..0000000000000000000000000000000000000000 --- a/preproc-headers/57dee46405fb01516cd1a9e39519649e3282b5a90f62b02f66bbfc88c555a4a7 +++ /dev/null @@ -1,68 +0,0 @@ -#line 13 -#include -#include - -#include -#line 71 -struct isl_stats { - long gbr_solved_lps; -}; -enum isl_error { - isl_error_none = 0, - isl_error_abort, - isl_error_alloc, - isl_error_unknown, - isl_error_internal, - isl_error_invalid, - isl_error_quota, - isl_error_unsupported -}; -typedef enum { - isl_stat_error = -1, - isl_stat_ok = 0 -} isl_stat; -isl_stat isl_stat_non_null(void *obj); -typedef enum { - isl_bool_error = -1, - isl_bool_false = 0, - isl_bool_true = 1 -} isl_bool; -isl_bool isl_bool_not(isl_bool b); -isl_bool isl_bool_ok(int b); -typedef int isl_size; - -struct isl_ctx; -typedef struct isl_ctx isl_ctx; -#line 119 -void *isl_malloc_or_die(isl_ctx *ctx, size_t size); -void *isl_calloc_or_die(isl_ctx *ctx, size_t nmemb, size_t size); -void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size); -#line 143 -void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg, - const char *file, int line); -#line 159 -struct isl_options *isl_ctx_options(isl_ctx *ctx); - -isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, - __isl_take void *opt); -isl_ctx *isl_ctx_alloc(void); -void *isl_ctx_peek_options(isl_ctx *ctx, struct isl_args *args); -int isl_ctx_parse_options(isl_ctx *ctx, int argc, char **argv, unsigned flags); -void isl_ctx_ref(struct isl_ctx *ctx); -void isl_ctx_deref(struct isl_ctx *ctx); -void isl_ctx_free(isl_ctx *ctx); - -void isl_ctx_abort(isl_ctx *ctx); -void isl_ctx_resume(isl_ctx *ctx); -int isl_ctx_aborted(isl_ctx *ctx); - -void isl_ctx_set_max_operations(isl_ctx *ctx, unsigned long max_operations); -unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); -void isl_ctx_reset_operations(isl_ctx *ctx); -#line 254 -enum isl_error isl_ctx_last_error(isl_ctx *ctx); -const char *isl_ctx_last_error_msg(isl_ctx *ctx); -const char *isl_ctx_last_error_file(isl_ctx *ctx); -int isl_ctx_last_error_line(isl_ctx *ctx); -void isl_ctx_reset_error(isl_ctx *ctx); -void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error); diff --git a/preproc-headers/75bdd384d9793d0adb0e1e3dbf44e2fba07f582322a93781f1cb8278717e26a2 b/preproc-headers/75bdd384d9793d0adb0e1e3dbf44e2fba07f582322a93781f1cb8278717e26a2 new file mode 100644 index 0000000000000000000000000000000000000000..389c9d0894c3691a3cb9d4b5d771e42671697d8e --- /dev/null +++ b/preproc-headers/75bdd384d9793d0adb0e1e3dbf44e2fba07f582322a93781f1cb8278717e26a2 @@ -0,0 +1,530 @@ +# 1 "isl_declaration_macros.h" +# 1 "" +# 1 "" +# 1 "./isl/include/isl/list.h" 1 +# 13 "./isl/include/isl/list.h" +# 1 "isl/include/isl/ctx.h" 1 +# 13 "isl/include/isl/ctx.h" +# 1 "/usr/include/stdio.h" 1 3 4 +# 27 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/features.h" 1 3 4 +# 352 "/usr/include/features.h" 3 4 +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 353 "/usr/include/features.h" 2 3 4 +# 374 "/usr/include/features.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4 +# 385 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 386 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 +# 375 "/usr/include/features.h" 2 3 4 +# 398 "/usr/include/features.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4 +# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4 +# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4 +# 399 "/usr/include/features.h" 2 3 4 +# 28 "/usr/include/stdio.h" 2 3 4 + + + + + +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 212 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 3 4 + +# 34 "/usr/include/stdio.h" 2 3 4 + +# 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4 +# 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 +#line 67 +# 121 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4 +# 122 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 +#line 138 +# 36 "/usr/include/stdio.h" 2 3 4 +# 44 "/usr/include/stdio.h" 3 4 +#line 150 +# 64 "/usr/include/stdio.h" 3 4 + +# 74 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/libio.h" 1 3 4 +# 31 "/usr/include/libio.h" 3 4 +# 1 "/usr/include/_G_config.h" 1 3 4 +# 15 "/usr/include/_G_config.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 16 "/usr/include/_G_config.h" 2 3 4 + + + + +# 1 "/usr/include/wchar.h" 1 3 4 +# 82 "/usr/include/wchar.h" 3 4 +#line 178 +# 21 "/usr/include/_G_config.h" 2 3 4 +#line 189 +# 32 "/usr/include/libio.h" 2 3 4 +# 49 "/usr/include/libio.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdarg.h" 1 3 4 +# 40 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdarg.h" 3 4 + +# 50 "/usr/include/libio.h" 2 3 4 +# 144 "/usr/include/libio.h" 3 4 + +# 154 "/usr/include/libio.h" 3 4 +#line 211 +# 177 "/usr/include/libio.h" 3 4 +#line 222 +# 245 "/usr/include/libio.h" 3 4 +#line 263 +# 293 "/usr/include/libio.h" 3 4 + +# 302 "/usr/include/libio.h" 3 4 +#line 287 +# 338 "/usr/include/libio.h" 3 4 +#line 309 +# 390 "/usr/include/libio.h" 3 4 + + + +# 434 "/usr/include/libio.h" 3 4 +#line 328 +# 464 "/usr/include/libio.h" 3 4 +#line 340 +# 75 "/usr/include/stdio.h" 2 3 4 + + + + + +# 90 "/usr/include/stdio.h" 3 4 + +# 102 "/usr/include/stdio.h" 3 4 +#line 362 +# 164 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4 +# 165 "/usr/include/stdio.h" 2 3 4 +#line 396 +# 209 "/usr/include/stdio.h" 3 4 +#line 404 +# 227 "/usr/include/stdio.h" 3 4 +#line 422 +# 252 "/usr/include/stdio.h" 3 4 + +# 266 "/usr/include/stdio.h" 3 4 +#line 440 +# 295 "/usr/include/stdio.h" 3 4 + +# 306 "/usr/include/stdio.h" 3 4 + +# 319 "/usr/include/stdio.h" 3 4 +#line 520 +# 412 "/usr/include/stdio.h" 3 4 +#line 544 +# 443 "/usr/include/stdio.h" 3 4 +#line 553 +# 463 "/usr/include/stdio.h" 3 4 +#line 577 +# 494 "/usr/include/stdio.h" 3 4 +#line 591 +# 522 "/usr/include/stdio.h" 3 4 +#line 610 +# 550 "/usr/include/stdio.h" 3 4 + + +# 561 "/usr/include/stdio.h" 3 4 +#line 635 +# 594 "/usr/include/stdio.h" 3 4 +#line 666 +# 638 "/usr/include/stdio.h" 3 4 + + + +# 665 "/usr/include/stdio.h" 3 4 +#line 724 +# 737 "/usr/include/stdio.h" 3 4 +#line 749 +# 773 "/usr/include/stdio.h" 3 4 + + + + + + +# 792 "/usr/include/stdio.h" 3 4 +#line 769 +# 815 "/usr/include/stdio.h" 3 4 + +# 824 "/usr/include/stdio.h" 3 4 +#line 801 +# 1 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 1 3 4 +# 26 "/usr/include/x86_64-linux-gnu/bits/sys_errlist.h" 3 4 + + +# 854 "/usr/include/stdio.h" 2 3 4 +#line 816 +# 873 "/usr/include/stdio.h" 3 4 +#line 830 +# 913 "/usr/include/stdio.h" 3 4 +#line 839 +# 943 "/usr/include/stdio.h" 3 4 + +# 14 "isl/include/isl/ctx.h" 2 +# 1 "/usr/include/stdlib.h" 1 3 4 +# 32 "/usr/include/stdlib.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 324 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 3 4 + +# 33 "/usr/include/stdlib.h" 2 3 4 +#line 856 +# 1 "/usr/include/x86_64-linux-gnu/bits/waitflags.h" 1 3 4 +# 50 "/usr/include/x86_64-linux-gnu/bits/waitflags.h" 3 4 + + + + + + +# 42 "/usr/include/stdlib.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/waitstatus.h" 1 3 4 +# 64 "/usr/include/x86_64-linux-gnu/bits/waitstatus.h" 3 4 +# 1 "/usr/include/endian.h" 1 3 4 +# 36 "/usr/include/endian.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/endian.h" 1 3 4 +# 37 "/usr/include/endian.h" 2 3 4 +# 60 "/usr/include/endian.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 1 3 4 +# 28 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 29 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 2 3 4 + + + + + + +# 1 "/usr/include/x86_64-linux-gnu/bits/byteswap-16.h" 1 3 4 +# 36 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 2 3 4 +# 44 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 3 4 + + + + + +# 108 "/usr/include/x86_64-linux-gnu/bits/byteswap.h" 3 4 + + + + + +# 61 "/usr/include/endian.h" 2 3 4 +# 65 "/usr/include/x86_64-linux-gnu/bits/waitstatus.h" 2 3 4 +#line 931 +# 43 "/usr/include/stdlib.h" 2 3 4 +# 67 "/usr/include/stdlib.h" 3 4 + + + + + +# 95 "/usr/include/stdlib.h" 3 4 +#line 968 +# 139 "/usr/include/stdlib.h" 3 4 +#line 1048 +# 305 "/usr/include/stdlib.h" 3 4 +#line 1058 +# 1 "/usr/include/x86_64-linux-gnu/sys/types.h" 1 3 4 +# 27 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +#line 1082 +# 60 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +#line 1104 +# 98 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +#line 1112 +# 115 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +#line 1121 +# 132 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +# 1 "/usr/include/time.h" 1 3 4 +# 57 "/usr/include/time.h" 3 4 + + + + + + +# 73 "/usr/include/time.h" 3 4 + + + + + + +# 91 "/usr/include/time.h" 3 4 + +# 103 "/usr/include/time.h" 3 4 + +# 133 "/usr/include/x86_64-linux-gnu/sys/types.h" 2 3 4 +# 146 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 147 "/usr/include/x86_64-linux-gnu/sys/types.h" 2 3 4 + + + + + + +# 194 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +#line 1164 +# 219 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/sys/select.h" 1 3 4 +# 30 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/select.h" 1 3 4 +# 22 "/usr/include/x86_64-linux-gnu/bits/select.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 23 "/usr/include/x86_64-linux-gnu/bits/select.h" 2 3 4 +# 31 "/usr/include/x86_64-linux-gnu/sys/select.h" 2 3 4 + + +# 1 "/usr/include/x86_64-linux-gnu/bits/sigset.h" 1 3 4 +# 22 "/usr/include/x86_64-linux-gnu/bits/sigset.h" 3 4 +#line 1185 +# 34 "/usr/include/x86_64-linux-gnu/sys/select.h" 2 3 4 +#line 1195 +# 1 "/usr/include/time.h" 1 3 4 +# 120 "/usr/include/time.h" 3 4 + + + + + +# 44 "/usr/include/x86_64-linux-gnu/sys/select.h" 2 3 4 + +# 1 "/usr/include/x86_64-linux-gnu/bits/time.h" 1 3 4 +# 30 "/usr/include/x86_64-linux-gnu/bits/time.h" 3 4 + + + + + +# 46 "/usr/include/x86_64-linux-gnu/sys/select.h" 2 3 4 +#line 1221 +# 64 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 +#line 1241 +# 96 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 + +# 106 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 + + + + +# 118 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 + + + + + +# 131 "/usr/include/x86_64-linux-gnu/sys/select.h" 3 4 + +# 220 "/usr/include/x86_64-linux-gnu/sys/types.h" 2 3 4 + + +# 1 "/usr/include/x86_64-linux-gnu/sys/sysmacros.h" 1 3 4 +# 24 "/usr/include/x86_64-linux-gnu/sys/sysmacros.h" 3 4 +#line 1273 +# 58 "/usr/include/x86_64-linux-gnu/sys/sysmacros.h" 3 4 + +# 223 "/usr/include/x86_64-linux-gnu/sys/types.h" 2 3 4 +#line 1297 +# 270 "/usr/include/x86_64-linux-gnu/sys/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 1 3 4 +# 21 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 22 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 2 3 4 +# 60 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 3 4 +#line 1323 +# 90 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 3 4 +#line 1341 +# 124 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 3 4 +#line 1411 +# 211 "/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h" 3 4 +#line 1442 +# 271 "/usr/include/x86_64-linux-gnu/sys/types.h" 2 3 4 + + + +# 315 "/usr/include/stdlib.h" 2 3 4 +#line 1624 +# 1 "/usr/include/alloca.h" 1 3 4 +# 24 "/usr/include/alloca.h" 3 4 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 25 "/usr/include/alloca.h" 2 3 4 +#line 1642 +# 493 "/usr/include/stdlib.h" 2 3 4 +#line 1655 +# 513 "/usr/include/stdlib.h" 3 4 +#line 1663 +# 530 "/usr/include/stdlib.h" 3 4 +#line 1700 +# 578 "/usr/include/stdlib.h" 3 4 +#line 1719 +# 606 "/usr/include/stdlib.h" 3 4 + +# 620 "/usr/include/stdlib.h" 3 4 + +# 642 "/usr/include/stdlib.h" 3 4 + +# 663 "/usr/include/stdlib.h" 3 4 + +# 712 "/usr/include/stdlib.h" 3 4 +#line 1735 +# 734 "/usr/include/stdlib.h" 3 4 +#line 1745 +# 752 "/usr/include/stdlib.h" 3 4 +#line 1761 +# 775 "/usr/include/stdlib.h" 3 4 +#line 1788 +# 812 "/usr/include/stdlib.h" 3 4 +#line 1866 +# 899 "/usr/include/stdlib.h" 3 4 + + + + +# 951 "/usr/include/stdlib.h" 3 4 + + + + +# 1 "/usr/include/x86_64-linux-gnu/bits/stdlib-float.h" 1 3 4 +# 956 "/usr/include/stdlib.h" 2 3 4 +# 968 "/usr/include/stdlib.h" 3 4 + +# 15 "isl/include/isl/ctx.h" 2 + +# 1 "isl/include/isl/arg.h" 1 +# 13 "isl/include/isl/arg.h" +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 1 3 4 +# 147 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stddef.h" 3 4 + +# 14 "isl/include/isl/arg.h" 2 +#line 1985 +# 290 "isl/include/isl/arg.h" + + + + +# 17 "isl/include/isl/ctx.h" 2 +# 68 "isl/include/isl/ctx.h" +#line 2016 +# 111 "isl/include/isl/ctx.h" + + + +# 135 "isl/include/isl/ctx.h" + + +# 151 "isl/include/isl/ctx.h" +#line 2042 +# 246 "isl/include/isl/ctx.h" + + + +# 14 "./isl/include/isl/list.h" 2 +# 1 "isl/include/isl/printer.h" 1 +# 11 "isl/include/isl/printer.h" +#line 2065 +# 35 "isl/include/isl/printer.h" +#line 2104 +# 15 "./isl/include/isl/list.h" 2 +# 1 "" 2 +# 1 "./isl/include/isl/multi.h" 1 + + + +# 1 "isl/include/isl/space.h" 1 +# 14 "isl/include/isl/space.h" +# 1 "isl/include/isl/id.h" 1 + + + + +# 1 "isl/include/isl/list.h" 1 +# 6 "isl/include/isl/id.h" 2 + +# 1 "isl-supplementary/isl/stdint.h" 1 +# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdint.h" 1 3 4 +# 9 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdint.h" 3 4 +# 1 "/usr/include/stdint.h" 1 3 4 +# 26 "/usr/include/stdint.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wchar.h" 1 3 4 +# 27 "/usr/include/stdint.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/stdint.h" 2 3 4 +# 48 "/usr/include/stdint.h" 3 4 +#line 2138 +# 65 "/usr/include/stdint.h" 3 4 +#line 2155 +# 90 "/usr/include/stdint.h" 3 4 + + + + + +# 103 "/usr/include/stdint.h" 3 4 + + + + + +# 119 "/usr/include/stdint.h" 3 4 + + + + +# 134 "/usr/include/stdint.h" 3 4 + + +# 10 "/usr/lib/gcc/x86_64-linux-gnu/4.9/include/stdint.h" 2 3 4 +# 1 "isl-supplementary/isl/stdint.h" 2 +# 8 "isl/include/isl/id.h" 2 +#line 2205 +# 15 "isl/include/isl/space.h" 2 +#line 2360 +# 5 "./isl/include/isl/multi.h" 2 + +# 1 "isl/include/isl/set_type.h" 1 + + + +# 1 "isl/include/isl/map_type.h" 1 +# 11 "isl/include/isl/map_type.h" +#line 2389 +# 5 "isl/include/isl/set_type.h" 2 +# 7 "./isl/include/isl/multi.h" 2 +# 1 "" 2 +# 1 "isl_declaration_macros.h" +# 9 "isl_declaration_macros.h" +struct isl_id; struct isl_id_list; typedef struct isl_id_list isl_id_list; isl_ctx *isl_id_list_get_ctx(__isl_keep isl_id_list *list); __isl_give isl_id_list *isl_id_list_from_id( __isl_take struct isl_id *el); __isl_give isl_id_list *isl_id_list_alloc(isl_ctx *ctx, int n); __isl_give isl_id_list *isl_id_list_copy( __isl_keep isl_id_list *list); isl_id_list *isl_id_list_free( __isl_take isl_id_list *list); __isl_give isl_id_list *isl_id_list_add( __isl_take isl_id_list *list, __isl_take struct isl_id *el); __isl_give isl_id_list *isl_id_list_insert( __isl_take isl_id_list *list, unsigned pos, __isl_take struct isl_id *el); __isl_give isl_id_list *isl_id_list_drop( __isl_take isl_id_list *list, unsigned first, unsigned n); __isl_give isl_id_list *isl_id_list_concat( __isl_take isl_id_list *list1, __isl_take isl_id_list *list2); int isl_id_list_n_id(__isl_keep isl_id_list *list); __isl_give struct isl_id *isl_id_list_get_id( __isl_keep isl_id_list *list, int index); __isl_give struct isl_id_list *isl_id_list_set_id( __isl_take struct isl_id_list *list, int index, __isl_take struct isl_id *el); isl_stat isl_id_list_foreach(__isl_keep isl_id_list *list, isl_stat (*fn)(__isl_take struct isl_id *el, void *user), void *user); __isl_give isl_id_list *isl_id_list_sort( __isl_take isl_id_list *list, int (*cmp)(__isl_keep struct isl_id *a, __isl_keep struct isl_id *b, void *user), void *user); isl_stat isl_id_list_foreach_scc(__isl_keep isl_id_list *list, isl_bool (*follows)(__isl_keep struct isl_id *a, __isl_keep struct isl_id *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_id_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_id_list( __isl_take isl_printer *p, __isl_keep isl_id_list *list); void isl_id_list_dump(__isl_keep isl_id_list *list); + +struct isl_val; struct isl_val_list; typedef struct isl_val_list isl_val_list; isl_ctx *isl_val_list_get_ctx(__isl_keep isl_val_list *list); __isl_give isl_val_list *isl_val_list_from_val( __isl_take struct isl_val *el); __isl_give isl_val_list *isl_val_list_alloc(isl_ctx *ctx, int n); __isl_give isl_val_list *isl_val_list_copy( __isl_keep isl_val_list *list); isl_val_list *isl_val_list_free( __isl_take isl_val_list *list); __isl_give isl_val_list *isl_val_list_add( __isl_take isl_val_list *list, __isl_take struct isl_val *el); __isl_give isl_val_list *isl_val_list_insert( __isl_take isl_val_list *list, unsigned pos, __isl_take struct isl_val *el); __isl_give isl_val_list *isl_val_list_drop( __isl_take isl_val_list *list, unsigned first, unsigned n); __isl_give isl_val_list *isl_val_list_concat( __isl_take isl_val_list *list1, __isl_take isl_val_list *list2); int isl_val_list_n_val(__isl_keep isl_val_list *list); __isl_give struct isl_val *isl_val_list_get_val( __isl_keep isl_val_list *list, int index); __isl_give struct isl_val_list *isl_val_list_set_val( __isl_take struct isl_val_list *list, int index, __isl_take struct isl_val *el); isl_stat isl_val_list_foreach(__isl_keep isl_val_list *list, isl_stat (*fn)(__isl_take struct isl_val *el, void *user), void *user); __isl_give isl_val_list *isl_val_list_sort( __isl_take isl_val_list *list, int (*cmp)(__isl_keep struct isl_val *a, __isl_keep struct isl_val *b, void *user), void *user); isl_stat isl_val_list_foreach_scc(__isl_keep isl_val_list *list, isl_bool (*follows)(__isl_keep struct isl_val *a, __isl_keep struct isl_val *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_val_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_val_list( __isl_take isl_printer *p, __isl_keep isl_val_list *list); void isl_val_list_dump(__isl_keep isl_val_list *list); +struct isl_aff; struct isl_aff_list; typedef struct isl_aff_list isl_aff_list; isl_ctx *isl_aff_list_get_ctx(__isl_keep isl_aff_list *list); __isl_give isl_aff_list *isl_aff_list_from_aff( __isl_take struct isl_aff *el); __isl_give isl_aff_list *isl_aff_list_alloc(isl_ctx *ctx, int n); __isl_give isl_aff_list *isl_aff_list_copy( __isl_keep isl_aff_list *list); isl_aff_list *isl_aff_list_free( __isl_take isl_aff_list *list); __isl_give isl_aff_list *isl_aff_list_add( __isl_take isl_aff_list *list, __isl_take struct isl_aff *el); __isl_give isl_aff_list *isl_aff_list_insert( __isl_take isl_aff_list *list, unsigned pos, __isl_take struct isl_aff *el); __isl_give isl_aff_list *isl_aff_list_drop( __isl_take isl_aff_list *list, unsigned first, unsigned n); __isl_give isl_aff_list *isl_aff_list_concat( __isl_take isl_aff_list *list1, __isl_take isl_aff_list *list2); int isl_aff_list_n_aff(__isl_keep isl_aff_list *list); __isl_give struct isl_aff *isl_aff_list_get_aff( __isl_keep isl_aff_list *list, int index); __isl_give struct isl_aff_list *isl_aff_list_set_aff( __isl_take struct isl_aff_list *list, int index, __isl_take struct isl_aff *el); isl_stat isl_aff_list_foreach(__isl_keep isl_aff_list *list, isl_stat (*fn)(__isl_take struct isl_aff *el, void *user), void *user); __isl_give isl_aff_list *isl_aff_list_sort( __isl_take isl_aff_list *list, int (*cmp)(__isl_keep struct isl_aff *a, __isl_keep struct isl_aff *b, void *user), void *user); isl_stat isl_aff_list_foreach_scc(__isl_keep isl_aff_list *list, isl_bool (*follows)(__isl_keep struct isl_aff *a, __isl_keep struct isl_aff *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_aff_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_aff_list( __isl_take isl_printer *p, __isl_keep isl_aff_list *list); void isl_aff_list_dump(__isl_keep isl_aff_list *list); +struct isl_pw_aff; struct isl_pw_aff_list; typedef struct isl_pw_aff_list isl_pw_aff_list; isl_ctx *isl_pw_aff_list_get_ctx(__isl_keep isl_pw_aff_list *list); __isl_give isl_pw_aff_list *isl_pw_aff_list_from_pw_aff( __isl_take struct isl_pw_aff *el); __isl_give isl_pw_aff_list *isl_pw_aff_list_alloc(isl_ctx *ctx, int n); __isl_give isl_pw_aff_list *isl_pw_aff_list_copy( __isl_keep isl_pw_aff_list *list); isl_pw_aff_list *isl_pw_aff_list_free( __isl_take isl_pw_aff_list *list); __isl_give isl_pw_aff_list *isl_pw_aff_list_add( __isl_take isl_pw_aff_list *list, __isl_take struct isl_pw_aff *el); __isl_give isl_pw_aff_list *isl_pw_aff_list_insert( __isl_take isl_pw_aff_list *list, unsigned pos, __isl_take struct isl_pw_aff *el); __isl_give isl_pw_aff_list *isl_pw_aff_list_drop( __isl_take isl_pw_aff_list *list, unsigned first, unsigned n); __isl_give isl_pw_aff_list *isl_pw_aff_list_concat( __isl_take isl_pw_aff_list *list1, __isl_take isl_pw_aff_list *list2); int isl_pw_aff_list_n_pw_aff(__isl_keep isl_pw_aff_list *list); __isl_give struct isl_pw_aff *isl_pw_aff_list_get_pw_aff( __isl_keep isl_pw_aff_list *list, int index); __isl_give struct isl_pw_aff_list *isl_pw_aff_list_set_pw_aff( __isl_take struct isl_pw_aff_list *list, int index, __isl_take struct isl_pw_aff *el); isl_stat isl_pw_aff_list_foreach(__isl_keep isl_pw_aff_list *list, isl_stat (*fn)(__isl_take struct isl_pw_aff *el, void *user), void *user); __isl_give isl_pw_aff_list *isl_pw_aff_list_sort( __isl_take isl_pw_aff_list *list, int (*cmp)(__isl_keep struct isl_pw_aff *a, __isl_keep struct isl_pw_aff *b, void *user), void *user); isl_stat isl_pw_aff_list_foreach_scc(__isl_keep isl_pw_aff_list *list, isl_bool (*follows)(__isl_keep struct isl_pw_aff *a, __isl_keep struct isl_pw_aff *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_pw_aff_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_pw_aff_list( __isl_take isl_printer *p, __isl_keep isl_pw_aff_list *list); void isl_pw_aff_list_dump(__isl_keep isl_pw_aff_list *list); +struct isl_constraint; struct isl_constraint_list; typedef struct isl_constraint_list isl_constraint_list; isl_ctx *isl_constraint_list_get_ctx(__isl_keep isl_constraint_list *list); __isl_give isl_constraint_list *isl_constraint_list_from_constraint( __isl_take struct isl_constraint *el); __isl_give isl_constraint_list *isl_constraint_list_alloc(isl_ctx *ctx, int n); __isl_give isl_constraint_list *isl_constraint_list_copy( __isl_keep isl_constraint_list *list); isl_constraint_list *isl_constraint_list_free( __isl_take isl_constraint_list *list); __isl_give isl_constraint_list *isl_constraint_list_add( __isl_take isl_constraint_list *list, __isl_take struct isl_constraint *el); __isl_give isl_constraint_list *isl_constraint_list_insert( __isl_take isl_constraint_list *list, unsigned pos, __isl_take struct isl_constraint *el); __isl_give isl_constraint_list *isl_constraint_list_drop( __isl_take isl_constraint_list *list, unsigned first, unsigned n); __isl_give isl_constraint_list *isl_constraint_list_concat( __isl_take isl_constraint_list *list1, __isl_take isl_constraint_list *list2); int isl_constraint_list_n_constraint(__isl_keep isl_constraint_list *list); __isl_give struct isl_constraint *isl_constraint_list_get_constraint( __isl_keep isl_constraint_list *list, int index); __isl_give struct isl_constraint_list *isl_constraint_list_set_constraint( __isl_take struct isl_constraint_list *list, int index, __isl_take struct isl_constraint *el); isl_stat isl_constraint_list_foreach(__isl_keep isl_constraint_list *list, isl_stat (*fn)(__isl_take struct isl_constraint *el, void *user), void *user); __isl_give isl_constraint_list *isl_constraint_list_sort( __isl_take isl_constraint_list *list, int (*cmp)(__isl_keep struct isl_constraint *a, __isl_keep struct isl_constraint *b, void *user), void *user); isl_stat isl_constraint_list_foreach_scc(__isl_keep isl_constraint_list *list, isl_bool (*follows)(__isl_keep struct isl_constraint *a, __isl_keep struct isl_constraint *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_constraint_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_constraint_list( __isl_take isl_printer *p, __isl_keep isl_constraint_list *list); void isl_constraint_list_dump(__isl_keep isl_constraint_list *list); + +struct isl_basic_set; struct isl_basic_set_list; typedef struct isl_basic_set_list isl_basic_set_list; isl_ctx *isl_basic_set_list_get_ctx(__isl_keep isl_basic_set_list *list); __isl_give isl_basic_set_list *isl_basic_set_list_from_basic_set( __isl_take struct isl_basic_set *el); __isl_give isl_basic_set_list *isl_basic_set_list_alloc(isl_ctx *ctx, int n); __isl_give isl_basic_set_list *isl_basic_set_list_copy( __isl_keep isl_basic_set_list *list); isl_basic_set_list *isl_basic_set_list_free( __isl_take isl_basic_set_list *list); __isl_give isl_basic_set_list *isl_basic_set_list_add( __isl_take isl_basic_set_list *list, __isl_take struct isl_basic_set *el); __isl_give isl_basic_set_list *isl_basic_set_list_insert( __isl_take isl_basic_set_list *list, unsigned pos, __isl_take struct isl_basic_set *el); __isl_give isl_basic_set_list *isl_basic_set_list_drop( __isl_take isl_basic_set_list *list, unsigned first, unsigned n); __isl_give isl_basic_set_list *isl_basic_set_list_concat( __isl_take isl_basic_set_list *list1, __isl_take isl_basic_set_list *list2); int isl_basic_set_list_n_basic_set(__isl_keep isl_basic_set_list *list); __isl_give struct isl_basic_set *isl_basic_set_list_get_basic_set( __isl_keep isl_basic_set_list *list, int index); __isl_give struct isl_basic_set_list *isl_basic_set_list_set_basic_set( __isl_take struct isl_basic_set_list *list, int index, __isl_take struct isl_basic_set *el); isl_stat isl_basic_set_list_foreach(__isl_keep isl_basic_set_list *list, isl_stat (*fn)(__isl_take struct isl_basic_set *el, void *user), void *user); __isl_give isl_basic_set_list *isl_basic_set_list_sort( __isl_take isl_basic_set_list *list, int (*cmp)(__isl_keep struct isl_basic_set *a, __isl_keep struct isl_basic_set *b, void *user), void *user); isl_stat isl_basic_set_list_foreach_scc(__isl_keep isl_basic_set_list *list, isl_bool (*follows)(__isl_keep struct isl_basic_set *a, __isl_keep struct isl_basic_set *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_basic_set_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_basic_set_list( __isl_take isl_printer *p, __isl_keep isl_basic_set_list *list); void isl_basic_set_list_dump(__isl_keep isl_basic_set_list *list); + +struct isl_basic_map; struct isl_basic_map_list; typedef struct isl_basic_map_list isl_basic_map_list; isl_ctx *isl_basic_map_list_get_ctx(__isl_keep isl_basic_map_list *list); __isl_give isl_basic_map_list *isl_basic_map_list_from_basic_map( __isl_take struct isl_basic_map *el); __isl_give isl_basic_map_list *isl_basic_map_list_alloc(isl_ctx *ctx, int n); __isl_give isl_basic_map_list *isl_basic_map_list_copy( __isl_keep isl_basic_map_list *list); isl_basic_map_list *isl_basic_map_list_free( __isl_take isl_basic_map_list *list); __isl_give isl_basic_map_list *isl_basic_map_list_add( __isl_take isl_basic_map_list *list, __isl_take struct isl_basic_map *el); __isl_give isl_basic_map_list *isl_basic_map_list_insert( __isl_take isl_basic_map_list *list, unsigned pos, __isl_take struct isl_basic_map *el); __isl_give isl_basic_map_list *isl_basic_map_list_drop( __isl_take isl_basic_map_list *list, unsigned first, unsigned n); __isl_give isl_basic_map_list *isl_basic_map_list_concat( __isl_take isl_basic_map_list *list1, __isl_take isl_basic_map_list *list2); int isl_basic_map_list_n_basic_map(__isl_keep isl_basic_map_list *list); __isl_give struct isl_basic_map *isl_basic_map_list_get_basic_map( __isl_keep isl_basic_map_list *list, int index); __isl_give struct isl_basic_map_list *isl_basic_map_list_set_basic_map( __isl_take struct isl_basic_map_list *list, int index, __isl_take struct isl_basic_map *el); isl_stat isl_basic_map_list_foreach(__isl_keep isl_basic_map_list *list, isl_stat (*fn)(__isl_take struct isl_basic_map *el, void *user), void *user); __isl_give isl_basic_map_list *isl_basic_map_list_sort( __isl_take isl_basic_map_list *list, int (*cmp)(__isl_keep struct isl_basic_map *a, __isl_keep struct isl_basic_map *b, void *user), void *user); isl_stat isl_basic_map_list_foreach_scc(__isl_keep isl_basic_map_list *list, isl_bool (*follows)(__isl_keep struct isl_basic_map *a, __isl_keep struct isl_basic_map *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_basic_map_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_basic_map_list( __isl_take isl_printer *p, __isl_keep isl_basic_map_list *list); void isl_basic_map_list_dump(__isl_keep isl_basic_map_list *list); + +struct isl_set; struct isl_set_list; typedef struct isl_set_list isl_set_list; isl_ctx *isl_set_list_get_ctx(__isl_keep isl_set_list *list); __isl_give isl_set_list *isl_set_list_from_set( __isl_take struct isl_set *el); __isl_give isl_set_list *isl_set_list_alloc(isl_ctx *ctx, int n); __isl_give isl_set_list *isl_set_list_copy( __isl_keep isl_set_list *list); isl_set_list *isl_set_list_free( __isl_take isl_set_list *list); __isl_give isl_set_list *isl_set_list_add( __isl_take isl_set_list *list, __isl_take struct isl_set *el); __isl_give isl_set_list *isl_set_list_insert( __isl_take isl_set_list *list, unsigned pos, __isl_take struct isl_set *el); __isl_give isl_set_list *isl_set_list_drop( __isl_take isl_set_list *list, unsigned first, unsigned n); __isl_give isl_set_list *isl_set_list_concat( __isl_take isl_set_list *list1, __isl_take isl_set_list *list2); int isl_set_list_n_set(__isl_keep isl_set_list *list); __isl_give struct isl_set *isl_set_list_get_set( __isl_keep isl_set_list *list, int index); __isl_give struct isl_set_list *isl_set_list_set_set( __isl_take struct isl_set_list *list, int index, __isl_take struct isl_set *el); isl_stat isl_set_list_foreach(__isl_keep isl_set_list *list, isl_stat (*fn)(__isl_take struct isl_set *el, void *user), void *user); __isl_give isl_set_list *isl_set_list_sort( __isl_take isl_set_list *list, int (*cmp)(__isl_keep struct isl_set *a, __isl_keep struct isl_set *b, void *user), void *user); isl_stat isl_set_list_foreach_scc(__isl_keep isl_set_list *list, isl_bool (*follows)(__isl_keep struct isl_set *a, __isl_keep struct isl_set *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_set_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_set_list( __isl_take isl_printer *p, __isl_keep isl_set_list *list); void isl_set_list_dump(__isl_keep isl_set_list *list); + +struct isl_map; struct isl_map_list; typedef struct isl_map_list isl_map_list; isl_ctx *isl_map_list_get_ctx(__isl_keep isl_map_list *list); __isl_give isl_map_list *isl_map_list_from_map( __isl_take struct isl_map *el); __isl_give isl_map_list *isl_map_list_alloc(isl_ctx *ctx, int n); __isl_give isl_map_list *isl_map_list_copy( __isl_keep isl_map_list *list); isl_map_list *isl_map_list_free( __isl_take isl_map_list *list); __isl_give isl_map_list *isl_map_list_add( __isl_take isl_map_list *list, __isl_take struct isl_map *el); __isl_give isl_map_list *isl_map_list_insert( __isl_take isl_map_list *list, unsigned pos, __isl_take struct isl_map *el); __isl_give isl_map_list *isl_map_list_drop( __isl_take isl_map_list *list, unsigned first, unsigned n); __isl_give isl_map_list *isl_map_list_concat( __isl_take isl_map_list *list1, __isl_take isl_map_list *list2); int isl_map_list_n_map(__isl_keep isl_map_list *list); __isl_give struct isl_map *isl_map_list_get_map( __isl_keep isl_map_list *list, int index); __isl_give struct isl_map_list *isl_map_list_set_map( __isl_take struct isl_map_list *list, int index, __isl_take struct isl_map *el); isl_stat isl_map_list_foreach(__isl_keep isl_map_list *list, isl_stat (*fn)(__isl_take struct isl_map *el, void *user), void *user); __isl_give isl_map_list *isl_map_list_sort( __isl_take isl_map_list *list, int (*cmp)(__isl_keep struct isl_map *a, __isl_keep struct isl_map *b, void *user), void *user); isl_stat isl_map_list_foreach_scc(__isl_keep isl_map_list *list, isl_bool (*follows)(__isl_keep struct isl_map *a, __isl_keep struct isl_map *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_map_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_map_list( __isl_take isl_printer *p, __isl_keep isl_map_list *list); void isl_map_list_dump(__isl_keep isl_map_list *list); +struct isl_union_set; struct isl_union_set_list; typedef struct isl_union_set_list isl_union_set_list; isl_ctx *isl_union_set_list_get_ctx(__isl_keep isl_union_set_list *list); __isl_give isl_union_set_list *isl_union_set_list_from_union_set( __isl_take struct isl_union_set *el); __isl_give isl_union_set_list *isl_union_set_list_alloc(isl_ctx *ctx, int n); __isl_give isl_union_set_list *isl_union_set_list_copy( __isl_keep isl_union_set_list *list); isl_union_set_list *isl_union_set_list_free( __isl_take isl_union_set_list *list); __isl_give isl_union_set_list *isl_union_set_list_add( __isl_take isl_union_set_list *list, __isl_take struct isl_union_set *el); __isl_give isl_union_set_list *isl_union_set_list_insert( __isl_take isl_union_set_list *list, unsigned pos, __isl_take struct isl_union_set *el); __isl_give isl_union_set_list *isl_union_set_list_drop( __isl_take isl_union_set_list *list, unsigned first, unsigned n); __isl_give isl_union_set_list *isl_union_set_list_concat( __isl_take isl_union_set_list *list1, __isl_take isl_union_set_list *list2); int isl_union_set_list_n_union_set(__isl_keep isl_union_set_list *list); __isl_give struct isl_union_set *isl_union_set_list_get_union_set( __isl_keep isl_union_set_list *list, int index); __isl_give struct isl_union_set_list *isl_union_set_list_set_union_set( __isl_take struct isl_union_set_list *list, int index, __isl_take struct isl_union_set *el); isl_stat isl_union_set_list_foreach(__isl_keep isl_union_set_list *list, isl_stat (*fn)(__isl_take struct isl_union_set *el, void *user), void *user); __isl_give isl_union_set_list *isl_union_set_list_sort( __isl_take isl_union_set_list *list, int (*cmp)(__isl_keep struct isl_union_set *a, __isl_keep struct isl_union_set *b, void *user), void *user); isl_stat isl_union_set_list_foreach_scc(__isl_keep isl_union_set_list *list, isl_bool (*follows)(__isl_keep struct isl_union_set *a, __isl_keep struct isl_union_set *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_union_set_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_union_set_list( __isl_take isl_printer *p, __isl_keep isl_union_set_list *list); void isl_union_set_list_dump(__isl_keep isl_union_set_list *list); + + +struct isl_ast_expr; struct isl_ast_expr_list; typedef struct isl_ast_expr_list isl_ast_expr_list; isl_ctx *isl_ast_expr_list_get_ctx(__isl_keep isl_ast_expr_list *list); __isl_give isl_ast_expr_list *isl_ast_expr_list_from_ast_expr( __isl_take struct isl_ast_expr *el); __isl_give isl_ast_expr_list *isl_ast_expr_list_alloc(isl_ctx *ctx, int n); __isl_give isl_ast_expr_list *isl_ast_expr_list_copy( __isl_keep isl_ast_expr_list *list); isl_ast_expr_list *isl_ast_expr_list_free( __isl_take isl_ast_expr_list *list); __isl_give isl_ast_expr_list *isl_ast_expr_list_add( __isl_take isl_ast_expr_list *list, __isl_take struct isl_ast_expr *el); __isl_give isl_ast_expr_list *isl_ast_expr_list_insert( __isl_take isl_ast_expr_list *list, unsigned pos, __isl_take struct isl_ast_expr *el); __isl_give isl_ast_expr_list *isl_ast_expr_list_drop( __isl_take isl_ast_expr_list *list, unsigned first, unsigned n); __isl_give isl_ast_expr_list *isl_ast_expr_list_concat( __isl_take isl_ast_expr_list *list1, __isl_take isl_ast_expr_list *list2); int isl_ast_expr_list_n_ast_expr(__isl_keep isl_ast_expr_list *list); __isl_give struct isl_ast_expr *isl_ast_expr_list_get_ast_expr( __isl_keep isl_ast_expr_list *list, int index); __isl_give struct isl_ast_expr_list *isl_ast_expr_list_set_ast_expr( __isl_take struct isl_ast_expr_list *list, int index, __isl_take struct isl_ast_expr *el); isl_stat isl_ast_expr_list_foreach(__isl_keep isl_ast_expr_list *list, isl_stat (*fn)(__isl_take struct isl_ast_expr *el, void *user), void *user); __isl_give isl_ast_expr_list *isl_ast_expr_list_sort( __isl_take isl_ast_expr_list *list, int (*cmp)(__isl_keep struct isl_ast_expr *a, __isl_keep struct isl_ast_expr *b, void *user), void *user); isl_stat isl_ast_expr_list_foreach_scc(__isl_keep isl_ast_expr_list *list, isl_bool (*follows)(__isl_keep struct isl_ast_expr *a, __isl_keep struct isl_ast_expr *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_ast_expr_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_ast_expr_list( __isl_take isl_printer *p, __isl_keep isl_ast_expr_list *list); void isl_ast_expr_list_dump(__isl_keep isl_ast_expr_list *list); +struct isl_ast_node; struct isl_ast_node_list; typedef struct isl_ast_node_list isl_ast_node_list; isl_ctx *isl_ast_node_list_get_ctx(__isl_keep isl_ast_node_list *list); __isl_give isl_ast_node_list *isl_ast_node_list_from_ast_node( __isl_take struct isl_ast_node *el); __isl_give isl_ast_node_list *isl_ast_node_list_alloc(isl_ctx *ctx, int n); __isl_give isl_ast_node_list *isl_ast_node_list_copy( __isl_keep isl_ast_node_list *list); isl_ast_node_list *isl_ast_node_list_free( __isl_take isl_ast_node_list *list); __isl_give isl_ast_node_list *isl_ast_node_list_add( __isl_take isl_ast_node_list *list, __isl_take struct isl_ast_node *el); __isl_give isl_ast_node_list *isl_ast_node_list_insert( __isl_take isl_ast_node_list *list, unsigned pos, __isl_take struct isl_ast_node *el); __isl_give isl_ast_node_list *isl_ast_node_list_drop( __isl_take isl_ast_node_list *list, unsigned first, unsigned n); __isl_give isl_ast_node_list *isl_ast_node_list_concat( __isl_take isl_ast_node_list *list1, __isl_take isl_ast_node_list *list2); int isl_ast_node_list_n_ast_node(__isl_keep isl_ast_node_list *list); __isl_give struct isl_ast_node *isl_ast_node_list_get_ast_node( __isl_keep isl_ast_node_list *list, int index); __isl_give struct isl_ast_node_list *isl_ast_node_list_set_ast_node( __isl_take struct isl_ast_node_list *list, int index, __isl_take struct isl_ast_node *el); isl_stat isl_ast_node_list_foreach(__isl_keep isl_ast_node_list *list, isl_stat (*fn)(__isl_take struct isl_ast_node *el, void *user), void *user); __isl_give isl_ast_node_list *isl_ast_node_list_sort( __isl_take isl_ast_node_list *list, int (*cmp)(__isl_keep struct isl_ast_node *a, __isl_keep struct isl_ast_node *b, void *user), void *user); isl_stat isl_ast_node_list_foreach_scc(__isl_keep isl_ast_node_list *list, isl_bool (*follows)(__isl_keep struct isl_ast_node *a, __isl_keep struct isl_ast_node *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_ast_node_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_ast_node_list( __isl_take isl_printer *p, __isl_keep isl_ast_node_list *list); void isl_ast_node_list_dump(__isl_keep isl_ast_node_list *list); +struct isl_band; struct isl_band_list; typedef struct isl_band_list isl_band_list; isl_ctx *isl_band_list_get_ctx(__isl_keep isl_band_list *list); __isl_give isl_band_list *isl_band_list_from_band( __isl_take struct isl_band *el); __isl_give isl_band_list *isl_band_list_alloc(isl_ctx *ctx, int n); __isl_give isl_band_list *isl_band_list_copy( __isl_keep isl_band_list *list); isl_band_list *isl_band_list_free( __isl_take isl_band_list *list); __isl_give isl_band_list *isl_band_list_add( __isl_take isl_band_list *list, __isl_take struct isl_band *el); __isl_give isl_band_list *isl_band_list_insert( __isl_take isl_band_list *list, unsigned pos, __isl_take struct isl_band *el); __isl_give isl_band_list *isl_band_list_drop( __isl_take isl_band_list *list, unsigned first, unsigned n); __isl_give isl_band_list *isl_band_list_concat( __isl_take isl_band_list *list1, __isl_take isl_band_list *list2); int isl_band_list_n_band(__isl_keep isl_band_list *list); __isl_give struct isl_band *isl_band_list_get_band( __isl_keep isl_band_list *list, int index); __isl_give struct isl_band_list *isl_band_list_set_band( __isl_take struct isl_band_list *list, int index, __isl_take struct isl_band *el); isl_stat isl_band_list_foreach(__isl_keep isl_band_list *list, isl_stat (*fn)(__isl_take struct isl_band *el, void *user), void *user); __isl_give isl_band_list *isl_band_list_sort( __isl_take isl_band_list *list, int (*cmp)(__isl_keep struct isl_band *a, __isl_keep struct isl_band *b, void *user), void *user); isl_stat isl_band_list_foreach_scc(__isl_keep isl_band_list *list, isl_bool (*follows)(__isl_keep struct isl_band *a, __isl_keep struct isl_band *b, void *user), void *follows_user, isl_stat (*fn)(__isl_take isl_band_list *scc, void *user), void *fn_user); __isl_give isl_printer *isl_printer_print_band_list( __isl_take isl_printer *p, __isl_keep isl_band_list *list); void isl_band_list_dump(__isl_keep isl_band_list *list); + +unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *multi, enum isl_dim_type type); isl_ctx *isl_multi_aff_get_ctx( __isl_keep isl_multi_aff *multi); __isl_give isl_space *isl_multi_aff_get_space( __isl_keep isl_multi_aff *multi); __isl_give isl_space *isl_multi_aff_get_domain_space( __isl_keep isl_multi_aff *multi); int isl_multi_aff_find_dim_by_name( __isl_keep isl_multi_aff *multi, enum isl_dim_type type, const char *name); __isl_give isl_multi_aff *isl_multi_aff_from_aff_list( __isl_take isl_space *space, __isl_take isl_aff_list *list); __isl_give isl_multi_aff *isl_multi_aff_zero( __isl_take isl_space *space); __isl_give isl_multi_aff *isl_multi_aff_copy( __isl_keep isl_multi_aff *multi); isl_multi_aff *isl_multi_aff_free( __isl_take isl_multi_aff *multi); isl_bool isl_multi_aff_plain_is_equal( __isl_keep isl_multi_aff *multi1, __isl_keep isl_multi_aff *multi2); int isl_multi_aff_find_dim_by_id( __isl_keep isl_multi_aff *multi, enum isl_dim_type type, __isl_keep isl_id *id); __isl_give isl_id *isl_multi_aff_get_dim_id( __isl_take isl_multi_aff *multi, enum isl_dim_type type, unsigned pos); __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( __isl_take isl_multi_aff *multi, enum isl_dim_type type, unsigned pos, const char *s); __isl_give isl_multi_aff *isl_multi_aff_set_dim_id( __isl_take isl_multi_aff *multi, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); const char *isl_multi_aff_get_tuple_name( __isl_keep isl_multi_aff *multi, enum isl_dim_type type); isl_bool isl_multi_aff_has_tuple_id( __isl_keep isl_multi_aff *multi, enum isl_dim_type type); __isl_give isl_id *isl_multi_aff_get_tuple_id( __isl_keep isl_multi_aff *multi, enum isl_dim_type type); __isl_give isl_multi_aff *isl_multi_aff_set_tuple_name( __isl_take isl_multi_aff *multi, enum isl_dim_type type, const char *s); __isl_give isl_multi_aff *isl_multi_aff_set_tuple_id( __isl_take isl_multi_aff *multi, enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_multi_aff *isl_multi_aff_reset_tuple_id( __isl_take isl_multi_aff *multi, enum isl_dim_type type); __isl_give isl_multi_aff *isl_multi_aff_reset_user( __isl_take isl_multi_aff *multi); __isl_give isl_multi_aff *isl_multi_aff_drop_dims( __isl_take isl_multi_aff *multi, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_aff *isl_multi_aff_get_aff( __isl_keep isl_multi_aff *multi, int pos); __isl_give isl_multi_aff *isl_multi_aff_set_aff( __isl_take isl_multi_aff *multi, int pos, __isl_take isl_aff *el); __isl_give isl_multi_aff *isl_multi_aff_range_splice( __isl_take isl_multi_aff *multi1, unsigned pos, __isl_take isl_multi_aff *multi2); __isl_give isl_multi_aff *isl_multi_aff_flatten_range( __isl_take isl_multi_aff *multi); __isl_give isl_multi_aff *isl_multi_aff_flat_range_product( __isl_take isl_multi_aff *multi1, __isl_take isl_multi_aff *multi2); __isl_give isl_multi_aff *isl_multi_aff_range_product( __isl_take isl_multi_aff *multi1, __isl_take isl_multi_aff *multi2); isl_bool isl_multi_aff_range_is_wrapping( __isl_keep isl_multi_aff *multi); __isl_give isl_multi_aff *isl_multi_aff_range_factor_domain( __isl_take isl_multi_aff *multi); __isl_give isl_multi_aff *isl_multi_aff_range_factor_range( __isl_take isl_multi_aff *multi); __isl_give isl_multi_aff *isl_multi_aff_scale_val( __isl_take isl_multi_aff *multi, __isl_take isl_val *v); __isl_give isl_multi_aff *isl_multi_aff_scale_down_val( __isl_take isl_multi_aff *multi, __isl_take isl_val *v); __isl_give isl_multi_aff *isl_multi_aff_scale_multi_val( __isl_take isl_multi_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_aff *isl_multi_aff_scale_down_multi_val( __isl_take isl_multi_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_aff *isl_multi_aff_mod_multi_val( __isl_take isl_multi_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_aff *isl_multi_aff_sub( __isl_take isl_multi_aff *multi1, __isl_take isl_multi_aff *multi2); __isl_give isl_multi_aff *isl_multi_aff_align_params( __isl_take isl_multi_aff *multi, __isl_take isl_space *model); __isl_give isl_multi_aff *isl_multi_aff_from_range( __isl_take isl_multi_aff *multi); +unsigned isl_multi_pw_aff_dim(__isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type); isl_ctx *isl_multi_pw_aff_get_ctx( __isl_keep isl_multi_pw_aff *multi); __isl_give isl_space *isl_multi_pw_aff_get_space( __isl_keep isl_multi_pw_aff *multi); __isl_give isl_space *isl_multi_pw_aff_get_domain_space( __isl_keep isl_multi_pw_aff *multi); int isl_multi_pw_aff_find_dim_by_name( __isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type, const char *name); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff_list( __isl_take isl_space *space, __isl_take isl_pw_aff_list *list); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero( __isl_take isl_space *space); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_copy( __isl_keep isl_multi_pw_aff *multi); isl_multi_pw_aff *isl_multi_pw_aff_free( __isl_take isl_multi_pw_aff *multi); isl_bool isl_multi_pw_aff_plain_is_equal( __isl_keep isl_multi_pw_aff *multi1, __isl_keep isl_multi_pw_aff *multi2); int isl_multi_pw_aff_find_dim_by_id( __isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type, __isl_keep isl_id *id); __isl_give isl_id *isl_multi_pw_aff_get_dim_id( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, unsigned pos); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_dim_name( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, unsigned pos, const char *s); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_dim_id( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); const char *isl_multi_pw_aff_get_tuple_name( __isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type); isl_bool isl_multi_pw_aff_has_tuple_id( __isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type); __isl_give isl_id *isl_multi_pw_aff_get_tuple_id( __isl_keep isl_multi_pw_aff *multi, enum isl_dim_type type); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_tuple_name( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, const char *s); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_tuple_id( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_reset_tuple_id( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_reset_user( __isl_take isl_multi_pw_aff *multi); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_drop_dims( __isl_take isl_multi_pw_aff *multi, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_pw_aff *isl_multi_pw_aff_get_pw_aff( __isl_keep isl_multi_pw_aff *multi, int pos); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_set_pw_aff( __isl_take isl_multi_pw_aff *multi, int pos, __isl_take isl_pw_aff *el); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_range_splice( __isl_take isl_multi_pw_aff *multi1, unsigned pos, __isl_take isl_multi_pw_aff *multi2); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_flatten_range( __isl_take isl_multi_pw_aff *multi); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_flat_range_product( __isl_take isl_multi_pw_aff *multi1, __isl_take isl_multi_pw_aff *multi2); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_range_product( __isl_take isl_multi_pw_aff *multi1, __isl_take isl_multi_pw_aff *multi2); isl_bool isl_multi_pw_aff_range_is_wrapping( __isl_keep isl_multi_pw_aff *multi); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_range_factor_domain( __isl_take isl_multi_pw_aff *multi); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_range_factor_range( __isl_take isl_multi_pw_aff *multi); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_val( __isl_take isl_multi_pw_aff *multi, __isl_take isl_val *v); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_down_val( __isl_take isl_multi_pw_aff *multi, __isl_take isl_val *v); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_multi_val( __isl_take isl_multi_pw_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_down_multi_val( __isl_take isl_multi_pw_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_mod_multi_val( __isl_take isl_multi_pw_aff *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_sub( __isl_take isl_multi_pw_aff *multi1, __isl_take isl_multi_pw_aff *multi2); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_align_params( __isl_take isl_multi_pw_aff *multi, __isl_take isl_space *model); __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_range( __isl_take isl_multi_pw_aff *multi); +unsigned isl_multi_val_dim(__isl_keep isl_multi_val *multi, enum isl_dim_type type); isl_ctx *isl_multi_val_get_ctx( __isl_keep isl_multi_val *multi); __isl_give isl_space *isl_multi_val_get_space( __isl_keep isl_multi_val *multi); __isl_give isl_space *isl_multi_val_get_domain_space( __isl_keep isl_multi_val *multi); int isl_multi_val_find_dim_by_name( __isl_keep isl_multi_val *multi, enum isl_dim_type type, const char *name); __isl_give isl_multi_val *isl_multi_val_from_val_list( __isl_take isl_space *space, __isl_take isl_val_list *list); __isl_give isl_multi_val *isl_multi_val_zero( __isl_take isl_space *space); __isl_give isl_multi_val *isl_multi_val_copy( __isl_keep isl_multi_val *multi); isl_multi_val *isl_multi_val_free( __isl_take isl_multi_val *multi); isl_bool isl_multi_val_plain_is_equal( __isl_keep isl_multi_val *multi1, __isl_keep isl_multi_val *multi2); int isl_multi_val_find_dim_by_id( __isl_keep isl_multi_val *multi, enum isl_dim_type type, __isl_keep isl_id *id); __isl_give isl_id *isl_multi_val_get_dim_id( __isl_take isl_multi_val *multi, enum isl_dim_type type, unsigned pos); __isl_give isl_multi_val *isl_multi_val_set_dim_name( __isl_take isl_multi_val *multi, enum isl_dim_type type, unsigned pos, const char *s); __isl_give isl_multi_val *isl_multi_val_set_dim_id( __isl_take isl_multi_val *multi, enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); const char *isl_multi_val_get_tuple_name( __isl_keep isl_multi_val *multi, enum isl_dim_type type); isl_bool isl_multi_val_has_tuple_id( __isl_keep isl_multi_val *multi, enum isl_dim_type type); __isl_give isl_id *isl_multi_val_get_tuple_id( __isl_keep isl_multi_val *multi, enum isl_dim_type type); __isl_give isl_multi_val *isl_multi_val_set_tuple_name( __isl_take isl_multi_val *multi, enum isl_dim_type type, const char *s); __isl_give isl_multi_val *isl_multi_val_set_tuple_id( __isl_take isl_multi_val *multi, enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_multi_val *isl_multi_val_reset_tuple_id( __isl_take isl_multi_val *multi, enum isl_dim_type type); __isl_give isl_multi_val *isl_multi_val_reset_user( __isl_take isl_multi_val *multi); __isl_give isl_multi_val *isl_multi_val_drop_dims( __isl_take isl_multi_val *multi, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_val *isl_multi_val_get_val( __isl_keep isl_multi_val *multi, int pos); __isl_give isl_multi_val *isl_multi_val_set_val( __isl_take isl_multi_val *multi, int pos, __isl_take isl_val *el); __isl_give isl_multi_val *isl_multi_val_range_splice( __isl_take isl_multi_val *multi1, unsigned pos, __isl_take isl_multi_val *multi2); __isl_give isl_multi_val *isl_multi_val_flatten_range( __isl_take isl_multi_val *multi); __isl_give isl_multi_val *isl_multi_val_flat_range_product( __isl_take isl_multi_val *multi1, __isl_take isl_multi_val *multi2); __isl_give isl_multi_val *isl_multi_val_range_product( __isl_take isl_multi_val *multi1, __isl_take isl_multi_val *multi2); isl_bool isl_multi_val_range_is_wrapping( __isl_keep isl_multi_val *multi); __isl_give isl_multi_val *isl_multi_val_range_factor_domain( __isl_take isl_multi_val *multi); __isl_give isl_multi_val *isl_multi_val_range_factor_range( __isl_take isl_multi_val *multi); __isl_give isl_multi_val *isl_multi_val_scale_val( __isl_take isl_multi_val *multi, __isl_take isl_val *v); __isl_give isl_multi_val *isl_multi_val_scale_down_val( __isl_take isl_multi_val *multi, __isl_take isl_val *v); __isl_give isl_multi_val *isl_multi_val_scale_multi_val( __isl_take isl_multi_val *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_val *isl_multi_val_scale_down_multi_val( __isl_take isl_multi_val *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_val *isl_multi_val_mod_multi_val( __isl_take isl_multi_val *multi, __isl_take isl_multi_val *mv); __isl_give isl_multi_val *isl_multi_val_sub( __isl_take isl_multi_val *multi1, __isl_take isl_multi_val *multi2); __isl_give isl_multi_val *isl_multi_val_align_params( __isl_take isl_multi_val *multi, __isl_take isl_space *model); __isl_give isl_multi_val *isl_multi_val_from_range( __isl_take isl_multi_val *multi); diff --git a/py_codegen.py b/py_codegen.py deleted file mode 100644 index 524a9dad93c6845314b428f5f13dd798d63ba395..0000000000000000000000000000000000000000 --- a/py_codegen.py +++ /dev/null @@ -1,101 +0,0 @@ -from __future__ import division, with_statement - -__copyright__ = "Copyright (C) 2009-2013 Andreas Kloeckner" - -__license__ = """ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" - - -# loosely based on -# http://effbot.org/zone/python-code-generator.htm - -class Indentation(object): - def __init__(self, generator): - self.generator = generator - - def __enter__(self): - self.generator.indent() - - def __exit__(self, exc_type, exc_val, exc_tb): - self.generator.dedent() - - -class PythonCodeGenerator(object): - def __init__(self): - self.code = [] - self.level = 0 - - def extend(self, sub_generator): - for line in sub_generator.code: - self.code.append(" "*(4*self.level) + line) - - def get(self): - result = "\n".join(self.code) - return result - - def __call__(self, s): - if not s.strip(): - self.code.append("") - else: - if "\n" in s: - s = remove_common_indentation(s) - - for l in s.split("\n"): - self.code.append(" "*(4*self.level) + l) - - def indent(self): - self.level += 1 - - def dedent(self): - if self.level == 0: - raise RuntimeError("internal error in python code generator") - self.level -= 1 - - -# {{{ remove common indentation - -def remove_common_indentation(code, require_leading_newline=True): - if "\n" not in code: - return code - - # accommodate pyopencl-ish syntax highlighting - code = code.lstrip("//CL//") - - if require_leading_newline and not code.startswith("\n"): - return code - - lines = code.split("\n") - while lines[0].strip() == "": - lines.pop(0) - while lines[-1].strip() == "": - lines.pop(-1) - - if lines: - base_indent = 0 - while lines[0][base_indent] in " \t": - base_indent += 1 - - for line in lines[1:]: - if line[:base_indent].strip(): - raise ValueError("inconsistent indentation") - - return "\n".join(line[base_indent:] for line in lines) - -# }}} diff --git a/setup.py b/setup.py index 7878a6e787ae1e9a5a6fdf6a212a9c7a005cfa5c..e2cb0567ed86ba756ceca5de4f22d697fa505543 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ #!/usr/bin/env python -__copyright__ = "Copyright (C) 2011-15 Andreas Kloeckner" +__copyright__ = """ +Copyright (C) 2011-20 Andreas Kloeckner +""" __license__ = """ Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,7 +24,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from codecs import open # pylint: disable=redefined-builtin +from aksetup_helper import ( + check_pybind11, get_pybind_include, + get_config, setup, check_git_submodules, Extension, + PybindBuildExtCommand) def get_config_schema(): @@ -30,6 +35,12 @@ def get_config_schema(): IncludeDir, LibraryDir, Libraries, Switch, StringListOption) + default_cxxflags = [ + # Required for pybind11: + # https://pybind11.readthedocs.io/en/stable/faq.html#someclass-declared-with-greater-visibility-than-the-type-of-its-field-someclass-member-wattributes + "-fvisibility=hidden" + ] + return ConfigSchema([ Switch("USE_SHIPPED_ISL", True, "Use included copy of isl"), Switch("USE_SHIPPED_IMATH", True, "Use included copy of imath in isl"), @@ -50,74 +61,74 @@ def get_config_schema(): LibraryDir("BARVINOK", []), Libraries("BARVINOK", ["barvinok", "polylibgmp"]), - StringListOption("CXXFLAGS", [], + StringListOption("CXXFLAGS", default_cxxflags, help="Any extra C++ compiler options to include"), StringListOption("LDFLAGS", [], help="Any extra linker options to include"), ]) -CFFI_TEMPLATE = """ -from cffi import FFI - -EXTRA_DEFINES = {EXTRA_DEFINES} - -INCLUDES = ''' -{INCLUDES} -''' - -ffi = FFI() -ffi.set_source( - "islpy._isl_cffi", - INCLUDES, - define_macros=list(EXTRA_DEFINES.items()), - sources={EXTRA_SOURCES}, - include_dirs={INCLUDE_DIRS}, - library_dirs={LIBRARY_DIRS}, - libraries={LIBRARIES}, - extra_compile_args={CFLAGS}, - extra_link_args={LDFLAGS}) - - -with open("wrapped-functions.h", "rt") as header_f: - header = header_f.read() - -ffi.cdef(header) - -if __name__ == "__main__": - ffi.compile() -""" - - -def write_cffi_build_script(headers, **kwargs): - format_args = dict((k, repr(v)) for k, v in kwargs.items()) - - format_args["INCLUDES"] = "\n".join( - "#include <%s>" % header - for header in headers) +# {{{ awful monkeypatching to build only isl (and not the wrapper) with -O2 + +class Hooked_compile: # noqa: N801 + def __init__(self, orig__compile, compiler): + self.orig__compile = orig__compile + self.compiler = compiler + + def __call__(self, obj, src, *args, **kwargs): + compiler = self.compiler + prev_compiler_so = compiler.compiler_so + + # The C++ wrapper takes an awfully long time to compile + # with any optimization, on gcc 10 (2020-06-30, AK). + if src.startswith("src/wrapper"): + compiler.compiler_so = [opt for opt in compiler.compiler_so + if not ( + opt.startswith("-O") + or opt.startswith("-g"))] + if src.endswith(".c"): + # Some C compilers (Apple clang IIRC?) really don't like having C++ + # flags passed to them. + args = args[:2] + ( + [opt for opt in args[2] if "gnu++" not in opt],) + args[3:] + + try: + result = self.orig__compile(obj, src, *args, **kwargs) + finally: + compiler.compiler_so = prev_compiler_so + return result + + +class IslPyBuildExtCommand(PybindBuildExtCommand): + def __getattribute__(self, name): + if name == "compiler": + compiler = PybindBuildExtCommand.__getattribute__(self, name) + if compiler is not None: + orig__compile = compiler._compile + if not isinstance(orig__compile, Hooked_compile): + compiler._compile = Hooked_compile(orig__compile, compiler) + return compiler + else: + return PybindBuildExtCommand.__getattribute__(self, name) - with open("islpy_cffi_build.py", "wt") as outf: - outf.write(CFFI_TEMPLATE.format(**format_args)) +# }}} def main(): - # pylint: disable=too-many-statements, too-many-branches, too-many-locals - - from aksetup_helper import (hack_distutils, - get_config, setup, check_git_submodules) - + check_pybind11() check_git_submodules() - hack_distutils(what_opt=None) conf = get_config(get_config_schema(), warn_about_no_config=False) - EXTRA_SOURCES = [] # noqa - EXTRA_DEFINES = {} # noqa - INCLUDE_DIRS = [] # noqa - LIBRARY_DIRS = [] # noqa - LIBRARIES = [] # noqa CXXFLAGS = conf["CXXFLAGS"] # noqa: N806 + EXTRA_OBJECTS = [] # noqa: N806 + EXTRA_DEFINES = {} # noqa: N806 + + INCLUDE_DIRS = ["src/wrapper"] # noqa: N806 + LIBRARY_DIRS = [] # noqa: N806 + LIBRARIES = [] # noqa: N806 + if conf["USE_SHIPPED_ISL"]: from glob import glob isl_blacklist = [ @@ -186,12 +197,12 @@ def main(): inf.close() if "int main(" not in contents and not blacklisted: - EXTRA_SOURCES.append(fn) + EXTRA_OBJECTS.append(fn) - conf["ISL_INC_DIR"] = ["isl-supplementary", "isl/include", "isl"] + conf["ISL_INC_DIR"] = ["isl-supplementary", "isl/include", "isl"] if conf["USE_SHIPPED_IMATH"]: - EXTRA_SOURCES.extend([ + EXTRA_OBJECTS.extend([ "isl/imath/imath.c", "isl/imath/imrat.c", "isl/imath/gmp_compat.c", @@ -233,7 +244,8 @@ def main(): wrapper_dirs.extend(conf["BARVINOK_INC_DIR"]) - #EXTRA_DEFINES["ISLPY_ISL_VERSION"] = 15 + EXTRA_DEFINES["ISLPY_ISL_VERSION"] = 14 + EXTRA_DEFINES["ISLPY_INCLUDE_BARVINOK"] = 1 # }}} @@ -251,20 +263,9 @@ def main(): exec(compile(version_py, init_filename, "exec"), conf) from gen_wrap import gen_wrapper - headers = gen_wrapper(wrapper_dirs, include_barvinok=conf["USE_BARVINOK"], + gen_wrapper(wrapper_dirs, include_barvinok=conf["USE_BARVINOK"], isl_version=EXTRA_DEFINES.get("ISLPY_ISL_VERSION")) - write_cffi_build_script( - headers, - EXTRA_DEFINES=EXTRA_DEFINES, - EXTRA_SOURCES=EXTRA_SOURCES, - INCLUDE_DIRS=INCLUDE_DIRS, - LIBRARY_DIRS=LIBRARY_DIRS, - LIBRARIES=LIBRARIES, - CFLAGS=CXXFLAGS, - LDFLAGS=conf["LDFLAGS"] - ) - with open("README.rst", "rt") as readme_f: readme = readme_f.read() @@ -286,12 +287,6 @@ def main(): 'Programming Language :: C++', 'Programming Language :: Python', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Multimedia :: Graphics :: 3D Modeling', 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Mathematics', @@ -302,15 +297,36 @@ def main(): packages=["islpy"], - setup_requires=["cffi>=1.1.0"], - cffi_modules=["islpy_cffi_build.py:ffi"], python_requires="~=3.6", + setup_requires=[ + "pybind11", + ], install_requires=[ "pytest>=2", - "cffi>=1.1.0", # "Mako>=0.3.6", "six", ], + ext_modules=[ + Extension( + "islpy._isl", + [ + "src/wrapper/wrap_isl.cpp", + "src/wrapper/wrap_isl_part1.cpp", + "src/wrapper/wrap_isl_part2.cpp", + "src/wrapper/wrap_isl_part3.cpp", + ] + EXTRA_OBJECTS, + include_dirs=INCLUDE_DIRS + [ + get_pybind_include(), + get_pybind_include(user=True) + ], + library_dirs=LIBRARY_DIRS, + libraries=LIBRARIES, + define_macros=list(EXTRA_DEFINES.items()), + extra_compile_args=CXXFLAGS, + extra_link_args=conf["LDFLAGS"], + ), + ], + cmdclass={'build_ext': IslPyBuildExtCommand}, ) diff --git a/src/wrapper/wrap_helpers.hpp b/src/wrapper/wrap_helpers.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bbdd1411649b07d469a0987ae201f12129bc3b1d --- /dev/null +++ b/src/wrapper/wrap_helpers.hpp @@ -0,0 +1,49 @@ +#ifndef PYCUDA_WRAP_HELPERS_HEADER_SEEN +#define PYCUDA_WRAP_HELPERS_HEADER_SEEN + + + +#include +#include + + +namespace py = pybind11; + + +#define PYTHON_ERROR(TYPE, REASON) \ +{ \ + PyErr_SetString(PyExc_##TYPE, REASON); \ + throw pybind11::error_already_set(); \ +} + +#define ENUM_VALUE(PREFIX, NAME) \ + value(#NAME, PREFIX##NAME) + +#define DEF_SIMPLE_METHOD(NAME) \ + def(#NAME, &cls::NAME) + +#define DEF_SIMPLE_METHOD_WITH_ARGS(NAME, ARGS) \ + def(#NAME, &cls::NAME, pybind11::args ARGS) + +#define DEF_SIMPLE_FUNCTION(NAME) \ + pybind11::def(#NAME, &NAME) + +#define DEF_SIMPLE_FUNCTION_WITH_ARGS(NAME, ARGS) \ + pybind11::def(#NAME, &NAME, pybind11::args ARGS) + +#define DEF_SIMPLE_RO_MEMBER(NAME) \ + def_readonly(#NAME, &cls::NAME) + +#define DEF_SIMPLE_RW_MEMBER(NAME) \ + def_readwrite(#NAME, &cls::NAME) + +namespace +{ + template + inline pybind11::object handle_from_new_ptr(T *ptr) + { + return py::cast(ptr, py::return_value_policy::take_ownership); + } +} + +#endif diff --git a/src/wrapper/wrap_isl.cpp b/src/wrapper/wrap_isl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3871607e4d1962940d046360af9e993433b8424d --- /dev/null +++ b/src/wrapper/wrap_isl.cpp @@ -0,0 +1,190 @@ +#include "wrap_isl.hpp" + +void islpy_expose_part1(py::module &m); +void islpy_expose_part2(py::module &m); +void islpy_expose_part3(py::module &m); + +namespace isl +{ + ctx_use_map_t ctx_use_map; +} + + +PYBIND11_MODULE(_isl, m) +{ + static py::exception ISLError(m, "Error", NULL); + py::register_exception_translator( + [](std::exception_ptr p) + { + try + { + if (p) std::rethrow_exception(p); + } + catch (isl::error &err) + { + ISLError(err.what()); + } + }); + + // py::docstring_options doc_opt(true, false, false); + + /* + { + typedef isl_options cls; + py::class_(m, "Options") + .DEF_SIMPLE_RW_MEMBER(lp_solver) + .DEF_SIMPLE_RW_MEMBER(ilp_solver) + .DEF_SIMPLE_RW_MEMBER(pip) + .DEF_SIMPLE_RW_MEMBER(context) + .DEF_SIMPLE_RW_MEMBER(gbr) + .DEF_SIMPLE_RW_MEMBER(gbr_only_first) + .DEF_SIMPLE_RW_MEMBER(closure) + .DEF_SIMPLE_RW_MEMBER(bound) + .DEF_SIMPLE_RW_MEMBER(bernstein_recurse) + .DEF_SIMPLE_RW_MEMBER(bernstein_triangulate) + .DEF_SIMPLE_RW_MEMBER(pip_symmetry) + .DEF_SIMPLE_RW_MEMBER(convex) + .DEF_SIMPLE_RW_MEMBER(schedule_parametric) + .DEF_SIMPLE_RW_MEMBER(schedule_outer_zero_distance) + .DEF_SIMPLE_RW_MEMBER(schedule_split_parallel) + ; + } + */ + + py::enum_(m, "error") + .ENUM_VALUE(isl_error_, none) + .ENUM_VALUE(isl_error_, abort) + .ENUM_VALUE(isl_error_, unknown) + .ENUM_VALUE(isl_error_, internal) + .ENUM_VALUE(isl_error_, invalid) + .ENUM_VALUE(isl_error_, unsupported) + ; + + py::enum_(m, "stat") + .ENUM_VALUE(isl_stat_, error) + .ENUM_VALUE(isl_stat_, ok) + ; + + py::enum_(m, "dim_type") + .ENUM_VALUE(isl_dim_, cst) + .ENUM_VALUE(isl_dim_, param) + .value("in_", isl_dim_in) + .ENUM_VALUE(isl_dim_, out) + .ENUM_VALUE(isl_dim_, set) + .ENUM_VALUE(isl_dim_, div) + .ENUM_VALUE(isl_dim_, all) + ; + + py::enum_(m, "schedule_node_type") + .ENUM_VALUE(isl_schedule_node_, error) + .ENUM_VALUE(isl_schedule_node_, band) + .ENUM_VALUE(isl_schedule_node_, context) + .ENUM_VALUE(isl_schedule_node_, domain) + .ENUM_VALUE(isl_schedule_node_, expansion) + .ENUM_VALUE(isl_schedule_node_, extension) + .ENUM_VALUE(isl_schedule_node_, filter) + .ENUM_VALUE(isl_schedule_node_, leaf) + .ENUM_VALUE(isl_schedule_node_, guard) + .ENUM_VALUE(isl_schedule_node_, mark) + .ENUM_VALUE(isl_schedule_node_, sequence) + .ENUM_VALUE(isl_schedule_node_, set) + ; + + py::enum_(m, "ast_expr_op_type") + .ENUM_VALUE(isl_ast_expr_op_, error) + .ENUM_VALUE(isl_ast_expr_op_, and) + .ENUM_VALUE(isl_ast_expr_op_, and_then) + .ENUM_VALUE(isl_ast_expr_op_, or) + .ENUM_VALUE(isl_ast_expr_op_, or_else) + .ENUM_VALUE(isl_ast_expr_op_, max) + .ENUM_VALUE(isl_ast_expr_op_, min) + .ENUM_VALUE(isl_ast_expr_op_, minus) + .ENUM_VALUE(isl_ast_expr_op_, add) + .ENUM_VALUE(isl_ast_expr_op_, sub) + .ENUM_VALUE(isl_ast_expr_op_, mul) + .ENUM_VALUE(isl_ast_expr_op_, div) + .ENUM_VALUE(isl_ast_expr_op_, fdiv_q) + .ENUM_VALUE(isl_ast_expr_op_, pdiv_q) + .ENUM_VALUE(isl_ast_expr_op_, pdiv_r) + .ENUM_VALUE(isl_ast_expr_op_, zdiv_r) + .ENUM_VALUE(isl_ast_expr_op_, cond) + .ENUM_VALUE(isl_ast_expr_op_, select) + .ENUM_VALUE(isl_ast_expr_op_, eq) + .ENUM_VALUE(isl_ast_expr_op_, le) + .ENUM_VALUE(isl_ast_expr_op_, lt) + .ENUM_VALUE(isl_ast_expr_op_, ge) + .ENUM_VALUE(isl_ast_expr_op_, gt) + .ENUM_VALUE(isl_ast_expr_op_, call) + .ENUM_VALUE(isl_ast_expr_op_, access) + .ENUM_VALUE(isl_ast_expr_op_, member) + .ENUM_VALUE(isl_ast_expr_op_, address_of) + ; + + py::enum_(m, "fold") + .ENUM_VALUE(isl_fold_, min) + .ENUM_VALUE(isl_fold_, max) + .ENUM_VALUE(isl_fold_, list) + ; + + py::enum_(m, "ast_expr_type") + .ENUM_VALUE(isl_ast_expr_, error) + .ENUM_VALUE(isl_ast_expr_, op) + .ENUM_VALUE(isl_ast_expr_, id) + .ENUM_VALUE(isl_ast_expr_, int) + ; + + py::enum_(m, "ast_node_type") + .ENUM_VALUE(isl_ast_node_, error) + .ENUM_VALUE(isl_ast_node_, for) + .ENUM_VALUE(isl_ast_node_, if) + .ENUM_VALUE(isl_ast_node_, block) + .ENUM_VALUE(isl_ast_node_, user) + ; + + py::enum_(m, "ast_loop_type") + .ENUM_VALUE(isl_ast_loop_, error) + .ENUM_VALUE(isl_ast_loop_, default) + .ENUM_VALUE(isl_ast_loop_, atomic) + .ENUM_VALUE(isl_ast_loop_, unroll) + .ENUM_VALUE(isl_ast_loop_, separate) + ; + +#define ADD_MACRO_ATTR(cls_name, prefix, name) cls_name.attr(#name) = prefix##name + + py::class_ cls_format(m, "format"); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, ISL); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, POLYLIB); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, POLYLIB_CONSTRAINTS); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, OMEGA); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, C); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, LATEX); + ADD_MACRO_ATTR(cls_format, ISL_FORMAT_, EXT_POLYLIB); + + py::class_ cls_yaml_style(m, "yaml_style"); + ADD_MACRO_ATTR(cls_yaml_style, ISL_YAML_STYLE_, BLOCK); + ADD_MACRO_ATTR(cls_yaml_style, ISL_YAML_STYLE_, FLOW); + + py::class_ cls_bound(m, "bound"); + ADD_MACRO_ATTR(cls_bound, ISL_BOUND_, BERNSTEIN); + ADD_MACRO_ATTR(cls_bound, ISL_BOUND_, RANGE); + + py::class_ cls_on_error(m, "on_error"); + ADD_MACRO_ATTR(cls_on_error, ISL_ON_ERROR_, WARN); + ADD_MACRO_ATTR(cls_on_error, ISL_ON_ERROR_, CONTINUE); + ADD_MACRO_ATTR(cls_on_error, ISL_ON_ERROR_, ABORT); + + py::class_ cls_schedule_algorithm(m, "schedule_algorithm"); + ADD_MACRO_ATTR(cls_schedule_algorithm, ISL_SCHEDULE_ALGORITHM_, ISL); + ADD_MACRO_ATTR(cls_schedule_algorithm, ISL_SCHEDULE_ALGORITHM_, FEAUTRIER); + + islpy_expose_part1(m); + islpy_expose_part2(m); + islpy_expose_part3(m); + + py::implicitly_convertible(); + py::implicitly_convertible(); + py::implicitly_convertible(); + py::implicitly_convertible(); + py::implicitly_convertible(); + py::implicitly_convertible(); +} diff --git a/src/wrapper/wrap_isl.hpp b/src/wrapper/wrap_isl.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1a99d3b18ff66e7bf1aaf6331f982641870d51c7 --- /dev/null +++ b/src/wrapper/wrap_isl.hpp @@ -0,0 +1,323 @@ +#include "wrap_helpers.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(ISLPY_ISL_VERSION) || (ISLPY_ISL_VERSION >= 15) +#include +#endif +#include +#include +#include +#include + +#ifdef ISLPY_INCLUDE_BARVINOK +#include +#endif + +#include +#include +#include + + +// TODO: flow.h +// TODO: better error reporting + +namespace py = pybind11; + +namespace isl +{ + class error : public std::runtime_error + { + public: + explicit error (const std::string &what) + : std::runtime_error(what) + { } + }; + + struct ctx; + + typedef std::unordered_map ctx_use_map_t; + extern ctx_use_map_t ctx_use_map; + + inline void ref_ctx(isl_ctx *data) + { + ctx_use_map_t::iterator it(ctx_use_map.find(data)); + if (it == ctx_use_map.end()) + ctx_use_map[data] = 1; + else + (it->second)++; + } + + inline void unref_ctx(isl_ctx *ctx) + { + ctx_use_map[ctx] -= 1; + if (ctx_use_map[ctx] == 0) + isl_ctx_free(ctx); + } + +#define WRAP_CLASS(name) \ + struct name { WRAP_CLASS_CONTENT(name) } + +#define MAKE_CAST_CTOR(name, from_type, cast_func) \ + name(from_type &data) \ + : m_data(nullptr) \ + { \ + isl_##from_type *copy = isl_##from_type##_copy(data.m_data); \ + if (!copy) \ + throw error("isl_" #from_type "_copy failed"); \ + m_data = cast_func(copy); \ + if (!m_data) \ + throw error(#cast_func " failed"); \ + \ + ref_ctx(get_ctx()); \ + } + +#define WRAP_CLASS_CONTENT(name) \ + public: \ + isl_##name *m_data; \ + \ + name(isl_##name *data) \ + : m_data(nullptr) \ + /* passing nullptr is allowed to create a (temporarily invalid) */ \ + /* instance during unpickling */ \ + { \ + take_possession_of(data); \ + } \ + \ + isl_ctx *get_ctx() \ + { \ + return isl_##name##_get_ctx(m_data); \ + } \ + \ + void invalidate() \ + { \ + if (m_data) \ + { \ + unref_ctx(get_ctx()); \ + m_data = nullptr; \ + } \ + } \ + \ + bool is_valid() const \ + { \ + return (bool) m_data; \ + } \ + \ + ~name() \ + { \ + free_instance(); \ + } \ + \ + void free_instance() \ + { \ + if (m_data) \ + { \ + unref_ctx(get_ctx()); \ + isl_##name##_free(m_data); \ + m_data = nullptr; \ + } \ + } \ + \ + void take_possession_of(isl_##name *data) \ + { \ + free_instance(); \ + if (data) \ + { \ + m_data = data; \ + ref_ctx(get_ctx()); \ + } \ + } \ + + struct ctx \ + { + public: + isl_ctx *m_data; + + ctx(isl_ctx *data) + : m_data(data) + { + ref_ctx(data); + } + + bool is_valid() const + { + return true; + } + + ~ctx() + { + unref_ctx(m_data); + } + + void reset_instance(ctx &other) + { + ref_ctx(other.m_data); + unref_ctx(m_data); + m_data = other.m_data; + } + + bool wraps_same_instance_as(ctx const &other) + { + return m_data == other.m_data; + } + }; + + // matches order in gen_wrap.py + + // {{{ part 1 + + WRAP_CLASS(id_list); + WRAP_CLASS(val_list); + WRAP_CLASS(basic_set_list); + WRAP_CLASS(basic_map_list); + WRAP_CLASS(set_list); + WRAP_CLASS(map_list); + WRAP_CLASS(union_set_list); + WRAP_CLASS(constraint_list); + WRAP_CLASS(aff_list); + WRAP_CLASS(pw_aff_list); + WRAP_CLASS(pw_multi_aff_list); + WRAP_CLASS(ast_expr_list); + WRAP_CLASS(ast_node_list); + WRAP_CLASS(pw_qpolynomial_list); + WRAP_CLASS(pw_qpolynomial_fold_list); + WRAP_CLASS(union_pw_aff_list); + WRAP_CLASS(union_pw_multi_aff_list); + WRAP_CLASS(union_map_list); + + WRAP_CLASS(id_to_ast_expr); + + WRAP_CLASS(printer); + WRAP_CLASS(val); + WRAP_CLASS(multi_val); + WRAP_CLASS(vec); + WRAP_CLASS(mat); + WRAP_CLASS(fixed_box); + + WRAP_CLASS(aff); + struct pw_aff + { + WRAP_CLASS_CONTENT(pw_aff); + MAKE_CAST_CTOR(pw_aff, aff, isl_pw_aff_from_aff); + }; + WRAP_CLASS(union_pw_aff); + WRAP_CLASS(multi_aff); + WRAP_CLASS(multi_pw_aff); + WRAP_CLASS(pw_multi_aff); + WRAP_CLASS(union_pw_multi_aff); + WRAP_CLASS(multi_union_pw_aff); + + WRAP_CLASS(id); + WRAP_CLASS(multi_id); + + WRAP_CLASS(constraint); + WRAP_CLASS(space); + struct local_space + { + WRAP_CLASS_CONTENT(local_space); + MAKE_CAST_CTOR(local_space, space, isl_local_space_from_space); + }; + + // }}} + + // {{{ part 2 + + WRAP_CLASS(basic_set); + WRAP_CLASS(basic_map); + + struct set + { + WRAP_CLASS_CONTENT(set); + MAKE_CAST_CTOR(set, basic_set, isl_set_from_basic_set); + }; + + struct map + { + WRAP_CLASS_CONTENT(map); + MAKE_CAST_CTOR(map, basic_map, isl_map_from_basic_map); + }; + + struct union_set + { + WRAP_CLASS_CONTENT(union_set); + MAKE_CAST_CTOR(union_set, set, isl_union_set_from_set); + }; + struct union_map + { + WRAP_CLASS_CONTENT(union_map); + MAKE_CAST_CTOR(union_map, map, isl_union_map_from_map); + }; + + WRAP_CLASS(point); + WRAP_CLASS(vertex); + WRAP_CLASS(cell); + WRAP_CLASS(vertices); + WRAP_CLASS(stride_info); + + // }}} + + // {{{ part 3 + + WRAP_CLASS(qpolynomial); + WRAP_CLASS(pw_qpolynomial); + WRAP_CLASS(qpolynomial_fold); + WRAP_CLASS(pw_qpolynomial_fold); + WRAP_CLASS(union_pw_qpolynomial); + WRAP_CLASS(union_pw_qpolynomial_fold); + WRAP_CLASS(term); + + WRAP_CLASS(schedule); + WRAP_CLASS(schedule_constraints); + WRAP_CLASS(schedule_node); + + WRAP_CLASS(access_info); + WRAP_CLASS(flow); + WRAP_CLASS(restriction); + WRAP_CLASS(union_access_info); + WRAP_CLASS(union_flow); + + WRAP_CLASS(ast_expr); + WRAP_CLASS(ast_node); + WRAP_CLASS(ast_print_options); + WRAP_CLASS(ast_build); + + // }}} + + class format { }; + class yaml_style { }; + class bound { }; + class on_error { }; + class schedule_algorithm { }; + + inline void my_decref(void *user) + { + Py_DECREF((PyObject *) user); + } +} + + + + + +#define MAKE_WRAP(name, py_name) \ + py::class_ wrap_##name(m, #py_name, py::dynamic_attr()); \ + wrap_##name.def("_is_valid", &isl::name::is_valid); \ + wrap_##name.attr("_base_name") = #name; \ + wrap_##name.attr("_isl_name") = "isl_"#name; \ + +// vim: foldmethod=marker diff --git a/src/wrapper/wrap_isl_part1.cpp b/src/wrapper/wrap_isl_part1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8d7c918a3f505e4fb41326d5a2f68158512bc001 --- /dev/null +++ b/src/wrapper/wrap_isl_part1.cpp @@ -0,0 +1,125 @@ +#include "wrap_isl.hpp" + +namespace isl +{ +#include "gen-wrap-part1.inc" + + class constants { }; +} + +namespace islpy +{ + bool id_eq(isl::id const *self, isl::id const *other) + { + return self == other; + } + + bool id_ne(isl::id const *self, isl::id const *other) + { + return self != other; + } +} + +void islpy_expose_part1(py::module &m) +{ + py::class_ > + wrap_ctx(m, "Context"); + wrap_ctx.def(py::init( + []() + { + isl_ctx *result = isl_ctx_alloc(); + if (result) + { + try + { return new isl::ctx(result); } + catch (...) + { + isl_ctx_free(result); + throw; + } + } + else + PYTHON_ERROR(RuntimeError, "failed to create context"); + })); + wrap_ctx.attr("_base_name") = "ctx"; + wrap_ctx.attr("_isl_name") = "isl_ctx"; + wrap_ctx.def("_is_valid", &isl::ctx::is_valid); + wrap_ctx.def("_reset_instance", &isl::ctx::reset_instance); + wrap_ctx.def("_wraps_same_instance_as", &isl::ctx::wraps_same_instance_as); + + // {{{ lists + + MAKE_WRAP(id_list, IdList); + MAKE_WRAP(val_list, ValList); + MAKE_WRAP(basic_set_list, BasicSetList); + MAKE_WRAP(basic_map_list, BasicMapList); + MAKE_WRAP(set_list, SetList); + MAKE_WRAP(map_list, MapList); + MAKE_WRAP(union_set_list, UnionSetList); + MAKE_WRAP(constraint_list, ConstraintList); + MAKE_WRAP(aff_list, AffList); + MAKE_WRAP(pw_aff_list, PwAffList); + MAKE_WRAP(pw_multi_aff_list, PwMultiAffList); + MAKE_WRAP(ast_expr_list, AstExprList); + MAKE_WRAP(ast_node_list, AstNodeList); + MAKE_WRAP(pw_qpolynomial_list, PwQPolynomialList); + MAKE_WRAP(pw_qpolynomial_fold_list, PwQPolynomialFoldList); + MAKE_WRAP(union_pw_aff_list, UnionPwAffList); + MAKE_WRAP(union_pw_multi_aff_list, UnionPwMultiAffList); + MAKE_WRAP(union_map_list, UnionMapList); + + // }}} + + // {{{ maps + + MAKE_WRAP(id_to_ast_expr, IdToAstExpr); + + // }}} + + MAKE_WRAP(printer, Printer); + MAKE_WRAP(val, Val); + + MAKE_WRAP(multi_val, MultiVal); + MAKE_WRAP(vec, Vec); + MAKE_WRAP(mat, Mat); + MAKE_WRAP(fixed_box, FixedBox); + + MAKE_WRAP(aff, Aff); + + MAKE_WRAP(pw_aff, PwAff); + wrap_pw_aff.def(py::init()); + + MAKE_WRAP(union_pw_aff, UnionPwAff); + + MAKE_WRAP(multi_id, MultiId); + + MAKE_WRAP(multi_aff, MultiAff); + + MAKE_WRAP(multi_pw_aff, MultiPwAff); + + MAKE_WRAP(pw_multi_aff, PwMultiAff); + + MAKE_WRAP(union_pw_multi_aff, UnionPwMultiAff); + + MAKE_WRAP(multi_union_pw_aff, MultiUnionPwAff); + + MAKE_WRAP(id, Id); + wrap_id.def("__eq__", islpy::id_eq, py::arg("other"), + "__eq__(self, other)\n\n" + ":param self: :class:`Id`\n" + ":param other: :class:`Id`\n" + ":return: bool "); + wrap_id.def("__ne__", islpy::id_ne, py::arg("other"), + "__ne__(self, other)\n\n" + ":param self: :class:`Id`\n" + ":param other: :class:`Id`\n" + ":return: bool "); + + MAKE_WRAP(constraint, Constraint); + + MAKE_WRAP(space, Space); + MAKE_WRAP(local_space, LocalSpace); + wrap_local_space.def(py::init()); + +#include "gen-expose-part1.inc" +} diff --git a/src/wrapper/wrap_isl_part2.cpp b/src/wrapper/wrap_isl_part2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79d5fc8fbeaeb4d95009c8086fea141c5d6ebe98 --- /dev/null +++ b/src/wrapper/wrap_isl_part2.cpp @@ -0,0 +1,36 @@ +#include "wrap_isl.hpp" + +namespace isl +{ +#include "gen-wrap-part2.inc" +} + +void islpy_expose_part2(py::module &m) +{ + MAKE_WRAP(basic_set, BasicSet); + + MAKE_WRAP(basic_map, BasicMap); + + MAKE_WRAP(set, Set); + wrap_set.def(py::init()); + + MAKE_WRAP(map, Map); + wrap_map.def(py::init()); + + MAKE_WRAP(union_set, UnionSet); + wrap_union_set.def(py::init()); + + MAKE_WRAP(union_map, UnionMap); + wrap_union_map.def(py::init()); + + MAKE_WRAP(point, Point); + + MAKE_WRAP(vertex, Vertex); + + MAKE_WRAP(cell, Cell); + + MAKE_WRAP(vertices, Vertices); + MAKE_WRAP(stride_info, StrideInfo); + +#include "gen-expose-part2.inc" +} diff --git a/src/wrapper/wrap_isl_part3.cpp b/src/wrapper/wrap_isl_part3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54bfed8d1a49bbf9bd84b943c8bcaf057c4020f1 --- /dev/null +++ b/src/wrapper/wrap_isl_part3.cpp @@ -0,0 +1,39 @@ +#include "wrap_isl.hpp" + +namespace isl +{ +#include "gen-wrap-part3.inc" +} + +void islpy_expose_part3(py::module &m) +{ + MAKE_WRAP(qpolynomial, QPolynomial); + MAKE_WRAP(pw_qpolynomial, PwQPolynomial); + MAKE_WRAP(qpolynomial_fold, QPolynomialFold); + MAKE_WRAP(pw_qpolynomial_fold, PwQPolynomialFold); + MAKE_WRAP(union_pw_qpolynomial_fold, UnionPwQPolynomialFold); + MAKE_WRAP(union_pw_qpolynomial, UnionPwQPolynomial); + + MAKE_WRAP(term, Term); + + MAKE_WRAP(schedule, Schedule); + MAKE_WRAP(schedule_constraints, ScheduleConstraints); +#if !defined(ISLPY_ISL_VERSION) || (ISLPY_ISL_VERSION >= 15) + MAKE_WRAP(schedule_node, ScheduleNode); +#endif + + MAKE_WRAP(access_info, AccessInfo); + MAKE_WRAP(flow, Flow); + MAKE_WRAP(restriction, Restriction); +#if !defined(ISLPY_ISL_VERSION) || (ISLPY_ISL_VERSION >= 15) + MAKE_WRAP(union_access_info, UnionAccessInfo); + MAKE_WRAP(union_flow, UnionFlow); +#endif + + MAKE_WRAP(ast_expr, AstExpr); + MAKE_WRAP(ast_node, AstNode); + MAKE_WRAP(ast_build, AstBuild); + MAKE_WRAP(ast_print_options, AstPrintOptions); + +#include "gen-expose-part3.inc" +} diff --git a/test/test_isl.py b/test/test_isl.py index 3902ddc26420eeb76f79935958007b934f14aff5..5a324e2edf5300812ec58ccdeedbeef8ebf1dcdf 100644 --- a/test/test_isl.py +++ b/test/test_isl.py @@ -58,12 +58,8 @@ def test_error_on_invalid_index(): my_set = isl.Set("{ [k, l] : 3l >= -k and 3l <= 10 - k " "and k >=0 and k <= 2 }", context=ctx) p = my_set.sample_point() - try: + with pytest.raises(isl.Error): p.get_coordinate_val(isl.dim_type.set, 99999999) - except isl.Error: - pass - else: - assert False def test_pwqpoly(): @@ -94,6 +90,14 @@ def test_val(): assert v.to_python() == 17 +def test_upcast(): + a = isl.PwAff("[n] -> { [(-1 - floor((-n)/4))] }") + b = isl.Aff("[n] -> { [(-1 - floor((-n)/4))] }") + + assert b.is_equal(a) + assert a.is_equal(b) + + def test_pickling(): instances = [ isl.Aff("[n] -> { [(-1 - floor((-n)/4))] }"), @@ -358,8 +362,8 @@ def test_bound(): def test_copy_context(): ctx = isl.Context() import copy - assert copy.copy(ctx).data != ctx.data - assert copy.copy(ctx).data != isl.DEFAULT_CONTEXT.data + assert not ctx._wraps_same_instance_as(copy.copy(ctx)) + assert not isl.DEFAULT_CONTEXT._wraps_same_instance_as(copy.copy(ctx)) def test_ast_node_list_free():