From 43cc6dbdab76a85ca72d943a125ce90fdf7ccac4 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Mon, 31 Oct 2011 16:24:19 -0400 Subject: [PATCH] Use straight integer division if isl can show the operands are nonnegative. --- MEMO | 6 +++--- loopy/isl_helpers.py | 17 +++++++++++++++++ loopy/symbolic.py | 14 ++++++++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/MEMO b/MEMO index 4b22218b8..6fa8a95c5 100644 --- a/MEMO +++ b/MEMO @@ -41,9 +41,6 @@ To-do - Automatically generate testing code vs. sequential. -- If isl can prove that all operands are positive, may use '/' instead of - 'floor_div'. - - Fix all tests - Deal with equality constraints. @@ -86,6 +83,9 @@ Future ideas Dealt with ^^^^^^^^^^ +- If isl can prove that all operands are positive, may use '/' instead of + 'floor_div'. + - For forced workgroup sizes: check that at least one iname maps to them. diff --git a/loopy/isl_helpers.py b/loopy/isl_helpers.py index ba79878e9..d48ca1331 100644 --- a/loopy/isl_helpers.py +++ b/loopy/isl_helpers.py @@ -227,4 +227,21 @@ def duplicate_axes(isl_obj, duplicate_inames, new_inames): +def is_nonnegative(expr, over_set): + space = over_set.get_space() + from loopy.symbolic import aff_from_expr + try: + aff = aff_from_expr(space, -expr-1) + except: + return None + expr_neg_set = isl.BasicSet.universe(space).add_constraint( + isl.Constraint.inequality_from_aff(aff)) + + return over_set.intersect(expr_neg_set).is_empty() + + + + + + # vim: foldmethod=marker diff --git a/loopy/symbolic.py b/loopy/symbolic.py index f41e1b5e3..b25dd2965 100644 --- a/loopy/symbolic.py +++ b/loopy/symbolic.py @@ -355,10 +355,16 @@ class LoopyCCodeMapper(CCodeMapper): raise RuntimeError("nothing known about variable '%s'" % expr.aggregate.name) def map_floor_div(self, expr, prec): - if isinstance(expr.denominator, int) and expr.denominator > 0: - return ("int_floor_div_pos_b(%s, %s)" - % (self.rec(expr.numerator, PREC_NONE), - expr.denominator)) + from loopy.isl_helpers import is_nonnegative + num_nonneg = is_nonnegative(expr.numerator, self.kernel.domain) + den_nonneg = is_nonnegative(expr.denominator, self.kernel.domain) + if den_nonneg: + if num_nonneg: + return CCodeMapper.map_quotient(self, expr, prec) + else: + return ("int_floor_div_pos_b(%s, %s)" + % (self.rec(expr.numerator, PREC_NONE), + expr.denominator)) else: return ("int_floor_div(%s, %s)" % (self.rec(expr.numerator, PREC_NONE), -- GitLab