From 4a4cc7203e76f4e7361c1af408651882fc61d062 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Wed, 19 Jun 2013 10:45:51 -0400
Subject: [PATCH] Provide a central diagnostics module, and provide context for
 failed static_value_*

---
 MEMO                  |  4 ++++
 loopy/__init__.py     | 12 +++++------
 loopy/check.py        |  2 +-
 loopy/codegen/loop.py | 10 ++++++---
 loopy/compiled.py     |  5 +----
 loopy/diagnostic.py   | 47 +++++++++++++++++++++++++++++++++++++++++++
 loopy/kernel/tools.py | 11 +++++-----
 loopy/preprocess.py   |  4 ++--
 loopy/schedule.py     |  2 +-
 9 files changed, 75 insertions(+), 22 deletions(-)
 create mode 100644 loopy/diagnostic.py

diff --git a/MEMO b/MEMO
index 1b1dd69af..a83ca7491 100644
--- a/MEMO
+++ b/MEMO
@@ -70,6 +70,10 @@ To-do
 
 - Test array access with modulo
 
+- Derive all errors from central hierarchy
+
+- Provide context for more errors?
+
 Fixes:
 
 - applied_iname_rewrites tracking for prefetch footprints isn't bulletproof
diff --git a/loopy/__init__.py b/loopy/__init__.py
index 45d65683b..e81ba1ebb 100644
--- a/loopy/__init__.py
+++ b/loopy/__init__.py
@@ -39,9 +39,6 @@ from pytools import MovedFunctionDeprecationWrapper
 from loopy.symbolic import ExpandingIdentityMapper, ExpandingSubstitutionMapper
 
 
-class LoopyAdvisory(UserWarning):
-    pass
-
 # {{{ imported user interface
 
 from loopy.kernel.data import (
@@ -346,9 +343,12 @@ def join_inames(kernel, inames, new_iname=None, tag=None, within=None):
 
         length = int(pw_aff_to_expr(
             static_max_of_pw_aff(bounds.size, constants_only=True)))
-        lower_bound_aff = static_value_of_pw_aff(
-                bounds.lower_bound_pw_aff.coalesce(),
-                constants_only=False)
+        try:
+            lower_bound_aff = static_value_of_pw_aff(
+                    bounds.lower_bound_pw_aff.coalesce(),
+                    constants_only=False)
+        except Exception, e:
+            raise type(e)("while finding lower bound of '%s': " % iname)
 
         my_val = var(new_iname) // base_divisor
         if i+1 < len(inames):
diff --git a/loopy/check.py b/loopy/check.py
index 87fcb1e86..fefd150d8 100644
--- a/loopy/check.py
+++ b/loopy/check.py
@@ -36,7 +36,7 @@ logger = logging.getLogger(__name__)
 def check_sizes(kernel):
     import loopy as lp
 
-    from loopy import LoopyAdvisory
+    from loopy.diagnostic import LoopyAdvisory
 
     parameters = {}
     for arg in kernel.args:
diff --git a/loopy/codegen/loop.py b/loopy/codegen/loop.py
index 60836279f..f94a256e8 100644
--- a/loopy/codegen/loop.py
+++ b/loopy/codegen/loop.py
@@ -124,9 +124,13 @@ def generate_unroll_loop(kernel, sched_index, codegen_state):
 
     length = int(pw_aff_to_expr(
         static_max_of_pw_aff(bounds.size, constants_only=True)))
-    lower_bound_aff = static_value_of_pw_aff(
-            bounds.lower_bound_pw_aff.coalesce(),
-            constants_only=False)
+
+    try:
+        lower_bound_aff = static_value_of_pw_aff(
+                bounds.lower_bound_pw_aff.coalesce(),
+                constants_only=False)
+    except Exception, e:
+        raise type(e)("while finding lower bound of '%s': " % iname)
 
     result = []
 
diff --git a/loopy/compiled.py b/loopy/compiled.py
index ae443679b..d3eb8ab52 100644
--- a/loopy/compiled.py
+++ b/loopy/compiled.py
@@ -27,10 +27,7 @@ import pyopencl as cl
 import pyopencl.tools  # noqa
 import numpy as np
 from pytools import Record, memoize_method
-
-
-class ParameterFinderWarning(UserWarning):
-    pass
+from loopy.diagnostic import ParameterFinderWarning
 
 
 # {{{ object array argument packing
diff --git a/loopy/diagnostic.py b/loopy/diagnostic.py
new file mode 100644
index 000000000..299b3564f
--- /dev/null
+++ b/loopy/diagnostic.py
@@ -0,0 +1,47 @@
+from __future__ import division
+
+__copyright__ = "Copyright (C) 2012 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.
+"""
+
+
+# {{{ warnings
+
+class LoopyWarningBase(UserWarning):
+    pass
+
+
+class LoopyAdvisory(LoopyWarningBase):
+    pass
+
+
+class ParameterFinderWarning(LoopyWarningBase):
+    pass
+
+# }}}
+
+# {{{ errors
+
+# FIXME
+
+# }}}
+
+# vim: foldmethod=marker
diff --git a/loopy/kernel/tools.py b/loopy/kernel/tools.py
index dd1da7532..d9b8169ab 100644
--- a/loopy/kernel/tools.py
+++ b/loopy/kernel/tools.py
@@ -214,8 +214,6 @@ class SetOperationCacheManager:
         else:
             idx = iname
 
-        del iname
-
         lower_bound_pw_aff = self.dim_min(set, idx)
         upper_bound_pw_aff = self.dim_max(set, idx)
 
@@ -225,9 +223,12 @@ class SetOperationCacheManager:
         size = pw_aff_to_expr(static_max_of_pw_aff(
                 upper_bound_pw_aff - lower_bound_pw_aff + 1, constants_only=True,
                 context=context))
-        base_index = pw_aff_to_expr(
-            static_value_of_pw_aff(lower_bound_pw_aff, constants_only=False,
-                context=context))
+        try:
+            base_index = pw_aff_to_expr(
+                    static_value_of_pw_aff(lower_bound_pw_aff, constants_only=False,
+                        context=context))
+        except Exception, e:
+            raise type(e)("while finding lower bound of '%s': " % iname)
 
         return base_index, size
 
diff --git a/loopy/preprocess.py b/loopy/preprocess.py
index fe6827f5c..fb33c152c 100644
--- a/loopy/preprocess.py
+++ b/loopy/preprocess.py
@@ -244,7 +244,7 @@ def mark_local_temporaries(kernel):
 
         if not wants_to_be_local_per_insn:
             from warnings import warn
-            from loopy import LoopyAdvisory
+            from loopy.diagnostic import LoopyAdvisory
             warn("temporary variable '%s' never written, eliminating"
                     % temp_var.name, LoopyAdvisory)
 
@@ -962,7 +962,7 @@ def adjust_local_temp_var_storage(kernel):
 
             if min_mult != 1:
                 from warnings import warn
-                from loopy import LoopyAdvisory
+                from loopy.diagnostic import LoopyAdvisory
                 warn("could not find a conflict-free mem layout "
                         "for local variable '%s' "
                         "(currently: %dx conflict, increment: %s, reason: %s)"
diff --git a/loopy/schedule.py b/loopy/schedule.py
index 3bcf975d9..75fa263fb 100644
--- a/loopy/schedule.py
+++ b/loopy/schedule.py
@@ -830,7 +830,7 @@ def generate_loop_schedules(kernel, debug_args={}):
             gen_sched, owed_barriers = insert_barriers(kernel, gen_sched)
             if owed_barriers:
                 from warnings import warn
-                from loopy import LoopyAdvisory
+                from loopy.diagnostic import LoopyAdvisory
                 warn("Barrier insertion finished without inserting barriers for "
                         "local memory writes in these instructions: '%s'. "
                         "This often means that local memory was "
-- 
GitLab